From 31398571b4df050754623129cea5747e8a534637 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Conradi=20=C3=98sthus?= Date: Fri, 25 Sep 2020 21:09:26 +0200 Subject: [PATCH] fix: show notification when app updates --- .../application-edit-component-test.js.snap | 11 ++++++++--- .../application-edit-component-test.js | 12 +++++++++--- .../application/application-edit-component.js | 17 ++++++++++++----- frontend/src/component/common/search-field.jsx | 4 ++-- .../__snapshots__/list-component-test.jsx.snap | 2 ++ frontend/src/store/application/actions.js | 7 ++++++- frontend/src/store/error-store.js | 3 +++ 7 files changed, 42 insertions(+), 14 deletions(-) diff --git a/frontend/src/component/application/__tests__/__snapshots__/application-edit-component-test.js.snap b/frontend/src/component/application/__tests__/__snapshots__/application-edit-component-test.js.snap index 5c43b94965..2f04a733d4 100644 --- a/frontend/src/component/application/__tests__/__snapshots__/application-edit-component-test.js.snap +++ b/frontend/src/component/application/__tests__/__snapshots__/application-edit-component-test.js.snap @@ -1,9 +1,14 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`renders correctly if no application 1`] = ` - +
+

+ Loading... +

+ +
`; exports[`renders correctly with permissions 1`] = ` diff --git a/frontend/src/component/application/__tests__/application-edit-component-test.js b/frontend/src/component/application/__tests__/application-edit-component-test.js index a2a8198394..cd3c82b968 100644 --- a/frontend/src/component/application/__tests__/application-edit-component-test.js +++ b/frontend/src/component/application/__tests__/application-edit-component-test.js @@ -11,9 +11,11 @@ test('renders correctly if no application', () => { const tree = renderer .create( Promise.resolve({})} storeApplicationMetaData={jest.fn()} + deleteApplication={jest.fn()} hasPermission={() => true} + history={{}} /> ) .toJSON(); @@ -26,8 +28,10 @@ test('renders correctly without permission', () => { .create( Promise.resolve({})} storeApplicationMetaData={jest.fn()} + deleteApplication={jest.fn()} + history={{}} application={{ appName: 'test-app', instances: [ @@ -80,8 +84,10 @@ test('renders correctly with permissions', () => { .create( Promise.resolve({})} storeApplicationMetaData={jest.fn()} + history={{}} + deleteApplication={jest.fn()} application={{ appName: 'test-app', instances: [ diff --git a/frontend/src/component/application/application-edit-component.js b/frontend/src/component/application/application-edit-component.js index 648593967a..41d63e9e90 100644 --- a/frontend/src/component/application/application-edit-component.js +++ b/frontend/src/component/application/application-edit-component.js @@ -21,13 +21,13 @@ class ClientApplications extends PureComponent { history: PropTypes.object.isRequired, }; - constructor() { + constructor(props) { super(); - this.state = { activeTab: 0 }; + this.state = { activeTab: 0, loading: !props.application }; } componentDidMount() { - this.props.fetchApplication(this.props.appName); + this.props.fetchApplication(this.props.appName).finally(() => this.setState({ loading: false })); } formatFullDateTime = v => formatFullDateTimeWithLocale(v, this.props.location.locale); @@ -39,8 +39,15 @@ class ClientApplications extends PureComponent { }; render() { - if (!this.props.application) { - return ; + if (this.state.loading) { + return ( +
+

Loading...

+ +
+ ); + } else if (!this.props.application) { + return

Application ({this.props.appName}) not found

; } const { application, storeApplicationMetaData, hasPermission } = this.props; const { appName, instances, strategies, seenToggles, url, description, icon = 'apps' } = application; diff --git a/frontend/src/component/common/search-field.jsx b/frontend/src/component/common/search-field.jsx index e6130a0c53..7ab69a5af8 100644 --- a/frontend/src/component/common/search-field.jsx +++ b/frontend/src/component/common/search-field.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { debounce } from 'debounce'; import { FABButton, Icon, Textfield } from 'react-mdl'; -function SearchField({ value, updateValue }) { +function SearchField({ value = '', updateValue }) { const [localValue, setLocalValue] = useState(value); const debounceUpdateValue = debounce(updateValue, 500); @@ -43,7 +43,7 @@ function SearchField({ value, updateValue }) { } SearchField.propTypes = { - value: PropTypes.string.isRequired, + value: PropTypes.string, updateValue: PropTypes.func.isRequired, }; 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 c18023ed3f..1e4fba446c 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 @@ -18,6 +18,7 @@ exports[`renders correctly with one feature 1`] = ` "width": "500px", } } + value="" /> api .storeApplicationMetaData(appName, key, value) - .then(() => dispatch({ type: UPDATE_APPLICATION_FIELD, appName, key, value })) + .then(() => { + const info = `${appName} successfully updated!`; + setTimeout(() => dispatch({ type: MUTE_ERROR, error: info }), 1000); + dispatch({ type: UPDATE_APPLICATION_FIELD, appName, key, value, info }); + }) .catch(dispatchAndThrow(dispatch, ERROR_UPDATING_APPLICATION_DATA)); } diff --git a/frontend/src/store/error-store.js b/frontend/src/store/error-store.js index c172f1fe9a..1cf06fc284 100644 --- a/frontend/src/store/error-store.js +++ b/frontend/src/store/error-store.js @@ -13,6 +13,8 @@ import { ERROR_UPDATING_STRATEGY, ERROR_CREATING_STRATEGY, ERROR_RECEIVE_STRATEG import { ERROR_ADD_CONTEXT_FIELD, ERROR_UPDATE_CONTEXT_FIELD } from './context/actions'; +import { UPDATE_APPLICATION_FIELD } from './application/actions'; + import { FORBIDDEN } from './util'; const debug = require('debug')('unleash:error-store'); @@ -49,6 +51,7 @@ const strategies = (state = getInitState(), action) => { return state.update('list', list => list.remove(list.indexOf(action.error))); case UPDATE_FEATURE_TOGGLE: case UPDATE_FEATURE_TOGGLE_STRATEGIES: + case UPDATE_APPLICATION_FIELD: return addErrorIfNotAlreadyInList(state, action.info); default: return state;