From 7e50ebbad9d1158ce997c42824531224c3c7ae27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Conradi=20=C3=98sthus?= Date: Mon, 10 Aug 2020 21:58:14 +0200 Subject: [PATCH] fix: some ux cleanup for toggle types --- .../feature-list-item-component-test.jsx.snap | 12 ++--------- .../list-component-test.jsx.snap | 2 ++ .../feature-list-item-component-test.jsx | 1 + .../feature/feature-list-item-component.jsx | 9 +++++---- .../feature/feature-type-component.jsx | 20 +++++++++++++++++++ .../feature/feature-type-container.jsx | 10 ++++++++++ .../src/component/feature/list-component.jsx | 7 ++++--- .../src/component/feature/list-container.jsx | 2 +- frontend/src/component/menu/header.jsx | 13 ++++-------- .../user/authentication-component.jsx | 9 +++------ .../user/authentication-container.jsx | 6 ++---- .../authentication-password-component.jsx | 6 ++---- .../user/authentication-simple-component.jsx | 6 ++---- frontend/src/store/loader.js | 11 ++++++++++ 14 files changed, 69 insertions(+), 45 deletions(-) create mode 100644 frontend/src/component/feature/feature-type-component.jsx create mode 100644 frontend/src/component/feature/feature-type-container.jsx create mode 100644 frontend/src/store/loader.js diff --git a/frontend/src/component/feature/__tests__/__snapshots__/feature-list-item-component-test.jsx.snap b/frontend/src/component/feature/__tests__/__snapshots__/feature-list-item-component-test.jsx.snap index f379b078d6..bcf0663e02 100644 --- a/frontend/src/component/feature/__tests__/__snapshots__/feature-list-item-component-test.jsx.snap +++ b/frontend/src/component/feature/__tests__/__snapshots__/feature-list-item-component-test.jsx.snap @@ -60,11 +60,7 @@ exports[`renders correctly with one feature 1`] = ` - - + /> `; @@ -128,11 +124,7 @@ exports[`renders correctly with one feature without permission 1`] = ` - - + /> `; diff --git a/frontend/src/component/feature/__tests__/__snapshots__/list-component-test.jsx.snap b/frontend/src/component/feature/__tests__/__snapshots__/list-component-test.jsx.snap index e445dfd8e7..e8573c6320 100644 --- a/frontend/src/component/feature/__tests__/__snapshots__/list-component-test.jsx.snap +++ b/frontend/src/component/feature/__tests__/__snapshots__/list-component-test.jsx.snap @@ -172,6 +172,7 @@ exports[`renders correctly with one feature 1`] = ` } } hasPermission={[Function]} + setFilter={[Function]} settings={ Object { "sort": "name", @@ -343,6 +344,7 @@ exports[`renders correctly with one feature without permissions 1`] = ` } } hasPermission={[Function]} + setFilter={[Function]} settings={ Object { "sort": "name", diff --git a/frontend/src/component/feature/__tests__/feature-list-item-component-test.jsx b/frontend/src/component/feature/__tests__/feature-list-item-component-test.jsx index f1fbc37825..add28bd054 100644 --- a/frontend/src/component/feature/__tests__/feature-list-item-component-test.jsx +++ b/frontend/src/component/feature/__tests__/feature-list-item-component-test.jsx @@ -6,6 +6,7 @@ import renderer from 'react-test-renderer'; import { UPDATE_FEATURE } from '../../../permissions'; jest.mock('react-mdl'); +jest.mock('../feature-type-container'); test('renders correctly with one feature', () => { const feature = { diff --git a/frontend/src/component/feature/feature-list-item-component.jsx b/frontend/src/component/feature/feature-list-item-component.jsx index 28cfe751a1..26eed3659a 100644 --- a/frontend/src/component/feature/feature-list-item-component.jsx +++ b/frontend/src/component/feature/feature-list-item-component.jsx @@ -1,12 +1,13 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Link } from 'react-router-dom'; -import { Switch, Chip, ListItem, ListItemAction, Icon } from 'react-mdl'; +import { Switch, ListItem, ListItemAction, Icon } from 'react-mdl'; import TimeAgo from 'react-timeago'; import Progress from './progress'; import { UPDATE_FEATURE } from '../../permissions'; import { calc, styles as commonStyles } from '../common'; -import StatusComponent from './status-component'; +import Status from './status-component'; +import FeatureType from './feature-type-container'; import styles from './feature.scss'; @@ -56,8 +57,8 @@ const Feature = ({ - - {type} + + {revive && hasPermission(UPDATE_FEATURE) ? ( revive(feature.name)}> diff --git a/frontend/src/component/feature/feature-type-component.jsx b/frontend/src/component/feature/feature-type-component.jsx new file mode 100644 index 0000000000..0d673e5a2f --- /dev/null +++ b/frontend/src/component/feature/feature-type-component.jsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { Chip } from 'react-mdl'; +import PropTypes from 'prop-types'; +import styles from './feature.scss'; + +export default function StatusComponent({ type, types, onClick }) { + const typeObject = types.find(o => o.id === type) || { id: type, name: type }; + + return ( + + {typeObject.name} + + ); +} + +StatusComponent.propTypes = { + type: PropTypes.string.isRequired, + types: PropTypes.array, + onClick: PropTypes.func, +}; diff --git a/frontend/src/component/feature/feature-type-container.jsx b/frontend/src/component/feature/feature-type-container.jsx new file mode 100644 index 0000000000..523506ed82 --- /dev/null +++ b/frontend/src/component/feature/feature-type-container.jsx @@ -0,0 +1,10 @@ +import { connect } from 'react-redux'; +import Component from './feature-type-component'; + +const mapStateToProps = state => ({ + types: state.featureTypes.toJS(), +}); + +const FeatureType = connect(mapStateToProps)(Component); + +export default FeatureType; diff --git a/frontend/src/component/feature/list-component.jsx b/frontend/src/component/feature/list-component.jsx index 12563228ce..2f664f0b9d 100644 --- a/frontend/src/component/feature/list-component.jsx +++ b/frontend/src/component/feature/list-component.jsx @@ -26,7 +26,7 @@ export default class FeatureListComponent extends React.Component { super(); this.state = { filter: props.settings.filter, - updateFilter: debounce(props.updateSetting.bind(this, 'filter'), 250), + updateFilter: debounce(props.updateSetting.bind(this, 'filter'), 150), }; } @@ -42,11 +42,11 @@ export default class FeatureListComponent extends React.Component { this.props.updateSetting('showLastHour', !this.props.settings.showLastHour); } - setFilter(v) { + setFilter = v => { const value = typeof v === 'string' ? v : ''; this.setState({ filter: value }); this.state.updateFilter(value); - } + }; setSort(v) { this.props.updateSetting('sort', typeof v === 'string' ? v.trim() : ''); @@ -138,6 +138,7 @@ export default class FeatureListComponent extends React.Component { toggleFeature={toggleFeature} revive={revive} hasPermission={hasPermission} + setFilter={this.setFilter} /> )) ) : ( diff --git a/frontend/src/component/feature/list-container.jsx b/frontend/src/component/feature/list-container.jsx index 47b5d6f9d6..b80db95cad 100644 --- a/frontend/src/component/feature/list-container.jsx +++ b/frontend/src/component/feature/list-container.jsx @@ -17,7 +17,7 @@ export const mapStateToPropsConfigurable = isFeature => state => { regex.test(feature.name) || regex.test(feature.description) || feature.strategies.some(s => s && s.name && regex.test(s.name)) || - regex.test(JSON.stringify(feature)) + (settings.filter.length > 1 && regex.test(JSON.stringify(feature))) ); } catch (e) { // Invalid filter regex diff --git a/frontend/src/component/menu/header.jsx b/frontend/src/component/menu/header.jsx index 67e2be7afd..b61eee69a7 100644 --- a/frontend/src/component/menu/header.jsx +++ b/frontend/src/component/menu/header.jsx @@ -6,20 +6,17 @@ import { Route } from 'react-router-dom'; import { DrawerMenu } from './drawer'; import Breadcrum from './breadcrumb'; import ShowUserContainer from '../user/show-user-container'; -import { fetchUIConfig } from './../../store/ui-config/actions'; -import { fetchContext } from './../../store/context/actions'; +import { loadInitalData } from './../../store/loader'; class HeaderComponent extends PureComponent { static propTypes = { uiConfig: PropTypes.object.isRequired, - fetchUIConfig: PropTypes.func.isRequired, - fetchContext: PropTypes.func.isRequired, + loadInitalData: PropTypes.func.isRequired, location: PropTypes.object.isRequired, }; componentDidMount() { - this.props.fetchUIConfig(); - this.props.fetchContext(); + this.props.loadInitalData(); } // eslint-disable-next-line camelcase @@ -53,6 +50,4 @@ class HeaderComponent extends PureComponent { } } -export default connect(state => ({ uiConfig: state.uiConfig.toJS() }), { fetchUIConfig, fetchContext })( - HeaderComponent -); +export default connect(state => ({ uiConfig: state.uiConfig.toJS() }), { loadInitalData })(HeaderComponent); diff --git a/frontend/src/component/user/authentication-component.jsx b/frontend/src/component/user/authentication-component.jsx index 260dc9c64e..470f9b8844 100644 --- a/frontend/src/component/user/authentication-component.jsx +++ b/frontend/src/component/user/authentication-component.jsx @@ -37,8 +37,7 @@ class AuthComponent extends React.Component { user: PropTypes.object.isRequired, unsecureLogin: PropTypes.func.isRequired, passwordLogin: PropTypes.func.isRequired, - fetchFeatureToggles: PropTypes.func.isRequired, - fetchUIConfig: PropTypes.func.isRequired, + loadInitalData: PropTypes.func.isRequired, history: PropTypes.object.isRequired, }; @@ -52,8 +51,7 @@ class AuthComponent extends React.Component { ); @@ -62,8 +60,7 @@ class AuthComponent extends React.Component { ); diff --git a/frontend/src/component/user/authentication-container.jsx b/frontend/src/component/user/authentication-container.jsx index 1dee4e0885..e62202f35f 100644 --- a/frontend/src/component/user/authentication-container.jsx +++ b/frontend/src/component/user/authentication-container.jsx @@ -1,14 +1,12 @@ import { connect } from 'react-redux'; import AuthenticationComponent from './authentication-component'; import { unsecureLogin, passwordLogin } from '../../store/user/actions'; -import { fetchFeatureToggles } from '../../store/feature-actions'; -import { fetchUIConfig } from '../../store/ui-config/actions'; +import { loadInitalData } from './../../store/loader'; const mapDispatchToProps = { unsecureLogin, passwordLogin, - fetchFeatureToggles, - fetchUIConfig, + loadInitalData, }; const mapStateToProps = state => ({ diff --git a/frontend/src/component/user/authentication-password-component.jsx b/frontend/src/component/user/authentication-password-component.jsx index e600baa82a..a81004829b 100644 --- a/frontend/src/component/user/authentication-password-component.jsx +++ b/frontend/src/component/user/authentication-password-component.jsx @@ -6,8 +6,7 @@ class EnterpriseAuthenticationComponent extends React.Component { static propTypes = { authDetails: PropTypes.object.isRequired, passwordLogin: PropTypes.func.isRequired, - fetchFeatureToggles: PropTypes.func.isRequired, - fetchUIConfig: PropTypes.func.isRequired, + loadInitalData: PropTypes.func.isRequired, history: PropTypes.object.isRequired, }; @@ -38,8 +37,7 @@ class EnterpriseAuthenticationComponent extends React.Component { try { await this.props.passwordLogin(path, user); - await this.props.fetchFeatureToggles(); - await this.props.fetchUIConfig(); + await this.props.loadInitalData(); this.props.history.push(`/`); } catch (error) { if (error.statusCode === 404) { diff --git a/frontend/src/component/user/authentication-simple-component.jsx b/frontend/src/component/user/authentication-simple-component.jsx index 58aa648b1c..76d69db45d 100644 --- a/frontend/src/component/user/authentication-simple-component.jsx +++ b/frontend/src/component/user/authentication-simple-component.jsx @@ -6,8 +6,7 @@ class SimpleAuthenticationComponent extends React.Component { static propTypes = { authDetails: PropTypes.object.isRequired, unsecureLogin: PropTypes.func.isRequired, - fetchFeatureToggles: PropTypes.func.isRequired, - fetchUIConfig: PropTypes.func.isRequired, + loadInitalData: PropTypes.func.isRequired, history: PropTypes.object.isRequired, }; @@ -19,8 +18,7 @@ class SimpleAuthenticationComponent extends React.Component { this.props .unsecureLogin(path, user) - .then(this.props.fetchFeatureToggles) - .then(this.props.fetchUIConfig) + .then(this.props.loadInitalData) .then(() => this.props.history.push(`/`)); }; diff --git a/frontend/src/store/loader.js b/frontend/src/store/loader.js new file mode 100644 index 0000000000..2aaad20d0b --- /dev/null +++ b/frontend/src/store/loader.js @@ -0,0 +1,11 @@ +import { fetchUIConfig } from './ui-config/actions'; +import { fetchContext } from './context/actions'; +import { fetchFeatureTypes } from './feature-type/actions'; + +export function loadInitalData() { + return dispatch => { + fetchUIConfig()(dispatch); + fetchContext()(dispatch); + fetchFeatureTypes()(dispatch); + }; +}