mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	Merge branch 'master' into archive.display
This commit is contained in:
		
						commit
						09bd67f1f1
					
				
							
								
								
									
										6
									
								
								frontend/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								frontend/.gitignore
									
									
									
									
										vendored
									
									
								
							@ -29,6 +29,7 @@ build/Release
 | 
				
			|||||||
# Dependency directories
 | 
					# Dependency directories
 | 
				
			||||||
node_modules
 | 
					node_modules
 | 
				
			||||||
jspm_packages
 | 
					jspm_packages
 | 
				
			||||||
 | 
					package-lock.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Optional npm cache directory
 | 
					# Optional npm cache directory
 | 
				
			||||||
.npm
 | 
					.npm
 | 
				
			||||||
@ -40,3 +41,8 @@ typings/
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Built
 | 
					# Built
 | 
				
			||||||
dist
 | 
					dist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# IDE
 | 
				
			||||||
 | 
					.idea/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.DS_Store
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 | 
				
			|||||||
The latest version of this document is always available in
 | 
					The latest version of this document is always available in
 | 
				
			||||||
[releases][releases-url].
 | 
					[releases][releases-url].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [3.0.0-alpha.8]
 | 
				
			||||||
 | 
					- feat(timestamps): Make formatting of timestamps configurable. 
 | 
				
			||||||
 | 
					- fix(package): Update react-mdl to version 1.11.0
 | 
				
			||||||
 | 
					- fix(package): update normalize.css to version 8.0.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## [3.0.0-alpha.7] 
 | 
					## [3.0.0-alpha.7] 
 | 
				
			||||||
- Move metrics poller to seperate class
 | 
					- Move metrics poller to seperate class
 | 
				
			||||||
- Bugfix: CreatedAt set when creating new toggle
 | 
					- Bugfix: CreatedAt set when creating new toggle
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "unleash-frontend",
 | 
					  "name": "unleash-frontend",
 | 
				
			||||||
  "description": "unleash your features",
 | 
					  "description": "unleash your features",
 | 
				
			||||||
  "version": "3.0.0-alpha.7",
 | 
					  "version": "3.0.0-alpha.8",
 | 
				
			||||||
  "keywords": [
 | 
					  "keywords": [
 | 
				
			||||||
    "unleash",
 | 
					    "unleash",
 | 
				
			||||||
    "feature toggle",
 | 
					    "feature toggle",
 | 
				
			||||||
@ -32,6 +32,7 @@
 | 
				
			|||||||
    "start": "NODE_ENV=development webpack-dev-server --progress --colors",
 | 
					    "start": "NODE_ENV=development webpack-dev-server --progress --colors",
 | 
				
			||||||
    "start:heroku": "UNLEASH_API=http://unleash.herokuapp.com npm run start",
 | 
					    "start:heroku": "UNLEASH_API=http://unleash.herokuapp.com npm run start",
 | 
				
			||||||
    "lint": "eslint . --ext js,jsx",
 | 
					    "lint": "eslint . --ext js,jsx",
 | 
				
			||||||
 | 
					    "lint:fix": "eslint . --ext js,jsx --fix",
 | 
				
			||||||
    "test": "jest",
 | 
					    "test": "jest",
 | 
				
			||||||
    "test:ci": "npm run lint && npm run build && npm run test",
 | 
					    "test:ci": "npm run lint && npm run build && npm run test",
 | 
				
			||||||
    "prepublish": "npm run build"
 | 
					    "prepublish": "npm run build"
 | 
				
			||||||
@ -40,13 +41,13 @@
 | 
				
			|||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "debug": "^3.1.0",
 | 
					    "debug": "^3.1.0",
 | 
				
			||||||
    "immutable": "^3.8.1",
 | 
					    "immutable": "^3.8.1",
 | 
				
			||||||
    "normalize.css": "^7.0.0",
 | 
					    "normalize.css": "^8.0.0",
 | 
				
			||||||
    "prop-types": "^15.5.10",
 | 
					    "prop-types": "^15.5.10",
 | 
				
			||||||
    "react": "^15.6.1",
 | 
					    "react": "^15.6.1",
 | 
				
			||||||
    "react-dnd": "^2.1.4",
 | 
					    "react-dnd": "^2.1.4",
 | 
				
			||||||
    "react-dnd-html5-backend": "^2.1.2",
 | 
					    "react-dnd-html5-backend": "^2.1.2",
 | 
				
			||||||
    "react-dom": "^15.6.1",
 | 
					    "react-dom": "^15.6.1",
 | 
				
			||||||
    "react-mdl": "^1.9.0",
 | 
					    "react-mdl": "^1.11.0",
 | 
				
			||||||
    "react-modal": "^1.6.4",
 | 
					    "react-modal": "^1.6.4",
 | 
				
			||||||
    "react-redux": "^4.4.5",
 | 
					    "react-redux": "^4.4.5",
 | 
				
			||||||
    "react-router": "^3.0.0",
 | 
					    "react-router": "^3.0.0",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								frontend/public/en-GB.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								frontend/public/en-GB.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 72 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/nb-NO.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								frontend/public/nb-NO.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 3.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/unknown-locale.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								frontend/public/unknown-locale.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 15 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/unknown-user.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								frontend/public/unknown-user.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 5.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/us-US.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								frontend/public/us-US.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 18 KiB  | 
@ -21,7 +21,7 @@ import {
 | 
				
			|||||||
    Switch,
 | 
					    Switch,
 | 
				
			||||||
} from 'react-mdl';
 | 
					} from 'react-mdl';
 | 
				
			||||||
import { IconLink, shorten, styles as commonStyles } from '../common';
 | 
					import { IconLink, shorten, styles as commonStyles } from '../common';
 | 
				
			||||||
import { formatFullDateTime } from '../common/util';
 | 
					import { formatFullDateTimeWithLocale } from '../common/util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StatefulTextfield extends Component {
 | 
					class StatefulTextfield extends Component {
 | 
				
			||||||
    static propTypes = {
 | 
					    static propTypes = {
 | 
				
			||||||
@ -59,6 +59,7 @@ class ClientApplications extends PureComponent {
 | 
				
			|||||||
        fetchApplication: PropTypes.func.isRequired,
 | 
					        fetchApplication: PropTypes.func.isRequired,
 | 
				
			||||||
        appName: PropTypes.string,
 | 
					        appName: PropTypes.string,
 | 
				
			||||||
        application: PropTypes.object,
 | 
					        application: PropTypes.object,
 | 
				
			||||||
 | 
					        location: PropTypes.object,
 | 
				
			||||||
        storeApplicationMetaData: PropTypes.func.isRequired,
 | 
					        storeApplicationMetaData: PropTypes.func.isRequired,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -70,7 +71,9 @@ class ClientApplications extends PureComponent {
 | 
				
			|||||||
    componentDidMount() {
 | 
					    componentDidMount() {
 | 
				
			||||||
        this.props.fetchApplication(this.props.appName);
 | 
					        this.props.fetchApplication(this.props.appName);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    formatFullDateTime(v) {
 | 
				
			||||||
 | 
					        return formatFullDateTimeWithLocale(v, this.props.location.locale);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
        if (!this.props.application) {
 | 
					        if (!this.props.application) {
 | 
				
			||||||
            return <ProgressBar indeterminate />;
 | 
					            return <ProgressBar indeterminate />;
 | 
				
			||||||
@ -142,7 +145,8 @@ class ClientApplications extends PureComponent {
 | 
				
			|||||||
                                        icon="timeline"
 | 
					                                        icon="timeline"
 | 
				
			||||||
                                        subtitle={
 | 
					                                        subtitle={
 | 
				
			||||||
                                            <span>
 | 
					                                            <span>
 | 
				
			||||||
                                                {clientIp} last seen at <small>{formatFullDateTime(lastSeen)}</small>
 | 
					                                                {clientIp} last seen at{' '}
 | 
				
			||||||
 | 
					                                                <small>{this.formatFullDateTime(lastSeen)}</small>
 | 
				
			||||||
                                            </span>
 | 
					                                            </span>
 | 
				
			||||||
                                        }
 | 
					                                        }
 | 
				
			||||||
                                    >
 | 
					                                    >
 | 
				
			||||||
 | 
				
			|||||||
@ -4,11 +4,13 @@ import { fetchApplication, storeApplicationMetaData } from '../../store/applicat
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const mapStateToProps = (state, props) => {
 | 
					const mapStateToProps = (state, props) => {
 | 
				
			||||||
    let application = state.applications.getIn(['apps', props.appName]);
 | 
					    let application = state.applications.getIn(['apps', props.appName]);
 | 
				
			||||||
 | 
					    const location = state.settings.toJS().location || {};
 | 
				
			||||||
    if (application) {
 | 
					    if (application) {
 | 
				
			||||||
        application = application.toJS();
 | 
					        application = application.toJS();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
        application,
 | 
					        application,
 | 
				
			||||||
 | 
					        location,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,17 @@
 | 
				
			|||||||
import { formatFullDateTime } from '../util';
 | 
					import { formatFullDateTimeWithLocale } from '../util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test('formats dates correctly', () => {
 | 
					test('formats dates correctly', () => {
 | 
				
			||||||
    expect(formatFullDateTime(1487861809466)).toEqual('2017-02-23 14:56:49');
 | 
					    expect(formatFullDateTimeWithLocale(1487861809466, 'nb-NO', 'UTC')).toEqual('2017-02-23 14:56:49');
 | 
				
			||||||
    expect(formatFullDateTime(1487232809466)).toEqual('2017-02-16 08:13:29');
 | 
					    expect(formatFullDateTimeWithLocale(1487861809466, 'nb-NO', 'Europe/Paris')).toEqual('2017-02-23 15:56:49');
 | 
				
			||||||
    expect(formatFullDateTime(1477232809466)).toEqual('2016-10-23 14:26:49');
 | 
					    expect(formatFullDateTimeWithLocale(1487861809466, 'nb-NO', 'Europe/Oslo')).toEqual('2017-02-23 15:56:49');
 | 
				
			||||||
 | 
					    expect(formatFullDateTimeWithLocale(1487861809466, 'nb-NO', 'Europe/London')).toEqual('2017-02-23 14:56:49');
 | 
				
			||||||
 | 
					    expect(formatFullDateTimeWithLocale(1487861809466, 'en-GB', 'Europe/Paris')).toEqual('02/23/2017, 3:56:49 PM');
 | 
				
			||||||
 | 
					    expect(formatFullDateTimeWithLocale(1487861809466, 'en-GB', 'Europe/Oslo')).toEqual('02/23/2017, 3:56:49 PM');
 | 
				
			||||||
 | 
					    expect(formatFullDateTimeWithLocale(1487861809466, 'en-GB', 'Europe/London')).toEqual('02/23/2017, 2:56:49 PM');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(formatFullDateTimeWithLocale(1487861809466, 'nb-NO')).toEqual(
 | 
				
			||||||
 | 
					        expect.stringMatching(/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/)
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    expect(formatFullDateTimeWithLocale(1487861809466, 'en-GB')).toEqual(expect.stringContaining('02/23/2017'));
 | 
				
			||||||
 | 
					    expect(formatFullDateTimeWithLocale(1487861809466, 'en-US')).toEqual(expect.stringContaining('02/23/2017'));
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
@ -6,5 +6,9 @@ const dateTimeOptions = {
 | 
				
			|||||||
    minute: '2-digit',
 | 
					    minute: '2-digit',
 | 
				
			||||||
    second: '2-digit',
 | 
					    second: '2-digit',
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					export const formatFullDateTimeWithLocale = (v, locale, tz) => {
 | 
				
			||||||
export const formatFullDateTime = v => new Date(v).toLocaleString('nb-NO', dateTimeOptions);
 | 
					    if (tz) {
 | 
				
			||||||
 | 
					        dateTimeOptions.timeZone = tz;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return new Date(v).toLocaleString(locale, dateTimeOptions);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ import { Grid, Cell, Icon, Chip, ChipContact } from 'react-mdl';
 | 
				
			|||||||
import Progress from './progress';
 | 
					import Progress from './progress';
 | 
				
			||||||
import { Link } from 'react-router';
 | 
					import { Link } from 'react-router';
 | 
				
			||||||
import { AppsLinkList, calc } from '../common';
 | 
					import { AppsLinkList, calc } from '../common';
 | 
				
			||||||
import { formatFullDateTime } from '../common/util';
 | 
					import { formatFullDateTimeWithLocale } from '../common/util';
 | 
				
			||||||
import styles from './metrics.scss';
 | 
					import styles from './metrics.scss';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const StrategyChipItem = ({ strategy }) => (
 | 
					const StrategyChipItem = ({ strategy }) => (
 | 
				
			||||||
@ -38,13 +38,16 @@ export default class MetricComponent extends React.Component {
 | 
				
			|||||||
        featureToggle: PropTypes.object.isRequired,
 | 
					        featureToggle: PropTypes.object.isRequired,
 | 
				
			||||||
        fetchSeenApps: PropTypes.func.isRequired,
 | 
					        fetchSeenApps: PropTypes.func.isRequired,
 | 
				
			||||||
        fetchFeatureMetrics: PropTypes.func.isRequired,
 | 
					        fetchFeatureMetrics: PropTypes.func.isRequired,
 | 
				
			||||||
 | 
					        location: PropTypes.object,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    componentWillMount() {
 | 
					    componentWillMount() {
 | 
				
			||||||
        this.props.fetchSeenApps();
 | 
					        this.props.fetchSeenApps();
 | 
				
			||||||
        this.props.fetchFeatureMetrics();
 | 
					        this.props.fetchFeatureMetrics();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    formatFullDateTime(v) {
 | 
				
			||||||
 | 
					        return formatFullDateTimeWithLocale(v, this.props.location.locale);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
        const { metrics = {}, featureToggle } = this.props;
 | 
					        const { metrics = {}, featureToggle } = this.props;
 | 
				
			||||||
        const {
 | 
					        const {
 | 
				
			||||||
@ -107,7 +110,7 @@ export default class MetricComponent extends React.Component {
 | 
				
			|||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
                        )}
 | 
					                        )}
 | 
				
			||||||
                        <AppsLinkList apps={seenApps} />
 | 
					                        <AppsLinkList apps={seenApps} />
 | 
				
			||||||
                        <span>Created {formatFullDateTime(featureToggle.createdAt)}</span>
 | 
					                        <span>Created {this.formatFullDateTime(featureToggle.createdAt)}</span>
 | 
				
			||||||
                    </Cell>
 | 
					                    </Cell>
 | 
				
			||||||
                </Grid>
 | 
					                </Grid>
 | 
				
			||||||
                <hr />
 | 
					                <hr />
 | 
				
			||||||
 | 
				
			|||||||
@ -23,6 +23,7 @@ function getMetricsForToggle(state, toggleName) {
 | 
				
			|||||||
export default connect(
 | 
					export default connect(
 | 
				
			||||||
    (state, props) => ({
 | 
					    (state, props) => ({
 | 
				
			||||||
        metrics: getMetricsForToggle(state, props.featureToggle.name),
 | 
					        metrics: getMetricsForToggle(state, props.featureToggle.name),
 | 
				
			||||||
 | 
					        location: state.settings.toJS().location || {},
 | 
				
			||||||
    }),
 | 
					    }),
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        fetchFeatureMetrics,
 | 
					        fetchFeatureMetrics,
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ import HistoryItemDiff from './history-item-diff';
 | 
				
			|||||||
import HistoryItemJson from './history-item-json';
 | 
					import HistoryItemJson from './history-item-json';
 | 
				
			||||||
import { Table, TableHeader } from 'react-mdl';
 | 
					import { Table, TableHeader } from 'react-mdl';
 | 
				
			||||||
import { DataTableHeader, SwitchWithLabel, styles as commonStyles } from '../common';
 | 
					import { DataTableHeader, SwitchWithLabel, styles as commonStyles } from '../common';
 | 
				
			||||||
import { formatFullDateTime } from '../common/util';
 | 
					import { formatFullDateTimeWithLocale } from '../common/util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import styles from './history.scss';
 | 
					import styles from './history.scss';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -13,13 +13,16 @@ class HistoryList extends Component {
 | 
				
			|||||||
        title: PropTypes.string,
 | 
					        title: PropTypes.string,
 | 
				
			||||||
        history: PropTypes.array,
 | 
					        history: PropTypes.array,
 | 
				
			||||||
        settings: PropTypes.object,
 | 
					        settings: PropTypes.object,
 | 
				
			||||||
 | 
					        location: PropTypes.object,
 | 
				
			||||||
        updateSetting: PropTypes.func.isRequired,
 | 
					        updateSetting: PropTypes.func.isRequired,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    toggleShowDiff() {
 | 
					    toggleShowDiff() {
 | 
				
			||||||
        this.props.updateSetting('showData', !this.props.settings.showData);
 | 
					        this.props.updateSetting('showData', !this.props.settings.showData);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    formatFulldateTime(v) {
 | 
				
			||||||
 | 
					        return formatFullDateTimeWithLocale(v, this.props.location.locale);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
        const showData = this.props.settings.showData;
 | 
					        const showData = this.props.settings.showData;
 | 
				
			||||||
        const { history } = this.props;
 | 
					        const { history } = this.props;
 | 
				
			||||||
@ -62,7 +65,12 @@ class HistoryList extends Component {
 | 
				
			|||||||
                        User
 | 
					                        User
 | 
				
			||||||
                    </TableHeader>
 | 
					                    </TableHeader>
 | 
				
			||||||
                    <TableHeader name="diff">Diff</TableHeader>
 | 
					                    <TableHeader name="diff">Diff</TableHeader>
 | 
				
			||||||
                    <TableHeader numeric name="createdAt" cellFormatter={formatFullDateTime} style={{ width: '165px' }}>
 | 
					                    <TableHeader
 | 
				
			||||||
 | 
					                        numeric
 | 
				
			||||||
 | 
					                        name="createdAt"
 | 
				
			||||||
 | 
					                        cellFormatter={this.formatFulldateTime.bind(this)}
 | 
				
			||||||
 | 
					                        style={{ width: '165px' }}
 | 
				
			||||||
 | 
					                    >
 | 
				
			||||||
                        Time
 | 
					                        Time
 | 
				
			||||||
                    </TableHeader>
 | 
					                    </TableHeader>
 | 
				
			||||||
                </Table>
 | 
					                </Table>
 | 
				
			||||||
 | 
				
			|||||||
@ -4,9 +4,10 @@ import { updateSettingForGroup } from '../../store/settings/actions';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const mapStateToProps = state => {
 | 
					const mapStateToProps = state => {
 | 
				
			||||||
    const settings = state.settings.toJS().history || {};
 | 
					    const settings = state.settings.toJS().history || {};
 | 
				
			||||||
 | 
					    const location = state.settings.toJS().location || {};
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
        settings,
 | 
					        settings,
 | 
				
			||||||
 | 
					        location,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -5,19 +5,51 @@ import styles from './user.scss';
 | 
				
			|||||||
export default class ShowUserComponent extends React.Component {
 | 
					export default class ShowUserComponent extends React.Component {
 | 
				
			||||||
    static propTypes = {
 | 
					    static propTypes = {
 | 
				
			||||||
        profile: PropTypes.object,
 | 
					        profile: PropTypes.object,
 | 
				
			||||||
 | 
					        location: PropTypes.object,
 | 
				
			||||||
        fetchUser: PropTypes.func.isRequired,
 | 
					        fetchUser: PropTypes.func.isRequired,
 | 
				
			||||||
 | 
					        updateSettingLocation: PropTypes.func.isRequired,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					    possibleLocales = [
 | 
				
			||||||
 | 
					        { value: 'nb-NO', image: 'nb-NO' },
 | 
				
			||||||
 | 
					        { value: 'us-US', image: 'us-US' },
 | 
				
			||||||
 | 
					        { value: 'en-GB', image: 'en-GB' },
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    componentDidMount() {
 | 
					    componentDidMount() {
 | 
				
			||||||
        this.props.fetchUser();
 | 
					        this.props.fetchUser();
 | 
				
			||||||
 | 
					        // find default locale and add it in choices if not present
 | 
				
			||||||
 | 
					        let locale = navigator.language;
 | 
				
			||||||
 | 
					        let found = this.possibleLocales.find(l => l.value === locale);
 | 
				
			||||||
 | 
					        if (!found) {
 | 
				
			||||||
 | 
					            this.possibleLocales.push({ value: locale, image: 'unknown-locale' });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    updateLocale() {
 | 
				
			||||||
 | 
					        const locale = this.props.location
 | 
				
			||||||
 | 
					            ? this.props.location.locale
 | 
				
			||||||
 | 
					            : this.possibleLocales[this.possibleLocales.length - 1];
 | 
				
			||||||
 | 
					        let index = this.possibleLocales.findIndex(v => v.value === locale);
 | 
				
			||||||
 | 
					        index = (index + 1) % this.possibleLocales.length;
 | 
				
			||||||
 | 
					        this.props.updateSettingLocation('locale', this.possibleLocales[index].value);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
        const email = this.props.profile ? this.props.profile.email : '';
 | 
					        const email = this.props.profile ? this.props.profile.email : '';
 | 
				
			||||||
        const imageUrl = email ? this.props.profile.imageUrl : '';
 | 
					        const locale = this.props.location
 | 
				
			||||||
 | 
					            ? this.props.location.locale
 | 
				
			||||||
 | 
					            : this.possibleLocales[this.possibleLocales.length - 1].value;
 | 
				
			||||||
 | 
					        let foundLocale = this.possibleLocales.find(l => l.value === locale);
 | 
				
			||||||
 | 
					        const imageUrl = email ? this.props.profile.imageUrl : 'public/unknown-user.png';
 | 
				
			||||||
 | 
					        const imageLocale = foundLocale ? `public/${foundLocale.image}.png` : `public/unknown-locale.png`;
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <div className={styles.showUser}>
 | 
					            <div className={styles.showUserSettings}>
 | 
				
			||||||
                <img src={imageUrl} title={email} alt={email} />
 | 
					                <div className={styles.showLocale}>
 | 
				
			||||||
 | 
					                    <img src={imageLocale} title={locale} alt={locale} onClick={this.updateLocale.bind(this)} />
 | 
				
			||||||
 | 
					                </div> 
 | 
				
			||||||
 | 
					                <div className={styles.showUser}>
 | 
				
			||||||
 | 
					                    <img src={imageUrl} title={email} alt={email} />
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,13 +1,16 @@
 | 
				
			|||||||
import { connect } from 'react-redux';
 | 
					import { connect } from 'react-redux';
 | 
				
			||||||
import ShowUserComponent from './show-user-component';
 | 
					import ShowUserComponent from './show-user-component';
 | 
				
			||||||
import { fetchUser } from '../../store/user/actions';
 | 
					import { fetchUser } from '../../store/user/actions';
 | 
				
			||||||
 | 
					import { updateSettingForGroup } from '../../store/settings/actions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const mapDispatchToProps = {
 | 
					const mapDispatchToProps = {
 | 
				
			||||||
    fetchUser,
 | 
					    fetchUser,
 | 
				
			||||||
 | 
					    updateSettingLocation: updateSettingForGroup('location'),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const mapStateToProps = state => ({
 | 
					const mapStateToProps = state => ({
 | 
				
			||||||
    profile: state.user.get('profile'),
 | 
					    profile: state.user.get('profile'),
 | 
				
			||||||
 | 
					    location: state.settings ? state.settings.toJS().location : {},
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default connect(mapStateToProps, mapDispatchToProps)(ShowUserComponent);
 | 
					export default connect(mapStateToProps, mapDispatchToProps)(ShowUserComponent);
 | 
				
			||||||
 | 
				
			|||||||
@ -2,4 +2,15 @@
 | 
				
			|||||||
    border-radius: 25px;
 | 
					    border-radius: 25px;
 | 
				
			||||||
    height: 32px;
 | 
					    height: 32px;
 | 
				
			||||||
    border: 2px solid #ffffff;
 | 
					    border: 2px solid #ffffff;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.showLocale img {
 | 
				
			||||||
 | 
					    border-radius: 2px;
 | 
				
			||||||
 | 
					    height: 30px;
 | 
				
			||||||
 | 
					    margin: 0 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.showUserSettings {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4271,9 +4271,9 @@ normalize-url@^1.4.0:
 | 
				
			|||||||
    query-string "^4.1.0"
 | 
					    query-string "^4.1.0"
 | 
				
			||||||
    sort-keys "^1.0.0"
 | 
					    sort-keys "^1.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
normalize.css@^7.0.0:
 | 
					normalize.css@^8.0.0:
 | 
				
			||||||
  version "7.0.0"
 | 
					  version "8.0.0"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-7.0.0.tgz#abfb1dd82470674e0322b53ceb1aaf412938e4bf"
 | 
					  resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-8.0.0.tgz#14ac5e461612538a4ce9be90a7da23f86e718493"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
npm-run-path@^2.0.0:
 | 
					npm-run-path@^2.0.0:
 | 
				
			||||||
  version "2.0.2"
 | 
					  version "2.0.2"
 | 
				
			||||||
@ -5035,9 +5035,9 @@ react-dom@^15.6.1:
 | 
				
			|||||||
    object-assign "^4.1.0"
 | 
					    object-assign "^4.1.0"
 | 
				
			||||||
    prop-types "^15.5.10"
 | 
					    prop-types "^15.5.10"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
react-mdl@^1.9.0:
 | 
					react-mdl@^1.11.0:
 | 
				
			||||||
  version "1.10.3"
 | 
					  version "1.11.0"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/react-mdl/-/react-mdl-1.10.3.tgz#f783e26a5eea4154a32129ab2562c09d5eeacf0d"
 | 
					  resolved "https://registry.yarnpkg.com/react-mdl/-/react-mdl-1.11.0.tgz#7e07ee1009dd9b358b616dc400ff2ae1845a2e67"
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    clamp "^1.0.1"
 | 
					    clamp "^1.0.1"
 | 
				
			||||||
    classnames "^2.2.3"
 | 
					    classnames "^2.2.3"
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user