diff --git a/frontend/src/component/app.jsx b/frontend/src/component/app.jsx index a905082e31..4fe0b65bc0 100644 --- a/frontend/src/component/app.jsx +++ b/frontend/src/component/app.jsx @@ -112,7 +112,7 @@ export default class App extends Component { return [0, 0]; } }; - const createListItem = (path, caption, icon, isDrawerNavigation = false, isAnchor = false) => { + const createListItem = (path, caption, icon, isDrawerNavigation = false) => { const linkColor = isDrawerNavigation && this.context.router.isActive(path) ? 'mdl-color-text--black' @@ -127,15 +127,7 @@ export default class App extends Component { className={isDrawerNavigation ? [styles.navigationIcon, iconColor].join(' ') : undefined} /> ); - return isAnchor ? ( - - {icon && renderIcon} - {caption} - - ) : ( + return (
@@ -197,7 +189,7 @@ export default class App extends Component { {createListItem('/history', 'Event History', '')} {createListItem('/archive', 'Archived Toggles', '')} {createListItem('/applications', 'Applications', '')} - Sign out + {createListItem('/logout', 'Sign out', '')} diff --git a/frontend/src/component/feature/list-component.jsx b/frontend/src/component/feature/list-component.jsx index 3b38518ddc..baf7777548 100644 --- a/frontend/src/component/feature/list-component.jsx +++ b/frontend/src/component/feature/list-component.jsx @@ -1,9 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import Feature from './feature-list-item-component'; -import { Link } from 'react-router'; +import { hashHistory, Link } from 'react-router'; import { Icon, FABButton, Textfield, Menu, MenuItem, Card, CardActions, List } from 'react-mdl'; - import { MenuItemWithIcon, DropdownButton, styles as commonStyles } from '../common'; import styles from './feature.scss'; @@ -13,6 +12,8 @@ export default class FeatureListComponent extends React.Component { featureMetrics: PropTypes.object.isRequired, fetchFeatureToggles: PropTypes.func, fetchArchive: PropTypes.func, + logoutUser: PropTypes.func, + logout: PropTypes.bool, revive: PropTypes.func, updateSetting: PropTypes.func.isRequired, toggleFeature: PropTypes.func, @@ -24,6 +25,10 @@ export default class FeatureListComponent extends React.Component { }; componentDidMount() { + if (this.props.logout) { + this.props.logoutUser(); + hashHistory.push(`/`); + } if (this.props.fetchFeatureToggles) { this.props.fetchFeatureToggles(); } else { diff --git a/frontend/src/component/feature/list-container.jsx b/frontend/src/component/feature/list-container.jsx index 3ca68741f1..65b9128ff2 100644 --- a/frontend/src/component/feature/list-container.jsx +++ b/frontend/src/component/feature/list-container.jsx @@ -3,6 +3,7 @@ import { toggleFeature, fetchFeatureToggles } from '../../store/feature-actions' import { updateSettingForGroup } from '../../store/settings/actions'; import FeatureListComponent from './list-component'; +import { logoutUser } from '../../store/user/actions'; export const mapStateToPropsConfigurable = isFeature => state => { const featureMetrics = state.featureMetrics.toJS(); @@ -71,6 +72,7 @@ export const mapStateToPropsConfigurable = isFeature => state => { }; const mapStateToProps = mapStateToPropsConfigurable(true); const mapDispatchToProps = { + logoutUser, toggleFeature, fetchFeatureToggles, updateSetting: updateSettingForGroup('feature'), diff --git a/frontend/src/data/user-api.js b/frontend/src/data/user-api.js index e2671ce8dc..ccab844390 100644 --- a/frontend/src/data/user-api.js +++ b/frontend/src/data/user-api.js @@ -2,6 +2,12 @@ import { throwIfNotSuccess, headers } from './helper'; const URI = 'api/admin/user'; +function logoutUser() { + return fetch(`${URI}/logout`, { method: 'GET', credentials: 'include' }) + .then(throwIfNotSuccess) + .then(response => response.json()); +} + function fetchUser() { return fetch(URI, { credentials: 'include' }) .then(throwIfNotSuccess) @@ -17,4 +23,5 @@ function unsecureLogin(path, user) { export default { fetchUser, unsecureLogin, + logoutUser, }; diff --git a/frontend/src/index.jsx b/frontend/src/index.jsx index 8e2000a9cd..188f331cce 100644 --- a/frontend/src/index.jsx +++ b/frontend/src/index.jsx @@ -26,6 +26,7 @@ import Archive from './page/archive'; import ShowArchive from './page/archive/show'; import Applications from './page/applications'; import ApplicationView from './page/applications/view'; +import LogoutFeatures from './page/user/logout'; let composeEnhancers; @@ -76,6 +77,9 @@ ReactDOM.render( + + + , diff --git a/frontend/src/page/user/logout.js b/frontend/src/page/user/logout.js new file mode 100644 index 0000000000..d2b3217548 --- /dev/null +++ b/frontend/src/page/user/logout.js @@ -0,0 +1,6 @@ +import React from 'react'; +import FeatureListContainer from './../../component/feature/list-container'; + +const render = () => ; + +export default render; diff --git a/frontend/src/store/user/actions.js b/frontend/src/store/user/actions.js index c52ca50c27..ba8cf0a852 100644 --- a/frontend/src/store/user/actions.js +++ b/frontend/src/store/user/actions.js @@ -36,3 +36,7 @@ export function unsecureLogin(path, user) { .catch(handleError); }; } + +export function logoutUser() { + return () => api.logoutUser().catch(handleError); +}