diff options
Diffstat (limited to 'src/components/auth')
-rw-r--r-- | src/components/auth/Import.js | 168 | ||||
-rw-r--r-- | src/components/auth/SetupAssistant.tsx (renamed from src/components/auth/SetupAssistant.jsx) | 65 |
2 files changed, 33 insertions, 200 deletions
diff --git a/src/components/auth/Import.js b/src/components/auth/Import.js deleted file mode 100644 index b897116e2..000000000 --- a/src/components/auth/Import.js +++ /dev/null | |||
@@ -1,168 +0,0 @@ | |||
1 | import { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | ||
4 | import { defineMessages, injectIntl } from 'react-intl'; | ||
5 | import { Link } from 'react-router-dom'; | ||
6 | import classnames from 'classnames'; | ||
7 | import Form from '../../lib/Form'; | ||
8 | import Toggle from '../ui/toggle'; | ||
9 | import Button from '../ui/button'; | ||
10 | import { H1 } from '../ui/headline'; | ||
11 | |||
12 | const messages = defineMessages({ | ||
13 | headline: { | ||
14 | id: 'import.headline', | ||
15 | defaultMessage: 'Import your Ferdium 4 services', | ||
16 | }, | ||
17 | notSupportedHeadline: { | ||
18 | id: 'import.notSupportedHeadline', | ||
19 | defaultMessage: 'Services not yet supported in Ferdium 5', | ||
20 | }, | ||
21 | submitButtonLabel: { | ||
22 | id: 'import.submit.label', | ||
23 | defaultMessage: 'Import {count} services', | ||
24 | }, | ||
25 | skipButtonLabel: { | ||
26 | id: 'import.skip.label', | ||
27 | defaultMessage: 'I want to add services manually', | ||
28 | }, | ||
29 | }); | ||
30 | |||
31 | class Import extends Component { | ||
32 | static propTypes = { | ||
33 | services: MobxPropTypes.arrayOrObservableArray.isRequired, | ||
34 | onSubmit: PropTypes.func.isRequired, | ||
35 | isSubmitting: PropTypes.bool.isRequired, | ||
36 | inviteRoute: PropTypes.string.isRequired, | ||
37 | }; | ||
38 | |||
39 | componentDidMount() { | ||
40 | const config = { | ||
41 | fields: { | ||
42 | import: [ | ||
43 | ...this.props.services | ||
44 | .filter(s => s.recipe) | ||
45 | .map(s => ({ | ||
46 | fields: { | ||
47 | add: { | ||
48 | default: true, | ||
49 | options: s, | ||
50 | }, | ||
51 | }, | ||
52 | })), | ||
53 | ], | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | this.form = new Form(config, this.props.intl); | ||
58 | } | ||
59 | |||
60 | submit(e) { | ||
61 | const { services } = this.props; | ||
62 | e.preventDefault(); | ||
63 | this.form.submit({ | ||
64 | onSuccess: form => { | ||
65 | const servicesImport = form | ||
66 | .values() | ||
67 | .import.map( | ||
68 | (value, i) => !value.add || services.filter(s => s.recipe)[i], | ||
69 | ) | ||
70 | .filter(s => typeof s !== 'boolean'); | ||
71 | |||
72 | this.props.onSubmit({ services: servicesImport }); | ||
73 | }, | ||
74 | onError: () => {}, | ||
75 | }); | ||
76 | } | ||
77 | |||
78 | render() { | ||
79 | const { intl } = this.props; | ||
80 | const { services, isSubmitting, inviteRoute } = this.props; | ||
81 | |||
82 | const availableServices = services.filter(s => s.recipe); | ||
83 | const unavailableServices = services.filter(s => !s.recipe); | ||
84 | |||
85 | return ( | ||
86 | <div className="auth__scroll-container"> | ||
87 | <div className="auth__container auth__container--signup"> | ||
88 | <form | ||
89 | className="franz-form auth__form" | ||
90 | onSubmit={e => this.submit(e)} | ||
91 | > | ||
92 | <img src="./assets/images/logo.svg" className="auth__logo" alt="" /> | ||
93 | <H1>{intl.formatMessage(messages.headline)}</H1> | ||
94 | <table className="service-table available-services"> | ||
95 | <tbody> | ||
96 | {this.form.$('import').map((service, i) => ( | ||
97 | <tr key={service.id} className="service-table__row"> | ||
98 | <td className="service-table__toggle"> | ||
99 | <Toggle {...service.$('add').bind()} showLabel={false} /> | ||
100 | </td> | ||
101 | <td className="service-table__column-icon"> | ||
102 | <img | ||
103 | src={ | ||
104 | availableServices[i].custom_icon || | ||
105 | availableServices[i].recipe.icons.svg | ||
106 | } | ||
107 | className={classnames({ | ||
108 | 'service-table__icon': true, | ||
109 | 'has-custom-icon': availableServices[i].custom_icon, | ||
110 | })} | ||
111 | alt="" | ||
112 | /> | ||
113 | </td> | ||
114 | <td className="service-table__column-name"> | ||
115 | {availableServices[i].name !== '' | ||
116 | ? availableServices[i].name | ||
117 | : availableServices[i].recipe.name} | ||
118 | </td> | ||
119 | </tr> | ||
120 | ))} | ||
121 | </tbody> | ||
122 | </table> | ||
123 | {unavailableServices.length > 0 && ( | ||
124 | <div className="unavailable-services"> | ||
125 | <strong> | ||
126 | {intl.formatMessage(messages.notSupportedHeadline)} | ||
127 | </strong> | ||
128 | <p> | ||
129 | {services | ||
130 | .filter(s => !s.recipe) | ||
131 | .map((service, i) => ( | ||
132 | <span key={service.id}> | ||
133 | {service.name !== '' ? service.name : service.service} | ||
134 | {unavailableServices.length > i + 1 ? ', ' : ''} | ||
135 | </span> | ||
136 | ))} | ||
137 | </p> | ||
138 | </div> | ||
139 | )} | ||
140 | |||
141 | {isSubmitting ? ( | ||
142 | <Button | ||
143 | className="auth__button is-loading" | ||
144 | label={`${intl.formatMessage(messages.submitButtonLabel)} ...`} | ||
145 | loaded={false} | ||
146 | disabled | ||
147 | /> | ||
148 | ) : ( | ||
149 | <Button | ||
150 | type="submit" | ||
151 | className="auth__button" | ||
152 | label={intl.formatMessage(messages.submitButtonLabel)} | ||
153 | /> | ||
154 | )} | ||
155 | <Link | ||
156 | to={inviteRoute} | ||
157 | className="franz-form__button franz-form__button--secondary auth__button auth__button--skip" | ||
158 | > | ||
159 | {intl.formatMessage(messages.skipButtonLabel)} | ||
160 | </Link> | ||
161 | </form> | ||
162 | </div> | ||
163 | </div> | ||
164 | ); | ||
165 | } | ||
166 | } | ||
167 | |||
168 | export default injectIntl(observer(Import)); | ||
diff --git a/src/components/auth/SetupAssistant.jsx b/src/components/auth/SetupAssistant.tsx index 8d15e36d1..c5fb79919 100644 --- a/src/components/auth/SetupAssistant.jsx +++ b/src/components/auth/SetupAssistant.tsx | |||
@@ -1,10 +1,8 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer } from 'mobx-react'; | 2 | import { observer } from 'mobx-react'; |
4 | import { defineMessages, injectIntl } from 'react-intl'; | 3 | import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; |
5 | import injectSheet from 'react-jss'; | 4 | import withStyles, { WithStylesProps } from 'react-jss'; |
6 | import classnames from 'classnames'; | 5 | import classnames from 'classnames'; |
7 | |||
8 | import Input from '../ui/input/index'; | 6 | import Input from '../ui/input/index'; |
9 | import Button from '../ui/button'; | 7 | import Button from '../ui/button'; |
10 | import Badge from '../ui/badge'; | 8 | import Badge from '../ui/badge'; |
@@ -12,7 +10,6 @@ import Modal from '../ui/Modal'; | |||
12 | import Infobox from '../ui/Infobox'; | 10 | import Infobox from '../ui/Infobox'; |
13 | import Appear from '../ui/effects/Appear'; | 11 | import Appear from '../ui/effects/Appear'; |
14 | import globalMessages from '../../i18n/globalMessages'; | 12 | import globalMessages from '../../i18n/globalMessages'; |
15 | |||
16 | import { CDN_URL } from '../../config'; | 13 | import { CDN_URL } from '../../config'; |
17 | import { H1, H2 } from '../ui/headline'; | 14 | import { H1, H2 } from '../ui/headline'; |
18 | 15 | ||
@@ -42,11 +39,10 @@ const messages = defineMessages({ | |||
42 | }, | 39 | }, |
43 | }); | 40 | }); |
44 | 41 | ||
45 | let transition = 'none'; | 42 | const transition = |
46 | 43 | window && window.matchMedia('(prefers-reduced-motion: no-preference)') | |
47 | if (window && window.matchMedia('(prefers-reduced-motion: no-preference)')) { | 44 | ? 'all 0.25s' |
48 | transition = 'all 0.25s'; | 45 | : 'none'; |
49 | } | ||
50 | 46 | ||
51 | const styles = theme => ({ | 47 | const styles = theme => ({ |
52 | root: { | 48 | root: { |
@@ -136,39 +132,41 @@ const styles = theme => ({ | |||
136 | }, | 132 | }, |
137 | }); | 133 | }); |
138 | 134 | ||
139 | class SetupAssistant extends Component { | 135 | interface IProps extends WithStylesProps<typeof styles>, WrappedComponentProps { |
140 | static propTypes = { | 136 | onSubmit: (...args: any[]) => void; |
141 | classes: PropTypes.object.isRequired, | 137 | isInviteSuccessful?: boolean; |
142 | onSubmit: PropTypes.func.isRequired, | 138 | services: any; // TODO - [TS DEBT] check legacy services type |
143 | isInviteSuccessful: PropTypes.bool, | 139 | isSettingUpServices: boolean; |
144 | services: PropTypes.object.isRequired, | 140 | } |
145 | isSettingUpServices: PropTypes.bool.isRequired, | ||
146 | }; | ||
147 | 141 | ||
148 | static defaultProps = { | 142 | interface IState { |
149 | isInviteSuccessful: false, | 143 | services: any[]; |
150 | }; | 144 | isSlackModalOpen: boolean; |
145 | slackWorkspace: string; | ||
146 | showSuccessInfo: boolean; | ||
147 | } | ||
151 | 148 | ||
152 | constructor() { | 149 | @observer |
153 | super(); | 150 | class SetupAssistant extends Component<IProps, IState> { |
151 | constructor(props: IProps) { | ||
152 | super(props); | ||
154 | 153 | ||
155 | this.state = { | 154 | this.state = { |
156 | services: [], | 155 | services: [], |
157 | isSlackModalOpen: false, | 156 | isSlackModalOpen: false, |
157 | showSuccessInfo: false, | ||
158 | slackWorkspace: '', | 158 | slackWorkspace: '', |
159 | }; | 159 | }; |
160 | } | 160 | } |
161 | 161 | ||
162 | slackWorkspaceHandler() { | 162 | slackWorkspaceHandler(): void { |
163 | const { slackWorkspace = '', services } = this.state; | 163 | const { slackWorkspace = '', services } = this.state; |
164 | |||
165 | const sanitizedWorkspace = slackWorkspace | 164 | const sanitizedWorkspace = slackWorkspace |
166 | .trim() | 165 | .trim() |
167 | .replace(/^https?:\/\//, ''); | 166 | .replace(/^https?:\/\//, ''); |
168 | 167 | ||
169 | if (sanitizedWorkspace) { | 168 | if (sanitizedWorkspace) { |
170 | const index = services.findIndex(s => s.id === SLACK_ID); | 169 | const index = services.findIndex(s => s.id === SLACK_ID); |
171 | |||
172 | if (index === -1) { | 170 | if (index === -1) { |
173 | const newServices = services; | 171 | const newServices = services; |
174 | newServices.push({ id: SLACK_ID, team: sanitizedWorkspace }); | 172 | newServices.push({ id: SLACK_ID, team: sanitizedWorkspace }); |
@@ -183,13 +181,13 @@ class SetupAssistant extends Component { | |||
183 | } | 181 | } |
184 | 182 | ||
185 | render() { | 183 | render() { |
186 | const { intl } = this.props; | ||
187 | const { | 184 | const { |
188 | classes, | 185 | classes, |
189 | isInviteSuccessful, | 186 | isInviteSuccessful = false, |
190 | onSubmit, | 187 | onSubmit, |
191 | services, | 188 | services, |
192 | isSettingUpServices, | 189 | isSettingUpServices, |
190 | intl, | ||
193 | } = this.props; | 191 | } = this.props; |
194 | const { | 192 | const { |
195 | isSlackModalOpen, | 193 | isSlackModalOpen, |
@@ -204,7 +202,7 @@ class SetupAssistant extends Component { | |||
204 | <Infobox | 202 | <Infobox |
205 | type="success" | 203 | type="success" |
206 | icon="checkbox-marked-circle-outline" | 204 | icon="checkbox-marked-circle-outline" |
207 | dismissable | 205 | dismissible |
208 | > | 206 | > |
209 | {intl.formatMessage(messages.inviteSuccessInfo)} | 207 | {intl.formatMessage(messages.inviteSuccessInfo)} |
210 | </Infobox> | 208 | </Infobox> |
@@ -300,11 +298,14 @@ class SetupAssistant extends Component { | |||
300 | label={intl.formatMessage(globalMessages.save)} | 298 | label={intl.formatMessage(globalMessages.save)} |
301 | /> | 299 | /> |
302 | <Button | 300 | <Button |
303 | type="link" | 301 | type="button" |
304 | buttonType="secondary" | 302 | buttonType="secondary" |
305 | label={intl.formatMessage(globalMessages.cancel)} | 303 | label={intl.formatMessage(globalMessages.cancel)} |
306 | className={classes.ctaCancel} | 304 | className={classes.ctaCancel} |
307 | onClick={() => this.setState({ slackWorkspace: '' })} | 305 | onClick={e => { |
306 | e.preventDefault(); | ||
307 | this.setState({ slackWorkspace: '' }); | ||
308 | }} | ||
308 | /> | 309 | /> |
309 | </div> | 310 | </div> |
310 | </form> | 311 | </form> |
@@ -332,5 +333,5 @@ class SetupAssistant extends Component { | |||
332 | } | 333 | } |
333 | 334 | ||
334 | export default injectIntl( | 335 | export default injectIntl( |
335 | injectSheet(styles, { injectTheme: true })(observer(SetupAssistant)), | 336 | withStyles(styles, { injectTheme: true })(SetupAssistant), |
336 | ); | 337 | ); |