aboutsummaryrefslogtreecommitdiffstats
path: root/src/features
diff options
context:
space:
mode:
authorLibravatar Dominik Guzei <dominik.guzei@gmail.com>2019-03-26 16:25:49 +0100
committerLibravatar Dominik Guzei <dominik.guzei@gmail.com>2019-03-26 16:25:59 +0100
commit03c76d7a6e5c5529e39f245dd350c0bc8abbd128 (patch)
tree00477465d79f7eb640b135781d5f2b15a0d984a2 /src/features
parentshow infobox when updating workspaces (diff)
downloadferdium-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')
-rw-r--r--src/features/workspaces/api.js2
-rw-r--r--src/features/workspaces/components/CreateWorkspaceForm.js7
-rw-r--r--src/features/workspaces/components/EditWorkspaceForm.js59
-rw-r--r--src/features/workspaces/components/WorkspacesDashboard.js38
-rw-r--r--src/features/workspaces/containers/EditWorkspaceScreen.js5
-rw-r--r--src/features/workspaces/containers/WorkspacesScreen.js9
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';
10const messages = defineMessages({ 10const 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';
11import Form from '../../../lib/Form'; 11import Form from '../../../lib/Form';
12import { required } from '../../../helpers/validation-helpers'; 12import { required } from '../../../helpers/validation-helpers';
13import ServiceListItem from './ServiceListItem'; 13import ServiceListItem from './ServiceListItem';
14import Request from '../../../stores/lib/Request';
14 15
15const messages = defineMessages({ 16const 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
37const styles = () => ({ 41const 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';
7import ServicesStore from '../../../stores/ServicesStore'; 7import ServicesStore from '../../../stores/ServicesStore';
8import Workspace from '../models/Workspace'; 8import Workspace from '../models/Workspace';
9import { workspaceStore } from '../index'; 9import { workspaceStore } from '../index';
10import { deleteWorkspaceRequest, updateWorkspaceRequest } from '../api';
10 11
11@inject('stores', 'actions') @observer 12@inject('stores', 'actions') @observer
12class EditWorkspaceScreen extends Component { 13class 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';
4import WorkspacesDashboard from '../components/WorkspacesDashboard'; 4import WorkspacesDashboard from '../components/WorkspacesDashboard';
5import ErrorBoundary from '../../../components/util/ErrorBoundary'; 5import ErrorBoundary from '../../../components/util/ErrorBoundary';
6import { workspaceStore } from '../index'; 6import { workspaceStore } from '../index';
7import { getUserWorkspacesRequest, updateWorkspaceRequest } from '../api'; 7import {
8 createWorkspaceRequest,
9 deleteWorkspaceRequest,
10 getUserWorkspacesRequest,
11 updateWorkspaceRequest,
12} from '../api';
8 13
9@inject('actions') @observer 14@inject('actions') @observer
10class WorkspacesScreen extends Component { 15class 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 })}