From 67bdb166592630619b799d51cd70b8843f78a91e Mon Sep 17 00:00:00 2001 From: ivaosthu Date: Thu, 24 Nov 2016 21:32:29 +0100 Subject: [PATCH 1/2] Show a dialog if the username cookie is not set. This is used by unleash server to show who changes what. By making this a required input allow us to make sure it is always set. --- frontend/src/component/app.jsx | 3 + .../src/component/user/user-component.jsx | 49 ++++++++++++++++ .../src/component/user/user-container.jsx | 15 +++++ frontend/src/store/index.js | 2 + frontend/src/store/user/actions.js | 11 ++++ frontend/src/store/user/index.js | 57 +++++++++++++++++++ 6 files changed, 137 insertions(+) create mode 100644 frontend/src/component/user/user-component.jsx create mode 100644 frontend/src/component/user/user-container.jsx create mode 100644 frontend/src/store/user/actions.js create mode 100644 frontend/src/store/user/index.js diff --git a/frontend/src/component/app.jsx b/frontend/src/component/app.jsx index 34f65038f4..5245e9dd3b 100644 --- a/frontend/src/component/app.jsx +++ b/frontend/src/component/app.jsx @@ -3,6 +3,8 @@ import { Layout, Panel, NavDrawer, AppBar } from 'react-toolbox'; import style from './styles.scss'; import ErrorContainer from './error/error-container'; +import UserContainer from './user/user-container'; + import Navigation from './nav'; export default class App extends Component { @@ -28,6 +30,7 @@ export default class App extends Component {
+ {this.props.children}
diff --git a/frontend/src/component/user/user-component.jsx b/frontend/src/component/user/user-component.jsx new file mode 100644 index 0000000000..a29fd59c69 --- /dev/null +++ b/frontend/src/component/user/user-component.jsx @@ -0,0 +1,49 @@ +import React, { PropTypes } from 'react'; +import Dialog from 'react-toolbox/lib/dialog'; +import Input from 'react-toolbox/lib/input'; + +class ErrorComponent extends React.Component { + static propTypes () { + return { + user: PropTypes.object.isRequired, + updateUserName: PropTypes.func.isRequired, + }; + } + + handleSubmit = (evt) => { + evt.preventDefault(); + this.props.save(); + } + + render () { + const actions = [ + { label: 'Save', onClick: this.props.save }, + ]; + + return ( + + +

+ You hav to specify a username to use Unleash. This will allow us to track changes. +

+
+ this.props.updateUserName(v)} + /> +
+ +
+ ); + } +} + +export default ErrorComponent; diff --git a/frontend/src/component/user/user-container.jsx b/frontend/src/component/user/user-container.jsx new file mode 100644 index 0000000000..6723a4a879 --- /dev/null +++ b/frontend/src/component/user/user-container.jsx @@ -0,0 +1,15 @@ +import { connect } from 'react-redux'; +import UserComponent from './user-component'; +import { updateUserName, save } from '../../store/user/actions'; + + +const mapDispatchToProps = { + updateUserName, + save, +}; + +const mapStateToProps = (state) => ({ + user: state.user.toJS(), +}); + +export default connect(mapStateToProps, mapDispatchToProps)(UserComponent); diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js index 8e75abe331..4b5025fa25 100644 --- a/frontend/src/store/index.js +++ b/frontend/src/store/index.js @@ -10,6 +10,7 @@ import metrics from './metrics-store'; import clientStrategies from './client-strategy-store'; import clientInstances from './client-instance-store'; import settings from './settings'; +import user from './user'; const unleashStore = combineReducers({ features, @@ -23,6 +24,7 @@ const unleashStore = combineReducers({ clientStrategies, clientInstances, settings, + user, }); export default unleashStore; diff --git a/frontend/src/store/user/actions.js b/frontend/src/store/user/actions.js new file mode 100644 index 0000000000..786df071da --- /dev/null +++ b/frontend/src/store/user/actions.js @@ -0,0 +1,11 @@ +export const USER_UPDATE_USERNAME = 'USER_UPDATE_USERNAME'; +export const USER_SAVE = 'USER_SAVE'; + +export const updateUserName = (value) => ({ + type: USER_UPDATE_USERNAME, + value, +}); + +export const save = () => ({ + type: USER_SAVE, +}); diff --git a/frontend/src/store/user/index.js b/frontend/src/store/user/index.js new file mode 100644 index 0000000000..c089abe067 --- /dev/null +++ b/frontend/src/store/user/index.js @@ -0,0 +1,57 @@ +import { Map as $Map } from 'immutable'; +import { USER_UPDATE_USERNAME, USER_SAVE } from './actions'; + +const COOKIE_NAME = 'username'; + +// Ref: http://stackoverflow.com/questions/10730362/get-cookie-by-name +function readCookie () { + const nameEQ = `${COOKIE_NAME}=`; + const ca = document.cookie.split(';'); + for (let i = 0;i < ca.length;i++) { + let c = ca[i]; + while (c.charAt(0) == ' ') { // eslint-disable-line eqeqeq + c = c.substring(1, c.length); + } + if (c.indexOf(nameEQ) === 0) { + return c.substring(nameEQ.length, c.length); + } + } +} + +function writeCookie (userName) { + document.cookie = `${COOKIE_NAME}=${userName}; expires=Thu, 18 Dec 2099 12:00:00 UTC`; +} + + +function getInitState () { + const userName = readCookie(COOKIE_NAME); + const showDialog = !userName; + return new $Map({ userName, showDialog }); +} + +function updateUserName (state, action) { + return state.set('userName', action.value); +} + +function save (state) { + const userName = state.get('userName'); + if (userName) { + writeCookie(userName); + return state.set('showDialog', false); + } else { + return state; + } +} + +const settingStore = (state = getInitState(), action) => { + switch (action.type) { + case USER_UPDATE_USERNAME: + return updateUserName(state, action); + case USER_SAVE: + return save(state); + default: + return state; + } +}; + +export default settingStore; From 6f8199a0141852ed5fdcc07ad31915ba7366c5a5 Mon Sep 17 00:00:00 2001 From: ivaosthu Date: Thu, 24 Nov 2016 21:45:22 +0100 Subject: [PATCH 2/2] fix linting --- frontend/src/component/user/user-component.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/component/user/user-component.jsx b/frontend/src/component/user/user-component.jsx index a29fd59c69..8da2763a47 100644 --- a/frontend/src/component/user/user-component.jsx +++ b/frontend/src/component/user/user-component.jsx @@ -40,7 +40,6 @@ class ErrorComponent extends React.Component { onChange={(v) => this.props.updateUserName(v)} /> - ); }