diff options
author | Dominik Guzei <dominik.guzei@gmail.com> | 2019-03-26 16:25:49 +0100 |
---|---|---|
committer | Dominik Guzei <dominik.guzei@gmail.com> | 2019-03-26 16:25:59 +0100 |
commit | 03c76d7a6e5c5529e39f245dd350c0bc8abbd128 (patch) | |
tree | 00477465d79f7eb640b135781d5f2b15a0d984a2 /src/features | |
parent | show infobox when updating workspaces (diff) | |
download | ferdium-app-03c76d7a6e5c5529e39f245dd350c0bc8abbd128.tar.gz ferdium-app-03c76d7a6e5c5529e39f245dd350c0bc8abbd128.tar.zst ferdium-app-03c76d7a6e5c5529e39f245dd350c0bc8abbd128.zip |
indicate any server interaction with spinners and infoboxes
Diffstat (limited to 'src/features')
6 files changed, 76 insertions, 44 deletions
diff --git a/src/features/workspaces/api.js b/src/features/workspaces/api.js index 3da265e5e..0ec20c9ea 100644 --- a/src/features/workspaces/api.js +++ b/src/features/workspaces/api.js | |||
@@ -36,7 +36,7 @@ export const workspaceApi = { | |||
36 | const result = await sendAuthRequest(url, { method: 'DELETE' }); | 36 | const result = await sendAuthRequest(url, { method: 'DELETE' }); |
37 | debug('deleteWorkspace RESULT', result); | 37 | debug('deleteWorkspace RESULT', result); |
38 | if (!result.ok) throw result; | 38 | if (!result.ok) throw result; |
39 | return (await result.json()).deleted; | 39 | return true; |
40 | }, | 40 | }, |
41 | 41 | ||
42 | updateWorkspace: async (workspace) => { | 42 | updateWorkspace: async (workspace) => { |
diff --git a/src/features/workspaces/components/CreateWorkspaceForm.js b/src/features/workspaces/components/CreateWorkspaceForm.js index 83f6e07f7..8b5039246 100644 --- a/src/features/workspaces/components/CreateWorkspaceForm.js +++ b/src/features/workspaces/components/CreateWorkspaceForm.js | |||
@@ -10,7 +10,7 @@ import { required } from '../../../helpers/validation-helpers'; | |||
10 | const messages = defineMessages({ | 10 | const messages = defineMessages({ |
11 | submitButton: { | 11 | submitButton: { |
12 | id: 'settings.workspace.add.form.submitButton', | 12 | id: 'settings.workspace.add.form.submitButton', |
13 | defaultMessage: '!!!Save workspace', | 13 | defaultMessage: '!!!Create workspace', |
14 | }, | 14 | }, |
15 | name: { | 15 | name: { |
16 | id: 'settings.workspace.add.form.name', | 16 | id: 'settings.workspace.add.form.name', |
@@ -40,6 +40,7 @@ class CreateWorkspaceForm extends Component { | |||
40 | 40 | ||
41 | static propTypes = { | 41 | static propTypes = { |
42 | classes: PropTypes.object.isRequired, | 42 | classes: PropTypes.object.isRequired, |
43 | isSubmitting: PropTypes.bool.isRequired, | ||
43 | onSubmit: PropTypes.func.isRequired, | 44 | onSubmit: PropTypes.func.isRequired, |
44 | }; | 45 | }; |
45 | 46 | ||
@@ -69,7 +70,7 @@ class CreateWorkspaceForm extends Component { | |||
69 | 70 | ||
70 | render() { | 71 | render() { |
71 | const { intl } = this.context; | 72 | const { intl } = this.context; |
72 | const { classes } = this.props; | 73 | const { classes, isSubmitting } = this.props; |
73 | const { form } = this; | 74 | const { form } = this; |
74 | return ( | 75 | return ( |
75 | <div className={classes.form}> | 76 | <div className={classes.form}> |
@@ -84,6 +85,8 @@ class CreateWorkspaceForm extends Component { | |||
84 | type="submit" | 85 | type="submit" |
85 | label={intl.formatMessage(messages.submitButton)} | 86 | label={intl.formatMessage(messages.submitButton)} |
86 | onClick={this.submitForm.bind(this, form)} | 87 | onClick={this.submitForm.bind(this, form)} |
88 | busy={isSubmitting} | ||
89 | buttonType={isSubmitting ? 'secondary' : 'primary'} | ||
87 | /> | 90 | /> |
88 | </div> | 91 | </div> |
89 | ); | 92 | ); |
diff --git a/src/features/workspaces/components/EditWorkspaceForm.js b/src/features/workspaces/components/EditWorkspaceForm.js index 48090f608..a9fd4d21c 100644 --- a/src/features/workspaces/components/EditWorkspaceForm.js +++ b/src/features/workspaces/components/EditWorkspaceForm.js | |||
@@ -11,6 +11,7 @@ import Service from '../../../models/Service'; | |||
11 | import Form from '../../../lib/Form'; | 11 | import Form from '../../../lib/Form'; |
12 | import { required } from '../../../helpers/validation-helpers'; | 12 | import { required } from '../../../helpers/validation-helpers'; |
13 | import ServiceListItem from './ServiceListItem'; | 13 | import ServiceListItem from './ServiceListItem'; |
14 | import Request from '../../../stores/lib/Request'; | ||
14 | 15 | ||
15 | const messages = defineMessages({ | 16 | const messages = defineMessages({ |
16 | buttonDelete: { | 17 | buttonDelete: { |
@@ -52,12 +53,12 @@ class EditWorkspaceForm extends Component { | |||
52 | 53 | ||
53 | static propTypes = { | 54 | static propTypes = { |
54 | classes: PropTypes.object.isRequired, | 55 | classes: PropTypes.object.isRequired, |
55 | isDeleting: PropTypes.bool.isRequired, | ||
56 | isSaving: PropTypes.bool.isRequired, | ||
57 | onDelete: PropTypes.func.isRequired, | 56 | onDelete: PropTypes.func.isRequired, |
58 | onSave: PropTypes.func.isRequired, | 57 | onSave: PropTypes.func.isRequired, |
59 | services: PropTypes.arrayOf(PropTypes.instanceOf(Service)).isRequired, | 58 | services: PropTypes.arrayOf(PropTypes.instanceOf(Service)).isRequired, |
60 | workspace: PropTypes.instanceOf(Workspace).isRequired, | 59 | workspace: PropTypes.instanceOf(Workspace).isRequired, |
60 | updateWorkspaceRequest: PropTypes.instanceOf(Request).isRequired, | ||
61 | deleteWorkspaceRequest: PropTypes.instanceOf(Request).isRequired, | ||
61 | }; | 62 | }; |
62 | 63 | ||
63 | form = this.prepareWorkspaceForm(this.props.workspace); | 64 | form = this.prepareWorkspaceForm(this.props.workspace); |
@@ -112,14 +113,16 @@ class EditWorkspaceForm extends Component { | |||
112 | const { intl } = this.context; | 113 | const { intl } = this.context; |
113 | const { | 114 | const { |
114 | classes, | 115 | classes, |
115 | isDeleting, | ||
116 | isSaving, | ||
117 | onDelete, | 116 | onDelete, |
118 | workspace, | 117 | workspace, |
119 | services, | 118 | services, |
119 | deleteWorkspaceRequest, | ||
120 | updateWorkspaceRequest, | ||
120 | } = this.props; | 121 | } = this.props; |
121 | const { form } = this; | 122 | const { form } = this; |
122 | const workspaceServices = form.$('services').value; | 123 | const workspaceServices = form.$('services').value; |
124 | const isDeleting = deleteWorkspaceRequest.isExecuting; | ||
125 | const isSaving = updateWorkspaceRequest.isExecuting; | ||
123 | return ( | 126 | return ( |
124 | <div className="settings__main"> | 127 | <div className="settings__main"> |
125 | <div className="settings__header"> | 128 | <div className="settings__header"> |
@@ -151,38 +154,24 @@ class EditWorkspaceForm extends Component { | |||
151 | </div> | 154 | </div> |
152 | <div className="settings__controls"> | 155 | <div className="settings__controls"> |
153 | {/* ===== Delete Button ===== */} | 156 | {/* ===== Delete Button ===== */} |
154 | {isDeleting ? ( | 157 | <Button |
155 | <Button | 158 | label={intl.formatMessage(messages.buttonDelete)} |
156 | label={intl.formatMessage(messages.buttonDelete)} | 159 | loaded={false} |
157 | loaded={false} | 160 | busy={isDeleting} |
158 | buttonType="secondary" | 161 | buttonType={isDeleting ? 'secondary' : 'danger'} |
159 | className="settings__delete-button" | 162 | className="settings__delete-button" |
160 | disabled | 163 | disabled={isDeleting} |
161 | /> | 164 | onClick={onDelete} |
162 | ) : ( | 165 | /> |
163 | <Button | ||
164 | buttonType="danger" | ||
165 | label={intl.formatMessage(messages.buttonDelete)} | ||
166 | className="settings__delete-button" | ||
167 | onClick={onDelete} | ||
168 | /> | ||
169 | )} | ||
170 | {/* ===== Save Button ===== */} | 166 | {/* ===== Save Button ===== */} |
171 | {isSaving ? ( | 167 | <Button |
172 | <Button | 168 | type="submit" |
173 | type="submit" | 169 | label={intl.formatMessage(messages.buttonSave)} |
174 | label={intl.formatMessage(messages.buttonSave)} | 170 | busy={isSaving} |
175 | loaded={!isSaving} | 171 | buttonType={isSaving ? 'secondary' : 'primary'} |
176 | buttonType="secondary" | 172 | onClick={this.submitForm.bind(this, form)} |
177 | disabled | 173 | disabled={isSaving} |
178 | /> | 174 | /> |
179 | ) : ( | ||
180 | <Button | ||
181 | type="submit" | ||
182 | label={intl.formatMessage(messages.buttonSave)} | ||
183 | onClick={this.submitForm.bind(this, form)} | ||
184 | /> | ||
185 | )} | ||
186 | </div> | 175 | </div> |
187 | </div> | 176 | </div> |
188 | ); | 177 | ); |
diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js index 3db38aff4..b31581a5b 100644 --- a/src/features/workspaces/components/WorkspacesDashboard.js +++ b/src/features/workspaces/components/WorkspacesDashboard.js | |||
@@ -32,6 +32,10 @@ const messages = defineMessages({ | |||
32 | id: 'settings.workspaces.updatedInfo', | 32 | id: 'settings.workspaces.updatedInfo', |
33 | defaultMessage: '!!!Your changes have been saved', | 33 | defaultMessage: '!!!Your changes have been saved', |
34 | }, | 34 | }, |
35 | deletedInfo: { | ||
36 | id: 'settings.workspaces.deletedInfo', | ||
37 | defaultMessage: '!!!Workspace has been deleted', | ||
38 | }, | ||
35 | }); | 39 | }); |
36 | 40 | ||
37 | const styles = () => ({ | 41 | const styles = () => ({ |
@@ -49,6 +53,8 @@ class WorkspacesDashboard extends Component { | |||
49 | static propTypes = { | 53 | static propTypes = { |
50 | classes: PropTypes.object.isRequired, | 54 | classes: PropTypes.object.isRequired, |
51 | getUserWorkspacesRequest: PropTypes.instanceOf(Request).isRequired, | 55 | getUserWorkspacesRequest: PropTypes.instanceOf(Request).isRequired, |
56 | createWorkspaceRequest: PropTypes.instanceOf(Request).isRequired, | ||
57 | deleteWorkspaceRequest: PropTypes.instanceOf(Request).isRequired, | ||
52 | updateWorkspaceRequest: PropTypes.instanceOf(Request).isRequired, | 58 | updateWorkspaceRequest: PropTypes.instanceOf(Request).isRequired, |
53 | onCreateWorkspaceSubmit: PropTypes.func.isRequired, | 59 | onCreateWorkspaceSubmit: PropTypes.func.isRequired, |
54 | onWorkspaceClick: PropTypes.func.isRequired, | 60 | onWorkspaceClick: PropTypes.func.isRequired, |
@@ -63,38 +69,63 @@ class WorkspacesDashboard extends Component { | |||
63 | const { | 69 | const { |
64 | classes, | 70 | classes, |
65 | getUserWorkspacesRequest, | 71 | getUserWorkspacesRequest, |
72 | createWorkspaceRequest, | ||
73 | deleteWorkspaceRequest, | ||
66 | updateWorkspaceRequest, | 74 | updateWorkspaceRequest, |
67 | onCreateWorkspaceSubmit, | 75 | onCreateWorkspaceSubmit, |
68 | onWorkspaceClick, | 76 | onWorkspaceClick, |
69 | workspaces, | 77 | workspaces, |
70 | } = this.props; | 78 | } = this.props; |
71 | const { intl } = this.context; | 79 | const { intl } = this.context; |
80 | console.log(deleteWorkspaceRequest.result); | ||
72 | return ( | 81 | return ( |
73 | <div className="settings__main"> | 82 | <div className="settings__main"> |
74 | <div className="settings__header"> | 83 | <div className="settings__header"> |
75 | <h1>{intl.formatMessage(messages.headline)}</h1> | 84 | <h1>{intl.formatMessage(messages.headline)}</h1> |
76 | </div> | 85 | </div> |
77 | <div className="settings__body"> | 86 | <div className="settings__body"> |
87 | |||
88 | {/* ===== Workspace updated info ===== */} | ||
78 | {updateWorkspaceRequest.wasExecuted && updateWorkspaceRequest.result && ( | 89 | {updateWorkspaceRequest.wasExecuted && updateWorkspaceRequest.result && ( |
79 | <Appear className={classes.appear}> | 90 | <Appear className={classes.appear}> |
80 | <Infobox | 91 | <Infobox |
81 | type="success" | 92 | type="success" |
82 | icon="checkbox-marked-circle-outline" | 93 | icon="mdiCheckboxMarkedCircleOutline" |
83 | dismissable | 94 | dismissable |
84 | onDismiss={updateWorkspaceRequest.reset} | ||
85 | onUnmount={updateWorkspaceRequest.reset} | 95 | onUnmount={updateWorkspaceRequest.reset} |
86 | > | 96 | > |
87 | {intl.formatMessage(messages.updatedInfo)} | 97 | {intl.formatMessage(messages.updatedInfo)} |
88 | </Infobox> | 98 | </Infobox> |
89 | </Appear> | 99 | </Appear> |
90 | )} | 100 | )} |
101 | |||
102 | {/* ===== Workspace deleted info ===== */} | ||
103 | {deleteWorkspaceRequest.wasExecuted && deleteWorkspaceRequest.result && ( | ||
104 | <Appear className={classes.appear}> | ||
105 | <Infobox | ||
106 | type="success" | ||
107 | icon="mdiCheckboxMarkedCircleOutline" | ||
108 | dismissable | ||
109 | onUnmount={deleteWorkspaceRequest.reset} | ||
110 | > | ||
111 | {intl.formatMessage(messages.deletedInfo)} | ||
112 | </Infobox> | ||
113 | </Appear> | ||
114 | )} | ||
115 | |||
116 | {/* ===== Create workspace form ===== */} | ||
91 | <div className={classes.createForm}> | 117 | <div className={classes.createForm}> |
92 | <CreateWorkspaceForm onSubmit={onCreateWorkspaceSubmit} /> | 118 | <CreateWorkspaceForm |
119 | isSubmitting={createWorkspaceRequest.isExecuting} | ||
120 | onSubmit={onCreateWorkspaceSubmit} | ||
121 | /> | ||
93 | </div> | 122 | </div> |
123 | |||
94 | {getUserWorkspacesRequest.isExecuting ? ( | 124 | {getUserWorkspacesRequest.isExecuting ? ( |
95 | <Loader /> | 125 | <Loader /> |
96 | ) : ( | 126 | ) : ( |
97 | <Fragment> | 127 | <Fragment> |
128 | {/* ===== Workspace could not be loaded error ===== */} | ||
98 | {getUserWorkspacesRequest.error ? ( | 129 | {getUserWorkspacesRequest.error ? ( |
99 | <Infobox | 130 | <Infobox |
100 | icon="alert" | 131 | icon="alert" |
@@ -107,6 +138,7 @@ class WorkspacesDashboard extends Component { | |||
107 | </Infobox> | 138 | </Infobox> |
108 | ) : ( | 139 | ) : ( |
109 | <table className="workspace-table"> | 140 | <table className="workspace-table"> |
141 | {/* ===== Workspaces list ===== */} | ||
110 | <tbody> | 142 | <tbody> |
111 | {workspaces.map(workspace => ( | 143 | {workspaces.map(workspace => ( |
112 | <WorkspaceItem | 144 | <WorkspaceItem |
diff --git a/src/features/workspaces/containers/EditWorkspaceScreen.js b/src/features/workspaces/containers/EditWorkspaceScreen.js index 1c4633e71..248b40131 100644 --- a/src/features/workspaces/containers/EditWorkspaceScreen.js +++ b/src/features/workspaces/containers/EditWorkspaceScreen.js | |||
@@ -7,6 +7,7 @@ import EditWorkspaceForm from '../components/EditWorkspaceForm'; | |||
7 | import ServicesStore from '../../../stores/ServicesStore'; | 7 | import ServicesStore from '../../../stores/ServicesStore'; |
8 | import Workspace from '../models/Workspace'; | 8 | import Workspace from '../models/Workspace'; |
9 | import { workspaceStore } from '../index'; | 9 | import { workspaceStore } from '../index'; |
10 | import { deleteWorkspaceRequest, updateWorkspaceRequest } from '../api'; | ||
10 | 11 | ||
11 | @inject('stores', 'actions') @observer | 12 | @inject('stores', 'actions') @observer |
12 | class EditWorkspaceScreen extends Component { | 13 | class EditWorkspaceScreen extends Component { |
@@ -48,8 +49,8 @@ class EditWorkspaceScreen extends Component { | |||
48 | services={stores.services.all} | 49 | services={stores.services.all} |
49 | onDelete={this.onDelete} | 50 | onDelete={this.onDelete} |
50 | onSave={this.onSave} | 51 | onSave={this.onSave} |
51 | isDeleting={false} | 52 | updateWorkspaceRequest={updateWorkspaceRequest} |
52 | isSaving={false} | 53 | deleteWorkspaceRequest={deleteWorkspaceRequest} |
53 | /> | 54 | /> |
54 | </ErrorBoundary> | 55 | </ErrorBoundary> |
55 | ); | 56 | ); |
diff --git a/src/features/workspaces/containers/WorkspacesScreen.js b/src/features/workspaces/containers/WorkspacesScreen.js index 3f41de0c2..2ab565fa1 100644 --- a/src/features/workspaces/containers/WorkspacesScreen.js +++ b/src/features/workspaces/containers/WorkspacesScreen.js | |||
@@ -4,7 +4,12 @@ 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, updateWorkspaceRequest } from '../api'; | 7 | import { |
8 | createWorkspaceRequest, | ||
9 | deleteWorkspaceRequest, | ||
10 | getUserWorkspacesRequest, | ||
11 | updateWorkspaceRequest, | ||
12 | } from '../api'; | ||
8 | 13 | ||
9 | @inject('actions') @observer | 14 | @inject('actions') @observer |
10 | class WorkspacesScreen extends Component { | 15 | class WorkspacesScreen extends Component { |
@@ -23,6 +28,8 @@ class WorkspacesScreen extends Component { | |||
23 | <WorkspacesDashboard | 28 | <WorkspacesDashboard |
24 | workspaces={workspaceStore.workspaces} | 29 | workspaces={workspaceStore.workspaces} |
25 | getUserWorkspacesRequest={getUserWorkspacesRequest} | 30 | getUserWorkspacesRequest={getUserWorkspacesRequest} |
31 | createWorkspaceRequest={createWorkspaceRequest} | ||
32 | deleteWorkspaceRequest={deleteWorkspaceRequest} | ||
26 | updateWorkspaceRequest={updateWorkspaceRequest} | 33 | updateWorkspaceRequest={updateWorkspaceRequest} |
27 | onCreateWorkspaceSubmit={data => actions.workspaces.create(data)} | 34 | onCreateWorkspaceSubmit={data => actions.workspaces.create(data)} |
28 | onWorkspaceClick={w => actions.workspaces.edit({ workspace: w })} | 35 | onWorkspaceClick={w => actions.workspaces.edit({ workspace: w })} |