aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar muhamedsalih-tw <104364298+muhamedsalih-tw@users.noreply.github.com>2022-11-19 15:21:09 +0530
committerLibravatar GitHub <noreply@github.com>2022-11-19 09:51:09 +0000
commita051331680b21f20201a47601d69505a4cfa9e40 (patch)
treef98dd4bc668c9814d58c0e49170aeeb19c2fe1de
parent6.2.1-nightly.46 [skip ci] (diff)
downloadferdium-app-a051331680b21f20201a47601d69505a4cfa9e40.tar.gz
ferdium-app-a051331680b21f20201a47601d69505a4cfa9e40.tar.zst
ferdium-app-a051331680b21f20201a47601d69505a4cfa9e40.zip
Transform service components to ts (#778)
-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.ts25
-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.tsx22
-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.tsx44
-rw-r--r--src/containers/layout/AppLayoutContainer.tsx12
-rw-r--r--src/containers/settings/ServicesScreen.tsx43
13 files changed, 285 insertions, 262 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 @@
1import { Component } from 'react'; 1import { Component, ReactElement } from 'react';
2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 2import { observer } from 'mobx-react';
4import injectSheet from 'react-jss'; 3import withStyles, { WithStylesProps } from 'react-jss';
5import { defineMessages, injectIntl } from 'react-intl'; 4import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
6
7import { mdiAlert } from '@mdi/js'; 5import { mdiAlert } from '@mdi/js';
8import { LIVE_API_FERDIUM_WEBSITE } from '../../../config'; 6import { LIVE_API_FERDIUM_WEBSITE } from '../../../config';
9import Icon from '../../ui/icon'; 7import Icon from '../../ui/icon';
@@ -23,11 +21,10 @@ const messages = defineMessages({
23 }, 21 },
24}); 22});
25 23
26let buttonTransition = 'none'; 24const buttonTransition =
27 25 window && window.matchMedia('(prefers-reduced-motion: no-preference)')
28if (window && window.matchMedia('(prefers-reduced-motion: no-preference)')) { 26 ? 'opacity 0.25s'
29 buttonTransition = 'opacity 0.25s'; 27 : 'none';
30}
31 28
32const styles = theme => ({ 29const styles = theme => ({
33 root: { 30 root: {
@@ -68,17 +65,15 @@ const styles = theme => ({
68 }, 65 },
69}); 66});
70 67
71class ConnectionLostBanner extends Component { 68interface 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
74class 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
104export default injectIntl(injectSheet(styles)(observer(ConnectionLostBanner))); 99export 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 @@
1export 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 @@
1import { Component } from 'react'; 1import { Component, ReactElement } from 'react';
2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 2import { observer } from 'mobx-react';
4import { defineMessages, injectIntl } from 'react-intl'; 3import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
5
6import Button from '../../ui/button'; 4import Button from '../../ui/button';
7import { H1 } from '../../ui/headline'; 5import { H1 } from '../../ui/headline';
8 6
@@ -17,15 +15,15 @@ const messages = defineMessages({
17 }, 15 },
18}); 16});
19 17
20class ServiceDisabled extends Component { 18interface 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; 24class 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
43export default injectIntl(observer(ServiceDisabled)); 41export 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 */
2import { Component } from 'react'; 1import { Component } from 'react';
3import PropTypes from 'prop-types'; 2import { autorun, IReactionDisposer } from 'mobx';
4import { autorun } from 'mobx';
5import { observer, inject } from 'mobx-react'; 3import { observer, inject } from 'mobx-react';
6import classnames from 'classnames'; 4import classnames from 'classnames';
7import TopBarProgress from 'react-topbar-progress-indicator'; 5import TopBarProgress from 'react-topbar-progress-indicator';
8
9import ServiceModel from '../../../models/Service'; 6import ServiceModel from '../../../models/Service';
10import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl'; 7import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl';
11import WebviewLoader from '../../ui/WebviewLoader'; 8import WebviewLoader from '../../ui/WebviewLoader';
12import WebviewCrashHandler from './WebviewCrashHandler'; 9import WebviewCrashHandler from './WebviewCrashHandler';
13import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; 10import WebviewErrorHandler from './WebviewErrorHandler';
14import ServiceDisabled from './ServiceDisabled'; 11import ServiceDisabled from './ServiceDisabled';
15import ServiceWebview from './ServiceWebview'; 12import ServiceWebview from './ServiceWebview';
16import SettingsStore from '../../../stores/SettingsStore';
17import WebControlsScreen from '../../../features/webControls/containers/WebControlsScreen'; 13import WebControlsScreen from '../../../features/webControls/containers/WebControlsScreen';
18import { CUSTOM_WEBSITE_RECIPE_ID } from '../../../config'; 14import { CUSTOM_WEBSITE_RECIPE_ID } from '../../../config';
15import { RealStores } from '../../../stores';
16
17interface 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
29interface IState {
30 forceRepaint: boolean;
31 targetUrl: string;
32 statusBarVisible: boolean;
33}
34
35@inject('stores', 'actions')
36@observer
37class ServiceView extends Component<IProps, IState> {
38 // hibernationTimer = null; // TODO - [TS DEBT] class property not reassigned, need to find its purpose
19 39
20class 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
190export default inject('stores', 'actions')(observer(ServiceView)); 192export 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
63class Services extends Component<IProps, IState> { 63class 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 @@
1import { Component } from 'react'; 1import { Component, ReactElement } from 'react';
2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 2import { observer } from 'mobx-react';
4import { defineMessages, injectIntl } from 'react-intl'; 3import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
5import ms from 'ms'; 4import ms from 'ms';
6
7import Button from '../../ui/button'; 5import Button from '../../ui/button';
8import { H1 } from '../../ui/headline'; 6import { H1 } from '../../ui/headline';
9 7
@@ -27,21 +25,30 @@ const messages = defineMessages({
27 }, 25 },
28}); 26});
29 27
30class WebviewCrashHandler extends Component { 28interface 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 = { 33interface IState {
37 countdown: ms('10s'), 34 countdown: number;
38 }; 35}
39 36
40 countdownInterval = null; 37@observer
38class 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
84export default injectIntl(observer(WebviewCrashHandler)); 90export 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 @@
1import { Component } from 'react'; 1import { Component, ReactElement } from 'react';
2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 2import { observer } from 'mobx-react';
4import { defineMessages, injectIntl } from 'react-intl'; 3import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
5import injectSheet from 'react-jss'; 4import withStyles, { WithStylesProps } from 'react-jss';
6 5import Button from '../../ui/button';
7import Button from '../../../ui/button'; 6import { H1 } from '../../ui/headline';
8
9import styles from './styles';
10import { H1 } from '../../../ui/headline';
11 7
12const messages = defineMessages({ 8const messages = defineMessages({
13 headline: { 9 headline: {
@@ -32,18 +28,43 @@ const messages = defineMessages({
32 }, 28 },
33}); 29});
34 30
35class WebviewErrorHandler extends Component { 31const 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
57interface 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; 65class 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
73export default injectIntl( 94export 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 @@
1import { Component } from 'react'; 1import { Component, ReactElement } from 'react';
2import { observer } from 'mobx-react'; 2import { observer } from 'mobx-react';
3import { Link } from 'react-router-dom'; 3import { Link } from 'react-router-dom';
4import { defineMessages, injectIntl } from 'react-intl'; 4import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
5
6import Infobox from '../../ui/Infobox'; 5import Infobox from '../../ui/Infobox';
7import Button from '../../ui/button'; 6import Button from '../../ui/button';
8 7
@@ -25,8 +24,11 @@ const messages = defineMessages({
25 }, 24 },
26}); 25});
27 26
28class ServiceError extends Component { 27interface IProps extends WrappedComponentProps {}
29 render() { 28
29@observer
30class 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
62export default injectIntl(observer(ServiceError)); 64export 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 @@
1import { Component } from 'react'; 1import { Component, ReactElement } from 'react';
2import PropTypes from 'prop-types'; 2import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
3import { defineMessages, injectIntl } from 'react-intl';
4import ReactTooltip from 'react-tooltip'; 3import ReactTooltip from 'react-tooltip';
5import { observer } from 'mobx-react'; 4import { observer } from 'mobx-react';
6import classnames from 'classnames'; 5import classnames from 'classnames';
7
8import { mdiBellOff, mdiMessageBulletedOff, mdiPower } from '@mdi/js'; 6import { mdiBellOff, mdiMessageBulletedOff, mdiPower } from '@mdi/js';
9import ServiceModel from '../../../models/Service'; 7import ServiceModel from '../../../models/Service';
10import Icon from '../../ui/icon'; 8import Icon from '../../ui/icon';
@@ -24,16 +22,17 @@ const messages = defineMessages({
24 }, 22 },
25}); 23});
26 24
27class ServiceItem extends Component { 25interface 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
31class 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
93export default injectIntl(observer(ServiceItem)); 112export 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 @@
1import { Component } from 'react'; 1import { Component, ReactElement } from 'react';
2import PropTypes from 'prop-types'; 2import { observer } from 'mobx-react';
3import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
4import { Link } from 'react-router-dom'; 3import { Link } from 'react-router-dom';
5import { defineMessages, injectIntl } from 'react-intl'; 4import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
6 5import { To } from 'history';
7import SearchInput from '../../ui/SearchInput'; 6import SearchInput from '../../ui/SearchInput';
8import Infobox from '../../ui/Infobox'; 7import Infobox from '../../ui/Infobox';
9import Loader from '../../ui/Loader'; 8import Loader from '../../ui/Loader';
@@ -11,6 +10,7 @@ import FAB from '../../ui/FAB';
11import ServiceItem from './ServiceItem'; 10import ServiceItem from './ServiceItem';
12import Appear from '../../ui/effects/Appear'; 11import Appear from '../../ui/effects/Appear';
13import { H1 } from '../../ui/headline'; 12import { H1 } from '../../ui/headline';
13import Service from '../../../models/Service';
14 14
15const messages = defineMessages({ 15const messages = defineMessages({
16 headline: { 16 headline: {
@@ -51,38 +51,35 @@ const messages = defineMessages({
51 }, 51 },
52}); 52});
53 53
54class ServicesDashboard extends Component { 54interface 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
68class 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
190export default injectIntl(observer(ServicesDashboard)); 188export 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/** 1import { Component, ReactElement, ReactNode } from 'react';
2 * Floating Action Button (FAB)
3 */
4import { Component, ReactChildren } from 'react';
5import { observer } from 'mobx-react'; 2import { observer } from 'mobx-react';
6import classnames from 'classnames'; 3import classnames from 'classnames';
4import { noop } from 'lodash';
7 5
8type Props = { 6interface 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
17class 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 } = 16class 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
48export default observer(Button); 46export default Button;
diff --git a/src/containers/layout/AppLayoutContainer.tsx b/src/containers/layout/AppLayoutContainer.tsx
index 0864fa027..b077cebd7 100644
--- a/src/containers/layout/AppLayoutContainer.tsx
+++ b/src/containers/layout/AppLayoutContainer.tsx
@@ -11,11 +11,11 @@ import AppLoader from '../../components/ui/AppLoader';
11import WorkspaceDrawer from '../../features/workspaces/components/WorkspaceDrawer'; 11import WorkspaceDrawer from '../../features/workspaces/components/WorkspaceDrawer';
12import { workspaceStore } from '../../features/workspaces'; 12import { workspaceStore } from '../../features/workspaces';
13 13
14interface AppLayoutContainerProps extends StoresProps {} 14interface IProps extends StoresProps {}
15 15
16@inject('stores', 'actions') 16@inject('stores', 'actions')
17@observer 17@observer
18class AppLayoutContainer extends Component<AppLayoutContainerProps> { 18class AppLayoutContainer extends Component<IProps> {
19 render(): ReactElement { 19 render(): ReactElement {
20 const { app, features, services, ui, settings, requests, user, router } = 20 const { app, features, services, ui, settings, requests, user, router } =
21 this.props.stores; 21 this.props.stores;
@@ -31,10 +31,10 @@ class AppLayoutContainer extends Component<AppLayoutContainerProps> {
31 31
32 const { 32 const {
33 setActive, 33 setActive,
34 handleIPCMessage, 34 // handleIPCMessage,
35 setWebviewReference, 35 setWebviewReference,
36 detachService, 36 detachService,
37 openWindow, 37 // openWindow,
38 reorder, 38 reorder,
39 reload, 39 reload,
40 toggleNotifications, 40 toggleNotifications,
@@ -118,10 +118,10 @@ class AppLayoutContainer extends Component<AppLayoutContainerProps> {
118 const servicesContainer = ( 118 const servicesContainer = (
119 <Services 119 <Services
120 services={services.allDisplayedUnordered} 120 services={services.allDisplayedUnordered}
121 handleIPCMessage={handleIPCMessage} 121 // handleIPCMessage={handleIPCMessage} // TODO - - [TECH DEBT] check it later
122 setWebviewReference={setWebviewReference} 122 setWebviewReference={setWebviewReference}
123 detachService={detachService} 123 detachService={detachService}
124 openWindow={openWindow} 124 // openWindow={openWindow} // TODO - - [TECH DEBT] check it later
125 reload={reload} 125 reload={reload}
126 openSettings={openSettings} 126 openSettings={openSettings}
127 update={updateService} 127 update={updateService}
diff --git a/src/containers/settings/ServicesScreen.tsx b/src/containers/settings/ServicesScreen.tsx
index affe965e9..780b7331e 100644
--- a/src/containers/settings/ServicesScreen.tsx
+++ b/src/containers/settings/ServicesScreen.tsx
@@ -1,39 +1,48 @@
1import { Component, ReactElement } from 'react'; 1import { Component, ReactElement } from 'react';
2import { inject, observer } from 'mobx-react'; 2import { inject, observer } from 'mobx-react';
3
4import { StoresProps } from '../../@types/ferdium-components.types'; 3import { StoresProps } from '../../@types/ferdium-components.types';
5import ServicesDashboard from '../../components/settings/services/ServicesDashboard'; 4import ServicesDashboard from '../../components/settings/services/ServicesDashboard';
6import ErrorBoundary from '../../components/util/ErrorBoundary'; 5import ErrorBoundary from '../../components/util/ErrorBoundary';
7 6
8class ServicesScreen extends Component<StoresProps> { 7interface IProps extends StoresProps {}
8
9@inject('stores', 'actions')
10@observer
11class ServicesScreen extends Component<IProps> {
9 componentWillUnmount(): void { 12 componentWillUnmount(): void {
10 this.props.actions.service.resetFilter(); 13 this.props.actions.service.resetFilter();
11 this.props.actions.service.resetStatus(); 14 this.props.actions.service.resetStatus();
12 } 15 }
13 16
14 deleteService(): void { 17 // TODO - [TECH DEBT] need to check it
15 this.props.actions.service.deleteService(); 18 // deleteService(): void {
16 this.props.actions.service.resetFilter(); 19 // this.props.actions.service.deleteService();
17 } 20 // this.props.actions.service.resetFilter();
21 // }
18 22
19 render(): ReactElement { 23 render(): ReactElement {
20 const { user, services, router } = this.props.stores; 24 const {
21 const { toggleService, filter, resetFilter } = this.props.actions.service; 25 // user,
26 services,
27 router,
28 } = this.props.stores;
29 const {
30 // toggleService,
31 filter,
32 resetFilter,
33 } = this.props.actions.service;
22 const isLoading = services.allServicesRequest.isExecuting; 34 const isLoading = services.allServicesRequest.isExecuting;
23 35 const allServices =
24 let allServices = services.all; 36 services.filterNeedle !== null ? services.filtered : services.all;
25 if (services.filterNeedle !== null) {
26 allServices = services.filtered;
27 }
28 37
29 return ( 38 return (
30 <ErrorBoundary> 39 <ErrorBoundary>
31 <ServicesDashboard 40 <ServicesDashboard
32 user={user.data} 41 // user={user.data} // TODO - [TECH DEBT][PROPS NOT EXIST IN COMPONENT] check it later
33 services={allServices} 42 services={allServices}
34 status={services.actionStatus} 43 status={services.actionStatus}
35 deleteService={() => this.deleteService()} 44 // deleteService={() => this.deleteService()} // TODO - [TECH DEBT][PROPS NOT EXIST IN COMPONENT] check it later
36 toggleService={toggleService} 45 // toggleService={toggleService} // TODO - [TECH DEBT][PROPS NOT USED IN COMPONENT] check it later
37 isLoading={isLoading} 46 isLoading={isLoading}
38 filterServices={filter} 47 filterServices={filter}
39 resetFilter={resetFilter} 48 resetFilter={resetFilter}
@@ -50,4 +59,4 @@ class ServicesScreen extends Component<StoresProps> {
50 } 59 }
51} 60}
52 61
53export default inject('stores', 'actions')(observer(ServicesScreen)); 62export default ServicesScreen;