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);
+ };
+}