aboutsummaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
authorLibravatar Ricardo Cino <ricardo@cino.io>2022-07-07 09:31:50 +0200
committerLibravatar GitHub <noreply@github.com>2022-07-07 09:31:50 +0200
commit71c52373f81cace664047edd19d9d289f45a4dff (patch)
tree69b3f1d45a8b3f1ceab9497ea3c96e9dc18e3166 /src/components
parent6.0.0-nightly.91 [skip ci] (diff)
downloadferdium-app-71c52373f81cace664047edd19d9d289f45a4dff.tar.gz
ferdium-app-71c52373f81cace664047edd19d9d289f45a4dff.tar.zst
ferdium-app-71c52373f81cace664047edd19d9d289f45a4dff.zip
chore: Mobx & React-Router upgrade (#406)
Co-authored-by: Vijay A <vraravam@users.noreply.github.com>
Diffstat (limited to 'src/components')
-rw-r--r--src/components/auth/Import.js2
-rw-r--r--src/components/auth/Invite.js2
-rw-r--r--src/components/auth/Login.js2
-rw-r--r--src/components/auth/Welcome.jsx (renamed from src/components/auth/Welcome.js)7
-rw-r--r--src/components/layout/AppLayout.js9
-rw-r--r--src/components/services/content/ServiceWebview.js4
-rw-r--r--src/components/services/content/Services.jsx (renamed from src/components/services/content/Services.js)20
-rw-r--r--src/components/services/tabs/TabItem.js5
-rw-r--r--src/components/settings/SettingsLayout.jsx (renamed from src/components/settings/SettingsLayout.js)8
-rw-r--r--src/components/settings/navigation/SettingsNavigation.jsx (renamed from src/components/settings/navigation/SettingsNavigation.js)96
-rw-r--r--src/components/settings/recipes/RecipesDashboard.jsx (renamed from src/components/settings/recipes/RecipesDashboard.js)67
-rw-r--r--src/components/settings/services/EditServiceForm.js2
-rw-r--r--src/components/settings/services/ServiceError.js2
-rw-r--r--src/components/settings/services/ServicesDashboard.js5
-rw-r--r--src/components/settings/user/EditUserForm.js2
-rw-r--r--src/components/ui/Link.js2
-rw-r--r--src/components/ui/button/index.tsx22
-rw-r--r--src/components/ui/infobox/index.tsx4
-rw-r--r--src/components/ui/select/index.tsx15
-rw-r--r--src/components/ui/textarea/index.tsx2
-rw-r--r--src/components/ui/toggle/index.tsx4
-rw-r--r--src/components/util/ErrorBoundary/index.tsx3
-rw-r--r--src/components/util/WithParams.tsx8
23 files changed, 163 insertions, 130 deletions
diff --git a/src/components/auth/Import.js b/src/components/auth/Import.js
index e43be07a8..41b887974 100644
--- a/src/components/auth/Import.js
+++ b/src/components/auth/Import.js
@@ -2,7 +2,7 @@ import { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; 3import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
4import { defineMessages, injectIntl } from 'react-intl'; 4import { defineMessages, injectIntl } from 'react-intl';
5import { Link } from 'react-router'; 5import { Link } from 'react-router-dom';
6import classnames from 'classnames'; 6import classnames from 'classnames';
7 7
8import Form from '../../lib/Form'; 8import Form from '../../lib/Form';
diff --git a/src/components/auth/Invite.js b/src/components/auth/Invite.js
index 8e1ab514e..9eca924cd 100644
--- a/src/components/auth/Invite.js
+++ b/src/components/auth/Invite.js
@@ -2,7 +2,7 @@ import { Component, Fragment } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4import { defineMessages, injectIntl } from 'react-intl'; 4import { defineMessages, injectIntl } from 'react-intl';
5import { Link } from 'react-router'; 5import { Link } from 'react-router-dom';
6import classnames from 'classnames'; 6import classnames from 'classnames';
7 7
8import Infobox from '../ui/Infobox'; 8import Infobox from '../ui/Infobox';
diff --git a/src/components/auth/Login.js b/src/components/auth/Login.js
index 3de576ca6..eb184f1ee 100644
--- a/src/components/auth/Login.js
+++ b/src/components/auth/Login.js
@@ -178,7 +178,7 @@ class Login extends Component {
178 <Link to={signupRoute}> 178 <Link to={signupRoute}>
179 {intl.formatMessage(messages.signupLink)} 179 {intl.formatMessage(messages.signupLink)}
180 </Link> 180 </Link>
181 <Link 181 <Link
182 // to={passwordRoute} // TODO: Uncomment this line after fixing password recovery in-app 182 // to={passwordRoute} // TODO: Uncomment this line after fixing password recovery in-app
183 to={`${serverBase()}/user/forgot`} // TODO: Remove this line after fixing password recovery in-app 183 to={`${serverBase()}/user/forgot`} // TODO: Remove this line after fixing password recovery in-app
184 target='_blank' // TODO: Remove this line after fixing password recovery in-app 184 target='_blank' // TODO: Remove this line after fixing password recovery in-app
diff --git a/src/components/auth/Welcome.js b/src/components/auth/Welcome.jsx
index c9d592a88..c784b75c3 100644
--- a/src/components/auth/Welcome.js
+++ b/src/components/auth/Welcome.jsx
@@ -25,7 +25,7 @@ const messages = defineMessages({
25 }, 25 },
26 changeServer: { 26 changeServer: {
27 id: 'login.changeServer', 27 id: 'login.changeServer',
28 defaultMessage: 'Change here!' 28 defaultMessage: 'Change here!',
29 }, 29 },
30 serverless: { 30 serverless: {
31 id: 'services.serverless', 31 id: 'services.serverless',
@@ -65,7 +65,6 @@ class Welcome extends Component {
65 className="welcome__logo" 65 className="welcome__logo"
66 alt="" 66 alt=""
67 /> 67 />
68 {/* <img src="./assets/images/welcome.png" className="welcome__services" alt="" /> */}
69 </div> 68 </div>
70 <div className="welcome__text"> 69 <div className="welcome__text">
71 <H1>Ferdium</H1> 70 <H1>Ferdium</H1>
@@ -82,9 +81,7 @@ class Welcome extends Component {
82 {intl.formatMessage(messages.changeServerMessage, { serverNameParse })} 81 {intl.formatMessage(messages.changeServerMessage, { serverNameParse })}
83 </span> 82 </span>
84 <Link to={changeServerRoute} className="button__change-server"> 83 <Link to={changeServerRoute} className="button__change-server">
85 <span> 84 <span>{intl.formatMessage(messages.changeServer)}</span>
86 {intl.formatMessage(messages.changeServer)}
87 </span>
88 </Link> 85 </Link>
89 </div> 86 </div>
90 <br /> 87 <br />
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js
index e22d4eb50..f7860afc6 100644
--- a/src/components/layout/AppLayout.js
+++ b/src/components/layout/AppLayout.js
@@ -7,6 +7,7 @@ import injectSheet from 'react-jss';
7import { ipcRenderer } from 'electron'; 7import { ipcRenderer } from 'electron';
8 8
9import { mdiFlash, mdiPowerPlug } from '@mdi/js'; 9import { mdiFlash, mdiPowerPlug } from '@mdi/js';
10import { Outlet } from 'react-router-dom';
10import InfoBar from '../ui/InfoBar'; 11import InfoBar from '../ui/InfoBar';
11import { Component as BasicAuth } from '../../features/basicAuth'; 12import { Component as BasicAuth } from '../../features/basicAuth';
12import { Component as QuickSwitch } from '../../features/quickSwitch'; 13import { Component as QuickSwitch } from '../../features/quickSwitch';
@@ -83,7 +84,6 @@ class AppLayout extends Component {
83 sidebar: PropTypes.element.isRequired, 84 sidebar: PropTypes.element.isRequired,
84 workspacesDrawer: PropTypes.element.isRequired, 85 workspacesDrawer: PropTypes.element.isRequired,
85 services: PropTypes.element.isRequired, 86 services: PropTypes.element.isRequired,
86 children: PropTypes.element,
87 showServicesUpdatedInfoBar: PropTypes.bool.isRequired, 87 showServicesUpdatedInfoBar: PropTypes.bool.isRequired,
88 appUpdateIsDownloaded: PropTypes.bool.isRequired, 88 appUpdateIsDownloaded: PropTypes.bool.isRequired,
89 authRequestFailed: PropTypes.bool.isRequired, 89 authRequestFailed: PropTypes.bool.isRequired,
@@ -99,10 +99,6 @@ class AppLayout extends Component {
99 shouldShowServicesUpdatedInfoBar: true, 99 shouldShowServicesUpdatedInfoBar: true,
100 }; 100 };
101 101
102 static defaultProps = {
103 children: [],
104 };
105
106 render() { 102 render() {
107 const { 103 const {
108 classes, 104 classes,
@@ -110,7 +106,6 @@ class AppLayout extends Component {
110 workspacesDrawer, 106 workspacesDrawer,
111 sidebar, 107 sidebar,
112 services, 108 services,
113 children,
114 showServicesUpdatedInfoBar, 109 showServicesUpdatedInfoBar,
115 appUpdateIsDownloaded, 110 appUpdateIsDownloaded,
116 authRequestFailed, 111 authRequestFailed,
@@ -205,7 +200,7 @@ class AppLayout extends Component {
205 <QuickSwitch /> 200 <QuickSwitch />
206 <PublishDebugInfo /> 201 <PublishDebugInfo />
207 {services} 202 {services}
208 {children} 203 <Outlet />
209 </div> 204 </div>
210 <Todos /> 205 <Todos />
211 </div> 206 </div>
diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js
index 66dc8af41..502f87225 100644
--- a/src/components/services/content/ServiceWebview.js
+++ b/src/components/services/content/ServiceWebview.js
@@ -1,7 +1,7 @@
1import { Component } from 'react'; 1import { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4import { observable, reaction } from 'mobx'; 4import { makeObservable, observable, reaction } from 'mobx';
5import ElectronWebView from 'react-electron-web-view'; 5import ElectronWebView from 'react-electron-web-view';
6import { join } from 'path'; 6import { join } from 'path';
7 7
@@ -22,6 +22,8 @@ class ServiceWebview extends Component {
22 constructor(props) { 22 constructor(props) {
23 super(props); 23 super(props);
24 24
25 makeObservable(this);
26
25 reaction( 27 reaction(
26 () => this.webview, 28 () => this.webview,
27 () => { 29 () => {
diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.jsx
index b38b0e3c3..da700b5b1 100644
--- a/src/components/services/content/Services.js
+++ b/src/components/services/content/Services.jsx
@@ -1,7 +1,7 @@
1import { Component } from 'react'; 1import { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer, PropTypes as MobxPropTypes, inject } from 'mobx-react'; 3import { observer, PropTypes as MobxPropTypes, inject } from 'mobx-react';
4import { Link } from 'react-router'; 4import { Link } from 'react-router-dom';
5import { defineMessages, injectIntl } from 'react-intl'; 5import { defineMessages, injectIntl } from 'react-intl';
6import Confetti from 'react-confetti'; 6import Confetti from 'react-confetti';
7import ms from 'ms'; 7import ms from 'ms';
@@ -50,6 +50,7 @@ class Services extends Component {
50 openSettings: PropTypes.func.isRequired, 50 openSettings: PropTypes.func.isRequired,
51 update: PropTypes.func.isRequired, 51 update: PropTypes.func.isRequired,
52 userHasCompletedSignup: PropTypes.bool.isRequired, 52 userHasCompletedSignup: PropTypes.bool.isRequired,
53 // eslint-disable-next-line react/forbid-prop-types
53 classes: PropTypes.object.isRequired, 54 classes: PropTypes.object.isRequired,
54 isSpellcheckerEnabled: PropTypes.bool.isRequired, 55 isSpellcheckerEnabled: PropTypes.bool.isRequired,
55 }; 56 };
@@ -58,12 +59,16 @@ class Services extends Component {
58 services: [], 59 services: [],
59 }; 60 };
60 61
61 state = {
62 showConfetti: true,
63 };
64
65 _confettiTimeout = null; 62 _confettiTimeout = null;
66 63
64 constructor() {
65 super();
66
67 this.state = {
68 showConfetti: true,
69 };
70 }
71
67 componentDidMount() { 72 componentDidMount() {
68 this._confettiTimeout = window.setTimeout(() => { 73 this._confettiTimeout = window.setTimeout(() => {
69 this.setState({ 74 this.setState({
@@ -117,10 +122,7 @@ class Services extends Component {
117 style={{ maxHeight: '50vh' }} 122 style={{ maxHeight: '50vh' }}
118 /> 123 />
119 <Appear timeout={300} transitionName="slideUp"> 124 <Appear timeout={300} transitionName="slideUp">
120 <Link 125 <Link to="/settings/recipes" className="button">
121 to='/settings/recipes'
122 className="button"
123 >
124 {intl.formatMessage(messages.getStarted)} 126 {intl.formatMessage(messages.getStarted)}
125 </Link> 127 </Link>
126 </Appear> 128 </Appear>
diff --git a/src/components/services/tabs/TabItem.js b/src/components/services/tabs/TabItem.js
index 9d2b6b333..a996990b5 100644
--- a/src/components/services/tabs/TabItem.js
+++ b/src/components/services/tabs/TabItem.js
@@ -8,7 +8,7 @@ import { SortableElement } from 'react-sortable-hoc';
8import injectSheet from 'react-jss'; 8import injectSheet from 'react-jss';
9import ms from 'ms'; 9import ms from 'ms';
10 10
11import { observable, autorun, reaction } from 'mobx'; 11import { observable, autorun, reaction, makeObservable } from 'mobx';
12import { mdiExclamation } from '@mdi/js'; 12import { mdiExclamation } from '@mdi/js';
13import ServiceModel from '../../../models/Service'; 13import ServiceModel from '../../../models/Service';
14import { cmdOrCtrlShortcutKey, shiftKey, altKey } from '../../../environment'; 14import { cmdOrCtrlShortcutKey, shiftKey, altKey } from '../../../environment';
@@ -144,6 +144,9 @@ class TabItem extends Component {
144 144
145 constructor(props) { 145 constructor(props) {
146 super(props); 146 super(props);
147
148 makeObservable(this);
149
147 this.state = { 150 this.state = {
148 showShortcutIndex: false, 151 showShortcutIndex: false,
149 }; 152 };
diff --git a/src/components/settings/SettingsLayout.js b/src/components/settings/SettingsLayout.jsx
index d70f471d5..dea4bb387 100644
--- a/src/components/settings/SettingsLayout.js
+++ b/src/components/settings/SettingsLayout.jsx
@@ -4,8 +4,8 @@ import { observer } from 'mobx-react';
4import { defineMessages, injectIntl } from 'react-intl'; 4import { defineMessages, injectIntl } from 'react-intl';
5 5
6import { mdiClose } from '@mdi/js'; 6import { mdiClose } from '@mdi/js';
7import { Outlet } from 'react-router-dom';
7import ErrorBoundary from '../util/ErrorBoundary'; 8import ErrorBoundary from '../util/ErrorBoundary';
8import { oneOrManyChildElements } from '../../prop-types';
9import Appear from '../ui/effects/Appear'; 9import Appear from '../ui/effects/Appear';
10import Icon from '../ui/icon'; 10import Icon from '../ui/icon';
11 11
@@ -19,7 +19,6 @@ const messages = defineMessages({
19class SettingsLayout extends Component { 19class SettingsLayout extends Component {
20 static propTypes = { 20 static propTypes = {
21 navigation: PropTypes.element.isRequired, 21 navigation: PropTypes.element.isRequired,
22 children: oneOrManyChildElements.isRequired,
23 closeSettings: PropTypes.func.isRequired, 22 closeSettings: PropTypes.func.isRequired,
24 }; 23 };
25 24
@@ -44,7 +43,7 @@ class SettingsLayout extends Component {
44 } 43 }
45 44
46 render() { 45 render() {
47 const { navigation, children, closeSettings } = this.props; 46 const { navigation, closeSettings } = this.props;
48 47
49 const { intl } = this.props; 48 const { intl } = this.props;
50 49
@@ -60,7 +59,8 @@ class SettingsLayout extends Component {
60 /> 59 />
61 <div className="settings franz-form"> 60 <div className="settings franz-form">
62 {navigation} 61 {navigation}
63 {children} 62
63 <Outlet />
64 <button 64 <button
65 type="button" 65 type="button"
66 className="settings__close" 66 className="settings__close"
diff --git a/src/components/settings/navigation/SettingsNavigation.js b/src/components/settings/navigation/SettingsNavigation.jsx
index ad1cef1e4..bbbe8d888 100644
--- a/src/components/settings/navigation/SettingsNavigation.js
+++ b/src/components/settings/navigation/SettingsNavigation.jsx
@@ -2,10 +2,10 @@ import { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { defineMessages, injectIntl } from 'react-intl'; 3import { defineMessages, injectIntl } from 'react-intl';
4import { inject, observer } from 'mobx-react'; 4import { inject, observer } from 'mobx-react';
5import { RouterStore } from 'mobx-react-router'; 5import { RouterStore } from '@superwf/mobx-react-router';
6 6
7import { NavLink } from 'react-router-dom';
7import { LOCAL_SERVER, LIVE_FERDIUM_API, LIVE_FRANZ_API } from '../../../config'; 8import { LOCAL_SERVER, LIVE_FERDIUM_API, LIVE_FRANZ_API } from '../../../config';
8import Link from '../../ui/Link';
9import UIStore from '../../../stores/UIStore'; 9import UIStore from '../../../stores/UIStore';
10import SettingsStore from '../../../stores/SettingsStore'; 10import SettingsStore from '../../../stores/SettingsStore';
11import UserStore from '../../../stores/UserStore'; 11import UserStore from '../../../stores/UserStore';
@@ -90,70 +90,94 @@ class SettingsNavigation extends Component {
90 90
91 return ( 91 return (
92 <div className="settings-navigation"> 92 <div className="settings-navigation">
93 <Link 93 <NavLink
94 to="/settings/recipes" 94 to="/settings/recipes"
95 className="settings-navigation__link" 95 className={({ isActive }) =>
96 activeClassName="is-active" 96 isActive
97 ? 'settings-navigation__link is-active'
98 : 'settings-navigation__link'
99 }
97 > 100 >
98 {intl.formatMessage(messages.availableServices)} 101 {intl.formatMessage(messages.availableServices)}
99 </Link> 102 </NavLink>
100 <Link 103 <NavLink
101 to="/settings/services" 104 to="/settings/services"
102 className="settings-navigation__link" 105 className={({ isActive }) =>
103 activeClassName="is-active" 106 isActive
107 ? 'settings-navigation__link is-active'
108 : 'settings-navigation__link'
109 }
104 > 110 >
105 {intl.formatMessage(messages.yourServices)}{' '} 111 {intl.formatMessage(messages.yourServices)}{' '}
106 <span className="badge">{serviceCount}</span> 112 <span className="badge">{serviceCount}</span>
107 </Link> 113 </NavLink>
108 <Link 114 <NavLink
109 to="/settings/workspaces" 115 to="/settings/workspaces"
110 className="settings-navigation__link" 116 className={({ isActive }) =>
111 activeClassName="is-active" 117 isActive
118 ? 'settings-navigation__link is-active'
119 : 'settings-navigation__link'
120 }
112 > 121 >
113 {intl.formatMessage(messages.yourWorkspaces)}{' '} 122 {intl.formatMessage(messages.yourWorkspaces)}{' '}
114 <span className="badge">{workspaceCount}</span> 123 <span className="badge">{workspaceCount}</span>
115 </Link> 124 </NavLink>
116 {!isUsingWithoutAccount && ( 125 {!isUsingWithoutAccount && (
117 <Link 126 <NavLink
118 to="/settings/user" 127 to="/settings/user"
119 className="settings-navigation__link" 128 className={({ isActive }) =>
120 activeClassName="is-active" 129 isActive
130 ? 'settings-navigation__link is-active'
131 : 'settings-navigation__link'
132 }
121 > 133 >
122 {intl.formatMessage(messages.account)} 134 {intl.formatMessage(messages.account)}
123 </Link> 135 </NavLink>
124 )} 136 )}
125 {isUsingFranzServer && ( 137 {isUsingFranzServer && (
126 <Link 138 <NavLink
127 to="/settings/team" 139 to="/settings/team"
128 className="settings-navigation__link" 140 className={({ isActive }) =>
129 activeClassName="is-active" 141 isActive
142 ? 'settings-navigation__link is-active'
143 : 'settings-navigation__link'
144 }
130 > 145 >
131 {intl.formatMessage(messages.team)} 146 {intl.formatMessage(messages.team)}
132 </Link> 147 </NavLink>
133 )} 148 )}
134 <Link 149 <NavLink
135 to="/settings/app" 150 to="/settings/app"
136 className="settings-navigation__link" 151 className={({ isActive }) =>
137 activeClassName="is-active" 152 isActive
153 ? 'settings-navigation__link is-active'
154 : 'settings-navigation__link'
155 }
138 > 156 >
139 {intl.formatMessage(globalMessages.settings)} 157 {intl.formatMessage(globalMessages.settings)}
140 {stores.settings.app.automaticUpdates && (stores.ui.showServicesUpdatedInfoBar || 158 {stores.settings.app.automaticUpdates &&
141 (stores.app.updateStatus === stores.app.updateStatusTypes.AVAILABLE || 159 (stores.ui.showServicesUpdatedInfoBar ||
142 stores.app.updateStatus === stores.app.updateStatusTypes.DOWNLOADED)) && ( 160 stores.app.updateStatus ===
143 <span className="update-available">•</span> 161 stores.app.updateStatusTypes.AVAILABLE ||
144 )} 162 stores.app.updateStatus ===
145 </Link> 163 stores.app.updateStatusTypes.DOWNLOADED) && (
146 <Link 164 <span className="update-available">•</span>
165 )}
166 </NavLink>
167 <NavLink
147 to="/settings/support" 168 to="/settings/support"
148 className="settings-navigation__link" 169 className={({ isActive }) =>
149 activeClassName="is-active" 170 isActive
171 ? 'settings-navigation__link is-active'
172 : 'settings-navigation__link'
173 }
150 > 174 >
151 {intl.formatMessage(messages.supportFerdium)} 175 {intl.formatMessage(messages.supportFerdium)}
152 </Link> 176 </NavLink>
153 <span className="settings-navigation__expander" /> 177 <span className="settings-navigation__expander" />
154 <button 178 <button
155 type="button" 179 type="button"
156 to='/auth/logout' 180 to="/auth/logout"
157 className="settings-navigation__link" 181 className="settings-navigation__link"
158 onClick={this.handleLogout.bind(this)} 182 onClick={this.handleLogout.bind(this)}
159 > 183 >
diff --git a/src/components/settings/recipes/RecipesDashboard.js b/src/components/settings/recipes/RecipesDashboard.jsx
index c05144117..589b97ecd 100644
--- a/src/components/settings/recipes/RecipesDashboard.js
+++ b/src/components/settings/recipes/RecipesDashboard.jsx
@@ -2,7 +2,7 @@ import { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; 3import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
4import { defineMessages, injectIntl } from 'react-intl'; 4import { defineMessages, injectIntl } from 'react-intl';
5import { Link } from 'react-router'; 5import { NavLink } from 'react-router-dom';
6 6
7import injectSheet from 'react-jss'; 7import injectSheet from 'react-jss';
8 8
@@ -179,30 +179,33 @@ class RecipesDashboard extends Component {
179 throttle 179 throttle
180 /> 180 />
181 <div className="recipes__navigation"> 181 <div className="recipes__navigation">
182 <Link 182 <NavLink
183 to="/settings/recipes" 183 to="/settings/recipes"
184 className="badge" 184 className={() =>
185 activeClassName={`${!searchNeedle ? 'badge--primary' : ''}`} 185 recipeFilter === 'featured' ? 'badge badge--primary' : 'badge'
186 }
186 onClick={() => resetSearch()} 187 onClick={() => resetSearch()}
187 > 188 >
188 {intl.formatMessage(messages.ferdiumPicksRecipes)} 189 {intl.formatMessage(messages.ferdiumPicksRecipes)}
189 </Link> 190 </NavLink>
190 <Link 191 <NavLink
191 to="/settings/recipes/all" 192 to="/settings/recipes/all"
192 className="badge" 193 className={({ isActive }) =>
193 activeClassName={`${!searchNeedle ? 'badge--primary' : ''}`} 194 isActive && recipeFilter === 'all' ? 'badge badge--primary' : 'badge'
195 }
194 onClick={() => resetSearch()} 196 onClick={() => resetSearch()}
195 > 197 >
196 {intl.formatMessage(messages.allRecipes)} 198 {intl.formatMessage(messages.allRecipes)}
197 </Link> 199 </NavLink>
198 <Link 200 <NavLink
199 to="/settings/recipes/dev" 201 to="/settings/recipes/dev"
200 className="badge" 202 className={({ isActive }) =>
201 activeClassName={`${!searchNeedle ? 'badge--primary' : ''}`} 203 isActive && !searchNeedle ? 'badge badge--primary' : 'badge'
204 }
202 onClick={() => resetSearch()} 205 onClick={() => resetSearch()}
203 > 206 >
204 {intl.formatMessage(messages.customRecipes)} 207 {intl.formatMessage(messages.customRecipes)}
205 </Link> 208 </NavLink>
206 <a 209 <a
207 href={FERDIUM_SERVICE_REQUEST} 210 href={FERDIUM_SERVICE_REQUEST}
208 target="_blank" 211 target="_blank"
@@ -257,24 +260,26 @@ class RecipesDashboard extends Component {
257 /> 260 />
258 ))} 261 ))}
259 </div> 262 </div>
260 {hasLoadedRecipes && recipes.length === 0 && recipeFilter !== 'dev' && ( 263 {hasLoadedRecipes &&
261 <div className="align-middle settings__empty-state"> 264 recipes.length === 0 &&
262 {customWebsiteRecipe && customWebsiteRecipe.id && ( 265 recipeFilter !== 'dev' && (
263 <RecipeItem 266 <div className="align-middle settings__empty-state">
264 key={customWebsiteRecipe.id} 267 {customWebsiteRecipe && customWebsiteRecipe.id && (
265 recipe={customWebsiteRecipe} 268 <RecipeItem
266 onClick={() => 269 key={customWebsiteRecipe.id}
267 showAddServiceInterface({ 270 recipe={customWebsiteRecipe}
268 recipeId: customWebsiteRecipe.id, 271 onClick={() =>
269 }) 272 showAddServiceInterface({
270 } 273 recipeId: customWebsiteRecipe.id,
271 /> 274 })
272 )} 275 }
273 <p className="settings__empty-state-text"> 276 />
274 {intl.formatMessage(messages.nothingFound)} 277 )}
275 </p> 278 <p className="settings__empty-state-text">
276 </div> 279 {intl.formatMessage(messages.nothingFound)}
277 )} 280 </p>
281 </div>
282 )}
278 {recipeFilter === 'dev' && devRecipes.length > 0 && ( 283 {recipeFilter === 'dev' && devRecipes.length > 0 && (
279 <div className={classes.devRecipeList}> 284 <div className={classes.devRecipeList}>
280 <H3>{intl.formatMessage(messages.headlineDevRecipes)}</H3> 285 <H3>{intl.formatMessage(messages.headlineDevRecipes)}</H3>
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js
index f69d86726..73136529a 100644
--- a/src/components/settings/services/EditServiceForm.js
+++ b/src/components/settings/services/EditServiceForm.js
@@ -1,7 +1,7 @@
1import { Component } from 'react'; 1import { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4import { Link } from 'react-router'; 4import { Link } from 'react-router-dom';
5import { defineMessages, injectIntl } from 'react-intl'; 5import { defineMessages, injectIntl } from 'react-intl';
6import normalizeUrl from 'normalize-url'; 6import normalizeUrl from 'normalize-url';
7 7
diff --git a/src/components/settings/services/ServiceError.js b/src/components/settings/services/ServiceError.js
index 991817175..fdcdb54c9 100644
--- a/src/components/settings/services/ServiceError.js
+++ b/src/components/settings/services/ServiceError.js
@@ -1,6 +1,6 @@
1import { Component } from 'react'; 1import { Component } from 'react';
2import { observer } from 'mobx-react'; 2import { observer } from 'mobx-react';
3import { Link } from 'react-router'; 3import { Link } from 'react-router-dom';
4import { defineMessages, injectIntl } from 'react-intl'; 4import { defineMessages, injectIntl } from 'react-intl';
5 5
6import Infobox from '../../ui/Infobox'; 6import Infobox from '../../ui/Infobox';
diff --git a/src/components/settings/services/ServicesDashboard.js b/src/components/settings/services/ServicesDashboard.js
index c5bb1433c..ac1c30ecb 100644
--- a/src/components/settings/services/ServicesDashboard.js
+++ b/src/components/settings/services/ServicesDashboard.js
@@ -1,7 +1,7 @@
1import { Component } from 'react'; 1import { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; 3import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
4import { Link } from 'react-router'; 4import { Link } from 'react-router-dom';
5import { defineMessages, injectIntl } from 'react-intl'; 5import { defineMessages, injectIntl } from 'react-intl';
6 6
7import SearchInput from '../../ui/SearchInput'; 7import SearchInput from '../../ui/SearchInput';
@@ -27,8 +27,7 @@ const messages = defineMessages({
27 }, 27 },
28 noServiceFound: { 28 noServiceFound: {
29 id: 'settings.services.nothingFound', 29 id: 'settings.services.nothingFound',
30 defaultMessage: 30 defaultMessage: 'Sorry, but no service matched your search term.',
31 'Sorry, but no service matched your search term.',
32 }, 31 },
33 discoverServices: { 32 discoverServices: {
34 id: 'settings.services.discoverServices', 33 id: 'settings.services.discoverServices',
diff --git a/src/components/settings/user/EditUserForm.js b/src/components/settings/user/EditUserForm.js
index 436a6b76b..c2773a47d 100644
--- a/src/components/settings/user/EditUserForm.js
+++ b/src/components/settings/user/EditUserForm.js
@@ -2,7 +2,7 @@ import { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; 3import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
4import { defineMessages, injectIntl } from 'react-intl'; 4import { defineMessages, injectIntl } from 'react-intl';
5import { Link } from 'react-router'; 5import { Link } from 'react-router-dom';
6 6
7import Input from '../../ui/input/index'; 7import Input from '../../ui/input/index';
8import Form from '../../../lib/Form'; 8import Form from '../../../lib/Form';
diff --git a/src/components/ui/Link.js b/src/components/ui/Link.js
index 5ab19bf74..714fc5a68 100644
--- a/src/components/ui/Link.js
+++ b/src/components/ui/Link.js
@@ -1,7 +1,7 @@
1import { Component } from 'react'; 1import { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { inject, observer } from 'mobx-react'; 3import { inject, observer } from 'mobx-react';
4import { RouterStore } from 'mobx-react-router'; 4import { RouterStore } from '@superwf/mobx-react-router';
5import classnames from 'classnames'; 5import classnames from 'classnames';
6 6
7import { oneOrManyChildElements } from '../../prop-types'; 7import { oneOrManyChildElements } from '../../prop-types';
diff --git a/src/components/ui/button/index.tsx b/src/components/ui/button/index.tsx
index 26fd6bcfe..a8bbfe730 100644
--- a/src/components/ui/button/index.tsx
+++ b/src/components/ui/button/index.tsx
@@ -169,20 +169,18 @@ class ButtonComponent extends Component<IProps> {
169 busy: false, 169 busy: false,
170 }; 170 };
171 171
172 componentWillMount() { 172 constructor(props: IProps) {
173 this.setState({ busy: this.props.busy }); 173 super(props);
174
175 this.state = {
176 busy: props.busy || false,
177 };
174 } 178 }
175 179
176 componentWillReceiveProps(nextProps: IProps) { 180 static getDerivedStateFromProps(nextProps: IProps) {
177 if (nextProps.busy !== this.props.busy) { 181 return {
178 if (this.props.busy) { 182 busy: nextProps.busy,
179 setTimeout(() => { 183 };
180 this.setState({ busy: nextProps.busy });
181 }, 300);
182 } else {
183 this.setState({ busy: nextProps.busy });
184 }
185 }
186 } 184 }
187 185
188 render() { 186 render() {
diff --git a/src/components/ui/infobox/index.tsx b/src/components/ui/infobox/index.tsx
index 976ed5bc4..d1d7ef6cd 100644
--- a/src/components/ui/infobox/index.tsx
+++ b/src/components/ui/infobox/index.tsx
@@ -199,6 +199,4 @@ class InfoboxComponent extends Component<IProps, IState> {
199 } 199 }
200} 200}
201 201
202export default injectStyle(styles, { injectTheme: true })( 202export default injectStyle(styles, { injectTheme: true })(InfoboxComponent);
203 InfoboxComponent,
204);
diff --git a/src/components/ui/select/index.tsx b/src/components/ui/select/index.tsx
index c3b5314e3..1ce6c674b 100644
--- a/src/components/ui/select/index.tsx
+++ b/src/components/ui/select/index.tsx
@@ -177,12 +177,16 @@ class SelectComponent extends Component<IProps> {
177 177
178 private keyListener: any; 178 private keyListener: any;
179 179
180 componentWillReceiveProps(nextProps: IProps) { 180 static getDerivedStateFromProps(nextProps: IProps, prevState: IProps) {
181 if (nextProps.value && nextProps.value !== this.props.value) { 181 if (nextProps.value && nextProps.value !== prevState.value) {
182 this.setState({ 182 return {
183 value: nextProps.value, 183 value: nextProps.value,
184 }); 184 };
185 } 185 }
186
187 return {
188 value: prevState.value,
189 };
186 } 190 }
187 191
188 componentDidUpdate() { 192 componentDidUpdate() {
@@ -199,6 +203,7 @@ class SelectComponent extends Component<IProps> {
199 203
200 if (data) { 204 if (data) {
201 Object.keys(data).map( 205 Object.keys(data).map(
206 // eslint-disable-next-line no-return-assign
202 key => (this.inputRef.current!.dataset[key] = data[key]), 207 key => (this.inputRef.current!.dataset[key] = data[key]),
203 ); 208 );
204 } 209 }
@@ -458,6 +463,6 @@ class SelectComponent extends Component<IProps> {
458 } 463 }
459} 464}
460 465
461export const Select = injectStyle(styles, { injectTheme: true })( 466export default injectStyle(styles, { injectTheme: true })(
462 SelectComponent, 467 SelectComponent,
463); 468);
diff --git a/src/components/ui/textarea/index.tsx b/src/components/ui/textarea/index.tsx
index e005767f8..6796ab83d 100644
--- a/src/components/ui/textarea/index.tsx
+++ b/src/components/ui/textarea/index.tsx
@@ -121,6 +121,6 @@ class TextareaComponent extends Component<IProps> {
121 } 121 }
122} 122}
123 123
124export const Textarea = injectSheet(styles, { injectTheme: true })( 124export default injectSheet(styles, { injectTheme: true })(
125 TextareaComponent, 125 TextareaComponent,
126); 126);
diff --git a/src/components/ui/toggle/index.tsx b/src/components/ui/toggle/index.tsx
index 0629d1a2c..d478cbba5 100644
--- a/src/components/ui/toggle/index.tsx
+++ b/src/components/ui/toggle/index.tsx
@@ -122,6 +122,4 @@ class ToggleComponent extends Component<IProps> {
122 } 122 }
123} 123}
124 124
125export default injectStyle(styles, { injectTheme: true })( 125export default injectStyle(styles, { injectTheme: true })(ToggleComponent);
126 ToggleComponent,
127);
diff --git a/src/components/util/ErrorBoundary/index.tsx b/src/components/util/ErrorBoundary/index.tsx
index 846d6dc3f..b042e62c8 100644
--- a/src/components/util/ErrorBoundary/index.tsx
+++ b/src/components/util/ErrorBoundary/index.tsx
@@ -32,8 +32,7 @@ class ErrorBoundary extends Component<ErrorBoundaryProps> {
32 } 32 }
33 33
34 render(): ReactNode { 34 render(): ReactNode {
35 const { classes } = this.props; 35 const { classes, intl } = this.props;
36 const { intl } = this.props;
37 36
38 if (this.state.hasError) { 37 if (this.state.hasError) {
39 return ( 38 return (
diff --git a/src/components/util/WithParams.tsx b/src/components/util/WithParams.tsx
new file mode 100644
index 000000000..6fc0957ff
--- /dev/null
+++ b/src/components/util/WithParams.tsx
@@ -0,0 +1,8 @@
1import { useParams } from 'react-router-dom';
2
3export default function withParams(Component: any) {
4 return (props: any) => {
5 const params = useParams();
6 return <Component {...props} params={params} />;
7 };
8}