diff options
author | muhamedsalih-tw <104364298+muhamedsalih-tw@users.noreply.github.com> | 2022-11-19 15:21:09 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-19 09:51:09 +0000 |
commit | a051331680b21f20201a47601d69505a4cfa9e40 (patch) | |
tree | f98dd4bc668c9814d58c0e49170aeeb19c2fe1de /src/components | |
parent | 6.2.1-nightly.46 [skip ci] (diff) | |
download | ferdium-app-a051331680b21f20201a47601d69505a4cfa9e40.tar.gz ferdium-app-a051331680b21f20201a47601d69505a4cfa9e40.tar.zst ferdium-app-a051331680b21f20201a47601d69505a4cfa9e40.zip |
Transform service components to ts (#778)
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/services/content/ConnectionLostBanner.tsx (renamed from src/components/services/content/ConnectionLostBanner.js) | 37 | ||||
-rw-r--r-- | src/components/services/content/ErrorHandlers/styles.ts | 25 | ||||
-rw-r--r-- | src/components/services/content/ServiceDisabled.tsx (renamed from src/components/services/content/ServiceDisabled.js) | 24 | ||||
-rw-r--r-- | src/components/services/content/ServiceView.tsx (renamed from src/components/services/content/ServiceView.js) | 100 | ||||
-rw-r--r-- | src/components/services/content/Services.tsx | 22 | ||||
-rw-r--r-- | src/components/services/content/WebviewCrashHandler.tsx (renamed from src/components/services/content/WebviewCrashHandler.js) | 44 | ||||
-rw-r--r-- | src/components/services/content/WebviewErrorHandler.tsx (renamed from src/components/services/content/ErrorHandlers/WebviewErrorHandler.js) | 63 | ||||
-rw-r--r-- | src/components/settings/services/ServiceError.tsx (renamed from src/components/settings/services/ServiceError.js) | 14 | ||||
-rw-r--r-- | src/components/settings/services/ServiceItem.tsx (renamed from src/components/settings/services/ServiceItem.js) | 53 | ||||
-rw-r--r-- | src/components/settings/services/ServicesDashboard.tsx (renamed from src/components/settings/services/ServicesDashboard.js) | 66 | ||||
-rw-r--r-- | src/components/ui/FAB.tsx | 44 |
11 files changed, 253 insertions, 239 deletions
diff --git a/src/components/services/content/ConnectionLostBanner.js b/src/components/services/content/ConnectionLostBanner.tsx index f2f70ca2e..88731f3b9 100644 --- a/src/components/services/content/ConnectionLostBanner.js +++ b/src/components/services/content/ConnectionLostBanner.tsx | |||
@@ -1,9 +1,7 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component, ReactElement } from 'react'; |
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer } from 'mobx-react'; | 2 | import { observer } from 'mobx-react'; |
4 | import injectSheet from 'react-jss'; | 3 | import withStyles, { WithStylesProps } from 'react-jss'; |
5 | import { defineMessages, injectIntl } from 'react-intl'; | 4 | import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; |
6 | |||
7 | import { mdiAlert } from '@mdi/js'; | 5 | import { mdiAlert } from '@mdi/js'; |
8 | import { LIVE_API_FERDIUM_WEBSITE } from '../../../config'; | 6 | import { LIVE_API_FERDIUM_WEBSITE } from '../../../config'; |
9 | import Icon from '../../ui/icon'; | 7 | import Icon from '../../ui/icon'; |
@@ -23,11 +21,10 @@ const messages = defineMessages({ | |||
23 | }, | 21 | }, |
24 | }); | 22 | }); |
25 | 23 | ||
26 | let buttonTransition = 'none'; | 24 | const buttonTransition = |
27 | 25 | window && window.matchMedia('(prefers-reduced-motion: no-preference)') | |
28 | if (window && window.matchMedia('(prefers-reduced-motion: no-preference)')) { | 26 | ? 'opacity 0.25s' |
29 | buttonTransition = 'opacity 0.25s'; | 27 | : 'none'; |
30 | } | ||
31 | 28 | ||
32 | const styles = theme => ({ | 29 | const styles = theme => ({ |
33 | root: { | 30 | root: { |
@@ -68,17 +65,15 @@ const styles = theme => ({ | |||
68 | }, | 65 | }, |
69 | }); | 66 | }); |
70 | 67 | ||
71 | class ConnectionLostBanner extends Component { | 68 | interface IProps extends WithStylesProps<typeof styles>, WrappedComponentProps { |
72 | static propTypes = { | 69 | name: string; |
73 | classes: PropTypes.object.isRequired, | 70 | reload: () => void; |
74 | name: PropTypes.string.isRequired, | 71 | } |
75 | reload: PropTypes.func.isRequired, | ||
76 | }; | ||
77 | |||
78 | render() { | ||
79 | const { classes, name, reload } = this.props; | ||
80 | 72 | ||
81 | const { intl } = this.props; | 73 | @observer |
74 | class ConnectionLostBanner extends Component<IProps> { | ||
75 | render(): ReactElement { | ||
76 | const { classes, name, reload, intl } = this.props; | ||
82 | 77 | ||
83 | return ( | 78 | return ( |
84 | <div className={classes.root}> | 79 | <div className={classes.root}> |
@@ -101,4 +96,4 @@ class ConnectionLostBanner extends Component { | |||
101 | } | 96 | } |
102 | } | 97 | } |
103 | 98 | ||
104 | export default injectIntl(injectSheet(styles)(observer(ConnectionLostBanner))); | 99 | export default injectIntl(withStyles(styles)(ConnectionLostBanner)); |
diff --git a/src/components/services/content/ErrorHandlers/styles.ts b/src/components/services/content/ErrorHandlers/styles.ts deleted file mode 100644 index 9e2509ee5..000000000 --- a/src/components/services/content/ErrorHandlers/styles.ts +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | export default theme => ({ | ||
2 | component: { | ||
3 | left: 0, | ||
4 | position: 'absolute', | ||
5 | top: 0, | ||
6 | width: '100%', | ||
7 | zIndex: 0, | ||
8 | alignItems: 'center', | ||
9 | background: theme.colorWebviewErrorHandlerBackground, | ||
10 | display: 'flex', | ||
11 | flexDirection: 'column', | ||
12 | justifyContent: 'center', | ||
13 | textAlign: 'center', | ||
14 | }, | ||
15 | buttonContainer: { | ||
16 | display: 'flex', | ||
17 | flexDirection: 'row', | ||
18 | height: 'auto', | ||
19 | margin: [40, 0, 20], | ||
20 | |||
21 | '& button': { | ||
22 | margin: [0, 10, 0, 10], | ||
23 | }, | ||
24 | }, | ||
25 | }); | ||
diff --git a/src/components/services/content/ServiceDisabled.js b/src/components/services/content/ServiceDisabled.tsx index d874a354e..2f0d439ec 100644 --- a/src/components/services/content/ServiceDisabled.js +++ b/src/components/services/content/ServiceDisabled.tsx | |||
@@ -1,8 +1,6 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component, ReactElement } 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 | |||
6 | import Button from '../../ui/button'; | 4 | import Button from '../../ui/button'; |
7 | import { H1 } from '../../ui/headline'; | 5 | import { H1 } from '../../ui/headline'; |
8 | 6 | ||
@@ -17,15 +15,15 @@ const messages = defineMessages({ | |||
17 | }, | 15 | }, |
18 | }); | 16 | }); |
19 | 17 | ||
20 | class ServiceDisabled extends Component { | 18 | interface IProps extends WrappedComponentProps { |
21 | static propTypes = { | 19 | name: string; |
22 | name: PropTypes.string.isRequired, | 20 | enable: () => void; |
23 | enable: PropTypes.func.isRequired, | 21 | } |
24 | }; | ||
25 | 22 | ||
26 | render() { | 23 | @observer |
27 | const { name, enable } = this.props; | 24 | class ServiceDisabled extends Component<IProps> { |
28 | const { intl } = this.props; | 25 | render(): ReactElement { |
26 | const { name, enable, intl } = this.props; | ||
29 | 27 | ||
30 | return ( | 28 | return ( |
31 | <div className="services__info-layer"> | 29 | <div className="services__info-layer"> |
@@ -40,4 +38,4 @@ class ServiceDisabled extends Component { | |||
40 | } | 38 | } |
41 | } | 39 | } |
42 | 40 | ||
43 | export default injectIntl(observer(ServiceDisabled)); | 41 | export default injectIntl(ServiceDisabled); |
diff --git a/src/components/services/content/ServiceView.js b/src/components/services/content/ServiceView.tsx index cae16ef49..e41184431 100644 --- a/src/components/services/content/ServiceView.js +++ b/src/components/services/content/ServiceView.tsx | |||
@@ -1,52 +1,55 @@ | |||
1 | /* eslint-disable react/jsx-no-useless-fragment */ | ||
2 | import { Component } from 'react'; | 1 | import { Component } from 'react'; |
3 | import PropTypes from 'prop-types'; | 2 | import { autorun, IReactionDisposer } from 'mobx'; |
4 | import { autorun } from 'mobx'; | ||
5 | import { observer, inject } from 'mobx-react'; | 3 | import { observer, inject } from 'mobx-react'; |
6 | import classnames from 'classnames'; | 4 | import classnames from 'classnames'; |
7 | import TopBarProgress from 'react-topbar-progress-indicator'; | 5 | import TopBarProgress from 'react-topbar-progress-indicator'; |
8 | |||
9 | import ServiceModel from '../../../models/Service'; | 6 | import ServiceModel from '../../../models/Service'; |
10 | import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl'; | 7 | import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl'; |
11 | import WebviewLoader from '../../ui/WebviewLoader'; | 8 | import WebviewLoader from '../../ui/WebviewLoader'; |
12 | import WebviewCrashHandler from './WebviewCrashHandler'; | 9 | import WebviewCrashHandler from './WebviewCrashHandler'; |
13 | import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; | 10 | import WebviewErrorHandler from './WebviewErrorHandler'; |
14 | import ServiceDisabled from './ServiceDisabled'; | 11 | import ServiceDisabled from './ServiceDisabled'; |
15 | import ServiceWebview from './ServiceWebview'; | 12 | import ServiceWebview from './ServiceWebview'; |
16 | import SettingsStore from '../../../stores/SettingsStore'; | ||
17 | import WebControlsScreen from '../../../features/webControls/containers/WebControlsScreen'; | 13 | import WebControlsScreen from '../../../features/webControls/containers/WebControlsScreen'; |
18 | import { CUSTOM_WEBSITE_RECIPE_ID } from '../../../config'; | 14 | import { CUSTOM_WEBSITE_RECIPE_ID } from '../../../config'; |
15 | import { RealStores } from '../../../stores'; | ||
16 | |||
17 | interface IProps { | ||
18 | service: ServiceModel; | ||
19 | setWebviewRef: () => void; | ||
20 | detachService: () => void; | ||
21 | reload: () => void; | ||
22 | edit: () => void; | ||
23 | enable: () => void; | ||
24 | // isActive?: boolean; // TODO - [TECH DEBT][PROP NOT USED IN COMPONENT] check it | ||
25 | stores?: RealStores; | ||
26 | isSpellcheckerEnabled: boolean; | ||
27 | } | ||
28 | |||
29 | interface IState { | ||
30 | forceRepaint: boolean; | ||
31 | targetUrl: string; | ||
32 | statusBarVisible: boolean; | ||
33 | } | ||
34 | |||
35 | @inject('stores', 'actions') | ||
36 | @observer | ||
37 | class ServiceView extends Component<IProps, IState> { | ||
38 | // hibernationTimer = null; // TODO - [TS DEBT] class property not reassigned, need to find its purpose | ||
19 | 39 | ||
20 | class ServiceView extends Component { | 40 | autorunDisposer: IReactionDisposer | undefined; |
21 | static propTypes = { | 41 | |
22 | service: PropTypes.instanceOf(ServiceModel).isRequired, | 42 | forceRepaintTimeout: NodeJS.Timeout | undefined; |
23 | setWebviewReference: PropTypes.func.isRequired, | 43 | |
24 | detachService: PropTypes.func.isRequired, | 44 | constructor(props: IProps) { |
25 | reload: PropTypes.func.isRequired, | 45 | super(props); |
26 | edit: PropTypes.func.isRequired, | 46 | |
27 | enable: PropTypes.func.isRequired, | 47 | this.state = { |
28 | isActive: PropTypes.bool, | 48 | forceRepaint: false, |
29 | stores: PropTypes.shape({ | 49 | targetUrl: '', |
30 | settings: PropTypes.instanceOf(SettingsStore).isRequired, | 50 | statusBarVisible: false, |
31 | }).isRequired, | 51 | }; |
32 | isSpellcheckerEnabled: PropTypes.bool.isRequired, | 52 | } |
33 | }; | ||
34 | |||
35 | static defaultProps = { | ||
36 | isActive: false, | ||
37 | }; | ||
38 | |||
39 | state = { | ||
40 | forceRepaint: false, | ||
41 | targetUrl: '', | ||
42 | statusBarVisible: false, | ||
43 | }; | ||
44 | |||
45 | hibernationTimer = null; | ||
46 | |||
47 | autorunDisposer = null; | ||
48 | |||
49 | forceRepaintTimeout = null; | ||
50 | 53 | ||
51 | componentDidMount() { | 54 | componentDidMount() { |
52 | this.autorunDisposer = autorun(() => { | 55 | this.autorunDisposer = autorun(() => { |
@@ -60,16 +63,16 @@ class ServiceView extends Component { | |||
60 | } | 63 | } |
61 | 64 | ||
62 | componentWillUnmount() { | 65 | componentWillUnmount() { |
63 | this.autorunDisposer(); | 66 | this.autorunDisposer!(); |
64 | clearTimeout(this.forceRepaintTimeout); | 67 | clearTimeout(this.forceRepaintTimeout!); |
65 | clearTimeout(this.hibernationTimer); | 68 | // clearTimeout(this.hibernationTimer); // TODO - [TS DEBT] class property not reassigned, need to find its purpose |
66 | } | 69 | } |
67 | 70 | ||
68 | render() { | 71 | render() { |
69 | const { | 72 | const { |
70 | detachService, | 73 | detachService, |
71 | service, | 74 | service, |
72 | setWebviewReference, | 75 | setWebviewRef, |
73 | reload, | 76 | reload, |
74 | edit, | 77 | edit, |
75 | enable, | 78 | enable, |
@@ -78,7 +81,7 @@ class ServiceView extends Component { | |||
78 | } = this.props; | 81 | } = this.props; |
79 | 82 | ||
80 | const { navigationBarBehaviour, navigationBarManualActive } = | 83 | const { navigationBarBehaviour, navigationBarManualActive } = |
81 | stores.settings.app; | 84 | stores!.settings.app; |
82 | 85 | ||
83 | const showNavBar = | 86 | const showNavBar = |
84 | navigationBarBehaviour === 'always' || | 87 | navigationBarBehaviour === 'always' || |
@@ -93,10 +96,9 @@ class ServiceView extends Component { | |||
93 | 'services__webview--force-repaint': this.state.forceRepaint, | 96 | 'services__webview--force-repaint': this.state.forceRepaint, |
94 | }); | 97 | }); |
95 | 98 | ||
96 | let statusBar = null; | 99 | const statusBar = this.state.statusBarVisible ? ( |
97 | if (this.state.statusBarVisible) { | 100 | <StatusBarTargetUrl text={this.state.targetUrl} /> |
98 | statusBar = <StatusBarTargetUrl text={this.state.targetUrl} />; | 101 | ) : null; |
99 | } | ||
100 | 102 | ||
101 | return ( | 103 | return ( |
102 | <div | 104 | <div |
@@ -109,7 +111,7 @@ class ServiceView extends Component { | |||
109 | {service.hasCrashed && ( | 111 | {service.hasCrashed && ( |
110 | <WebviewCrashHandler | 112 | <WebviewCrashHandler |
111 | name={service.recipe.name} | 113 | name={service.recipe.name} |
112 | webview={service.webview} | 114 | // webview={service.webview} // TODO - [TECH DEBT][PROPS NOT EXIST IN COMPONENT] check it |
113 | reload={reload} | 115 | reload={reload} |
114 | /> | 116 | /> |
115 | )} | 117 | )} |
@@ -138,7 +140,7 @@ class ServiceView extends Component { | |||
138 | {service.isActive && ( | 140 | {service.isActive && ( |
139 | <ServiceDisabled | 141 | <ServiceDisabled |
140 | name={service.name !== '' ? service.name : service.recipe.name} | 142 | name={service.name !== '' ? service.name : service.recipe.name} |
141 | webview={service.webview} | 143 | // webview={service.webview} // TODO - [TECH DEBT][PROPS NOT EXIST IN COMPONENT] check it |
142 | enable={enable} | 144 | enable={enable} |
143 | /> | 145 | /> |
144 | )} | 146 | )} |
@@ -150,7 +152,7 @@ class ServiceView extends Component { | |||
150 | {showNavBar && <WebControlsScreen service={service} />} | 152 | {showNavBar && <WebControlsScreen service={service} />} |
151 | <ServiceWebview | 153 | <ServiceWebview |
152 | service={service} | 154 | service={service} |
153 | setWebviewReference={setWebviewReference} | 155 | setWebviewReference={setWebviewRef} |
154 | detachService={detachService} | 156 | detachService={detachService} |
155 | isSpellcheckerEnabled={isSpellcheckerEnabled} | 157 | isSpellcheckerEnabled={isSpellcheckerEnabled} |
156 | /> | 158 | /> |
@@ -187,4 +189,4 @@ class ServiceView extends Component { | |||
187 | } | 189 | } |
188 | } | 190 | } |
189 | 191 | ||
190 | export default inject('stores', 'actions')(observer(ServiceView)); | 192 | export default ServiceView; |
diff --git a/src/components/services/content/Services.tsx b/src/components/services/content/Services.tsx index 53cddd907..fa26edaa6 100644 --- a/src/components/services/content/Services.tsx +++ b/src/components/services/content/Services.tsx | |||
@@ -42,8 +42,8 @@ interface IProps extends WrappedComponentProps, WithStylesProps<typeof styles> { | |||
42 | services?: Service[]; | 42 | services?: Service[]; |
43 | setWebviewReference: () => void; | 43 | setWebviewReference: () => void; |
44 | detachService: () => void; | 44 | detachService: () => void; |
45 | handleIPCMessage: () => void; | 45 | // handleIPCMessage: () => void; // TODO - [TECH DEBT] later check it |
46 | openWindow: () => void; | 46 | // openWindow: () => void; // TODO - [TECH DEBT] later check it |
47 | reload: (options: { serviceId: string }) => void; | 47 | reload: (options: { serviceId: string }) => void; |
48 | openSettings: (options: { path: string }) => void; | 48 | openSettings: (options: { path: string }) => void; |
49 | update: (options: { | 49 | update: (options: { |
@@ -61,7 +61,7 @@ interface IState { | |||
61 | 61 | ||
62 | @observer | 62 | @observer |
63 | class Services extends Component<IProps, IState> { | 63 | class Services extends Component<IProps, IState> { |
64 | _confettiTimeout: number | null = null; | 64 | confettiTimeout: number | null = null; |
65 | 65 | ||
66 | constructor(props: IProps) { | 66 | constructor(props: IProps) { |
67 | super(props); | 67 | super(props); |
@@ -72,7 +72,7 @@ class Services extends Component<IProps, IState> { | |||
72 | } | 72 | } |
73 | 73 | ||
74 | componentDidMount(): void { | 74 | componentDidMount(): void { |
75 | this._confettiTimeout = window.setTimeout(() => { | 75 | this.confettiTimeout = window.setTimeout(() => { |
76 | this.setState({ | 76 | this.setState({ |
77 | showConfetti: false, | 77 | showConfetti: false, |
78 | }); | 78 | }); |
@@ -80,18 +80,18 @@ class Services extends Component<IProps, IState> { | |||
80 | } | 80 | } |
81 | 81 | ||
82 | componentWillUnmount(): void { | 82 | componentWillUnmount(): void { |
83 | if (this._confettiTimeout) { | 83 | if (this.confettiTimeout) { |
84 | clearTimeout(this._confettiTimeout); | 84 | clearTimeout(this.confettiTimeout); |
85 | } | 85 | } |
86 | } | 86 | } |
87 | 87 | ||
88 | render(): ReactElement { | 88 | render(): ReactElement { |
89 | const { | 89 | const { |
90 | services = [], | 90 | services = [], |
91 | handleIPCMessage, | 91 | // handleIPCMessage, // TODO - [TECH DEBT] later check it |
92 | setWebviewReference, | 92 | setWebviewReference, |
93 | detachService, | 93 | detachService, |
94 | openWindow, | 94 | // openWindow, // TODO - [TECH DEBT] later check it |
95 | reload, | 95 | reload, |
96 | openSettings, | 96 | openSettings, |
97 | update, | 97 | update, |
@@ -136,10 +136,10 @@ class Services extends Component<IProps, IState> { | |||
136 | <ServiceView | 136 | <ServiceView |
137 | key={service.id} | 137 | key={service.id} |
138 | service={service} | 138 | service={service} |
139 | handleIPCMessage={handleIPCMessage} | 139 | // handleIPCMessage={handleIPCMessage} // TODO - [TECH DEBT][PROPS NOT EXIST IN COMPONENT] later check it |
140 | setWebviewReference={setWebviewReference} | 140 | setWebviewRef={setWebviewReference} |
141 | detachService={detachService} | 141 | detachService={detachService} |
142 | openWindow={openWindow} | 142 | // openWindow={openWindow} // TODO - [TECH DEBT][PROPS NOT EXIST IN COMPONENT] later check it |
143 | reload={() => reload({ serviceId: service.id })} | 143 | reload={() => reload({ serviceId: service.id })} |
144 | edit={() => openSettings({ path: `services/edit/${service.id}` })} | 144 | edit={() => openSettings({ path: `services/edit/${service.id}` })} |
145 | enable={() => | 145 | enable={() => |
diff --git a/src/components/services/content/WebviewCrashHandler.js b/src/components/services/content/WebviewCrashHandler.tsx index 0e6e61be8..e9b17e8aa 100644 --- a/src/components/services/content/WebviewCrashHandler.js +++ b/src/components/services/content/WebviewCrashHandler.tsx | |||
@@ -1,9 +1,7 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component, ReactElement } 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 ms from 'ms'; | 4 | import ms from 'ms'; |
6 | |||
7 | import Button from '../../ui/button'; | 5 | import Button from '../../ui/button'; |
8 | import { H1 } from '../../ui/headline'; | 6 | import { H1 } from '../../ui/headline'; |
9 | 7 | ||
@@ -27,21 +25,30 @@ const messages = defineMessages({ | |||
27 | }, | 25 | }, |
28 | }); | 26 | }); |
29 | 27 | ||
30 | class WebviewCrashHandler extends Component { | 28 | interface IProps extends WrappedComponentProps { |
31 | static propTypes = { | 29 | name: string; |
32 | name: PropTypes.string.isRequired, | 30 | reload: () => void; |
33 | reload: PropTypes.func.isRequired, | 31 | } |
34 | }; | ||
35 | 32 | ||
36 | state = { | 33 | interface IState { |
37 | countdown: ms('10s'), | 34 | countdown: number; |
38 | }; | 35 | } |
39 | 36 | ||
40 | countdownInterval = null; | 37 | @observer |
38 | class WebviewCrashHandler extends Component<IProps, IState> { | ||
39 | countdownInterval: NodeJS.Timer | undefined; | ||
41 | 40 | ||
42 | countdownIntervalTimeout = ms('1s'); | 41 | countdownIntervalTimeout = ms('1s'); |
43 | 42 | ||
44 | componentDidMount() { | 43 | constructor(props: IProps) { |
44 | super(props); | ||
45 | |||
46 | this.state = { | ||
47 | countdown: ms('10s'), | ||
48 | }; | ||
49 | } | ||
50 | |||
51 | componentDidMount(): void { | ||
45 | const { reload } = this.props; | 52 | const { reload } = this.props; |
46 | 53 | ||
47 | this.countdownInterval = setInterval(() => { | 54 | this.countdownInterval = setInterval(() => { |
@@ -51,14 +58,13 @@ class WebviewCrashHandler extends Component { | |||
51 | 58 | ||
52 | if (this.state.countdown <= 0) { | 59 | if (this.state.countdown <= 0) { |
53 | reload(); | 60 | reload(); |
54 | clearInterval(this.countdownInterval); | 61 | clearInterval(this.countdownInterval!); |
55 | } | 62 | } |
56 | }, this.countdownIntervalTimeout); | 63 | }, this.countdownIntervalTimeout); |
57 | } | 64 | } |
58 | 65 | ||
59 | render() { | 66 | render(): ReactElement { |
60 | const { name, reload } = this.props; | 67 | const { name, reload, intl } = this.props; |
61 | const { intl } = this.props; | ||
62 | 68 | ||
63 | return ( | 69 | return ( |
64 | <div className="services__info-layer"> | 70 | <div className="services__info-layer"> |
@@ -81,4 +87,4 @@ class WebviewCrashHandler extends Component { | |||
81 | } | 87 | } |
82 | } | 88 | } |
83 | 89 | ||
84 | export default injectIntl(observer(WebviewCrashHandler)); | 90 | export default injectIntl(WebviewCrashHandler); |
diff --git a/src/components/services/content/ErrorHandlers/WebviewErrorHandler.js b/src/components/services/content/WebviewErrorHandler.tsx index a658bec8b..b99c15006 100644 --- a/src/components/services/content/ErrorHandlers/WebviewErrorHandler.js +++ b/src/components/services/content/WebviewErrorHandler.tsx | |||
@@ -1,13 +1,9 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component, ReactElement } 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 | 5 | import Button from '../../ui/button'; | |
7 | import Button from '../../../ui/button'; | 6 | import { H1 } from '../../ui/headline'; |
8 | |||
9 | import styles from './styles'; | ||
10 | import { H1 } from '../../../ui/headline'; | ||
11 | 7 | ||
12 | const messages = defineMessages({ | 8 | const messages = defineMessages({ |
13 | headline: { | 9 | headline: { |
@@ -32,18 +28,43 @@ const messages = defineMessages({ | |||
32 | }, | 28 | }, |
33 | }); | 29 | }); |
34 | 30 | ||
35 | class WebviewErrorHandler extends Component { | 31 | const styles = theme => ({ |
36 | static propTypes = { | 32 | component: { |
37 | name: PropTypes.string.isRequired, | 33 | left: 0, |
38 | reload: PropTypes.func.isRequired, | 34 | position: 'absolute', |
39 | edit: PropTypes.func.isRequired, | 35 | top: 0, |
40 | errorMessage: PropTypes.string.isRequired, | 36 | width: '100%', |
41 | classes: PropTypes.object.isRequired, | 37 | zIndex: 0, |
42 | }; | 38 | alignItems: 'center', |
39 | background: theme.colorWebviewErrorHandlerBackground, | ||
40 | display: 'flex', | ||
41 | flexDirection: 'column', | ||
42 | justifyContent: 'center', | ||
43 | textAlign: 'center', | ||
44 | }, | ||
45 | buttonContainer: { | ||
46 | display: 'flex', | ||
47 | flexDirection: 'row', | ||
48 | height: 'auto', | ||
49 | margin: [40, 0, 20], | ||
50 | |||
51 | '& button': { | ||
52 | margin: [0, 10, 0, 10], | ||
53 | }, | ||
54 | }, | ||
55 | }); | ||
56 | |||
57 | interface IProps extends WithStylesProps<typeof styles>, WrappedComponentProps { | ||
58 | name: string; | ||
59 | reload: () => void; | ||
60 | edit: () => void; | ||
61 | errorMessage: string; | ||
62 | } | ||
43 | 63 | ||
44 | render() { | 64 | @observer |
45 | const { name, reload, edit, errorMessage, classes } = this.props; | 65 | class WebviewErrorHandler extends Component<IProps> { |
46 | const { intl } = this.props; | 66 | render(): ReactElement { |
67 | const { name, reload, edit, errorMessage, classes, intl } = this.props; | ||
47 | 68 | ||
48 | return ( | 69 | return ( |
49 | <div className={classes.component}> | 70 | <div className={classes.component}> |
@@ -71,5 +92,5 @@ class WebviewErrorHandler extends Component { | |||
71 | } | 92 | } |
72 | 93 | ||
73 | export default injectIntl( | 94 | export default injectIntl( |
74 | injectSheet(styles, { injectTheme: true })(observer(WebviewErrorHandler)), | 95 | withStyles(styles, { injectTheme: true })(WebviewErrorHandler), |
75 | ); | 96 | ); |
diff --git a/src/components/settings/services/ServiceError.js b/src/components/settings/services/ServiceError.tsx index fdcdb54c9..87efdeb96 100644 --- a/src/components/settings/services/ServiceError.js +++ b/src/components/settings/services/ServiceError.tsx | |||
@@ -1,8 +1,7 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component, ReactElement } from 'react'; |
2 | import { observer } from 'mobx-react'; | 2 | import { observer } from 'mobx-react'; |
3 | import { Link } from 'react-router-dom'; | 3 | import { Link } from 'react-router-dom'; |
4 | import { defineMessages, injectIntl } from 'react-intl'; | 4 | import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; |
5 | |||
6 | import Infobox from '../../ui/Infobox'; | 5 | import Infobox from '../../ui/Infobox'; |
7 | import Button from '../../ui/button'; | 6 | import Button from '../../ui/button'; |
8 | 7 | ||
@@ -25,8 +24,11 @@ const messages = defineMessages({ | |||
25 | }, | 24 | }, |
26 | }); | 25 | }); |
27 | 26 | ||
28 | class ServiceError extends Component { | 27 | interface IProps extends WrappedComponentProps {} |
29 | render() { | 28 | |
29 | @observer | ||
30 | class ServiceError extends Component<IProps> { | ||
31 | render(): ReactElement { | ||
30 | const { intl } = this.props; | 32 | const { intl } = this.props; |
31 | 33 | ||
32 | return ( | 34 | return ( |
@@ -59,4 +61,4 @@ class ServiceError extends Component { | |||
59 | } | 61 | } |
60 | } | 62 | } |
61 | 63 | ||
62 | export default injectIntl(observer(ServiceError)); | 64 | export default injectIntl(ServiceError); |
diff --git a/src/components/settings/services/ServiceItem.js b/src/components/settings/services/ServiceItem.tsx index c666b7dd2..fd961a0a8 100644 --- a/src/components/settings/services/ServiceItem.js +++ b/src/components/settings/services/ServiceItem.tsx | |||
@@ -1,10 +1,8 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component, ReactElement } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; |
3 | import { defineMessages, injectIntl } from 'react-intl'; | ||
4 | import ReactTooltip from 'react-tooltip'; | 3 | import ReactTooltip from 'react-tooltip'; |
5 | import { observer } from 'mobx-react'; | 4 | import { observer } from 'mobx-react'; |
6 | import classnames from 'classnames'; | 5 | import classnames from 'classnames'; |
7 | |||
8 | import { mdiBellOff, mdiMessageBulletedOff, mdiPower } from '@mdi/js'; | 6 | import { mdiBellOff, mdiMessageBulletedOff, mdiPower } from '@mdi/js'; |
9 | import ServiceModel from '../../../models/Service'; | 7 | import ServiceModel from '../../../models/Service'; |
10 | import Icon from '../../ui/icon'; | 8 | import Icon from '../../ui/icon'; |
@@ -24,16 +22,17 @@ const messages = defineMessages({ | |||
24 | }, | 22 | }, |
25 | }); | 23 | }); |
26 | 24 | ||
27 | class ServiceItem extends Component { | 25 | interface IProps extends WrappedComponentProps { |
28 | static propTypes = { | 26 | service: ServiceModel; |
29 | service: PropTypes.instanceOf(ServiceModel).isRequired, | 27 | goToServiceForm: () => void; |
30 | goToServiceForm: PropTypes.func.isRequired, | 28 | } |
31 | }; | ||
32 | 29 | ||
33 | render() { | 30 | @observer |
31 | class ServiceItem extends Component<IProps> { | ||
32 | render(): ReactElement { | ||
34 | const { | 33 | const { |
35 | service, | 34 | service, |
36 | // toggleAction, | 35 | // toggleAction, // TODO - [TECH DEBT][PROP NOT USED IN COMPONENT] check it later |
37 | goToServiceForm, | 36 | goToServiceForm, |
38 | } = this.props; | 37 | } = this.props; |
39 | const { intl } = this.props; | 38 | const { intl } = this.props; |
@@ -45,7 +44,11 @@ class ServiceItem extends Component { | |||
45 | 'service-table__row--disabled': !service.isEnabled, | 44 | 'service-table__row--disabled': !service.isEnabled, |
46 | })} | 45 | })} |
47 | > | 46 | > |
48 | <td className="service-table__column-icon" onClick={goToServiceForm}> | 47 | <td |
48 | className="service-table__column-icon" | ||
49 | onClick={goToServiceForm} | ||
50 | role="gridcell" | ||
51 | > | ||
49 | <img | 52 | <img |
50 | src={service.icon} | 53 | src={service.icon} |
51 | className={classnames({ | 54 | className={classnames({ |
@@ -55,10 +58,18 @@ class ServiceItem extends Component { | |||
55 | alt="" | 58 | alt="" |
56 | /> | 59 | /> |
57 | </td> | 60 | </td> |
58 | <td className="service-table__column-name" onClick={goToServiceForm}> | 61 | <td |
62 | className="service-table__column-name" | ||
63 | onClick={goToServiceForm} | ||
64 | role="gridcell" | ||
65 | > | ||
59 | {service.name !== '' ? service.name : service.recipe.name} | 66 | {service.name !== '' ? service.name : service.recipe.name} |
60 | </td> | 67 | </td> |
61 | <td className="service-table__column-info" onClick={goToServiceForm}> | 68 | <td |
69 | className="service-table__column-info" | ||
70 | onClick={goToServiceForm} | ||
71 | role="gridcell" | ||
72 | > | ||
62 | {service.isMuted && ( | 73 | {service.isMuted && ( |
63 | <Icon | 74 | <Icon |
64 | icon={mdiBellOff} | 75 | icon={mdiBellOff} |
@@ -66,7 +77,11 @@ class ServiceItem extends Component { | |||
66 | /> | 77 | /> |
67 | )} | 78 | )} |
68 | </td> | 79 | </td> |
69 | <td className="service-table__column-info" onClick={goToServiceForm}> | 80 | <td |
81 | className="service-table__column-info" | ||
82 | onClick={goToServiceForm} | ||
83 | role="gridcell" | ||
84 | > | ||
70 | {!service.isEnabled && ( | 85 | {!service.isEnabled && ( |
71 | <Icon | 86 | <Icon |
72 | icon={mdiPower} | 87 | icon={mdiPower} |
@@ -74,7 +89,11 @@ class ServiceItem extends Component { | |||
74 | /> | 89 | /> |
75 | )} | 90 | )} |
76 | </td> | 91 | </td> |
77 | <td className="service-table__column-info" onClick={goToServiceForm}> | 92 | <td |
93 | className="service-table__column-info" | ||
94 | onClick={goToServiceForm} | ||
95 | role="gridcell" | ||
96 | > | ||
78 | {!service.isNotificationEnabled && ( | 97 | {!service.isNotificationEnabled && ( |
79 | <Icon | 98 | <Icon |
80 | icon={mdiMessageBulletedOff} | 99 | icon={mdiMessageBulletedOff} |
@@ -90,4 +109,4 @@ class ServiceItem extends Component { | |||
90 | } | 109 | } |
91 | } | 110 | } |
92 | 111 | ||
93 | export default injectIntl(observer(ServiceItem)); | 112 | export default injectIntl(ServiceItem); |
diff --git a/src/components/settings/services/ServicesDashboard.js b/src/components/settings/services/ServicesDashboard.tsx index ac1c30ecb..36057902f 100644 --- a/src/components/settings/services/ServicesDashboard.js +++ b/src/components/settings/services/ServicesDashboard.tsx | |||
@@ -1,9 +1,8 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component, ReactElement } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import { observer } from 'mobx-react'; |
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | ||
4 | import { Link } from 'react-router-dom'; | 3 | import { Link } from 'react-router-dom'; |
5 | import { defineMessages, injectIntl } from 'react-intl'; | 4 | import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; |
6 | 5 | import { To } from 'history'; | |
7 | import SearchInput from '../../ui/SearchInput'; | 6 | import SearchInput from '../../ui/SearchInput'; |
8 | import Infobox from '../../ui/Infobox'; | 7 | import Infobox from '../../ui/Infobox'; |
9 | import Loader from '../../ui/Loader'; | 8 | import Loader from '../../ui/Loader'; |
@@ -11,6 +10,7 @@ import FAB from '../../ui/FAB'; | |||
11 | import ServiceItem from './ServiceItem'; | 10 | import ServiceItem from './ServiceItem'; |
12 | import Appear from '../../ui/effects/Appear'; | 11 | import Appear from '../../ui/effects/Appear'; |
13 | import { H1 } from '../../ui/headline'; | 12 | import { H1 } from '../../ui/headline'; |
13 | import Service from '../../../models/Service'; | ||
14 | 14 | ||
15 | const messages = defineMessages({ | 15 | const messages = defineMessages({ |
16 | headline: { | 16 | headline: { |
@@ -51,38 +51,35 @@ const messages = defineMessages({ | |||
51 | }, | 51 | }, |
52 | }); | 52 | }); |
53 | 53 | ||
54 | class ServicesDashboard extends Component { | 54 | interface IProps extends WrappedComponentProps { |
55 | static propTypes = { | 55 | services: Service[]; |
56 | services: MobxPropTypes.arrayOrObservableArray.isRequired, | 56 | isLoading: boolean; |
57 | isLoading: PropTypes.bool.isRequired, | 57 | // toggleService: any; // TODO - - [TECH DEBT] check it later |
58 | toggleService: PropTypes.func.isRequired, | 58 | filterServices: any; |
59 | filterServices: PropTypes.func.isRequired, | 59 | resetFilter: () => void; |
60 | resetFilter: PropTypes.func.isRequired, | 60 | goTo: (to: To, state?: any) => void; |
61 | goTo: PropTypes.func.isRequired, | 61 | servicesRequestFailed: boolean; |
62 | servicesRequestFailed: PropTypes.bool.isRequired, | 62 | retryServicesRequest: () => void; |
63 | retryServicesRequest: PropTypes.func.isRequired, | 63 | status: any; |
64 | status: MobxPropTypes.arrayOrObservableArray.isRequired, | 64 | searchNeedle: string | null; |
65 | searchNeedle: PropTypes.string, | 65 | } |
66 | }; | ||
67 | |||
68 | static defaultProps = { | ||
69 | searchNeedle: '', | ||
70 | }; | ||
71 | 66 | ||
72 | render() { | 67 | @observer |
68 | class ServicesDashboard extends Component<IProps> { | ||
69 | render(): ReactElement { | ||
73 | const { | 70 | const { |
74 | services, | 71 | services, |
75 | isLoading, | 72 | isLoading, |
76 | toggleService, | 73 | // toggleService, // TODO - - [TECH DEBT] check it later |
77 | filterServices, | 74 | filterServices, |
78 | resetFilter, | 75 | resetFilter, |
79 | goTo, | 76 | goTo, |
80 | servicesRequestFailed, | 77 | servicesRequestFailed, |
81 | retryServicesRequest, | 78 | retryServicesRequest, |
82 | status, | 79 | status, |
83 | searchNeedle, | 80 | searchNeedle = '', |
81 | intl, | ||
84 | } = this.props; | 82 | } = this.props; |
85 | const { intl } = this.props; | ||
86 | 83 | ||
87 | return ( | 84 | return ( |
88 | <div className="settings__main"> | 85 | <div className="settings__main"> |
@@ -115,7 +112,7 @@ class ServicesDashboard extends Component { | |||
115 | <Infobox | 112 | <Infobox |
116 | type="success" | 113 | type="success" |
117 | icon="checkbox-marked-circle-outline" | 114 | icon="checkbox-marked-circle-outline" |
118 | dismissable | 115 | dismissible |
119 | > | 116 | > |
120 | {intl.formatMessage(messages.updatedInfo)} | 117 | {intl.formatMessage(messages.updatedInfo)} |
121 | </Infobox> | 118 | </Infobox> |
@@ -127,7 +124,7 @@ class ServicesDashboard extends Component { | |||
127 | <Infobox | 124 | <Infobox |
128 | type="success" | 125 | type="success" |
129 | icon="checkbox-marked-circle-outline" | 126 | icon="checkbox-marked-circle-outline" |
130 | dismissable | 127 | dismissible |
131 | > | 128 | > |
132 | {intl.formatMessage(messages.deletedInfo)} | 129 | {intl.formatMessage(messages.deletedInfo)} |
133 | </Infobox> | 130 | </Infobox> |
@@ -160,15 +157,16 @@ class ServicesDashboard extends Component { | |||
160 | {isLoading ? ( | 157 | {isLoading ? ( |
161 | <Loader /> | 158 | <Loader /> |
162 | ) : ( | 159 | ) : ( |
163 | <table className="service-table"> | 160 | <table className="service-table" role="grid"> |
164 | <tbody> | 161 | <tbody> |
165 | {services.map(service => ( | 162 | {services.map(service => ( |
166 | <ServiceItem | 163 | <ServiceItem |
167 | key={service.id} | 164 | key={service.id} |
168 | service={service} | 165 | service={service} |
169 | toggleAction={() => | 166 | // TODO - - [TECH DEBT][PROPS NOT USED IN COMPONENT] check it later |
170 | toggleService({ serviceId: service.id }) | 167 | // toggleAction={() => |
171 | } | 168 | // toggleService({ serviceId: service.id }) |
169 | // } | ||
172 | goToServiceForm={() => | 170 | goToServiceForm={() => |
173 | goTo(`/settings/services/edit/${service.id}`) | 171 | goTo(`/settings/services/edit/${service.id}`) |
174 | } | 172 | } |
@@ -178,7 +176,7 @@ class ServicesDashboard extends Component { | |||
178 | </table> | 176 | </table> |
179 | )} | 177 | )} |
180 | 178 | ||
181 | <FAB> | 179 | <FAB className="FAB-class"> |
182 | <Link to="/settings/recipes">+</Link> | 180 | <Link to="/settings/recipes">+</Link> |
183 | </FAB> | 181 | </FAB> |
184 | </div> | 182 | </div> |
@@ -187,4 +185,4 @@ class ServicesDashboard extends Component { | |||
187 | } | 185 | } |
188 | } | 186 | } |
189 | 187 | ||
190 | export default injectIntl(observer(ServicesDashboard)); | 188 | export default injectIntl(ServicesDashboard); |
diff --git a/src/components/ui/FAB.tsx b/src/components/ui/FAB.tsx index 37c3c9ec7..acb0f690e 100644 --- a/src/components/ui/FAB.tsx +++ b/src/components/ui/FAB.tsx | |||
@@ -1,30 +1,28 @@ | |||
1 | /** | 1 | import { Component, ReactElement, ReactNode } from 'react'; |
2 | * Floating Action Button (FAB) | ||
3 | */ | ||
4 | import { Component, ReactChildren } from 'react'; | ||
5 | import { observer } from 'mobx-react'; | 2 | import { observer } from 'mobx-react'; |
6 | import classnames from 'classnames'; | 3 | import classnames from 'classnames'; |
4 | import { noop } from 'lodash'; | ||
7 | 5 | ||
8 | type Props = { | 6 | interface IProps { |
9 | className: string; | 7 | className: string; |
10 | disabled: boolean; | 8 | disabled?: boolean; |
11 | onClick: () => void; | 9 | onClick?: () => void; |
12 | type: string; | 10 | type?: string; |
13 | children: ReactChildren; | 11 | children: ReactNode; |
14 | htmlForm: string; | 12 | htmlForm?: string; |
15 | }; | 13 | } |
16 | |||
17 | class Button extends Component<Props> { | ||
18 | static defaultProps = { | ||
19 | disabled: false, | ||
20 | onClick: () => {}, | ||
21 | type: 'button', | ||
22 | htmlForm: '', | ||
23 | }; | ||
24 | 14 | ||
25 | render() { | 15 | @observer |
26 | const { className, disabled, onClick, type, children, htmlForm } = | 16 | class Button extends Component<IProps> { |
27 | this.props; | 17 | render(): ReactElement { |
18 | const { | ||
19 | className, | ||
20 | disabled = false, | ||
21 | onClick = noop, | ||
22 | type = 'button', | ||
23 | children, | ||
24 | htmlForm = '', | ||
25 | } = this.props; | ||
28 | 26 | ||
29 | const buttonProps = { | 27 | const buttonProps = { |
30 | className: classnames({ | 28 | className: classnames({ |
@@ -45,4 +43,4 @@ class Button extends Component<Props> { | |||
45 | } | 43 | } |
46 | } | 44 | } |
47 | 45 | ||
48 | export default observer(Button); | 46 | export default Button; |