diff options
author | Dominik Guzei <dominik.guzei@gmail.com> | 2019-03-26 15:26:20 +0100 |
---|---|---|
committer | Dominik Guzei <dominik.guzei@gmail.com> | 2019-03-26 15:26:20 +0100 |
commit | a2e4316879908c5bc2c38cef81eef9152476b6f6 (patch) | |
tree | 0542dc53ea28dd26a7b6b1731c856eb2887582d8 /src/features/workspaces | |
parent | handle get workspaces request errors in the ui (diff) | |
download | ferdium-app-a2e4316879908c5bc2c38cef81eef9152476b6f6.tar.gz ferdium-app-a2e4316879908c5bc2c38cef81eef9152476b6f6.tar.zst ferdium-app-a2e4316879908c5bc2c38cef81eef9152476b6f6.zip |
show infobox when updating workspaces
Diffstat (limited to 'src/features/workspaces')
-rw-r--r-- | src/features/workspaces/components/WorkspacesDashboard.js | 89 | ||||
-rw-r--r-- | src/features/workspaces/containers/WorkspacesScreen.js | 3 | ||||
-rw-r--r-- | src/features/workspaces/store.js | 15 |
3 files changed, 62 insertions, 45 deletions
diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js index 2ccea1d55..3db38aff4 100644 --- a/src/features/workspaces/components/WorkspacesDashboard.js +++ b/src/features/workspaces/components/WorkspacesDashboard.js | |||
@@ -3,12 +3,13 @@ import PropTypes from 'prop-types'; | |||
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | 3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; |
4 | import { defineMessages, intlShape } from 'react-intl'; | 4 | import { defineMessages, intlShape } from 'react-intl'; |
5 | import injectSheet from 'react-jss'; | 5 | import injectSheet from 'react-jss'; |
6 | import { Infobox } from '@meetfranz/ui'; | ||
6 | 7 | ||
7 | import Loader from '../../../components/ui/Loader'; | 8 | import Loader from '../../../components/ui/Loader'; |
8 | import WorkspaceItem from './WorkspaceItem'; | 9 | import WorkspaceItem from './WorkspaceItem'; |
9 | import CreateWorkspaceForm from './CreateWorkspaceForm'; | 10 | import CreateWorkspaceForm from './CreateWorkspaceForm'; |
10 | import Request from '../../../stores/lib/Request'; | 11 | import Request from '../../../stores/lib/Request'; |
11 | import Infobox from '../../../components/ui/Infobox'; | 12 | import Appear from '../../../components/ui/effects/Appear'; |
12 | 13 | ||
13 | const messages = defineMessages({ | 14 | const messages = defineMessages({ |
14 | headline: { | 15 | headline: { |
@@ -27,6 +28,10 @@ const messages = defineMessages({ | |||
27 | id: 'settings.workspaces.tryReloadWorkspaces', | 28 | id: 'settings.workspaces.tryReloadWorkspaces', |
28 | defaultMessage: '!!!Try again', | 29 | defaultMessage: '!!!Try again', |
29 | }, | 30 | }, |
31 | updatedInfo: { | ||
32 | id: 'settings.workspaces.updatedInfo', | ||
33 | defaultMessage: '!!!Your changes have been saved', | ||
34 | }, | ||
30 | }); | 35 | }); |
31 | 36 | ||
32 | const styles = () => ({ | 37 | const styles = () => ({ |
@@ -34,6 +39,9 @@ const styles = () => ({ | |||
34 | height: 'auto', | 39 | height: 'auto', |
35 | marginBottom: '20px', | 40 | marginBottom: '20px', |
36 | }, | 41 | }, |
42 | appear: { | ||
43 | height: 'auto', | ||
44 | }, | ||
37 | }); | 45 | }); |
38 | 46 | ||
39 | @injectSheet(styles) @observer | 47 | @injectSheet(styles) @observer |
@@ -41,6 +49,7 @@ class WorkspacesDashboard extends Component { | |||
41 | static propTypes = { | 49 | static propTypes = { |
42 | classes: PropTypes.object.isRequired, | 50 | classes: PropTypes.object.isRequired, |
43 | getUserWorkspacesRequest: PropTypes.instanceOf(Request).isRequired, | 51 | getUserWorkspacesRequest: PropTypes.instanceOf(Request).isRequired, |
52 | updateWorkspaceRequest: PropTypes.instanceOf(Request).isRequired, | ||
44 | onCreateWorkspaceSubmit: PropTypes.func.isRequired, | 53 | onCreateWorkspaceSubmit: PropTypes.func.isRequired, |
45 | onWorkspaceClick: PropTypes.func.isRequired, | 54 | onWorkspaceClick: PropTypes.func.isRequired, |
46 | workspaces: MobxPropTypes.arrayOrObservableArray.isRequired, | 55 | workspaces: MobxPropTypes.arrayOrObservableArray.isRequired, |
@@ -54,6 +63,7 @@ class WorkspacesDashboard extends Component { | |||
54 | const { | 63 | const { |
55 | classes, | 64 | classes, |
56 | getUserWorkspacesRequest, | 65 | getUserWorkspacesRequest, |
66 | updateWorkspaceRequest, | ||
57 | onCreateWorkspaceSubmit, | 67 | onCreateWorkspaceSubmit, |
58 | onWorkspaceClick, | 68 | onWorkspaceClick, |
59 | workspaces, | 69 | workspaces, |
@@ -65,40 +75,51 @@ class WorkspacesDashboard extends Component { | |||
65 | <h1>{intl.formatMessage(messages.headline)}</h1> | 75 | <h1>{intl.formatMessage(messages.headline)}</h1> |
66 | </div> | 76 | </div> |
67 | <div className="settings__body"> | 77 | <div className="settings__body"> |
68 | <div className={classes.body}> | 78 | {updateWorkspaceRequest.wasExecuted && updateWorkspaceRequest.result && ( |
69 | <div className={classes.createForm}> | 79 | <Appear className={classes.appear}> |
70 | <CreateWorkspaceForm onSubmit={onCreateWorkspaceSubmit} /> | 80 | <Infobox |
71 | </div> | 81 | type="success" |
72 | {getUserWorkspacesRequest.isExecuting ? ( | 82 | icon="checkbox-marked-circle-outline" |
73 | <Loader /> | 83 | dismissable |
74 | ) : ( | 84 | onDismiss={updateWorkspaceRequest.reset} |
75 | <Fragment> | 85 | onUnmount={updateWorkspaceRequest.reset} |
76 | {getUserWorkspacesRequest.error ? ( | 86 | > |
77 | <Infobox | 87 | {intl.formatMessage(messages.updatedInfo)} |
78 | icon="alert" | 88 | </Infobox> |
79 | type="danger" | 89 | </Appear> |
80 | ctaLabel={intl.formatMessage(messages.tryReloadWorkspaces)} | 90 | )} |
81 | ctaLoading={getUserWorkspacesRequest.isExecuting} | 91 | <div className={classes.createForm}> |
82 | ctaOnClick={getUserWorkspacesRequest.retry} | 92 | <CreateWorkspaceForm onSubmit={onCreateWorkspaceSubmit} /> |
83 | > | ||
84 | {intl.formatMessage(messages.workspacesRequestFailed)} | ||
85 | </Infobox> | ||
86 | ) : ( | ||
87 | <table className="workspace-table"> | ||
88 | <tbody> | ||
89 | {workspaces.map(workspace => ( | ||
90 | <WorkspaceItem | ||
91 | key={workspace.id} | ||
92 | workspace={workspace} | ||
93 | onItemClick={w => onWorkspaceClick(w)} | ||
94 | /> | ||
95 | ))} | ||
96 | </tbody> | ||
97 | </table> | ||
98 | )} | ||
99 | </Fragment> | ||
100 | )} | ||
101 | </div> | 93 | </div> |
94 | {getUserWorkspacesRequest.isExecuting ? ( | ||
95 | <Loader /> | ||
96 | ) : ( | ||
97 | <Fragment> | ||
98 | {getUserWorkspacesRequest.error ? ( | ||
99 | <Infobox | ||
100 | icon="alert" | ||
101 | type="danger" | ||
102 | ctaLabel={intl.formatMessage(messages.tryReloadWorkspaces)} | ||
103 | ctaLoading={getUserWorkspacesRequest.isExecuting} | ||
104 | ctaOnClick={getUserWorkspacesRequest.retry} | ||
105 | > | ||
106 | {intl.formatMessage(messages.workspacesRequestFailed)} | ||
107 | </Infobox> | ||
108 | ) : ( | ||
109 | <table className="workspace-table"> | ||
110 | <tbody> | ||
111 | {workspaces.map(workspace => ( | ||
112 | <WorkspaceItem | ||
113 | key={workspace.id} | ||
114 | workspace={workspace} | ||
115 | onItemClick={w => onWorkspaceClick(w)} | ||
116 | /> | ||
117 | ))} | ||
118 | </tbody> | ||
119 | </table> | ||
120 | )} | ||
121 | </Fragment> | ||
122 | )} | ||
102 | </div> | 123 | </div> |
103 | </div> | 124 | </div> |
104 | ); | 125 | ); |
diff --git a/src/features/workspaces/containers/WorkspacesScreen.js b/src/features/workspaces/containers/WorkspacesScreen.js index 89bd2a2ef..3f41de0c2 100644 --- a/src/features/workspaces/containers/WorkspacesScreen.js +++ b/src/features/workspaces/containers/WorkspacesScreen.js | |||
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; | |||
4 | import WorkspacesDashboard from '../components/WorkspacesDashboard'; | 4 | import WorkspacesDashboard from '../components/WorkspacesDashboard'; |
5 | import ErrorBoundary from '../../../components/util/ErrorBoundary'; | 5 | import ErrorBoundary from '../../../components/util/ErrorBoundary'; |
6 | import { workspaceStore } from '../index'; | 6 | import { workspaceStore } from '../index'; |
7 | import { getUserWorkspacesRequest } from '../api'; | 7 | import { getUserWorkspacesRequest, updateWorkspaceRequest } from '../api'; |
8 | 8 | ||
9 | @inject('actions') @observer | 9 | @inject('actions') @observer |
10 | class WorkspacesScreen extends Component { | 10 | class WorkspacesScreen extends Component { |
@@ -23,6 +23,7 @@ class WorkspacesScreen extends Component { | |||
23 | <WorkspacesDashboard | 23 | <WorkspacesDashboard |
24 | workspaces={workspaceStore.workspaces} | 24 | workspaces={workspaceStore.workspaces} |
25 | getUserWorkspacesRequest={getUserWorkspacesRequest} | 25 | getUserWorkspacesRequest={getUserWorkspacesRequest} |
26 | updateWorkspaceRequest={updateWorkspaceRequest} | ||
26 | onCreateWorkspaceSubmit={data => actions.workspaces.create(data)} | 27 | onCreateWorkspaceSubmit={data => actions.workspaces.create(data)} |
27 | onWorkspaceClick={w => actions.workspaces.edit({ workspace: w })} | 28 | onWorkspaceClick={w => actions.workspaces.edit({ workspace: w })} |
28 | /> | 29 | /> |
diff --git a/src/features/workspaces/store.js b/src/features/workspaces/store.js index 3cec5f360..f7df7b29c 100644 --- a/src/features/workspaces/store.js +++ b/src/features/workspaces/store.js | |||
@@ -102,9 +102,7 @@ export default class WorkspacesStore { | |||
102 | @action _create = async ({ name }) => { | 102 | @action _create = async ({ name }) => { |
103 | try { | 103 | try { |
104 | const workspace = await createWorkspaceRequest.execute(name); | 104 | const workspace = await createWorkspaceRequest.execute(name); |
105 | await getUserWorkspacesRequest.patch((result) => { | 105 | await getUserWorkspacesRequest.result.push(workspace); |
106 | result.push(workspace); | ||
107 | }); | ||
108 | this._edit({ workspace }); | 106 | this._edit({ workspace }); |
109 | } catch (error) { | 107 | } catch (error) { |
110 | throw error; | 108 | throw error; |
@@ -114,9 +112,7 @@ export default class WorkspacesStore { | |||
114 | @action _delete = async ({ workspace }) => { | 112 | @action _delete = async ({ workspace }) => { |
115 | try { | 113 | try { |
116 | await deleteWorkspaceRequest.execute(workspace); | 114 | await deleteWorkspaceRequest.execute(workspace); |
117 | await getUserWorkspacesRequest.patch((result) => { | 115 | await getUserWorkspacesRequest.result.remove(workspace); |
118 | result.remove(workspace); | ||
119 | }); | ||
120 | this.stores.router.push('/settings/workspaces'); | 116 | this.stores.router.push('/settings/workspaces'); |
121 | } catch (error) { | 117 | } catch (error) { |
122 | throw error; | 118 | throw error; |
@@ -126,10 +122,9 @@ export default class WorkspacesStore { | |||
126 | @action _update = async ({ workspace }) => { | 122 | @action _update = async ({ workspace }) => { |
127 | try { | 123 | try { |
128 | await updateWorkspaceRequest.execute(workspace); | 124 | await updateWorkspaceRequest.execute(workspace); |
129 | await getUserWorkspacesRequest.patch((result) => { | 125 | // Path local result optimistically |
130 | const localWorkspace = result.find(ws => ws.id === workspace.id); | 126 | const localWorkspace = this._getWorkspaceById(workspace.id); |
131 | Object.assign(localWorkspace, workspace); | 127 | Object.assign(localWorkspace, workspace); |
132 | }); | ||
133 | this.stores.router.push('/settings/workspaces'); | 128 | this.stores.router.push('/settings/workspaces'); |
134 | } catch (error) { | 129 | } catch (error) { |
135 | throw error; | 130 | throw error; |