diff options
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/layout/AppLayout.js | 2 | ||||
-rw-r--r-- | src/components/services/content/ServiceView.js | 136 | ||||
-rw-r--r-- | src/components/services/content/ServiceWebview.js | 145 | ||||
-rw-r--r-- | src/components/services/content/Services.js | 7 | ||||
-rw-r--r-- | src/components/services/content/WebviewCrashHandler.js | 7 | ||||
-rw-r--r-- | src/components/settings/account/AccountDashboard.js | 75 | ||||
-rw-r--r-- | src/components/settings/user/EditUserForm.js | 25 | ||||
-rw-r--r-- | src/components/subscription/SubscriptionForm.js | 60 | ||||
-rw-r--r-- | src/components/subscription/SubscriptionPopup.js | 3 | ||||
-rw-r--r-- | src/components/ui/Modal/index.js | 26 | ||||
-rw-r--r-- | src/components/ui/Modal/styles.js | 1 |
11 files changed, 251 insertions, 236 deletions
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js index bce792e56..593149e72 100644 --- a/src/components/layout/AppLayout.js +++ b/src/components/layout/AppLayout.js | |||
@@ -7,6 +7,7 @@ import { TitleBar } from 'electron-react-titlebar'; | |||
7 | import InfoBar from '../ui/InfoBar'; | 7 | import InfoBar from '../ui/InfoBar'; |
8 | import { Component as DelayApp } from '../../features/delayApp'; | 8 | import { Component as DelayApp } from '../../features/delayApp'; |
9 | import { Component as BasicAuth } from '../../features/basicAuth'; | 9 | import { Component as BasicAuth } from '../../features/basicAuth'; |
10 | import { Component as ShareFranz } from '../../features/shareFranz'; | ||
10 | import ErrorBoundary from '../util/ErrorBoundary'; | 11 | import ErrorBoundary from '../util/ErrorBoundary'; |
11 | 12 | ||
12 | // import globalMessages from '../../i18n/globalMessages'; | 13 | // import globalMessages from '../../i18n/globalMessages'; |
@@ -164,6 +165,7 @@ export default @observer class AppLayout extends Component { | |||
164 | )} | 165 | )} |
165 | {isDelayAppScreenVisible && (<DelayApp />)} | 166 | {isDelayAppScreenVisible && (<DelayApp />)} |
166 | <BasicAuth /> | 167 | <BasicAuth /> |
168 | <ShareFranz /> | ||
167 | {services} | 169 | {services} |
168 | </div> | 170 | </div> |
169 | </div> | 171 | </div> |
diff --git a/src/components/services/content/ServiceView.js b/src/components/services/content/ServiceView.js new file mode 100644 index 000000000..5afc54f9d --- /dev/null +++ b/src/components/services/content/ServiceView.js | |||
@@ -0,0 +1,136 @@ | |||
1 | import React, { Component, Fragment } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { autorun } from 'mobx'; | ||
4 | import { observer } from 'mobx-react'; | ||
5 | import classnames from 'classnames'; | ||
6 | |||
7 | import ServiceModel from '../../../models/Service'; | ||
8 | import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl'; | ||
9 | import WebviewLoader from '../../ui/WebviewLoader'; | ||
10 | import WebviewCrashHandler from './WebviewCrashHandler'; | ||
11 | import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; | ||
12 | import ServiceDisabled from './ServiceDisabled'; | ||
13 | import ServiceWebview from './ServiceWebview'; | ||
14 | |||
15 | export default @observer class ServiceView extends Component { | ||
16 | static propTypes = { | ||
17 | service: PropTypes.instanceOf(ServiceModel).isRequired, | ||
18 | setWebviewReference: PropTypes.func.isRequired, | ||
19 | detachService: PropTypes.func.isRequired, | ||
20 | reload: PropTypes.func.isRequired, | ||
21 | edit: PropTypes.func.isRequired, | ||
22 | enable: PropTypes.func.isRequired, | ||
23 | isActive: PropTypes.bool, | ||
24 | }; | ||
25 | |||
26 | static defaultProps = { | ||
27 | isActive: false, | ||
28 | }; | ||
29 | |||
30 | state = { | ||
31 | forceRepaint: false, | ||
32 | targetUrl: '', | ||
33 | statusBarVisible: false, | ||
34 | }; | ||
35 | |||
36 | autorunDisposer = null; | ||
37 | |||
38 | componentDidMount() { | ||
39 | this.autorunDisposer = autorun(() => { | ||
40 | if (this.props.service.isActive) { | ||
41 | this.setState({ forceRepaint: true }); | ||
42 | setTimeout(() => { | ||
43 | this.setState({ forceRepaint: false }); | ||
44 | }, 100); | ||
45 | } | ||
46 | }); | ||
47 | } | ||
48 | |||
49 | componentWillUnmount() { | ||
50 | this.autorunDisposer(); | ||
51 | } | ||
52 | |||
53 | updateTargetUrl = (event) => { | ||
54 | let visible = true; | ||
55 | if (event.url === '' || event.url === '#') { | ||
56 | visible = false; | ||
57 | } | ||
58 | this.setState({ | ||
59 | targetUrl: event.url, | ||
60 | statusBarVisible: visible, | ||
61 | }); | ||
62 | }; | ||
63 | |||
64 | render() { | ||
65 | const { | ||
66 | detachService, | ||
67 | service, | ||
68 | setWebviewReference, | ||
69 | reload, | ||
70 | edit, | ||
71 | enable, | ||
72 | } = this.props; | ||
73 | |||
74 | const webviewClasses = classnames({ | ||
75 | services__webview: true, | ||
76 | 'services__webview-wrapper': true, | ||
77 | 'is-active': service.isActive, | ||
78 | 'services__webview--force-repaint': this.state.forceRepaint, | ||
79 | }); | ||
80 | |||
81 | let statusBar = null; | ||
82 | if (this.state.statusBarVisible) { | ||
83 | statusBar = ( | ||
84 | <StatusBarTargetUrl text={this.state.targetUrl} /> | ||
85 | ); | ||
86 | } | ||
87 | |||
88 | return ( | ||
89 | <div className={webviewClasses}> | ||
90 | {service.isActive && service.isEnabled && ( | ||
91 | <Fragment> | ||
92 | {service.hasCrashed && ( | ||
93 | <WebviewCrashHandler | ||
94 | name={service.recipe.name} | ||
95 | webview={service.webview} | ||
96 | reload={reload} | ||
97 | /> | ||
98 | )} | ||
99 | {service.isEnabled && service.isLoading && service.isFirstLoad && ( | ||
100 | <WebviewLoader | ||
101 | loaded={false} | ||
102 | name={service.name} | ||
103 | /> | ||
104 | )} | ||
105 | {service.isError && ( | ||
106 | <WebviewErrorHandler | ||
107 | name={service.recipe.name} | ||
108 | errorMessage={service.errorMessage} | ||
109 | reload={reload} | ||
110 | edit={edit} | ||
111 | /> | ||
112 | )} | ||
113 | </Fragment> | ||
114 | )} | ||
115 | {!service.isEnabled ? ( | ||
116 | <Fragment> | ||
117 | {service.isActive && ( | ||
118 | <ServiceDisabled | ||
119 | name={service.recipe.name} | ||
120 | webview={service.webview} | ||
121 | enable={enable} | ||
122 | /> | ||
123 | )} | ||
124 | </Fragment> | ||
125 | ) : ( | ||
126 | <ServiceWebview | ||
127 | service={service} | ||
128 | setWebviewReference={setWebviewReference} | ||
129 | detachService={detachService} | ||
130 | /> | ||
131 | )} | ||
132 | {statusBar} | ||
133 | </div> | ||
134 | ); | ||
135 | } | ||
136 | } | ||
diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js index bb577e4cc..7252c695f 100644 --- a/src/components/services/content/ServiceWebview.js +++ b/src/components/services/content/ServiceWebview.js | |||
@@ -1,145 +1,50 @@ | |||
1 | import React, { Component, Fragment } from 'react'; | 1 | import React, { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { autorun } from 'mobx'; | ||
4 | import { observer } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
5 | import Webview from 'react-electron-web-view'; | 4 | import ElectronWebView from 'react-electron-web-view'; |
6 | import classnames from 'classnames'; | ||
7 | 5 | ||
8 | import ServiceModel from '../../../models/Service'; | 6 | import ServiceModel from '../../../models/Service'; |
9 | import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl'; | ||
10 | import WebviewLoader from '../../ui/WebviewLoader'; | ||
11 | import WebviewCrashHandler from './WebviewCrashHandler'; | ||
12 | import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; | ||
13 | import ServiceDisabled from './ServiceDisabled'; | ||
14 | 7 | ||
15 | export default @observer class ServiceWebview extends Component { | 8 | @observer |
9 | class ServiceWebview extends Component { | ||
16 | static propTypes = { | 10 | static propTypes = { |
17 | service: PropTypes.instanceOf(ServiceModel).isRequired, | 11 | service: PropTypes.instanceOf(ServiceModel).isRequired, |
18 | setWebviewReference: PropTypes.func.isRequired, | 12 | setWebviewReference: PropTypes.func.isRequired, |
19 | reload: PropTypes.func.isRequired, | 13 | detachService: PropTypes.func.isRequired, |
20 | edit: PropTypes.func.isRequired, | ||
21 | enable: PropTypes.func.isRequired, | ||
22 | isActive: PropTypes.bool, | ||
23 | }; | 14 | }; |
24 | 15 | ||
25 | static defaultProps = { | ||
26 | isActive: false, | ||
27 | }; | ||
28 | |||
29 | state = { | ||
30 | forceRepaint: false, | ||
31 | targetUrl: '', | ||
32 | statusBarVisible: false, | ||
33 | }; | ||
34 | |||
35 | autorunDisposer = null; | ||
36 | |||
37 | webview = null; | 16 | webview = null; |
38 | 17 | ||
39 | componentDidMount() { | ||
40 | this.autorunDisposer = autorun(() => { | ||
41 | if (this.props.service.isActive) { | ||
42 | this.setState({ forceRepaint: true }); | ||
43 | setTimeout(() => { | ||
44 | this.setState({ forceRepaint: false }); | ||
45 | }, 100); | ||
46 | } | ||
47 | }); | ||
48 | } | ||
49 | |||
50 | componentWillUnmount() { | 18 | componentWillUnmount() { |
51 | this.autorunDisposer(); | 19 | const { service, detachService } = this.props; |
52 | } | 20 | detachService({ service }); |
53 | |||
54 | updateTargetUrl = (event) => { | ||
55 | let visible = true; | ||
56 | if (event.url === '' || event.url === '#') { | ||
57 | visible = false; | ||
58 | } | ||
59 | this.setState({ | ||
60 | targetUrl: event.url, | ||
61 | statusBarVisible: visible, | ||
62 | }); | ||
63 | } | 21 | } |
64 | 22 | ||
65 | render() { | 23 | render() { |
66 | const { | 24 | const { |
67 | service, | 25 | service, |
68 | setWebviewReference, | 26 | setWebviewReference, |
69 | reload, | ||
70 | edit, | ||
71 | enable, | ||
72 | } = this.props; | 27 | } = this.props; |
73 | 28 | ||
74 | const webviewClasses = classnames({ | ||
75 | services__webview: true, | ||
76 | 'services__webview-wrapper': true, | ||
77 | 'is-active': service.isActive, | ||
78 | 'services__webview--force-repaint': this.state.forceRepaint, | ||
79 | }); | ||
80 | |||
81 | let statusBar = null; | ||
82 | if (this.state.statusBarVisible) { | ||
83 | statusBar = ( | ||
84 | <StatusBarTargetUrl text={this.state.targetUrl} /> | ||
85 | ); | ||
86 | } | ||
87 | |||
88 | return ( | 29 | return ( |
89 | <div className={webviewClasses}> | 30 | <ElectronWebView |
90 | {service.isActive && service.isEnabled && ( | 31 | ref={(webview) => { this.webview = webview; }} |
91 | <Fragment> | 32 | autosize |
92 | {service.hasCrashed && ( | 33 | src={service.url} |
93 | <WebviewCrashHandler | 34 | preload="./webview/recipe.js" |
94 | name={service.recipe.name} | 35 | partition={`persist:service-${service.id}`} |
95 | webview={service.webview} | 36 | onDidAttach={() => { |
96 | reload={reload} | 37 | setWebviewReference({ |
97 | /> | 38 | serviceId: service.id, |
98 | )} | 39 | webview: this.webview.view, |
99 | {service.isEnabled && service.isLoading && service.isFirstLoad && ( | 40 | }); |
100 | <WebviewLoader | 41 | }} |
101 | loaded={false} | 42 | onUpdateTargetUrl={this.updateTargetUrl} |
102 | name={service.name} | 43 | useragent={service.userAgent} |
103 | /> | 44 | allowpopups |
104 | )} | 45 | /> |
105 | {service.isError && ( | ||
106 | <WebviewErrorHandler | ||
107 | name={service.recipe.name} | ||
108 | errorMessage={service.errorMessage} | ||
109 | reload={reload} | ||
110 | edit={edit} | ||
111 | /> | ||
112 | )} | ||
113 | </Fragment> | ||
114 | )} | ||
115 | {!service.isEnabled ? ( | ||
116 | <Fragment> | ||
117 | {service.isActive && ( | ||
118 | <ServiceDisabled | ||
119 | name={service.recipe.name} | ||
120 | webview={service.webview} | ||
121 | enable={enable} | ||
122 | /> | ||
123 | )} | ||
124 | </Fragment> | ||
125 | ) : ( | ||
126 | <Webview | ||
127 | ref={(element) => { this.webview = element; }} | ||
128 | autosize | ||
129 | src={service.url} | ||
130 | preload="./webview/recipe.js" | ||
131 | partition={`persist:service-${service.id}`} | ||
132 | onDidAttach={() => setWebviewReference({ | ||
133 | serviceId: service.id, | ||
134 | webview: this.webview.view, | ||
135 | })} | ||
136 | onUpdateTargetUrl={this.updateTargetUrl} | ||
137 | useragent={service.userAgent} | ||
138 | allowpopups | ||
139 | /> | ||
140 | )} | ||
141 | {statusBar} | ||
142 | </div> | ||
143 | ); | 46 | ); |
144 | } | 47 | } |
145 | } | 48 | } |
49 | |||
50 | export default ServiceWebview; | ||
diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js index 54f16ba12..8f8c38a11 100644 --- a/src/components/services/content/Services.js +++ b/src/components/services/content/Services.js | |||
@@ -4,7 +4,7 @@ import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | |||
4 | import { Link } from 'react-router'; | 4 | import { Link } from 'react-router'; |
5 | import { defineMessages, intlShape } from 'react-intl'; | 5 | import { defineMessages, intlShape } from 'react-intl'; |
6 | 6 | ||
7 | import Webview from './ServiceWebview'; | 7 | import ServiceView from './ServiceView'; |
8 | import Appear from '../../ui/effects/Appear'; | 8 | import Appear from '../../ui/effects/Appear'; |
9 | 9 | ||
10 | const messages = defineMessages({ | 10 | const messages = defineMessages({ |
@@ -22,6 +22,7 @@ export default @observer class Services extends Component { | |||
22 | static propTypes = { | 22 | static propTypes = { |
23 | services: MobxPropTypes.arrayOrObservableArray, | 23 | services: MobxPropTypes.arrayOrObservableArray, |
24 | setWebviewReference: PropTypes.func.isRequired, | 24 | setWebviewReference: PropTypes.func.isRequired, |
25 | detachService: PropTypes.func.isRequired, | ||
25 | handleIPCMessage: PropTypes.func.isRequired, | 26 | handleIPCMessage: PropTypes.func.isRequired, |
26 | openWindow: PropTypes.func.isRequired, | 27 | openWindow: PropTypes.func.isRequired, |
27 | reload: PropTypes.func.isRequired, | 28 | reload: PropTypes.func.isRequired, |
@@ -42,6 +43,7 @@ export default @observer class Services extends Component { | |||
42 | services, | 43 | services, |
43 | handleIPCMessage, | 44 | handleIPCMessage, |
44 | setWebviewReference, | 45 | setWebviewReference, |
46 | detachService, | ||
45 | openWindow, | 47 | openWindow, |
46 | reload, | 48 | reload, |
47 | openSettings, | 49 | openSettings, |
@@ -71,11 +73,12 @@ export default @observer class Services extends Component { | |||
71 | </Appear> | 73 | </Appear> |
72 | )} | 74 | )} |
73 | {services.map(service => ( | 75 | {services.map(service => ( |
74 | <Webview | 76 | <ServiceView |
75 | key={service.id} | 77 | key={service.id} |
76 | service={service} | 78 | service={service} |
77 | handleIPCMessage={handleIPCMessage} | 79 | handleIPCMessage={handleIPCMessage} |
78 | setWebviewReference={setWebviewReference} | 80 | setWebviewReference={setWebviewReference} |
81 | detachService={detachService} | ||
79 | openWindow={openWindow} | 82 | openWindow={openWindow} |
80 | reload={() => reload({ serviceId: service.id })} | 83 | reload={() => reload({ serviceId: service.id })} |
81 | edit={() => openSettings({ path: `services/edit/${service.id}` })} | 84 | edit={() => openSettings({ path: `services/edit/${service.id}` })} |
diff --git a/src/components/services/content/WebviewCrashHandler.js b/src/components/services/content/WebviewCrashHandler.js index 42bc3c877..7a69dba87 100644 --- a/src/components/services/content/WebviewCrashHandler.js +++ b/src/components/services/content/WebviewCrashHandler.js | |||
@@ -2,6 +2,7 @@ import React, { Component } from 'react'; | |||
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { observer } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
4 | import { defineMessages, intlShape } from 'react-intl'; | 4 | import { defineMessages, intlShape } from 'react-intl'; |
5 | import ms from 'ms'; | ||
5 | 6 | ||
6 | import Button from '../../ui/Button'; | 7 | import Button from '../../ui/Button'; |
7 | 8 | ||
@@ -35,12 +36,12 @@ export default @observer class WebviewCrashHandler extends Component { | |||
35 | }; | 36 | }; |
36 | 37 | ||
37 | state = { | 38 | state = { |
38 | countdown: 10000, | 39 | countdown: ms('10s'), |
39 | } | 40 | } |
40 | 41 | ||
41 | countdownInterval = null; | 42 | countdownInterval = null; |
42 | 43 | ||
43 | countdownIntervalTimeout = 1000; | 44 | countdownIntervalTimeout = ms('1s'); |
44 | 45 | ||
45 | 46 | ||
46 | componentDidMount() { | 47 | componentDidMount() { |
@@ -75,7 +76,7 @@ export default @observer class WebviewCrashHandler extends Component { | |||
75 | <p className="footnote"> | 76 | <p className="footnote"> |
76 | {intl.formatMessage(messages.autoReload, { | 77 | {intl.formatMessage(messages.autoReload, { |
77 | name, | 78 | name, |
78 | seconds: this.state.countdown / 1000, | 79 | seconds: this.state.countdown / ms('1s'), |
79 | })} | 80 | })} |
80 | </p> | 81 | </p> |
81 | </div> | 82 | </div> |
diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js index 9c9543749..181b95c8c 100644 --- a/src/components/settings/account/AccountDashboard.js +++ b/src/components/settings/account/AccountDashboard.js | |||
@@ -44,10 +44,6 @@ const messages = defineMessages({ | |||
44 | id: 'settings.account.accountType.premium', | 44 | id: 'settings.account.accountType.premium', |
45 | defaultMessage: '!!!Premium Supporter Account', | 45 | defaultMessage: '!!!Premium Supporter Account', |
46 | }, | 46 | }, |
47 | accountTypeEnterprise: { | ||
48 | id: 'settings.account.accountType.enterprise', | ||
49 | defaultMessage: '!!!Enterprise Account', | ||
50 | }, | ||
51 | accountEditButton: { | 47 | accountEditButton: { |
52 | id: 'settings.account.account.editButton', | 48 | id: 'settings.account.account.editButton', |
53 | defaultMessage: '!!!Edit Account', | 49 | defaultMessage: '!!!Edit Account', |
@@ -169,15 +165,9 @@ export default @observer class AccountDashboard extends Component { | |||
169 | {user.organization && `${user.organization}, `} | 165 | {user.organization && `${user.organization}, `} |
170 | {user.email} | 166 | {user.email} |
171 | <br /> | 167 | <br /> |
172 | {!user.isEnterprise && !user.isPremium && ( | ||
173 | <span className="badge badge">{intl.formatMessage(messages.accountTypeBasic)}</span> | ||
174 | )} | ||
175 | {user.isPremium && ( | 168 | {user.isPremium && ( |
176 | <span className="badge badge--premium">{intl.formatMessage(messages.accountTypePremium)}</span> | 169 | <span className="badge badge--premium">{intl.formatMessage(messages.accountTypePremium)}</span> |
177 | )} | 170 | )} |
178 | {user.isEnterprise && ( | ||
179 | <span className="badge badge--success">{intl.formatMessage(messages.accountTypeEnterprise)}</span> | ||
180 | )} | ||
181 | </div> | 171 | </div> |
182 | <Link to="/settings/user/edit" className="button"> | 172 | <Link to="/settings/user/edit" className="button"> |
183 | {intl.formatMessage(messages.accountEditButton)} | 173 | {intl.formatMessage(messages.accountEditButton)} |
@@ -235,34 +225,7 @@ export default @observer class AccountDashboard extends Component { | |||
235 | ) | 225 | ) |
236 | )} | 226 | )} |
237 | 227 | ||
238 | {user.isEnterprise && ( | 228 | {!user.isPremium && ( |
239 | <div className="account"> | ||
240 | <div className="account__box"> | ||
241 | <h2>{user.company.name}</h2> | ||
242 | <p> | ||
243 | Technical contact: | ||
244 | <Link | ||
245 | className="link" | ||
246 | target="_blank" | ||
247 | to={`mailto:${user.company.contact.technical}?subject=Franz`} | ||
248 | > | ||
249 | {user.company.contact.technical} | ||
250 | </Link> | ||
251 | <br /> | ||
252 | General contact: | ||
253 | <Link | ||
254 | className="link" | ||
255 | target="_blank" | ||
256 | to={`mailto:${user.company.contact.default}?subject=Franz`} | ||
257 | > | ||
258 | {user.company.contact.default} | ||
259 | </Link> | ||
260 | </p> | ||
261 | </div> | ||
262 | </div> | ||
263 | )} | ||
264 | |||
265 | {!user.isEnterprise && !user.isPremium && ( | ||
266 | isLoadingPlans ? ( | 229 | isLoadingPlans ? ( |
267 | <Loader /> | 230 | <Loader /> |
268 | ) : ( | 231 | ) : ( |
@@ -277,27 +240,25 @@ export default @observer class AccountDashboard extends Component { | |||
277 | ) | 240 | ) |
278 | )} | 241 | )} |
279 | 242 | ||
280 | {!user.isEnterprise && ( | 243 | <div className="account franz-form"> |
281 | <div className="account franz-form"> | 244 | <div className="account__box"> |
282 | <div className="account__box"> | 245 | <h2>{intl.formatMessage(messages.headlineDangerZone)}</h2> |
283 | <h2>{intl.formatMessage(messages.headlineDangerZone)}</h2> | 246 | {!isDeleteAccountSuccessful && ( |
284 | {!isDeleteAccountSuccessful && ( | 247 | <div className="account__subscription"> |
285 | <div className="account__subscription"> | 248 | <p>{intl.formatMessage(messages.deleteInfo)}</p> |
286 | <p>{intl.formatMessage(messages.deleteInfo)}</p> | 249 | <Button |
287 | <Button | 250 | label={intl.formatMessage(messages.deleteAccount)} |
288 | label={intl.formatMessage(messages.deleteAccount)} | 251 | buttonType="danger" |
289 | buttonType="danger" | 252 | onClick={() => deleteAccount()} |
290 | onClick={() => deleteAccount()} | 253 | loaded={!isLoadingDeleteAccount} |
291 | loaded={!isLoadingDeleteAccount} | 254 | /> |
292 | /> | ||
293 | </div> | ||
294 | )} | ||
295 | {isDeleteAccountSuccessful && ( | ||
296 | <p>{intl.formatMessage(messages.deleteEmailSent)}</p> | ||
297 | )} | ||
298 | </div> | 255 | </div> |
256 | )} | ||
257 | {isDeleteAccountSuccessful && ( | ||
258 | <p>{intl.formatMessage(messages.deleteEmailSent)}</p> | ||
259 | )} | ||
299 | </div> | 260 | </div> |
300 | )} | 261 | </div> |
301 | </Fragment> | 262 | </Fragment> |
302 | )} | 263 | )} |
303 | </div> | 264 | </div> |
diff --git a/src/components/settings/user/EditUserForm.js b/src/components/settings/user/EditUserForm.js index 0e3ac6b10..a1a353e57 100644 --- a/src/components/settings/user/EditUserForm.js +++ b/src/components/settings/user/EditUserForm.js | |||
@@ -3,11 +3,10 @@ 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 { Link } from 'react-router'; | 5 | import { Link } from 'react-router'; |
6 | 6 | import { Input } from '@meetfranz/forms'; | |
7 | // import { Link } from 'react-router'; | ||
8 | 7 | ||
9 | import Form from '../../../lib/Form'; | 8 | import Form from '../../../lib/Form'; |
10 | import Input from '../../ui/Input'; | 9 | // import Input from '../../ui/Input'; |
11 | import Button from '../../ui/Button'; | 10 | import Button from '../../ui/Button'; |
12 | import Radio from '../../ui/Radio'; | 11 | import Radio from '../../ui/Radio'; |
13 | import Infobox from '../../ui/Infobox'; | 12 | import Infobox from '../../ui/Infobox'; |
@@ -39,13 +38,12 @@ const messages = defineMessages({ | |||
39 | }, | 38 | }, |
40 | }); | 39 | }); |
41 | 40 | ||
42 | export default @observer class EditServiceForm extends Component { | 41 | export default @observer class EditUserForm extends Component { |
43 | static propTypes = { | 42 | static propTypes = { |
44 | status: MobxPropTypes.observableArray.isRequired, | 43 | status: MobxPropTypes.observableArray.isRequired, |
45 | form: PropTypes.instanceOf(Form).isRequired, | 44 | form: PropTypes.instanceOf(Form).isRequired, |
46 | onSubmit: PropTypes.func.isRequired, | 45 | onSubmit: PropTypes.func.isRequired, |
47 | isSaving: PropTypes.bool.isRequired, | 46 | isSaving: PropTypes.bool.isRequired, |
48 | isEnterprise: PropTypes.bool.isRequired, | ||
49 | }; | 47 | }; |
50 | 48 | ||
51 | static contextTypes = { | 49 | static contextTypes = { |
@@ -68,7 +66,6 @@ export default @observer class EditServiceForm extends Component { | |||
68 | // user, | 66 | // user, |
69 | status, | 67 | status, |
70 | form, | 68 | form, |
71 | isEnterprise, | ||
72 | isSaving, | 69 | isSaving, |
73 | } = this.props; | 70 | } = this.props; |
74 | const { intl } = this.context; | 71 | const { intl } = this.context; |
@@ -98,23 +95,21 @@ export default @observer class EditServiceForm extends Component { | |||
98 | )} | 95 | )} |
99 | <h2>{intl.formatMessage(messages.headlineAccount)}</h2> | 96 | <h2>{intl.formatMessage(messages.headlineAccount)}</h2> |
100 | <div className="grid__row"> | 97 | <div className="grid__row"> |
101 | <Input field={form.$('firstname')} focus /> | 98 | <Input {...form.$('firstname').bind()} focus /> |
102 | <Input field={form.$('lastname')} /> | 99 | <Input {...form.$('lastname').bind()} /> |
103 | </div> | 100 | </div> |
104 | <Input field={form.$('email')} /> | 101 | <Input {...form.$('email').bind()} /> |
105 | {!isEnterprise && ( | 102 | <Radio field={form.$('accountType')} /> |
106 | <Radio field={form.$('accountType')} /> | 103 | {form.$('accountType').value === 'company' && ( |
107 | )} | ||
108 | {!isEnterprise && form.$('accountType').value === 'company' && ( | ||
109 | <Input field={form.$('organization')} /> | 104 | <Input field={form.$('organization')} /> |
110 | )} | 105 | )} |
111 | <h2>{intl.formatMessage(messages.headlinePassword)}</h2> | 106 | <h2>{intl.formatMessage(messages.headlinePassword)}</h2> |
112 | <Input | 107 | <Input |
113 | field={form.$('oldPassword')} | 108 | {...form.$('oldPassword').bind()} |
114 | showPasswordToggle | 109 | showPasswordToggle |
115 | /> | 110 | /> |
116 | <Input | 111 | <Input |
117 | field={form.$('newPassword')} | 112 | {...form.$('newPassword').bind()} |
118 | showPasswordToggle | 113 | showPasswordToggle |
119 | scorePassword | 114 | scorePassword |
120 | /> | 115 | /> |
diff --git a/src/components/subscription/SubscriptionForm.js b/src/components/subscription/SubscriptionForm.js index 90da8ddc3..7a818d100 100644 --- a/src/components/subscription/SubscriptionForm.js +++ b/src/components/subscription/SubscriptionForm.js | |||
@@ -35,31 +35,29 @@ const messages = defineMessages({ | |||
35 | id: 'subscription.includedFeatures', | 35 | id: 'subscription.includedFeatures', |
36 | defaultMessage: '!!!The Franz Premium Supporter Account includes', | 36 | defaultMessage: '!!!The Franz Premium Supporter Account includes', |
37 | }, | 37 | }, |
38 | features: { | 38 | onpremise: { |
39 | onpremise: { | 39 | id: 'subscription.features.onpremise.mattermost', |
40 | id: 'subscription.features.onpremise.mattermost', | 40 | defaultMessage: '!!!Add on-premise/hosted services like Mattermost', |
41 | defaultMessage: '!!!Add on-premise/hosted services like Mattermost', | 41 | }, |
42 | }, | 42 | noInterruptions: { |
43 | noInterruptions: { | 43 | id: 'subscription.features.noInterruptions', |
44 | id: 'subscription.features.noInterruptions', | 44 | defaultMessage: '!!!No app delays & nagging to upgrade license', |
45 | defaultMessage: '!!!No app delays & nagging to upgrade license', | 45 | }, |
46 | }, | 46 | proxy: { |
47 | proxy: { | 47 | id: 'subscription.features.proxy', |
48 | id: 'subscription.features.proxy', | 48 | defaultMessage: '!!!Proxy support for services', |
49 | defaultMessage: '!!!Proxy support for services', | 49 | }, |
50 | }, | 50 | spellchecker: { |
51 | spellchecker: { | 51 | id: 'subscription.features.spellchecker', |
52 | id: 'subscription.features.spellchecker', | 52 | defaultMessage: '!!!Support for Spellchecker', |
53 | defaultMessage: '!!!Support for Spellchecker', | 53 | }, |
54 | }, | 54 | ads: { |
55 | ads: { | 55 | id: 'subscription.features.ads', |
56 | id: 'subscription.features.ads', | 56 | defaultMessage: '!!!No ads, ever!', |
57 | defaultMessage: '!!!No ads, ever!', | 57 | }, |
58 | }, | 58 | comingSoon: { |
59 | comingSoon: { | 59 | id: 'subscription.features.comingSoon', |
60 | id: 'subscription.features.comingSoon', | 60 | defaultMessage: '!!!coming soon', |
61 | defaultMessage: '!!!coming soon', | ||
62 | }, | ||
63 | }, | 61 | }, |
64 | euTaxInfo: { | 62 | euTaxInfo: { |
65 | id: 'subscription.euTaxInfo', | 63 | id: 'subscription.euTaxInfo', |
@@ -85,7 +83,7 @@ export default @observer class SubscriptionForm extends Component { | |||
85 | showSkipOption: false, | 83 | showSkipOption: false, |
86 | skipAction: () => null, | 84 | skipAction: () => null, |
87 | skipButtonLabel: '', | 85 | skipButtonLabel: '', |
88 | } | 86 | }; |
89 | 87 | ||
90 | static contextTypes = { | 88 | static contextTypes = { |
91 | intl: intlShape, | 89 | intl: intlShape, |
@@ -162,18 +160,18 @@ export default @observer class SubscriptionForm extends Component { | |||
162 | </p> | 160 | </p> |
163 | <div className="subscription"> | 161 | <div className="subscription"> |
164 | <ul className="subscription__premium-features"> | 162 | <ul className="subscription__premium-features"> |
165 | <li>{intl.formatMessage(messages.features.onpremise)}</li> | 163 | <li>{intl.formatMessage(messages.onpremise)}</li> |
166 | <li> | 164 | <li> |
167 | {intl.formatMessage(messages.features.noInterruptions)} | 165 | {intl.formatMessage(messages.noInterruptions)} |
168 | </li> | 166 | </li> |
169 | <li> | 167 | <li> |
170 | {intl.formatMessage(messages.features.spellchecker)} | 168 | {intl.formatMessage(messages.spellchecker)} |
171 | </li> | 169 | </li> |
172 | <li> | 170 | <li> |
173 | {intl.formatMessage(messages.features.proxy)} | 171 | {intl.formatMessage(messages.proxy)} |
174 | </li> | 172 | </li> |
175 | <li> | 173 | <li> |
176 | {intl.formatMessage(messages.features.ads)} | 174 | {intl.formatMessage(messages.ads)} |
177 | </li> | 175 | </li> |
178 | </ul> | 176 | </ul> |
179 | </div> | 177 | </div> |
diff --git a/src/components/subscription/SubscriptionPopup.js b/src/components/subscription/SubscriptionPopup.js index b5d7c4b2d..0f6f0260f 100644 --- a/src/components/subscription/SubscriptionPopup.js +++ b/src/components/subscription/SubscriptionPopup.js | |||
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; | |||
3 | import { observer } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
4 | import { defineMessages, intlShape } from 'react-intl'; | 4 | import { defineMessages, intlShape } from 'react-intl'; |
5 | import Webview from 'react-electron-web-view'; | 5 | import Webview from 'react-electron-web-view'; |
6 | import ms from 'ms'; | ||
6 | 7 | ||
7 | import Button from '../ui/Button'; | 8 | import Button from '../ui/Button'; |
8 | 9 | ||
@@ -42,7 +43,7 @@ export default @observer class SubscriptionPopup extends Component { | |||
42 | 43 | ||
43 | setTimeout(() => { | 44 | setTimeout(() => { |
44 | this.props.closeWindow(); | 45 | this.props.closeWindow(); |
45 | }, 4000); | 46 | }, ms('4s')); |
46 | } | 47 | } |
47 | 48 | ||
48 | render() { | 49 | render() { |
diff --git a/src/components/ui/Modal/index.js b/src/components/ui/Modal/index.js index d84e4c713..0b7154760 100644 --- a/src/components/ui/Modal/index.js +++ b/src/components/ui/Modal/index.js | |||
@@ -3,9 +3,12 @@ import ReactModal from 'react-modal'; | |||
3 | import PropTypes from 'prop-types'; | 3 | import PropTypes from 'prop-types'; |
4 | import classnames from 'classnames'; | 4 | import classnames from 'classnames'; |
5 | import injectCSS from 'react-jss'; | 5 | import injectCSS from 'react-jss'; |
6 | import { Icon } from '@meetfranz/ui'; | ||
6 | 7 | ||
7 | import styles from './styles'; | 8 | import styles from './styles'; |
8 | 9 | ||
10 | // ReactModal.setAppElement('#root'); | ||
11 | |||
9 | export default @injectCSS(styles) class Modal extends Component { | 12 | export default @injectCSS(styles) class Modal extends Component { |
10 | static propTypes = { | 13 | static propTypes = { |
11 | children: PropTypes.node.isRequired, | 14 | children: PropTypes.node.isRequired, |
@@ -14,11 +17,15 @@ export default @injectCSS(styles) class Modal extends Component { | |||
14 | isOpen: PropTypes.bool.isRequired, | 17 | isOpen: PropTypes.bool.isRequired, |
15 | portal: PropTypes.string, | 18 | portal: PropTypes.string, |
16 | close: PropTypes.func.isRequired, | 19 | close: PropTypes.func.isRequired, |
20 | shouldCloseOnOverlayClick: PropTypes.bool, | ||
21 | showClose: PropTypes.bool, | ||
17 | } | 22 | } |
18 | 23 | ||
19 | static defaultProps = { | 24 | static defaultProps = { |
20 | className: null, | 25 | className: null, |
21 | portal: 'modal-portal', | 26 | portal: 'modal-portal', |
27 | shouldCloseOnOverlayClick: false, | ||
28 | showClose: true, | ||
22 | } | 29 | } |
23 | 30 | ||
24 | render() { | 31 | render() { |
@@ -29,6 +36,8 @@ export default @injectCSS(styles) class Modal extends Component { | |||
29 | isOpen, | 36 | isOpen, |
30 | portal, | 37 | portal, |
31 | close, | 38 | close, |
39 | shouldCloseOnOverlayClick, | ||
40 | showClose, | ||
32 | } = this.props; | 41 | } = this.props; |
33 | 42 | ||
34 | return ( | 43 | return ( |
@@ -42,14 +51,17 @@ export default @injectCSS(styles) class Modal extends Component { | |||
42 | overlayClassName={classes.overlay} | 51 | overlayClassName={classes.overlay} |
43 | portal={portal} | 52 | portal={portal} |
44 | onRequestClose={close} | 53 | onRequestClose={close} |
54 | shouldCloseOnOverlayClick={shouldCloseOnOverlayClick} | ||
45 | > | 55 | > |
46 | {/* <button | 56 | {showClose && close && ( |
47 | type="button" | 57 | <button |
48 | className={classnames({ | 58 | type="button" |
49 | [`${classes.close}`]: true, | 59 | className={classes.close} |
50 | 'mdi mdi-close': true, | 60 | onClick={close} |
51 | })} | 61 | > |
52 | /> */} | 62 | <Icon icon="mdiClose" size={1.5} /> |
63 | </button> | ||
64 | )} | ||
53 | <div className={classes.content}> | 65 | <div className={classes.content}> |
54 | {children} | 66 | {children} |
55 | </div> | 67 | </div> |
diff --git a/src/components/ui/Modal/styles.js b/src/components/ui/Modal/styles.js index 56fecbf55..49b970c97 100644 --- a/src/components/ui/Modal/styles.js +++ b/src/components/ui/Modal/styles.js | |||
@@ -28,5 +28,6 @@ export default theme => ({ | |||
28 | position: 'absolute', | 28 | position: 'absolute', |
29 | top: 0, | 29 | top: 0, |
30 | right: 0, | 30 | right: 0, |
31 | padding: 20, | ||
31 | }, | 32 | }, |
32 | }); | 33 | }); |