diff options
author | Dominik Guzei <dominik.guzei@gmail.com> | 2019-02-22 12:34:27 +0100 |
---|---|---|
committer | Dominik Guzei <dominik.guzei@gmail.com> | 2019-02-22 12:34:27 +0100 |
commit | 7e40b08e2f8ab2448dcbe2ce7b4e38ca66764b9c (patch) | |
tree | 6d02d9c1b096604ea70fbae4b04d7af0760ffc5f /src/features/workspaces | |
parent | add on enter key handler for form input component (diff) | |
download | ferdium-app-7e40b08e2f8ab2448dcbe2ce7b4e38ca66764b9c.tar.gz ferdium-app-7e40b08e2f8ab2448dcbe2ce7b4e38ca66764b9c.tar.zst ferdium-app-7e40b08e2f8ab2448dcbe2ce7b4e38ca66764b9c.zip |
add form for creating workspaces
Diffstat (limited to 'src/features/workspaces')
-rw-r--r-- | src/features/workspaces/actions.js | 3 | ||||
-rw-r--r-- | src/features/workspaces/api.js | 9 | ||||
-rw-r--r-- | src/features/workspaces/components/CreateWorkspaceForm.js | 94 | ||||
-rw-r--r-- | src/features/workspaces/components/WorkspacesDashboard.js | 58 | ||||
-rw-r--r-- | src/features/workspaces/containers/WorkspacesScreen.js | 1 | ||||
-rw-r--r-- | src/features/workspaces/store.js | 14 |
6 files changed, 160 insertions, 19 deletions
diff --git a/src/features/workspaces/actions.js b/src/features/workspaces/actions.js index 30866af96..390af0696 100644 --- a/src/features/workspaces/actions.js +++ b/src/features/workspaces/actions.js | |||
@@ -5,4 +5,7 @@ export default { | |||
5 | edit: { | 5 | edit: { |
6 | workspace: PropTypes.instanceOf(Workspace).isRequired, | 6 | workspace: PropTypes.instanceOf(Workspace).isRequired, |
7 | }, | 7 | }, |
8 | create: { | ||
9 | name: PropTypes.string.isRequired, | ||
10 | }, | ||
8 | }; | 11 | }; |
diff --git a/src/features/workspaces/api.js b/src/features/workspaces/api.js index 97badbd01..65108a077 100644 --- a/src/features/workspaces/api.js +++ b/src/features/workspaces/api.js | |||
@@ -10,4 +10,13 @@ export default { | |||
10 | if (!request.ok) throw request; | 10 | if (!request.ok) throw request; |
11 | return request.json(); | 11 | return request.json(); |
12 | }, | 12 | }, |
13 | createWorkspace: async (name) => { | ||
14 | const url = `${API}/${API_VERSION}/workspace`; | ||
15 | const request = await window.fetch(url, prepareAuthRequest({ | ||
16 | method: 'POST', | ||
17 | body: JSON.stringify({ name }), | ||
18 | })); | ||
19 | if (!request.ok) throw request; | ||
20 | return request.json(); | ||
21 | }, | ||
13 | }; | 22 | }; |
diff --git a/src/features/workspaces/components/CreateWorkspaceForm.js b/src/features/workspaces/components/CreateWorkspaceForm.js new file mode 100644 index 000000000..d440b9bae --- /dev/null +++ b/src/features/workspaces/components/CreateWorkspaceForm.js | |||
@@ -0,0 +1,94 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer } from 'mobx-react'; | ||
4 | import { defineMessages, intlShape } from 'react-intl'; | ||
5 | import { Input, Button } from '@meetfranz/forms'; | ||
6 | import injectSheet from 'react-jss'; | ||
7 | |||
8 | import Form from '../../../lib/Form'; | ||
9 | |||
10 | const messages = defineMessages({ | ||
11 | submitButton: { | ||
12 | id: 'settings.workspace.add.form.submitButton', | ||
13 | defaultMessage: '!!!Save workspace', | ||
14 | }, | ||
15 | name: { | ||
16 | id: 'settings.workspace.add.form.name', | ||
17 | defaultMessage: '!!!Name', | ||
18 | }, | ||
19 | }); | ||
20 | |||
21 | const styles = () => ({ | ||
22 | form: { | ||
23 | display: 'flex', | ||
24 | }, | ||
25 | input: { | ||
26 | flexGrow: 1, | ||
27 | marginRight: '10px', | ||
28 | }, | ||
29 | submitButton: { | ||
30 | height: 'inherit', | ||
31 | marginTop: '17px', | ||
32 | }, | ||
33 | }); | ||
34 | |||
35 | @observer @injectSheet(styles) | ||
36 | class CreateWorkspaceForm extends Component { | ||
37 | static contextTypes = { | ||
38 | intl: intlShape, | ||
39 | }; | ||
40 | |||
41 | static propTypes = { | ||
42 | classes: PropTypes.object.isRequired, | ||
43 | onSubmit: PropTypes.func.isRequired, | ||
44 | }; | ||
45 | |||
46 | prepareForm() { | ||
47 | const { intl } = this.context; | ||
48 | const config = { | ||
49 | fields: { | ||
50 | name: { | ||
51 | label: intl.formatMessage(messages.name), | ||
52 | placeholder: intl.formatMessage(messages.name), | ||
53 | value: '', | ||
54 | }, | ||
55 | }, | ||
56 | }; | ||
57 | return new Form(config); | ||
58 | } | ||
59 | |||
60 | submitForm(form) { | ||
61 | form.submit({ | ||
62 | onSuccess: async (f) => { | ||
63 | const { onSubmit } = this.props; | ||
64 | const values = f.values(); | ||
65 | onSubmit(values); | ||
66 | }, | ||
67 | onError: async () => {}, | ||
68 | }); | ||
69 | } | ||
70 | |||
71 | render() { | ||
72 | const { intl } = this.context; | ||
73 | const { classes } = this.props; | ||
74 | const form = this.prepareForm(); | ||
75 | |||
76 | return ( | ||
77 | <div className={classes.form}> | ||
78 | <Input | ||
79 | className={classes.input} | ||
80 | {...form.$('name').bind()} | ||
81 | onEnterKey={this.submitForm.bind(this, form)} | ||
82 | /> | ||
83 | <Button | ||
84 | className={classes.submitButton} | ||
85 | type="button" | ||
86 | label={intl.formatMessage(messages.submitButton)} | ||
87 | onClick={this.submitForm.bind(this, form)} | ||
88 | /> | ||
89 | </div> | ||
90 | ); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | export default CreateWorkspaceForm; | ||
diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js index 2a8b3a5ee..917807302 100644 --- a/src/features/workspaces/components/WorkspacesDashboard.js +++ b/src/features/workspaces/components/WorkspacesDashboard.js | |||
@@ -2,9 +2,11 @@ import React, { Component } from 'react'; | |||
2 | import PropTypes from 'prop-types'; | 2 | 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 | 6 | ||
6 | import Loader from '../../../components/ui/Loader'; | 7 | import Loader from '../../../components/ui/Loader'; |
7 | import WorkspaceItem from './WorkspaceItem'; | 8 | import WorkspaceItem from './WorkspaceItem'; |
9 | import CreateWorkspaceForm from './CreateWorkspaceForm'; | ||
8 | 10 | ||
9 | const messages = defineMessages({ | 11 | const messages = defineMessages({ |
10 | headline: { | 12 | headline: { |
@@ -17,12 +19,21 @@ const messages = defineMessages({ | |||
17 | }, | 19 | }, |
18 | }); | 20 | }); |
19 | 21 | ||
20 | @observer | 22 | const styles = () => ({ |
23 | createForm: { | ||
24 | height: 'auto', | ||
25 | marginBottom: '20px', | ||
26 | }, | ||
27 | }); | ||
28 | |||
29 | @observer @injectSheet(styles) | ||
21 | class WorkspacesDashboard extends Component { | 30 | class WorkspacesDashboard extends Component { |
22 | static propTypes = { | 31 | static propTypes = { |
23 | workspaces: MobxPropTypes.arrayOrObservableArray.isRequired, | 32 | classes: PropTypes.object.isRequired, |
24 | isLoading: PropTypes.bool.isRequired, | 33 | isLoading: PropTypes.bool.isRequired, |
34 | onCreateWorkspaceSubmit: PropTypes.func.isRequired, | ||
25 | onWorkspaceClick: PropTypes.func.isRequired, | 35 | onWorkspaceClick: PropTypes.func.isRequired, |
36 | workspaces: MobxPropTypes.arrayOrObservableArray.isRequired, | ||
26 | }; | 37 | }; |
27 | 38 | ||
28 | static contextTypes = { | 39 | static contextTypes = { |
@@ -30,7 +41,13 @@ class WorkspacesDashboard extends Component { | |||
30 | }; | 41 | }; |
31 | 42 | ||
32 | render() { | 43 | render() { |
33 | const { workspaces, isLoading, onWorkspaceClick } = this.props; | 44 | const { |
45 | workspaces, | ||
46 | isLoading, | ||
47 | onCreateWorkspaceSubmit, | ||
48 | onWorkspaceClick, | ||
49 | classes, | ||
50 | } = this.props; | ||
34 | const { intl } = this.context; | 51 | const { intl } = this.context; |
35 | 52 | ||
36 | return ( | 53 | return ( |
@@ -39,21 +56,26 @@ class WorkspacesDashboard extends Component { | |||
39 | <h1>{intl.formatMessage(messages.headline)}</h1> | 56 | <h1>{intl.formatMessage(messages.headline)}</h1> |
40 | </div> | 57 | </div> |
41 | <div className="settings__body"> | 58 | <div className="settings__body"> |
42 | {isLoading ? ( | 59 | <div className={classes.body}> |
43 | <Loader /> | 60 | <div className={classes.createForm}> |
44 | ) : ( | 61 | <CreateWorkspaceForm onSubmit={onCreateWorkspaceSubmit} /> |
45 | <table className="workspace-table"> | 62 | </div> |
46 | <tbody> | 63 | {isLoading ? ( |
47 | {workspaces.map(workspace => ( | 64 | <Loader /> |
48 | <WorkspaceItem | 65 | ) : ( |
49 | key={workspace.id} | 66 | <table className="workspace-table"> |
50 | workspace={workspace} | 67 | <tbody> |
51 | onItemClick={w => onWorkspaceClick(w)} | 68 | {workspaces.map(workspace => ( |
52 | /> | 69 | <WorkspaceItem |
53 | ))} | 70 | key={workspace.id} |
54 | </tbody> | 71 | workspace={workspace} |
55 | </table> | 72 | onItemClick={w => onWorkspaceClick(w)} |
56 | )} | 73 | /> |
74 | ))} | ||
75 | </tbody> | ||
76 | </table> | ||
77 | )} | ||
78 | </div> | ||
57 | </div> | 79 | </div> |
58 | </div> | 80 | </div> |
59 | ); | 81 | ); |
diff --git a/src/features/workspaces/containers/WorkspacesScreen.js b/src/features/workspaces/containers/WorkspacesScreen.js index f129edec5..eb3287952 100644 --- a/src/features/workspaces/containers/WorkspacesScreen.js +++ b/src/features/workspaces/containers/WorkspacesScreen.js | |||
@@ -27,6 +27,7 @@ class WorkspacesScreen extends Component { | |||
27 | <WorkspacesDashboard | 27 | <WorkspacesDashboard |
28 | workspaces={state.workspaces} | 28 | workspaces={state.workspaces} |
29 | isLoading={state.isLoading} | 29 | isLoading={state.isLoading} |
30 | onCreateWorkspaceSubmit={data => workspace.create(data)} | ||
30 | onWorkspaceClick={w => workspace.edit({ workspace: w })} | 31 | onWorkspaceClick={w => workspace.edit({ workspace: w })} |
31 | /> | 32 | /> |
32 | </ErrorBoundary> | 33 | </ErrorBoundary> |
diff --git a/src/features/workspaces/store.js b/src/features/workspaces/store.js index ea61cec31..d90f9caac 100644 --- a/src/features/workspaces/store.js +++ b/src/features/workspaces/store.js | |||
@@ -49,6 +49,7 @@ export default class WorkspacesStore extends Store { | |||
49 | ); | 49 | ); |
50 | 50 | ||
51 | this.actions.workspace.edit.listen(this._edit); | 51 | this.actions.workspace.edit.listen(this._edit); |
52 | this.actions.workspace.create.listen(this._create); | ||
52 | } | 53 | } |
53 | 54 | ||
54 | _setWorkspaces = (workspaces) => { | 55 | _setWorkspaces = (workspaces) => { |
@@ -64,5 +65,16 @@ export default class WorkspacesStore extends Store { | |||
64 | 65 | ||
65 | _edit = ({ workspace }) => { | 66 | _edit = ({ workspace }) => { |
66 | this.stores.router.push(`/settings/workspaces/edit/${workspace.id}`); | 67 | this.stores.router.push(`/settings/workspaces/edit/${workspace.id}`); |
67 | } | 68 | }; |
69 | |||
70 | _create = async ({ name }) => { | ||
71 | try { | ||
72 | const result = await this.api.createWorkspace(name); | ||
73 | const workspace = new Workspace(result); | ||
74 | this.state.workspaces.push(workspace); | ||
75 | this._edit({ workspace }); | ||
76 | } catch (error) { | ||
77 | throw error; | ||
78 | } | ||
79 | }; | ||
68 | } | 80 | } |