From 537697a6e9757f118d09d9e76362ba1ff617e2c6 Mon Sep 17 00:00:00 2001 From: Markus Hatvan Date: Mon, 13 Sep 2021 14:45:46 +0200 Subject: chore: upgrade intl dependencies (#1920) --- src/containers/settings/AccountScreen.js | 11 +- src/containers/settings/EditServiceScreen.js | 121 ++++++++++--------- src/containers/settings/EditSettingsScreen.js | 166 ++++++++++++++------------ src/containers/settings/EditUserScreen.js | 60 +++++----- src/containers/settings/InviteScreen.js | 8 +- src/containers/settings/RecipesScreen.js | 92 ++++++++------ src/containers/settings/ServicesScreen.js | 17 +-- src/containers/settings/SettingsWindow.js | 21 ++-- src/containers/settings/SupportScreen.js | 9 +- src/containers/settings/TeamScreen.js | 11 +- 10 files changed, 289 insertions(+), 227 deletions(-) (limited to 'src/containers/settings') diff --git a/src/containers/settings/AccountScreen.js b/src/containers/settings/AccountScreen.js index 8d92b01be..cc3929656 100644 --- a/src/containers/settings/AccountScreen.js +++ b/src/containers/settings/AccountScreen.js @@ -12,7 +12,6 @@ import ErrorBoundary from '../../components/util/ErrorBoundary'; import { LIVE_FRANZ_API } from '../../config'; import { WEBSITE } from '../../environment'; -export default @inject('stores', 'actions') @observer class AccountScreen extends Component { @@ -58,16 +57,16 @@ class AccountScreen extends Component { user={user.data} isLoading={isLoadingUserInfo} userInfoRequestFailed={ - user.getUserInfoRequest.wasExecuted - && user.getUserInfoRequest.isError + user.getUserInfoRequest.wasExecuted && + user.getUserInfoRequest.isError } retryUserInfoRequest={() => this.reloadData()} onCloseSubscriptionWindow={() => this.onCloseWindow()} deleteAccount={userActions.delete} isLoadingDeleteAccount={user.deleteAccountRequest.isExecuting} isDeleteAccountSuccessful={ - user.deleteAccountRequest.wasExecuted - && !user.deleteAccountRequest.isError + user.deleteAccountRequest.wasExecuted && + !user.deleteAccountRequest.isError } openEditAccount={() => this.handleWebsiteLink('/user/profile')} openInvoices={() => this.handleWebsiteLink('/user/invoices')} @@ -89,3 +88,5 @@ AccountScreen.wrappedComponent.propTypes = { user: PropTypes.instanceOf(UserStore).isRequired, }).isRequired, }; + +export default AccountScreen; diff --git a/src/containers/settings/EditServiceScreen.js b/src/containers/settings/EditServiceScreen.js index c880e97ae..12e7b9e95 100644 --- a/src/containers/settings/EditServiceScreen.js +++ b/src/containers/settings/EditServiceScreen.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { inject, observer } from 'mobx-react'; -import { defineMessages, intlShape } from 'react-intl'; +import { defineMessages, injectIntl } from 'react-intl'; import { RouterStore } from 'mobx-react-router'; import UserStore from '../../stores/UserStore'; @@ -27,87 +27,85 @@ import globalMessages from '../../i18n/globalMessages'; const messages = defineMessages({ name: { id: 'settings.service.form.name', - defaultMessage: '!!!Name', + defaultMessage: 'Name', }, enableService: { id: 'settings.service.form.enableService', - defaultMessage: '!!!Enable service', + defaultMessage: 'Enable service', }, enableHibernation: { id: 'settings.service.form.enableHibernation', - defaultMessage: '!!!Enable hibernation', + defaultMessage: 'Enable hibernation', }, enableNotification: { id: 'settings.service.form.enableNotification', - defaultMessage: '!!!Enable Notifications', + defaultMessage: 'Enable Notifications', }, enableBadge: { id: 'settings.service.form.enableBadge', - defaultMessage: '!!!Show unread message badges', + defaultMessage: 'Show unread message badges', }, enableAudio: { id: 'settings.service.form.enableAudio', - defaultMessage: '!!!Enable audio', + defaultMessage: 'Enable audio', }, team: { id: 'settings.service.form.team', - defaultMessage: '!!!Team', + defaultMessage: 'Team', }, customUrl: { id: 'settings.service.form.customUrl', - defaultMessage: '!!!Service URL', + defaultMessage: 'Service URL', }, indirectMessages: { id: 'settings.service.form.indirectMessages', - defaultMessage: '!!!Show message badge for all new messages', + defaultMessage: 'Show message badge for all new messages', }, icon: { id: 'settings.service.form.icon', - defaultMessage: '!!!Custom icon', + defaultMessage: 'Custom icon', }, enableDarkMode: { id: 'settings.service.form.enableDarkMode', - defaultMessage: '!!!Enable Dark Mode', + defaultMessage: 'Enable Dark Mode', }, darkReaderBrightness: { id: 'settings.service.form.darkReaderBrightness', - defaultMessage: '!!!Dark Reader Brightness', + defaultMessage: 'Dark Reader Brightness', }, darkReaderContrast: { id: 'settings.service.form.darkReaderContrast', - defaultMessage: '!!!Dark Reader Contrast', + defaultMessage: 'Dark Reader Contrast', }, darkReaderSepia: { id: 'settings.service.form.darkReaderSepia', - defaultMessage: '!!!Dark Reader Sepia', + defaultMessage: 'Dark Reader Sepia', }, enableProxy: { id: 'settings.service.form.proxy.isEnabled', - defaultMessage: '!!!Use Proxy', + defaultMessage: 'Use Proxy', }, proxyHost: { id: 'settings.service.form.proxy.host', - defaultMessage: '!!!Proxy Host/IP', + defaultMessage: 'Proxy Host/IP', }, proxyPort: { id: 'settings.service.form.proxy.port', - defaultMessage: '!!!Port', + defaultMessage: 'Port', }, proxyUser: { id: 'settings.service.form.proxy.user', - defaultMessage: '!!!User', + defaultMessage: 'User', }, proxyPassword: { id: 'settings.service.form.proxy.password', - defaultMessage: '!!!Password', + defaultMessage: 'Password', }, }); -export default @inject('stores', 'actions') @observer class EditServiceScreen extends Component { - static contextTypes = { - intl: intlShape, - }; - +@inject('stores', 'actions') +@observer +class EditServiceScreen extends Component { onSubmit(data) { const { action } = this.props.router.params; const { recipes, services } = this.props.stores; @@ -132,27 +130,31 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex } prepareForm(recipe, service, proxy) { - const { - intl, - } = this.context; + const { intl } = this.props; - const { - stores, - router, - } = this.props; + const { stores, router } = this.props; const { action } = router.params; - let defaultSpellcheckerLanguage = SPELLCHECKER_LOCALES[stores.settings.app.spellcheckerLanguage]; + let defaultSpellcheckerLanguage = + SPELLCHECKER_LOCALES[stores.settings.app.spellcheckerLanguage]; if (stores.settings.app.spellcheckerLanguage === 'automatic') { - defaultSpellcheckerLanguage = intl.formatMessage(globalMessages.spellcheckerAutomaticDetectionShort); + defaultSpellcheckerLanguage = intl.formatMessage( + globalMessages.spellcheckerAutomaticDetectionShort, + ); } const spellcheckerLanguage = getSelectOptions({ locales: SPELLCHECKER_LOCALES, - resetToDefaultText: intl.formatMessage(globalMessages.spellcheckerSystemDefault, { default: defaultSpellcheckerLanguage }), - automaticDetectionText: stores.settings.app.spellcheckerLanguage !== 'automatic' ? intl.formatMessage(globalMessages.spellcheckerAutomaticDetection) : '', + resetToDefaultText: intl.formatMessage( + globalMessages.spellcheckerSystemDefault, + { default: defaultSpellcheckerLanguage }, + ), + automaticDetectionText: + stores.settings.app.spellcheckerLanguage !== 'automatic' + ? intl.formatMessage(globalMessages.spellcheckerAutomaticDetection) + : '', }); const config = { @@ -169,7 +171,10 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex }, isHibernationEnabled: { label: intl.formatMessage(messages.enableHibernation), - value: action !== 'edit' ? recipe.autoHibernate : service.isHibernationEnabled, + value: + action !== 'edit' + ? recipe.autoHibernate + : service.isHibernationEnabled, default: true, }, isNotificationEnabled: { @@ -200,17 +205,23 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex }, darkReaderBrightness: { label: intl.formatMessage(messages.darkReaderBrightness), - value: service.darkReaderSettings ? service.darkReaderSettings.brightness : undefined, + value: service.darkReaderSettings + ? service.darkReaderSettings.brightness + : undefined, default: 100, }, darkReaderContrast: { label: intl.formatMessage(messages.darkReaderContrast), - value: service.darkReaderSettings ? service.darkReaderSettings.contrast : undefined, + value: service.darkReaderSettings + ? service.darkReaderSettings.contrast + : undefined, default: 90, }, darkReaderSepia: { label: intl.formatMessage(messages.darkReaderSepia), - value: service.darkReaderSettings ? service.darkReaderSettings.sepia : undefined, + value: service.darkReaderSettings + ? service.darkReaderSettings.sepia + : undefined, default: 10, }, spellcheckerLanguage: { @@ -252,7 +263,10 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex // More fine grained and use case specific validation rules if (recipe.hasTeamId && recipe.hasCustomUrl) { config.fields.team.validators = [oneRequired(['team', 'customUrl'])]; - config.fields.customUrl.validators = [url, oneRequired(['team', 'customUrl'])]; + config.fields.customUrl.validators = [ + url, + oneRequired(['team', 'customUrl']), + ]; } // If a service can be hosted and has a teamId or customUrl @@ -344,9 +358,7 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex } render() { - const { - recipes, services, user, - } = this.props.stores; + const { recipes, services, user } = this.props.stores; const { action } = this.props.router.params; let recipe; @@ -358,9 +370,7 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex // TODO: render error message when recipe is `null` if (!recipe) { - return ( - - ); + return ; } } else { service = services.activeSettings; @@ -372,13 +382,11 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex } if (isLoading) { - return (
Loading...
); + return
Loading...
; } if (!recipe) { - return ( -
something went wrong
- ); + return
something went wrong
; } const form = this.prepareForm(recipe, service, proxyFeature); @@ -392,11 +400,14 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex user={user.data} form={form} status={services.actionStatus} - isSaving={services.updateServiceRequest.isExecuting || services.createServiceRequest.isExecuting} + isSaving={ + services.updateServiceRequest.isExecuting || + services.createServiceRequest.isExecuting + } isDeleting={services.deleteServiceRequest.isExecuting} - onSubmit={(d) => this.onSubmit(d)} + onSubmit={d => this.onSubmit(d)} onDelete={() => this.deleteService()} - openRecipeFile={(file) => this.openRecipeFile(file)} + openRecipeFile={file => this.openRecipeFile(file)} isProxyFeatureEnabled={proxyFeature.isEnabled} /> @@ -417,3 +428,5 @@ EditServiceScreen.wrappedComponent.propTypes = { service: PropTypes.instanceOf(ServicesStore).isRequired, }).isRequired, }; + +export default injectIntl(EditServiceScreen); diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js index 09244bc3c..8834aa1ae 100644 --- a/src/containers/settings/EditSettingsScreen.js +++ b/src/containers/settings/EditSettingsScreen.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { inject, observer } from 'mobx-react'; -import { defineMessages, intlShape } from 'react-intl'; +import { defineMessages, injectIntl } from 'react-intl'; import AppStore from '../../stores/AppStore'; import SettingsStore from '../../stores/SettingsStore'; @@ -10,8 +10,15 @@ import TodosStore from '../../features/todos/store'; import Form from '../../lib/Form'; import { APP_LOCALES, SPELLCHECKER_LOCALES } from '../../i18n/languages'; import { - HIBERNATION_STRATEGIES, SIDEBAR_WIDTH, ICON_SIZES, NAVIGATION_BAR_BEHAVIOURS, SEARCH_ENGINE_NAMES, TODO_APPS, - DEFAULT_SETTING_KEEP_ALL_WORKSPACES_LOADED, DEFAULT_IS_FEATURE_ENABLED_BY_USER, WAKE_UP_STRATEGIES, + HIBERNATION_STRATEGIES, + SIDEBAR_WIDTH, + ICON_SIZES, + NAVIGATION_BAR_BEHAVIOURS, + SEARCH_ENGINE_NAMES, + TODO_APPS, + DEFAULT_SETTING_KEEP_ALL_WORKSPACES_LOADED, + DEFAULT_IS_FEATURE_ENABLED_BY_USER, + WAKE_UP_STRATEGIES, } from '../../config'; import { DEFAULT_APP_SETTINGS, isMac } from '../../environment'; @@ -31,195 +38,193 @@ const debug = require('debug')('Ferdi:EditSettingsScreen'); const messages = defineMessages({ autoLaunchOnStart: { id: 'settings.app.form.autoLaunchOnStart', - defaultMessage: '!!!Launch Ferdi on start', + defaultMessage: 'Launch Ferdi on start', }, autoLaunchInBackground: { id: 'settings.app.form.autoLaunchInBackground', - defaultMessage: '!!!Open in background', + defaultMessage: 'Open in background', }, runInBackground: { id: 'settings.app.form.runInBackground', - defaultMessage: '!!!Keep Ferdi in background when closing the window', + defaultMessage: 'Keep Ferdi in background when closing the window', }, startMinimized: { id: 'settings.app.form.startMinimized', - defaultMessage: '!!!Start minimized', + defaultMessage: 'Start minimized', }, confirmOnQuit: { id: 'settings.app.form.confirmOnQuit', - defaultMessage: '!!!Confirm when quitting Ferdi', + defaultMessage: 'Confirm when quitting Ferdi', }, enableSystemTray: { id: 'settings.app.form.enableSystemTray', - defaultMessage: '!!!Always show Ferdi in System Tray', + defaultMessage: 'Always show Ferdi in System Tray', }, enableMenuBar: { id: 'settings.app.form.enableMenuBar', - defaultMessage: '!!!Always show Ferdi in Menu Bar', + defaultMessage: 'Always show Ferdi in Menu Bar', }, reloadAfterResume: { id: 'settings.app.form.reloadAfterResume', - defaultMessage: '!!!Reload Ferdi after system resume', + defaultMessage: 'Reload Ferdi after system resume', }, minimizeToSystemTray: { id: 'settings.app.form.minimizeToSystemTray', - defaultMessage: '!!!Minimize Ferdi to system tray', + defaultMessage: 'Minimize Ferdi to system tray', }, closeToSystemTray: { id: 'settings.app.form.closeToSystemTray', - defaultMessage: '!!!Close Ferdi to system tray', + defaultMessage: 'Close Ferdi to system tray', }, privateNotifications: { id: 'settings.app.form.privateNotifications', - defaultMessage: '!!!Don\'t show message content in notifications', + defaultMessage: "Don't show message content in notifications", }, clipboardNotifications: { id: 'settings.app.form.clipboardNotifications', - defaultMessage: '!!!Don\'t show notifications for clipboard events', + defaultMessage: "Don't show notifications for clipboard events", }, notifyTaskBarOnMessage: { id: 'settings.app.form.notifyTaskBarOnMessage', - defaultMessage: '!!!Notify TaskBar/Dock on new message', + defaultMessage: 'Notify TaskBar/Dock on new message', }, navigationBarBehaviour: { id: 'settings.app.form.navigationBarBehaviour', - defaultMessage: '!!!Navigation bar behaviour', + defaultMessage: 'Navigation bar behaviour', }, searchEngine: { id: 'settings.app.form.searchEngine', - defaultMessage: '!!!Search engine', + defaultMessage: 'Search engine', }, sentry: { id: 'settings.app.form.sentry', - defaultMessage: '!!!Send telemetry data', + defaultMessage: 'Send telemetry data', }, hibernateOnStartup: { id: 'settings.app.form.hibernateOnStartup', - defaultMessage: '!!!Keep services in hibernation on startup', + defaultMessage: 'Keep services in hibernation on startup', }, hibernationStrategy: { id: 'settings.app.form.hibernationStrategy', - defaultMessage: '!!!Hibernation strategy', + defaultMessage: 'Hibernation strategy', }, wakeUpStrategy: { id: 'settings.app.form.wakeUpStrategy', - defaultMessage: '!!!Wake up strategy', + defaultMessage: 'Wake up strategy', }, predefinedTodoServer: { id: 'settings.app.form.predefinedTodoServer', - defaultMessage: '!!!Todo Server', + defaultMessage: 'Todo Server', }, customTodoServer: { id: 'settings.app.form.customTodoServer', - defaultMessage: '!!!Custom TodoServer', + defaultMessage: 'Custom TodoServer', }, enableLock: { id: 'settings.app.form.enableLock', - defaultMessage: '!!!Enable Password Lock', + defaultMessage: 'Enable Password Lock', }, lockPassword: { id: 'settings.app.form.lockPassword', - defaultMessage: '!!!Password', + defaultMessage: 'Password', }, useTouchIdToUnlock: { id: 'settings.app.form.useTouchIdToUnlock', - defaultMessage: '!!!Allow using Touch ID to unlock', + defaultMessage: 'Allow using Touch ID to unlock', }, inactivityLock: { id: 'settings.app.form.inactivityLock', - defaultMessage: '!!!Lock after inactivity', + defaultMessage: 'Lock after inactivity', }, scheduledDNDEnabled: { id: 'settings.app.form.scheduledDNDEnabled', - defaultMessage: '!!!Enable scheduled Do-not-Disturb', + defaultMessage: 'Enable scheduled Do-not-Disturb', }, scheduledDNDStart: { id: 'settings.app.form.scheduledDNDStart', - defaultMessage: '!!!From', + defaultMessage: 'From', }, scheduledDNDEnd: { id: 'settings.app.form.scheduledDNDEnd', - defaultMessage: '!!!To', + defaultMessage: 'To', }, language: { id: 'settings.app.form.language', - defaultMessage: '!!!Language', + defaultMessage: 'Language', }, darkMode: { id: 'settings.app.form.darkMode', - defaultMessage: '!!!Dark Mode', + defaultMessage: 'Dark Mode', }, adaptableDarkMode: { id: 'settings.app.form.adaptableDarkMode', - defaultMessage: '!!!Synchronize dark mode with my OS\'s dark mode setting', + defaultMessage: "Synchronize dark mode with my OS's dark mode setting", }, universalDarkMode: { id: 'settings.app.form.universalDarkMode', - defaultMessage: '!!!Enable universal Dark Mode', + defaultMessage: 'Enable universal Dark Mode', }, serviceRibbonWidth: { id: 'settings.app.form.serviceRibbonWidth', - defaultMessage: '!!!Sidebar width', + defaultMessage: 'Sidebar width', }, iconSize: { id: 'settings.app.form.iconSize', - defaultMessage: '!!!Service icon size', + defaultMessage: 'Service icon size', }, useVerticalStyle: { id: 'settings.app.form.useVerticalStyle', - defaultMessage: '!!!Use horizontal style', + defaultMessage: 'Use horizontal style', }, alwaysShowWorkspaces: { id: 'settings.app.form.alwaysShowWorkspaces', - defaultMessage: '!!!Always show workspace drawer', + defaultMessage: 'Always show workspace drawer', }, accentColor: { id: 'settings.app.form.accentColor', - defaultMessage: '!!!Accent color', + defaultMessage: 'Accent color', }, showDisabledServices: { id: 'settings.app.form.showDisabledServices', - defaultMessage: '!!!Display disabled services tabs', + defaultMessage: 'Display disabled services tabs', }, showMessageBadgeWhenMuted: { id: 'settings.app.form.showMessagesBadgesWhenMuted', - defaultMessage: '!!!Show unread message badge when notifications are disabled', + defaultMessage: 'Show unread message badge when notifications are disabled', }, showDragArea: { id: 'settings.app.form.showDragArea', - defaultMessage: '!!!Show draggable area on window', + defaultMessage: 'Show draggable area on window', }, enableSpellchecking: { id: 'settings.app.form.enableSpellchecking', - defaultMessage: '!!!Enable spell checking', + defaultMessage: 'Enable spell checking', }, enableGPUAcceleration: { id: 'settings.app.form.enableGPUAcceleration', - defaultMessage: '!!!Enable GPU Acceleration', + defaultMessage: 'Enable GPU Acceleration', }, beta: { id: 'settings.app.form.beta', - defaultMessage: '!!!Include beta versions', + defaultMessage: 'Include beta versions', }, automaticUpdates: { id: 'settings.app.form.automaticUpdates', - defaultMessage: '!!!Enable updates', + defaultMessage: 'Enable updates', }, enableTodos: { id: 'settings.app.form.enableTodos', - defaultMessage: '!!!Enable Franz Todos', + defaultMessage: 'Enable Franz Todos', }, keepAllWorkspacesLoaded: { id: 'settings.app.form.keepAllWorkspacesLoaded', - defaultMessage: '!!!Keep all workspaces loaded', + defaultMessage: 'Keep all workspaces loaded', }, }); -export default @inject('stores', 'actions') @observer class EditSettingsScreen extends Component { - static contextTypes = { - intl: intlShape, - }; - +@inject('stores', 'actions') +@observer +class EditSettingsScreen extends Component { constructor(props) { super(props); @@ -288,7 +293,9 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e useVerticalStyle: Boolean(settingsData.useVerticalStyle), alwaysShowWorkspaces: Boolean(settingsData.alwaysShowWorkspaces), accentColor: settingsData.accentColor, - showMessageBadgeWhenMuted: Boolean(settingsData.showMessageBadgeWhenMuted), + showMessageBadgeWhenMuted: Boolean( + settingsData.showMessageBadgeWhenMuted, + ), showDragArea: Boolean(settingsData.showDragArea), enableSpellchecking: Boolean(settingsData.enableSpellchecking), spellcheckerLanguage: settingsData.spellcheckerLanguage, @@ -309,24 +316,27 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e if (workspaces.isFeatureActive) { const { keepAllWorkspacesLoaded } = workspaces.settings; - if (Boolean(keepAllWorkspacesLoaded) !== Boolean(settingsData.keepAllWorkspacesLoaded)) { + if ( + Boolean(keepAllWorkspacesLoaded) !== + Boolean(settingsData.keepAllWorkspacesLoaded) + ) { workspaceActions.toggleKeepAllWorkspacesLoadedSetting(); } } if (todos.isFeatureActive) { const { isFeatureEnabledByUser } = todos.settings; - if (Boolean(isFeatureEnabledByUser) !== Boolean(settingsData.enableTodos)) { + if ( + Boolean(isFeatureEnabledByUser) !== Boolean(settingsData.enableTodos) + ) { todosActions.toggleTodosFeatureVisibility(); } } } prepareForm() { - const { - app, settings, user, todos, workspaces, - } = this.props.stores; - const { intl } = this.context; + const { app, settings, user, todos, workspaces } = this.props.stores; + const { intl } = this.props; const { lockedPassword } = this.state; const locales = getSelectOptions({ @@ -370,7 +380,9 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e const spellcheckingLanguages = getSelectOptions({ locales: SPELLCHECKER_LOCALES, - automaticDetectionText: this.context.intl.formatMessage(globalMessages.spellcheckerAutomaticDetection), + automaticDetectionText: intl.formatMessage( + globalMessages.spellcheckerAutomaticDetection, + ), }); const config = { @@ -401,7 +413,9 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e default: DEFAULT_APP_SETTINGS.confirmOnQuit, }, enableSystemTray: { - label: intl.formatMessage(isMac ? messages.enableMenuBar : messages.enableSystemTray), + label: intl.formatMessage( + isMac ? messages.enableMenuBar : messages.enableSystemTray, + ), value: settings.all.app.enableSystemTray, default: DEFAULT_APP_SETTINGS.enableSystemTray, }, @@ -637,23 +651,15 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e } render() { - const { - app, - todos, - workspaces, - services, - } = this.props.stores; + const { app, todos, workspaces, services } = this.props.stores; const { updateStatus, updateStatusTypes, isClearingAllCache, lockingFeatureEnabled, } = app; - const { - checkForUpdates, - installUpdate, - clearAllCache, - } = this.props.actions.app; + const { checkForUpdates, installUpdate, clearAllCache } = + this.props.actions.app; const form = this.prepareForm(); return ( @@ -666,7 +672,7 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e isUpdateAvailable={updateStatus === updateStatusTypes.AVAILABLE} noUpdateAvailable={updateStatus === updateStatusTypes.NOT_AVAILABLE} updateIsReadyToInstall={updateStatus === updateStatusTypes.DOWNLOADED} - onSubmit={(d) => this.onSubmit(d)} + onSubmit={d => this.onSubmit(d)} getCacheSize={() => app.cacheSize} isClearingAllCache={isClearingAllCache} onClearAllCache={clearAllCache} @@ -675,9 +681,13 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e lockingFeatureEnabled={lockingFeatureEnabled} automaticUpdates={this.props.stores.settings.app.automaticUpdates} isDarkmodeEnabled={this.props.stores.settings.app.darkMode} - isAdaptableDarkModeEnabled={this.props.stores.settings.app.adaptableDarkMode} + isAdaptableDarkModeEnabled={ + this.props.stores.settings.app.adaptableDarkMode + } isTodosActivated={this.props.stores.todos.isFeatureEnabledByUser} - isUsingCustomTodoService={this.props.stores.todos.isUsingCustomTodoService} + isUsingCustomTodoService={ + this.props.stores.todos.isUsingCustomTodoService + } isNightlyEnabled={this.props.stores.settings.app.nightly} hasAddedTodosAsService={services.isTodosServiceAdded} isOnline={app.isOnline} @@ -704,3 +714,5 @@ EditSettingsScreen.wrappedComponent.propTypes = { workspaces: PropTypes.instanceOf(WorkspacesStore).isRequired, }).isRequired, }; + +export default injectIntl(EditSettingsScreen); diff --git a/src/containers/settings/EditUserScreen.js b/src/containers/settings/EditUserScreen.js index 820b5e4d3..92ef94c29 100644 --- a/src/containers/settings/EditUserScreen.js +++ b/src/containers/settings/EditUserScreen.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { inject, observer } from 'mobx-react'; -import { defineMessages, intlShape } from 'react-intl'; +import { defineMessages, injectIntl } from 'react-intl'; import UserStore from '../../stores/UserStore'; import Form from '../../lib/Form'; @@ -13,47 +13,45 @@ import { required, email, minLength } from '../../helpers/validation-helpers'; const messages = defineMessages({ firstname: { id: 'settings.user.form.firstname', - defaultMessage: '!!!Firstname', + defaultMessage: 'Firstname', }, lastname: { id: 'settings.user.form.lastname', - defaultMessage: '!!!Lastname', + defaultMessage: 'Lastname', }, email: { id: 'settings.user.form.email', - defaultMessage: '!!!Email', + defaultMessage: 'Email', }, accountTypeLabel: { id: 'settings.user.form.accountType.label', - defaultMessage: '!!!Account type', + defaultMessage: 'Account type', }, accountTypeIndividual: { id: 'settings.user.form.accountType.individual', - defaultMessage: '!!!Individual', + defaultMessage: 'Individual', }, accountTypeNonProfit: { id: 'settings.user.form.accountType.non-profit', - defaultMessage: '!!!Non-Profit', + defaultMessage: 'Non-Profit', }, accountTypeCompany: { id: 'settings.user.form.accountType.company', - defaultMessage: '!!!Company', + defaultMessage: 'Company', }, currentPassword: { id: 'settings.user.form.currentPassword', - defaultMessage: '!!!Current password', + defaultMessage: 'Current password', }, newPassword: { id: 'settings.user.form.newPassword', - defaultMessage: '!!!New password', + defaultMessage: 'New password', }, }); -export default @inject('stores', 'actions') @observer class EditUserScreen extends Component { - static contextTypes = { - intl: intlShape, - }; - +@inject('stores', 'actions') +@observer +class EditUserScreen extends Component { componentWillUnmount() { this.props.actions.user.resetStatus(); } @@ -67,7 +65,7 @@ export default @inject('stores', 'actions') @observer class EditUserScreen exten } prepareForm(user) { - const { intl } = this.context; + const { intl } = this.props; const config = { fields: { @@ -93,16 +91,20 @@ export default @inject('stores', 'actions') @observer class EditUserScreen exten value: user.accountType, validators: [required], label: intl.formatMessage(messages.accountTypeLabel), - options: [{ - value: 'individual', - label: intl.formatMessage(messages.accountTypeIndividual), - }, { - value: 'non-profit', - label: intl.formatMessage(messages.accountTypeNonProfit), - }, { - value: 'company', - label: intl.formatMessage(messages.accountTypeCompany), - }], + options: [ + { + value: 'individual', + label: intl.formatMessage(messages.accountTypeIndividual), + }, + { + value: 'non-profit', + label: intl.formatMessage(messages.accountTypeNonProfit), + }, + { + value: 'company', + label: intl.formatMessage(messages.accountTypeCompany), + }, + ], }, organization: { label: intl.formatMessage(messages.accountTypeCompany), @@ -129,7 +131,7 @@ export default @inject('stores', 'actions') @observer class EditUserScreen exten const { user } = this.props.stores; if (user.getUserInfoRequest.isExecuting) { - return (
Loading...
); + return
Loading...
; } const form = this.prepareForm(user.data); @@ -141,7 +143,7 @@ export default @inject('stores', 'actions') @observer class EditUserScreen exten status={user.actionStatus} form={form} isSaving={user.updateUserInfoRequest.isExecuting} - onSubmit={(d) => this.onSubmit(d)} + onSubmit={d => this.onSubmit(d)} /> ); @@ -156,3 +158,5 @@ EditUserScreen.wrappedComponent.propTypes = { user: PropTypes.instanceOf(UserStore).isRequired, }).isRequired, }; + +export default injectIntl(EditUserScreen); diff --git a/src/containers/settings/InviteScreen.js b/src/containers/settings/InviteScreen.js index 4fdaef08b..f17f6390c 100644 --- a/src/containers/settings/InviteScreen.js +++ b/src/containers/settings/InviteScreen.js @@ -6,7 +6,9 @@ import Invite from '../../components/auth/Invite'; import ErrorBoundary from '../../components/util/ErrorBoundary'; import UserStore from '../../stores/UserStore'; -export default @inject('stores', 'actions') @observer class InviteScreen extends Component { +@inject('stores', 'actions') +@observer +class InviteScreen extends Component { componentWillUnmount() { this.props.stores.user.inviteRequest.reset(); } @@ -20,7 +22,9 @@ export default @inject('stores', 'actions') @observer class InviteScreen extends diff --git a/src/containers/settings/RecipesScreen.js b/src/containers/settings/RecipesScreen.js index 784052bbe..06ddabe4c 100644 --- a/src/containers/settings/RecipesScreen.js +++ b/src/containers/settings/RecipesScreen.js @@ -18,7 +18,9 @@ import RecipePreview from '../../models/RecipePreview'; import AppStore from '../../stores/AppStore'; import { openPath } from '../../helpers/url-helpers'; -export default @inject('stores', 'actions') @observer class RecipesScreen extends Component { +@inject('stores', 'actions') +@observer +class RecipesScreen extends Component { static propTypes = { params: PropTypes.shape({ filter: PropTypes.string, @@ -75,25 +77,32 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend } _sortByName(recipe1, recipe2) { - if (recipe1.name.toLowerCase() < recipe2.name.toLowerCase()) { return -1; } - if (recipe1.name.toLowerCase() > recipe2.name.toLowerCase()) { return 1; } + if (recipe1.name.toLowerCase() < recipe2.name.toLowerCase()) { + return -1; + } + if (recipe1.name.toLowerCase() > recipe2.name.toLowerCase()) { + return 1; + } return 0; } prepareRecipes(recipes) { - return recipes - // Filter out duplicate recipes - .filter((recipe, index, self) => { - const ids = self.map((rec) => rec.id); - return ids.indexOf(recipe.id) === index; - - // Sort alphabetically - }).sort(this._sortByName); + return ( + recipes + // Filter out duplicate recipes + .filter((recipe, index, self) => { + const ids = self.map(rec => rec.id); + return ids.indexOf(recipe.id) === index; + + // Sort alphabetically + }) + .sort(this._sortByName) + ); } // Create an array of RecipePreviews from an array of recipe objects createPreviews(recipes) { - return recipes.map((recipe) => new RecipePreview(recipe)); + return recipes.map(recipe => new RecipePreview(recipe)); } resetSearch() { @@ -101,16 +110,9 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend } render() { - const { - recipePreviews, - recipes, - services, - } = this.props.stores; + const { recipePreviews, recipes, services } = this.props.stores; - const { - app: appActions, - service: serviceActions, - } = this.props.actions; + const { app: appActions, service: serviceActions } = this.props.actions; const { filter } = { filter: 'all', ...this.props.params }; let recipeFilter; @@ -125,21 +127,33 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend } recipeFilter = recipeFilter.sort(this._sortByName); - const allRecipes = this.state.needle ? this.prepareRecipes([ - // All search recipes from server - ...recipePreviews.searchResults, - // All search recipes from local recipes - ...this.createPreviews( - this.customRecipes - .filter((service) => service.name.toLowerCase().includes(this.state.needle.toLowerCase()) || (service.aliases || []).some(alias => alias.toLowerCase().includes(this.state.needle.toLowerCase()))), - ), - ]).sort(this._sortByName) : recipeFilter; - - const customWebsiteRecipe = recipePreviews.all.find((service) => service.id === CUSTOM_WEBSITE_RECIPE_ID); + const allRecipes = this.state.needle + ? this.prepareRecipes([ + // All search recipes from server + ...recipePreviews.searchResults, + // All search recipes from local recipes + ...this.createPreviews( + this.customRecipes.filter( + service => + service.name + .toLowerCase() + .includes(this.state.needle.toLowerCase()) || + (service.aliases || []).some(alias => + alias.toLowerCase().includes(this.state.needle.toLowerCase()), + ), + ), + ), + ]).sort(this._sortByName) + : recipeFilter; + + const customWebsiteRecipe = recipePreviews.all.find( + service => service.id === CUSTOM_WEBSITE_RECIPE_ID, + ); - const isLoading = recipePreviews.allRecipePreviewsRequest.isExecuting - || recipes.installRecipeRequest.isExecuting - || recipePreviews.searchRecipePreviewsRequest.isExecuting; + const isLoading = + recipePreviews.allRecipePreviewsRequest.isExecuting || + recipes.installRecipeRequest.isExecuting || + recipePreviews.searchRecipePreviewsRequest.isExecuting; const recipeDirectory = userDataRecipesPath('dev'); @@ -151,14 +165,16 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend isLoading={isLoading} addedServiceCount={services.all.length} showAddServiceInterface={serviceActions.showAddServiceInterface} - searchRecipes={(e) => this.searchRecipes(e)} + searchRecipes={e => this.searchRecipes(e)} resetSearch={() => this.resetSearch()} searchNeedle={this.state.needle} serviceStatus={services.actionStatus} recipeFilter={filter} recipeDirectory={recipeDirectory} openRecipeDirectory={() => openPath(recipeDirectory)} - openDevDocs={() => appActions.openExternalUrl({ url: FRANZ_DEV_DOCS })} + openDevDocs={() => + appActions.openExternalUrl({ url: FRANZ_DEV_DOCS }) + } /> ); @@ -180,3 +196,5 @@ RecipesScreen.wrappedComponent.propTypes = { }).isRequired, }).isRequired, }; + +export default RecipesScreen; diff --git a/src/containers/settings/ServicesScreen.js b/src/containers/settings/ServicesScreen.js index eb2b1bcb5..c9dfc68d0 100644 --- a/src/containers/settings/ServicesScreen.js +++ b/src/containers/settings/ServicesScreen.js @@ -10,7 +10,9 @@ import ServiceStore from '../../stores/ServicesStore'; import ServicesDashboard from '../../components/settings/services/ServicesDashboard'; import ErrorBoundary from '../../components/util/ErrorBoundary'; -export default @inject('stores', 'actions') @observer class ServicesScreen extends Component { +@inject('stores', 'actions') +@observer +class ServicesScreen extends Component { componentWillUnmount() { this.props.actions.service.resetFilter(); this.props.actions.service.resetStatus(); @@ -23,11 +25,7 @@ export default @inject('stores', 'actions') @observer class ServicesScreen exten render() { const { user, services, router } = this.props.stores; - const { - toggleService, - filter, - resetFilter, - } = this.props.actions.service; + const { toggleService, filter, resetFilter } = this.props.actions.service; const isLoading = services.allServicesRequest.isExecuting; let allServices = services.all; @@ -47,7 +45,10 @@ export default @inject('stores', 'actions') @observer class ServicesScreen exten filterServices={filter} resetFilter={resetFilter} goTo={router.push} - servicesRequestFailed={services.allServicesRequest.wasExecuted && services.allServicesRequest.isError} + servicesRequestFailed={ + services.allServicesRequest.wasExecuted && + services.allServicesRequest.isError + } retryServicesRequest={() => services.allServicesRequest.reload()} searchNeedle={services.filterNeedle} /> @@ -66,3 +67,5 @@ ServicesScreen.wrappedComponent.propTypes = { service: PropTypes.instanceOf(ServiceStore).isRequired, }).isRequired, }; + +export default ServicesScreen; diff --git a/src/containers/settings/SettingsWindow.js b/src/containers/settings/SettingsWindow.js index 9bb64b6fe..58e73f2f3 100644 --- a/src/containers/settings/SettingsWindow.js +++ b/src/containers/settings/SettingsWindow.js @@ -11,7 +11,9 @@ import ErrorBoundary from '../../components/util/ErrorBoundary'; import { workspaceStore } from '../../features/workspaces'; import UIStore from '../../stores/UIStore'; -export default @inject('stores', 'actions') @observer class SettingsContainer extends Component { +@inject('stores', 'actions') +@observer +class SettingsContainer extends Component { portalRoot = document.querySelector('#portalContainer'); el = document.createElement('div'); @@ -36,16 +38,11 @@ export default @inject('stores', 'actions') @observer class SettingsContainer ex ); return ReactDOM.createPortal( - ( - - - {children} - - - ), + + + {children} + + , this.el, ); } @@ -60,3 +57,5 @@ SettingsContainer.wrappedComponent.propTypes = { ui: PropTypes.instanceOf(UIStore).isRequired, }).isRequired, }; + +export default SettingsContainer; diff --git a/src/containers/settings/SupportScreen.js b/src/containers/settings/SupportScreen.js index 7d3b22f19..646f672ce 100644 --- a/src/containers/settings/SupportScreen.js +++ b/src/containers/settings/SupportScreen.js @@ -6,7 +6,8 @@ import SupportFerdi from '../../components/settings/supportFerdi/SupportFerdiDas import ErrorBoundary from '../../components/util/ErrorBoundary'; import AppStore from '../../stores/AppStore'; -export default @inject('actions') class SupportScreen extends Component { +@inject('actions') +class SupportScreen extends Component { constructor(props) { super(props); @@ -20,9 +21,7 @@ export default @inject('actions') class SupportScreen extends Component { render() { return ( - + ); } @@ -33,3 +32,5 @@ SupportScreen.wrappedComponent.propTypes = { app: PropTypes.instanceOf(AppStore).isRequired, }).isRequired, }; + +export default SupportScreen; diff --git a/src/containers/settings/TeamScreen.js b/src/containers/settings/TeamScreen.js index 10c2e36ef..ea447469b 100644 --- a/src/containers/settings/TeamScreen.js +++ b/src/containers/settings/TeamScreen.js @@ -10,7 +10,9 @@ import TeamDashboard from '../../components/settings/team/TeamDashboard'; import ErrorBoundary from '../../components/util/ErrorBoundary'; import { DEV_API_FRANZ_WEBSITE } from '../../config'; -export default @inject('stores', 'actions') @observer class TeamScreen extends Component { +@inject('stores', 'actions') +@observer +class TeamScreen extends Component { handleWebsiteLink(route) { const { actions, stores } = this.props; @@ -29,7 +31,10 @@ export default @inject('stores', 'actions') @observer class TeamScreen extends C this.reloadData()} openTeamManagement={() => this.handleWebsiteLink('/user/team')} server={server} @@ -50,3 +55,5 @@ TeamScreen.wrappedComponent.propTypes = { user: PropTypes.instanceOf(UserStore).isRequired, }).isRequired, }; + +export default TeamScreen; -- cgit v1.2.3-70-g09d2 From 318153ec7b93dfb10011f8337a9dd7c658239335 Mon Sep 17 00:00:00 2001 From: Markus Hatvan Date: Tue, 14 Sep 2021 09:00:12 +0200 Subject: fix: regression from intl upgrades (#1933) --- src/containers/auth/ChangeServerScreen.js | 2 ++ src/containers/auth/ImportScreen.js | 2 ++ src/containers/auth/LockedScreen.js | 2 ++ src/containers/auth/LoginScreen.js | 2 ++ src/containers/auth/PasswordScreen.js | 2 ++ src/containers/settings/InviteScreen.js | 2 ++ 6 files changed, 12 insertions(+) (limited to 'src/containers/settings') diff --git a/src/containers/auth/ChangeServerScreen.js b/src/containers/auth/ChangeServerScreen.js index 94fc98b61..a8910e7b1 100644 --- a/src/containers/auth/ChangeServerScreen.js +++ b/src/containers/auth/ChangeServerScreen.js @@ -43,3 +43,5 @@ ChangeServerScreen.wrappedComponent.propTypes = { router: PropTypes.instanceOf(RouterStore).isRequired, }).isRequired, }; + +export default ChangeServerScreen; diff --git a/src/containers/auth/ImportScreen.js b/src/containers/auth/ImportScreen.js index ff2854f6e..ce786bdb8 100644 --- a/src/containers/auth/ImportScreen.js +++ b/src/containers/auth/ImportScreen.js @@ -35,3 +35,5 @@ ImportScreen.wrappedComponent.propTypes = { router: PropTypes.instanceOf(RouterStore).isRequired, }).isRequired, }; + +export default ImportScreen; diff --git a/src/containers/auth/LockedScreen.js b/src/containers/auth/LockedScreen.js index 87205c4b9..a49549731 100644 --- a/src/containers/auth/LockedScreen.js +++ b/src/containers/auth/LockedScreen.js @@ -85,3 +85,5 @@ LockedScreen.wrappedComponent.propTypes = { user: PropTypes.instanceOf(UserStore).isRequired, }).isRequired, }; + +export default LockedScreen; diff --git a/src/containers/auth/LoginScreen.js b/src/containers/auth/LoginScreen.js index d24eb1d22..cab73316b 100644 --- a/src/containers/auth/LoginScreen.js +++ b/src/containers/auth/LoginScreen.js @@ -40,3 +40,5 @@ LoginScreen.wrappedComponent.propTypes = { user: PropTypes.instanceOf(UserStore).isRequired, }).isRequired, }; + +export default LoginScreen; diff --git a/src/containers/auth/PasswordScreen.js b/src/containers/auth/PasswordScreen.js index 47f6dfd01..86a746b9b 100644 --- a/src/containers/auth/PasswordScreen.js +++ b/src/containers/auth/PasswordScreen.js @@ -30,3 +30,5 @@ PasswordScreen.wrappedComponent.propTypes = { user: PropTypes.instanceOf(UserStore).isRequired, }).isRequired, }; + +export default PasswordScreen; diff --git a/src/containers/settings/InviteScreen.js b/src/containers/settings/InviteScreen.js index f17f6390c..bf393f42f 100644 --- a/src/containers/settings/InviteScreen.js +++ b/src/containers/settings/InviteScreen.js @@ -40,3 +40,5 @@ InviteScreen.wrappedComponent.propTypes = { user: PropTypes.instanceOf(UserStore).isRequired, }).isRequired, }; + +export default InviteScreen; -- cgit v1.2.3-70-g09d2 From e708f25598358a6ac835d5b15a71811b043e3f77 Mon Sep 17 00:00:00 2001 From: Vijay A Date: Tue, 14 Sep 2021 16:19:26 +0530 Subject: refactor: revert the text for some more fields. --- src/components/auth/Signup.js | 4 ++-- src/components/services/tabs/TabItem.js | 10 +++++----- src/components/settings/recipes/RecipesDashboard.js | 6 +++--- src/components/settings/services/EditServiceForm.js | 2 +- src/components/settings/supportFerdi/SupportFerdiDashboard.js | 2 +- src/containers/settings/EditServiceScreen.js | 8 ++++---- src/containers/settings/EditSettingsScreen.js | 6 +++--- src/containers/settings/EditUserScreen.js | 4 ++-- src/features/workspaces/components/WorkspaceDrawer.js | 4 ++-- src/features/workspaces/components/WorkspacesDashboard.js | 2 +- src/helpers/validation-helpers.ts | 8 ++++---- 11 files changed, 28 insertions(+), 28 deletions(-) (limited to 'src/containers/settings') diff --git a/src/components/auth/Signup.js b/src/components/auth/Signup.js index 4d39835a2..936e0202d 100644 --- a/src/components/auth/Signup.js +++ b/src/components/auth/Signup.js @@ -23,11 +23,11 @@ const messages = defineMessages({ }, firstnameLabel: { id: 'signup.firstname.label', - defaultMessage: 'Firstname', + defaultMessage: 'First Name', }, lastnameLabel: { id: 'signup.lastname.label', - defaultMessage: 'Lastname', + defaultMessage: 'Last Name', }, emailLabel: { id: 'signup.email.label', diff --git a/src/components/services/tabs/TabItem.js b/src/components/services/tabs/TabItem.js index b1a3ffbbb..84cef8c0e 100644 --- a/src/components/services/tabs/TabItem.js +++ b/src/components/services/tabs/TabItem.js @@ -48,23 +48,23 @@ const messages = defineMessages({ }, disableService: { id: 'tabs.item.disableService', - defaultMessage: 'Disable Service', + defaultMessage: 'Disable service', }, enableService: { id: 'tabs.item.enableService', - defaultMessage: 'Enable Service', + defaultMessage: 'Enable service', }, hibernateService: { id: 'tabs.item.hibernateService', - defaultMessage: 'Hibernate Service', + defaultMessage: 'Hibernate service', }, wakeUpService: { id: 'tabs.item.wakeUpService', - defaultMessage: 'Wake Up Service', + defaultMessage: 'Wake up service', }, deleteService: { id: 'tabs.item.deleteService', - defaultMessage: 'Delete Service', + defaultMessage: 'Delete service', }, confirmDeleteService: { id: 'tabs.item.confirmDeleteService', diff --git a/src/components/settings/recipes/RecipesDashboard.js b/src/components/settings/recipes/RecipesDashboard.js index e620abf93..44f5bc39a 100644 --- a/src/components/settings/recipes/RecipesDashboard.js +++ b/src/components/settings/recipes/RecipesDashboard.js @@ -18,7 +18,7 @@ import RecipePreview from '../../../models/RecipePreview'; const messages = defineMessages({ headline: { id: 'settings.recipes.headline', - defaultMessage: 'Available Services', + defaultMessage: 'Available services', }, searchService: { id: 'settings.searchService', @@ -47,11 +47,11 @@ const messages = defineMessages({ }, customRecipeIntro: { id: 'settings.recipes.customService.intro', - defaultMessage: 'To add a custom service, copy the recipe folder into:', + defaultMessage: 'To add a custom service, copy the service recipe to:', }, openFolder: { id: 'settings.recipes.customService.openFolder', - defaultMessage: 'Open directory', + defaultMessage: 'Open folder', }, openDevDocs: { id: 'settings.recipes.customService.openDevDocs', diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js index 3fbb57cbb..9a9abeab4 100644 --- a/src/components/settings/services/EditServiceForm.js +++ b/src/components/settings/services/EditServiceForm.js @@ -26,7 +26,7 @@ const messages = defineMessages({ }, deleteService: { id: 'settings.service.form.deleteButton', - defaultMessage: 'Delete Service', + defaultMessage: 'Delete service', }, openDarkmodeCss: { id: 'settings.service.form.openDarkmodeCss', diff --git a/src/components/settings/supportFerdi/SupportFerdiDashboard.js b/src/components/settings/supportFerdi/SupportFerdiDashboard.js index 64ffe8692..f24e4bd62 100644 --- a/src/components/settings/supportFerdi/SupportFerdiDashboard.js +++ b/src/components/settings/supportFerdi/SupportFerdiDashboard.js @@ -63,7 +63,7 @@ const messages = defineMessages({ }, openSurvey: { id: 'settings.supportFerdi.openSurvey', - defaultMessage: 'Open Survey', + defaultMessage: 'Open survey', }, bannerText: { id: 'settings.supportFerdi.bannerText', diff --git a/src/containers/settings/EditServiceScreen.js b/src/containers/settings/EditServiceScreen.js index 12e7b9e95..e2ed4eeac 100644 --- a/src/containers/settings/EditServiceScreen.js +++ b/src/containers/settings/EditServiceScreen.js @@ -39,7 +39,7 @@ const messages = defineMessages({ }, enableNotification: { id: 'settings.service.form.enableNotification', - defaultMessage: 'Enable Notifications', + defaultMessage: 'Enable notifications', }, enableBadge: { id: 'settings.service.form.enableBadge', @@ -55,7 +55,7 @@ const messages = defineMessages({ }, customUrl: { id: 'settings.service.form.customUrl', - defaultMessage: 'Service URL', + defaultMessage: 'Custom server', }, indirectMessages: { id: 'settings.service.form.indirectMessages', @@ -95,11 +95,11 @@ const messages = defineMessages({ }, proxyUser: { id: 'settings.service.form.proxy.user', - defaultMessage: 'User', + defaultMessage: 'User (optional)', }, proxyPassword: { id: 'settings.service.form.proxy.password', - defaultMessage: 'Password', + defaultMessage: 'Password (optional)', }, }); diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js index 8834aa1ae..3df433160 100644 --- a/src/containers/settings/EditSettingsScreen.js +++ b/src/containers/settings/EditSettingsScreen.js @@ -118,7 +118,7 @@ const messages = defineMessages({ }, customTodoServer: { id: 'settings.app.form.customTodoServer', - defaultMessage: 'Custom TodoServer', + defaultMessage: 'Custom Todo Server', }, enableLock: { id: 'settings.app.form.enableLock', @@ -130,7 +130,7 @@ const messages = defineMessages({ }, useTouchIdToUnlock: { id: 'settings.app.form.useTouchIdToUnlock', - defaultMessage: 'Allow using Touch ID to unlock', + defaultMessage: 'Allow using TouchID to unlock Ferdi', }, inactivityLock: { id: 'settings.app.form.inactivityLock', @@ -154,7 +154,7 @@ const messages = defineMessages({ }, darkMode: { id: 'settings.app.form.darkMode', - defaultMessage: 'Dark Mode', + defaultMessage: 'Enable Dark Mode', }, adaptableDarkMode: { id: 'settings.app.form.adaptableDarkMode', diff --git a/src/containers/settings/EditUserScreen.js b/src/containers/settings/EditUserScreen.js index 92ef94c29..ca1363c59 100644 --- a/src/containers/settings/EditUserScreen.js +++ b/src/containers/settings/EditUserScreen.js @@ -13,11 +13,11 @@ import { required, email, minLength } from '../../helpers/validation-helpers'; const messages = defineMessages({ firstname: { id: 'settings.user.form.firstname', - defaultMessage: 'Firstname', + defaultMessage: 'First Name', }, lastname: { id: 'settings.user.form.lastname', - defaultMessage: 'Lastname', + defaultMessage: 'Last Name', }, email: { id: 'settings.user.form.email', diff --git a/src/features/workspaces/components/WorkspaceDrawer.js b/src/features/workspaces/components/WorkspaceDrawer.js index 2f57e34a2..63eb4f75c 100644 --- a/src/features/workspaces/components/WorkspaceDrawer.js +++ b/src/features/workspaces/components/WorkspaceDrawer.js @@ -22,11 +22,11 @@ const messages = defineMessages({ }, workspacesSettingsTooltip: { id: 'workspaceDrawer.workspacesSettingsTooltip', - defaultMessage: 'Workspaces settings', + defaultMessage: 'Edit workspaces settings', }, workspaceFeatureInfo: { id: 'workspaceDrawer.workspaceFeatureInfo', - defaultMessage: 'Info about workspace feature', + defaultMessage: '

Ferdi Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.

You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.

', }, addNewWorkspaceLabel: { id: 'workspaceDrawer.addNewWorkspaceLabel', diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js index fd279f896..49552df6b 100644 --- a/src/features/workspaces/components/WorkspacesDashboard.js +++ b/src/features/workspaces/components/WorkspacesDashboard.js @@ -40,7 +40,7 @@ const messages = defineMessages({ }, workspaceFeatureInfo: { id: 'settings.workspaces.workspaceFeatureInfo', - defaultMessage: 'Info about workspace feature', + defaultMessage: 'Ferdi Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time. You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.', }, workspaceFeatureHeadline: { id: 'settings.workspaces.workspaceFeatureHeadline', diff --git a/src/helpers/validation-helpers.ts b/src/helpers/validation-helpers.ts index 80d368b2e..3a9622309 100644 --- a/src/helpers/validation-helpers.ts +++ b/src/helpers/validation-helpers.ts @@ -4,19 +4,19 @@ import isEmail from 'validator/lib/isEmail'; const messages = defineMessages({ required: { id: 'validation.required', - defaultMessage: 'Field is required', + defaultMessage: '{field} is required', }, email: { id: 'validation.email', - defaultMessage: 'Email not valid', + defaultMessage: '{field} is not valid', }, url: { id: 'validation.url', - defaultMessage: 'Not a valid URL', + defaultMessage: '{field} is not a valid URL', }, minLength: { id: 'validation.minLength', - defaultMessage: 'Too few characters', + defaultMessage: '{field} should be at least {length} characters long', }, oneRequired: { id: 'validation.oneRequired', -- cgit v1.2.3-70-g09d2 From b1243eff99bbfadab8f7deb8d714bbebae13e39a Mon Sep 17 00:00:00 2001 From: mhatvan Date: Tue, 14 Sep 2021 14:12:07 +0200 Subject: chore: add --preserve-whitespace flag for extract script and sync translations --- package.json | 2 +- src/components/settings/account/AccountDashboard.js | 2 +- src/containers/settings/EditSettingsScreen.js | 2 +- src/i18n/locales/en-US.json | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/containers/settings') diff --git a/package.json b/package.json index c85e73eb8..9add26ec6 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "test": "jest", "test:watch": "jest --watch", "lint": "eslint \"{src,scripts,packages,uidev}/**/*.{js,jsx,ts,tsx}\" --quiet --fix", - "extract": "formatjs extract 'src/**/*.{js,ts}' --out-file temp.json --flatten --id-interpolation-pattern '[sha512:contenthash:base64:6]'", + "extract": "formatjs extract 'src/**/*.{js,ts}' --out-file temp.json --flatten --id-interpolation-pattern '[sha512:contenthash:base64:6]' --preserve-whitespace", "compile": "formatjs compile 'temp.json' --out-file src/i18n/locales/en-US.json", "manage-translations": "npm run extract && npm run compile && rimraf temp.json", "prebuild": "preval-build-info-cli && gulp build", diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js index 66edc4975..544821e9a 100644 --- a/src/components/settings/account/AccountDashboard.js +++ b/src/components/settings/account/AccountDashboard.js @@ -51,7 +51,7 @@ const messages = defineMessages({ }, yourLicense: { id: 'settings.account.yourLicense', - defaultMessage: 'Your Franz License:', + defaultMessage: 'Your Ferdi License:', }, accountUnavailable: { id: 'settings.account.accountUnavailable', diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js index 3df433160..92985b68c 100644 --- a/src/containers/settings/EditSettingsScreen.js +++ b/src/containers/settings/EditSettingsScreen.js @@ -214,7 +214,7 @@ const messages = defineMessages({ }, enableTodos: { id: 'settings.app.form.enableTodos', - defaultMessage: 'Enable Franz Todos', + defaultMessage: 'Enable Ferdi Todos', }, keepAllWorkspacesLoaded: { id: 'settings.app.form.keepAllWorkspacesLoaded', diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index aae78999d..e2e0cdc83 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -253,9 +253,9 @@ "settings.app.hibernateInfo": "By default, Ferdi will keep all your services open and loaded in the background so they are ready when you want to use them. Service Hibernation will unload your services after a specified amount. This is useful to save RAM or keeping services from slowing down your computer.", "settings.app.inactivityLockInfo": "Minutes of inactivity, after which Ferdi should automatically lock. Use 0 to disable", "settings.app.languageDisclaimer": "Official translations are English & German. All other languages are community based translations.", - "settings.app.lockInfo": "Password Lock allows you to keep your messages protected. Using Password Lock, you will be prompted to enter your password everytime you start Ferdi or lock Ferdi yourself using the lock symbol in the bottom left corner or the shortcut {lockShortcut}.", + "settings.app.lockInfo": "Password Lock allows you to keep your messages protected.\nUsing Password Lock, you will be prompted to enter your password everytime you start Ferdi or lock Ferdi yourself using the lock symbol in the bottom left corner or the shortcut {lockShortcut}.", "settings.app.lockedPassword": "Password", - "settings.app.lockedPasswordInfo": "Please make sure to set a password you'll remember. If you loose this password, you will have to reinstall Ferdi.", + "settings.app.lockedPasswordInfo": "Please make sure to set a password you'll remember.\nIf you loose this password, you will have to reinstall Ferdi.", "settings.app.restartRequired": "Changes require restart", "settings.app.scheduledDNDInfo": "Scheduled Do-not-Disturb allows you to define a period of time in which you do not want to get Notifications from Ferdi.", "settings.app.scheduledDNDTimeInfo": "Times in 24-Hour-Format. End time can be before start time (e.g. start 17:00, end 09:00) to enable Do-not-Disturb overnight.", -- cgit v1.2.3-70-g09d2 From 95df3522a15631abc51a4295cae0ea401a8d4e1e Mon Sep 17 00:00:00 2001 From: Markus Hatvan Date: Tue, 14 Sep 2021 19:58:52 +0200 Subject: feat: add eslint-plugin-unicorn (#1936) --- .eslintrc | 165 ------------ .eslintrc.js | 186 +++++++++++++ package-lock.json | 86 ++++++ package.json | 4 +- packages/forms/src/button/index.tsx | 70 +++-- packages/forms/src/input/scorePassword.ts | 10 +- packages/forms/src/select/index.tsx | 7 +- packages/theme/src/themes/dark/index.ts | 2 +- scripts/build-theme-info.js | 40 +-- scripts/link-readme.js | 8 +- src/actions/lib/actions.ts | 3 + src/api/apiBase.ts | 17 +- src/api/server/ServerApi.js | 80 +++--- src/api/utils/auth.js | 15 +- src/app.js | 2 +- src/components/auth/Invite.js | 10 +- src/components/settings/SettingsLayout.js | 1 + .../settings/services/EditServiceForm.js | 4 +- .../settings/services/ServicesDashboard.js | 2 +- src/components/ui/ImageUpload.js | 4 +- src/components/ui/InfoBar.js | 3 +- src/components/ui/Infobox.js | 3 +- src/components/ui/Modal/index.js | 2 +- src/components/ui/Select.js | 2 +- src/components/ui/effects/Appear.js | 10 +- src/config.ts | 2 +- src/containers/settings/AccountScreen.js | 14 +- src/containers/settings/SettingsWindow.js | 4 +- src/electron/ipc-api/appIndicator.ts | 4 +- src/electron/ipc-api/autoUpdate.ts | 4 +- src/electron/ipc-api/cld.ts | 4 +- src/electron/ipc-api/dnd.ts | 4 +- src/electron/ipc-api/download.ts | 10 +- src/features/appearance/index.js | 26 +- src/features/communityRecipes/store.js | 8 +- src/features/quickSwitch/Component.js | 6 +- src/features/serviceProxy/index.js | 4 +- src/features/settingsWS/store.js | 20 +- src/features/todos/preload.js | 12 +- src/features/utils/FeatureStore.js | 8 +- .../webControls/containers/WebControlsScreen.js | 28 +- .../workspaces/components/EditWorkspaceForm.js | 2 +- .../workspaces/components/WorkspaceDrawerItem.js | 2 +- src/features/workspaces/models/Workspace.js | 2 +- src/features/workspaces/store.js | 8 +- src/helpers/i18n-helpers.ts | 12 +- src/helpers/password-helpers.ts | 14 +- src/helpers/recipe-helpers.ts | 14 +- src/helpers/schedule-helpers.ts | 8 +- src/helpers/url-helpers.ts | 2 +- src/helpers/userAgent-helpers.ts | 2 +- src/helpers/validation-helpers.ts | 19 +- src/i18n/apply-branding.js | 15 +- src/i18n/translations.js | 10 +- src/index.js | 6 +- .../app/Controllers/Http/RecipeController.js | 51 ++-- .../app/Controllers/Http/ServiceController.js | 16 +- .../app/Controllers/Http/UserController.js | 176 +++++++------ .../app/Middleware/ConvertEmptyStringsToNull.js | 2 +- src/internal-server/app/Models/Recipe.js | 3 +- src/internal-server/app/Models/Service.js | 3 +- src/internal-server/app/Models/Token.js | 3 +- src/internal-server/app/Models/User.js | 3 +- src/internal-server/app/Models/Workspace.js | 3 +- src/internal-server/config/shield.js | 3 +- src/internal-server/public/js/transfer.js | 20 +- src/internal-server/start/kernel.js | 10 +- src/internal-server/start/migrate.js | 24 +- src/internal-server/test.js | 2 +- src/lib/Menu.js | 38 +-- src/lib/TouchBar.js | 8 +- src/models/News.ts | 6 +- src/models/Recipe.ts | 6 +- src/models/RecipePreview.ts | 6 +- src/models/Service.js | 142 +++++++--- src/models/User.ts | 4 +- src/models/UserAgent.js | 19 +- src/prop-types.ts | 1 - src/stores/AppStore.js | 32 ++- src/stores/FeaturesStore.js | 16 +- src/stores/GlobalErrorStore.js | 10 +- src/stores/RecipesStore.js | 51 ++-- src/stores/RequestStore.js | 18 +- src/stores/ServicesStore.js | 291 +++++++++++---------- src/stores/SettingsStore.js | 60 +++-- src/stores/UserStore.js | 78 ++++-- src/stores/index.ts | 4 +- src/stores/lib/CachedRequest.js | 96 ++++--- src/stores/lib/Request.js | 2 +- src/stores/lib/Store.js | 6 +- src/webview/badge.ts | 2 +- src/webview/contextMenuBuilder.js | 248 +++++++++++------- src/webview/darkmode.ts | 6 +- src/webview/lib/RecipeWebview.js | 25 +- src/webview/lib/Userscript.js | 10 +- src/webview/recipe.js | 41 ++- src/webview/sessionHandler.ts | 17 +- src/webview/spellchecker.ts | 2 +- uidev/src/index.tsx | 2 +- 99 files changed, 1439 insertions(+), 1137 deletions(-) delete mode 100644 .eslintrc create mode 100644 .eslintrc.js (limited to 'src/containers/settings') diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 26159ed87..000000000 --- a/.eslintrc +++ /dev/null @@ -1,165 +0,0 @@ -{ - "root": true, - "parser": "@babel/eslint-parser", - "extends": "eslint-config-airbnb", - "plugins": [ - "jest" - ], - "overrides": [ - { - "files": [ - "**/*.ts", - "**/*.tsx" - ], - "env": { - "browser": true, - "es6": true, - "node": true - }, - "extends": [ - "airbnb-typescript" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaFeatures": { - "jsx": true - }, - "ecmaVersion": 2018, - "sourceType": "module", - "project": "./tsconfig.json" - }, - "plugins": [ - "@typescript-eslint" - ], - "rules": { - // eslint - "arrow-parens": 0, - "array-callback-return": 1, - "class-methods-use-this": 0, - "consistent-return": 0, - "function-paren-newline": 0, - "implicit-arrow-linebreak": 0, - "linebreak-style": 0, - "max-len": 0, - "no-confusing-arrow": 0, - "no-console": 0, - "no-param-reassign": 0, - "no-return-assign": 1, - "no-underscore-dangle": 0, - "no-use-before-define": 0, - "prefer-destructuring": 1, - "object-curly-newline": 0, - "operator-linebreak": 0, - // @typescript-eslint - "@typescript-eslint/indent": 0, - "@typescript-eslint/no-shadow": 0, - "@typescript-eslint/no-unused-expressions": 0, - // eslint-plugin-import - "import/extensions": 0, - "import/no-cycle": 1, - "import/no-extraneous-dependencies": 0, - "import/no-unresolved": 0, - "import/prefer-default-export": 0, - // eslint-plugin-react - "react/destructuring-assignment": 0, - "react/button-has-type": 0, - "react/forbid-prop-types": 0, - "react/jsx-curly-newline": 0, - "react/jsx-no-bind": 0, - "react/jsx-no-target-blank": 0, - "react/jsx-props-no-spreading": 0, - "react/no-deprecated": 1, - "react/no-array-index-key": 0, - "react/prefer-stateless-function": 0, - "react/sort-comp": 0, - "react/state-in-constructor": 0, - "react/static-property-placement": 0, - // eslint-plugin-jsx-a11y - "jsx-a11y/click-events-have-key-events": 1, - "jsx-a11y/mouse-events-have-key-events": 1, - "jsx-a11y/label-has-for": [ - 2, - { - "components": [ - "Label" - ], - "required": { - "every": [ - "id" - ] - }, - "allowChildren": false - } - ], - "jsx-a11y/no-static-element-interactions": 0, - "jsx-a11y/no-noninteractive-element-interactions": 1 - } - } - ], - "settings": { - "react": { - "pragma": "React", // Pragma to use, default to "React" - "version": "detect" // React version. "detect" automatically picks the version you have installed. - } - }, - "globals": { - "window": true, - "document": true, - "FormData": true, - "localStorage": true, - "navigator": true, - "Element": true, - "use": true, - "FileReader": true - }, - "env": { - "jest/globals": true - }, - "rules": { - // eslint - "arrow-parens": 0, - "class-methods-use-this": 0, - "consistent-return": 1, - "implicit-arrow-linebreak": 0, - "function-paren-newline": 0, - "max-len": 0, - "no-await-in-loop": 1, - "no-console": [ - 1, - { - "allow": [ - "warn", - "error" - ] - } - ], - "no-param-reassign": 1, - "no-restricted-syntax": 0, - "no-underscore-dangle": 0, - "operator-linebreak": 0, - "prefer-destructuring": 1, - "object-curly-newline": 0, - // eslint-plugin-import - "import/extensions": 1, - "import/prefer-default-export": 0, - "import/no-extraneous-dependencies": 0, // various false positives, re-enable at some point - "import/no-unresolved": 1, - // eslint-plugin-react - "react/forbid-prop-types": 1, - "react/destructuring-assignment": 0, - "react/jsx-curly-newline": 0, - "react/jsx-filename-extension": 1, - "react/jsx-one-expression-per-line": 0, - "react/jsx-no-bind": 1, - "react/jsx-props-no-spreading": 0, - "react/prefer-stateless-function": 1, - "react/prop-types": 0, - "react/static-property-placement": 0, - "react/state-in-constructor": 1, - "react/sort-comp": 0, - // eslint-plugin-jsx-a11y - "jsx-a11y/click-events-have-key-events": 1, - "jsx-a11y/no-static-element-interactions": 1, - "jsx-a11y/no-noninteractive-element-interactions": 1 - } -} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..057631708 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,186 @@ +module.exports = { + root: true, + parser: '@babel/eslint-parser', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + ecmaVersion: 2018, + sourceType: 'module', + project: './tsconfig.json', + }, + extends: ['eslint-config-airbnb', 'plugin:unicorn/recommended'], + plugins: ['jest'], + settings: { + react: { + pragma: 'React', // Pragma to use, default to "React" + version: 'detect', // React version. "detect" automatically picks the version you have installed. + }, + }, + globals: { + window: true, + document: true, + FormData: true, + localStorage: true, + navigator: true, + Element: true, + use: true, + FileReader: true, + }, + env: { + browser: true, + es6: true, + node: true, + jest: true, + }, + overrides: [ + { + files: ['**/*.ts', '**/*.tsx'], + extends: ['airbnb-typescript', 'plugin:unicorn/recommended'], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint'], + rules: { + // eslint + 'arrow-parens': 0, + 'array-callback-return': 1, + 'class-methods-use-this': 0, + 'consistent-return': 0, + 'function-paren-newline': 0, + 'implicit-arrow-linebreak': 0, + 'linebreak-style': 0, + 'max-len': 0, + 'no-confusing-arrow': 0, + 'no-console': 0, + 'no-param-reassign': 0, + 'no-restricted-syntax': 0, + 'no-return-assign': 1, + 'no-underscore-dangle': 0, + 'no-use-before-define': 0, + 'prefer-destructuring': 1, + 'object-curly-newline': 0, + 'operator-linebreak': 0, + // @typescript-eslint + '@typescript-eslint/indent': 0, + '@typescript-eslint/no-shadow': 0, + '@typescript-eslint/no-unused-expressions': 0, + // eslint-plugin-import + 'import/extensions': 0, + 'import/no-cycle': 1, + 'import/no-extraneous-dependencies': 0, + 'import/no-unresolved': 0, + 'import/prefer-default-export': 0, + // eslint-plugin-react + 'react/destructuring-assignment': 0, + 'react/button-has-type': 0, + 'react/forbid-prop-types': 0, + 'react/jsx-curly-newline': 0, + 'react/jsx-no-bind': 0, + 'react/jsx-no-target-blank': 0, + 'react/jsx-props-no-spreading': 0, + 'react/no-deprecated': 1, + 'react/no-array-index-key': 0, + 'react/prefer-stateless-function': 0, + 'react/sort-comp': 0, + 'react/state-in-constructor': 0, + 'react/static-property-placement': 0, + // eslint-plugin-jsx-a11y + 'jsx-a11y/click-events-have-key-events': 1, + 'jsx-a11y/mouse-events-have-key-events': 1, + 'jsx-a11y/label-has-for': [ + 2, + { + components: ['Label'], + required: { + every: ['id'], + }, + allowChildren: false, + }, + ], + 'jsx-a11y/no-static-element-interactions': 0, + 'jsx-a11y/no-noninteractive-element-interactions': 1, + // eslint-plugin-unicorn + 'unicorn/filename-case': 0, + 'unicorn/no-null': 0, + 'unicorn/no-useless-undefined': 0, + 'unicorn/prefer-module': 0, + 'unicorn/prevent-abbreviations': 0, + 'unicorn/prefer-node-protocol': 0, + 'unicorn/import-style': [ + 2, + { + styles: { + path: { + named: true, + }, + }, + }, + ], + 'unicorn/consistent-destructuring': 0, + }, + }, + ], + rules: { + // eslint + 'arrow-parens': 0, + 'class-methods-use-this': 0, + 'consistent-return': 1, + 'implicit-arrow-linebreak': 0, + indent: 0, + 'function-paren-newline': 0, + 'linebreak-style': 0, + 'max-len': 0, + 'no-await-in-loop': 1, + 'no-console': [ + 1, + { + allow: ['warn', 'error'], + }, + ], + 'no-param-reassign': 1, + 'no-restricted-syntax': 0, + 'no-underscore-dangle': 0, + 'operator-linebreak': 0, + 'prefer-destructuring': 1, + 'object-curly-newline': 0, + // eslint-plugin-import + 'import/extensions': 0, + 'import/prefer-default-export': 0, + 'import/no-extraneous-dependencies': 0, // various false positives, re-enable at some point + 'import/no-unresolved': 0, + // eslint-plugin-react + 'react/forbid-prop-types': 1, + 'react/destructuring-assignment': 0, + 'react/jsx-curly-newline': 0, + 'react/jsx-filename-extension': 1, + 'react/jsx-one-expression-per-line': 0, + 'react/jsx-no-bind': 1, + 'react/jsx-props-no-spreading': 0, + 'react/prefer-stateless-function': 1, + 'react/prop-types': 0, + 'react/static-property-placement': 0, + 'react/state-in-constructor': 1, + 'react/sort-comp': 0, + // eslint-plugin-jsx-a11y + 'jsx-a11y/click-events-have-key-events': 1, + 'jsx-a11y/no-static-element-interactions': 1, + 'jsx-a11y/no-noninteractive-element-interactions': 1, + // eslint-plugin-unicorn + 'unicorn/filename-case': 0, + 'unicorn/no-null': 0, + 'unicorn/no-useless-undefined': 0, + 'unicorn/prefer-module': 0, + 'unicorn/prevent-abbreviations': 0, + 'unicorn/prefer-node-protocol': 0, + 'unicorn/import-style': [ + 2, + { + styles: { + path: { + named: true, + }, + }, + }, + ], + 'unicorn/consistent-destructuring': 0, + }, +}; diff --git a/package-lock.json b/package-lock.json index a278c76f1..a3076c7d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9851,6 +9851,12 @@ "sax": "^1.2.4" } }, + "builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true + }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", @@ -10394,6 +10400,15 @@ } } }, + "clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -14424,6 +14439,43 @@ "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==", "dev": true }, + "eslint-plugin-unicorn": { + "version": "36.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-36.0.0.tgz", + "integrity": "sha512-xxN2vSctGWnDW6aLElm/LKIwcrmk6mdiEcW55Uv5krcrVcIFSWMmEgc/hwpemYfZacKZ5npFERGNz4aThsp1AA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.9", + "ci-info": "^3.2.0", + "clean-regexp": "^1.0.0", + "eslint-template-visitor": "^2.3.2", + "eslint-utils": "^3.0.0", + "is-builtin-module": "^3.1.0", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.23", + "safe-regex": "^2.1.1", + "semver": "^7.3.5" + }, + "dependencies": { + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true + }, + "safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "requires": { + "regexp-tree": "~0.1.1" + } + } + } + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -14434,6 +14486,19 @@ "estraverse": "^4.1.1" } }, + "eslint-template-visitor": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz", + "integrity": "sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==", + "dev": true, + "requires": { + "@babel/core": "^7.12.16", + "@babel/eslint-parser": "^7.12.16", + "eslint-visitor-keys": "^2.0.0", + "esquery": "^1.3.1", + "multimap": "^1.1.0" + } + }, "eslint-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", @@ -17902,6 +17967,15 @@ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, + "is-builtin-module": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", + "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "dev": true, + "requires": { + "builtin-modules": "^3.0.0" + } + }, "is-callable": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", @@ -22324,6 +22398,12 @@ "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", "dev": true }, + "multimap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz", + "integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==", + "dev": true + }, "multimatch": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", @@ -25934,6 +26014,12 @@ } } }, + "regexp-tree": { + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.23.tgz", + "integrity": "sha512-+7HWfb4Bvu8Rs2eQTUIpX9I/PlQkYOuTNbRpKLJlQpSgwSkzFYh+pUj0gtvglnOZLKB6YgnIgRuJ2/IlpL48qw==", + "dev": true + }, "regexp.prototype.flags": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", diff --git a/package.json b/package.json index 9add26ec6..d0675ba6b 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,8 @@ "dev": "cross-env NODE_ENV=development gulp dev", "test": "jest", "test:watch": "jest --watch", - "lint": "eslint \"{src,scripts,packages,uidev}/**/*.{js,jsx,ts,tsx}\" --quiet --fix", + "lint": "eslint \"{src,scripts,packages,uidev}/**/*.{js,jsx,ts,tsx}\" --quiet", + "lint:fix": "npm run lint -- --fix", "extract": "formatjs extract 'src/**/*.{js,ts}' --out-file temp.json --flatten --id-interpolation-pattern '[sha512:contenthash:base64:6]' --preserve-whitespace", "compile": "formatjs compile 'temp.json' --out-file src/i18n/locales/en-US.json", "manage-translations": "npm run extract && npm run compile && rimraf temp.json", @@ -187,6 +188,7 @@ "eslint-plugin-prettier": "3.4.0", "eslint-plugin-react": "7.25.1", "eslint-plugin-react-hooks": "4.2.0", + "eslint-plugin-unicorn": "36.0.0", "expect.js": "0.3.1", "gulp": "4.0.2", "gulp-babel": "8.0.0", diff --git a/packages/forms/src/button/index.tsx b/packages/forms/src/button/index.tsx index 48fb61635..c9ae47d55 100644 --- a/packages/forms/src/button/index.tsx +++ b/packages/forms/src/button/index.tsx @@ -227,44 +227,38 @@ class ButtonComponent extends Component { ); - let wrapperComponent: JSX.Element; - - if (!href) { - wrapperComponent = ( - - ); - } else { - wrapperComponent = ( - - {content} - - ); - } + const wrapperComponent = !href ? ( + + ) : ( + + {content} + + ); return wrapperComponent; } diff --git a/packages/forms/src/input/scorePassword.ts b/packages/forms/src/input/scorePassword.ts index bc30de4b8..59502e2b0 100644 --- a/packages/forms/src/input/scorePassword.ts +++ b/packages/forms/src/input/scorePassword.ts @@ -18,9 +18,9 @@ export function scorePasswordFunc(password: string): number { // award every unique letter until 5 repetitions const letters: ILetters = {}; - for (let i = 0; i < password.length; i += 1) { - letters[password[i]] = (letters[password[i]] || 0) + 1; - score += 5.0 / letters[password[i]]; + for (const element of password) { + letters[element] = (letters[element] || 0) + 1; + score += 5 / letters[element]; } // bonus points for mixing it up @@ -32,9 +32,9 @@ export function scorePasswordFunc(password: string): number { }; let variationCount = 0; - Object.keys(variations).forEach(key => { + for (const key of Object.keys(variations)) { variationCount += variations[key] === true ? 1 : 0; - }); + } score += (variationCount - 1) * 10; diff --git a/packages/forms/src/select/index.tsx b/packages/forms/src/select/index.tsx index d7479f63e..7806baa2a 100644 --- a/packages/forms/src/select/index.tsx +++ b/packages/forms/src/select/index.tsx @@ -187,10 +187,8 @@ class SelectComponent extends Component { componentDidUpdate() { const { open } = this.state; - if (this.searchInputRef && this.searchInputRef.current) { - if (open) { - this.searchInputRef.current.focus(); - } + if (this.searchInputRef && this.searchInputRef.current && open) { + this.searchInputRef.current.focus(); } } @@ -228,6 +226,7 @@ class SelectComponent extends Component { } componentWillUnmount() { + // eslint-disable-next-line unicorn/no-invalid-remove-event-listener window.removeEventListener('keydown', this.arrowKeysHandler.bind(this)); } diff --git a/packages/theme/src/themes/dark/index.ts b/packages/theme/src/themes/dark/index.ts index 87a68cb5d..aa132c743 100644 --- a/packages/theme/src/themes/dark/index.ts +++ b/packages/theme/src/themes/dark/index.ts @@ -9,7 +9,7 @@ export default (brandPrimary: string) => { let brandPrimaryColor = color(legacyStyles.themeBrandPrimary); try { brandPrimaryColor = color(defaultStyles.brandPrimary); - } catch (e) { + } catch { // Ignore invalid color and fall back to default. } diff --git a/scripts/build-theme-info.js b/scripts/build-theme-info.js index 4058be942..8aee96ab7 100644 --- a/scripts/build-theme-info.js +++ b/scripts/build-theme-info.js @@ -23,7 +23,7 @@ async function getRulesFromCssFile(file) { const cssSrc = (await fs.readFile(file)).toString(); const cssTree = css.parse(cssSrc); - return cssTree.stylesheet.rules; + return cssTree.stylesheet?.rules; } /** @@ -49,25 +49,30 @@ async function getRulesFromCssFile(file) { function getSelectorsDeclaringValues(rules, values) { const output = {}; - rules.forEach((rule) => { + for (const rule of rules) { if (rule.declarations) { - rule.declarations.forEach((declaration) => { - if (declaration.type === 'declaration' - && values.includes(declaration.value.toLowerCase())) { + for (const declaration of rule.declarations) { + if ( + declaration.type === 'declaration' && + values.includes(declaration.value.toLowerCase()) + ) { if (!output[declaration.property]) { output[declaration.property] = []; } - output[declaration.property] = output[declaration.property].concat(rule.selectors); + // eslint-disable-next-line unicorn/prefer-spread + output[declaration.property] = output[declaration.property].concat( + rule.selectors, + ); } - }); + } } - }); + } return output; } async function generateThemeInfo() { - if (!await fs.pathExists(cssFile)) { + if (!(await fs.pathExists(cssFile))) { console.log('Please make sure to build the project first.'); return; } @@ -75,23 +80,24 @@ async function generateThemeInfo() { // Read and parse css bundle const rules = await getRulesFromCssFile(cssFile); - console.log(`Found ${rules.length} rules`); + console.log(`Found ${rules?.length} rules`); // Get rules specifying the brand colors const brandRules = getSelectorsDeclaringValues(rules, accentColors); - console.log(`Found ${Object.keys(brandRules).join(', ')} properties that set color to brand color`); + console.log( + `Found ${Object.keys(brandRules).join( + ', ', + )} properties that set color to brand color`, + ); // Join array of declarations into a single string - Object.keys(brandRules).forEach((rule) => { + for (const rule of Object.keys(brandRules)) { brandRules[rule] = brandRules[rule].join(', '); - }); + } // Write object with theme info to file - fs.writeFile( - outputFile, - JSON.stringify(brandRules), - ); + fs.writeFile(outputFile, JSON.stringify(brandRules)); } generateThemeInfo(); diff --git a/scripts/link-readme.js b/scripts/link-readme.js index 1e47cddf8..2ab38912c 100644 --- a/scripts/link-readme.js +++ b/scripts/link-readme.js @@ -22,7 +22,7 @@ let replacements = 0; // Regex matches strings that don't begin with a "[", i.e. are not already linked // followed by a "franz#" and digits to indicate // a GitHub issue, and not ending with a "]" -readme = readme.replace(/(? { +readme = readme.replace(/(? { const issueNr = match.replace('franz#', ''); replacements += 1; return `[franz#${issueNr}](https://github.com/meetfranz/franz/issues/${issueNr})`; @@ -31,7 +31,7 @@ readme = readme.replace(/(? { // Replace external issues // Regex matches strings that don't begin with a "[", followed a repo name in the format "user/repo" // followed by a "#" and digits to indicate a GitHub issue, and not ending with a "]" -readme = readme.replace(/(? { +readme = readme.replace(/(? { const issueNr = match.replace(/\D/g, ''); const repo = match.replace(/#\d+/g, ''); replacements += 1; @@ -42,7 +42,7 @@ readme = readme.replace(/(? { // Regex matches strings that don't begin with a "[", i.e. are not already linked and // don't begin with "franz", i.e. are not Franz issues, followed by a "#" and digits to indicate // a GitHub issue, and not ending with a "]" -readme = readme.replace(/(? { +readme = readme.replace(/(? { const issueNr = match.replace('#', ''); replacements += 1; return `[#${issueNr}](https://github.com/getferdi/ferdi/issues/${issueNr})`; @@ -51,7 +51,7 @@ readme = readme.replace(/(? { // Link GitHub users // Regex matches strings that don't begin with a "[", i.e. are not already linked // followed by a "@" and at least one word character and not ending with a "]" -readme = readme.replace(/(? { +readme = readme.replace(/(? { const username = match.replace('@', ''); replacements += 1; return `[@${username}](https://github.com/${username})`; diff --git a/src/actions/lib/actions.ts b/src/actions/lib/actions.ts index ed42eabc0..412a0d895 100644 --- a/src/actions/lib/actions.ts +++ b/src/actions/lib/actions.ts @@ -1,5 +1,6 @@ export const createActionsFromDefinitions = (actionDefinitions, validate) => { const actions = {}; + // eslint-disable-next-line unicorn/no-array-for-each Object.keys(actionDefinitions).forEach(actionName => { const action = (params = {}) => { const schema = actionDefinitions[actionName]; @@ -14,6 +15,7 @@ export const createActionsFromDefinitions = (actionDefinitions, validate) => { listeners.splice(listeners.indexOf(listener), 1); }; action.notify = params => + // eslint-disable-next-line unicorn/no-array-for-each action.listeners.forEach(listener => listener(params)); }); return actions; @@ -21,6 +23,7 @@ export const createActionsFromDefinitions = (actionDefinitions, validate) => { export default (definitions, validate) => { const newActions = {}; + // eslint-disable-next-line unicorn/no-array-for-each Object.keys(definitions).forEach(scopeName => { newActions[scopeName] = createActionsFromDefinitions( definitions[scopeName], diff --git a/src/api/apiBase.ts b/src/api/apiBase.ts index dc10fad91..510ccb619 100644 --- a/src/api/apiBase.ts +++ b/src/api/apiBase.ts @@ -12,8 +12,6 @@ import { // Note: This cannot be used from the internal-server since we are not running within the context of a browser window const apiBase = (withVersion = true) => { - let url: string; - if ( !(window as any).ferdi || !(window as any).ferdi.stores.settings || @@ -23,15 +21,12 @@ const apiBase = (withVersion = true) => { // Stores have not yet been loaded - return SERVER_NOT_LOADED to force a retry when stores are loaded return SERVER_NOT_LOADED; } - if ((window as any).ferdi.stores.settings.all.app.server === LOCAL_SERVER) { - // Use URL for local server - url = `http://${LOCAL_HOSTNAME}:${ - (window as any).ferdi.stores.requests.localServerPort - }`; - } else { - // Load URL from store - url = (window as any).ferdi.stores.settings.all.app.server; - } + const url = + (window as any).ferdi.stores.settings.all.app.server === LOCAL_SERVER + ? `http://${LOCAL_HOSTNAME}:${ + (window as any).ferdi.stores.requests.localServerPort + }` + : (window as any).ferdi.stores.settings.all.app.server; return withVersion ? `${url}/${API_VERSION}` : url; }; diff --git a/src/api/server/ServerApi.js b/src/api/server/ServerApi.js index b5042525a..fb0495b19 100644 --- a/src/api/server/ServerApi.js +++ b/src/api/server/ServerApi.js @@ -1,6 +1,16 @@ +/* eslint-disable global-require */ import { join } from 'path'; import tar from 'tar'; -import { readdirSync, statSync, writeFileSync, copySync, ensureDirSync, pathExistsSync, readJsonSync, removeSync } from 'fs-extra'; +import { + readdirSync, + statSync, + writeFileSync, + copySync, + ensureDirSync, + pathExistsSync, + readJsonSync, + removeSync, +} from 'fs-extra'; import { require as remoteRequire } from '@electron/remote'; import ServiceModel from '../../models/Service'; @@ -12,7 +22,14 @@ import UserModel from '../../models/User'; import { sleep } from '../../helpers/async-helpers'; import { SERVER_NOT_LOADED } from '../../config'; -import { osArch, osPlatform, asarRecipesPath, userDataRecipesPath, userDataPath, ferdiVersion } from '../../environment'; +import { + osArch, + osPlatform, + asarRecipesPath, + userDataRecipesPath, + userDataPath, + ferdiVersion, +} from '../../environment'; import apiBase from '../apiBase'; import { prepareAuthRequest, sendAuthRequest } from '../utils/auth'; @@ -310,22 +327,22 @@ export default class ServerApi { // Recipes async getInstalledRecipes() { const recipesDirectory = getRecipeDirectory(); - const paths = readdirSync(recipesDirectory) - .filter( - file => - statSync(join(recipesDirectory, file)).isDirectory() && - file !== 'temp' && - file !== 'dev', - ); + const paths = readdirSync(recipesDirectory).filter( + file => + statSync(join(recipesDirectory, file)).isDirectory() && + file !== 'temp' && + file !== 'dev', + ); this.recipes = paths .map(id => { - // eslint-disable-next-line + // eslint-disable-next-line import/no-dynamic-require const Recipe = require(id)(RecipeModel); return new Recipe(loadRecipeConfig(id)); }) .filter(recipe => recipe.id); + // eslint-disable-next-line unicorn/prefer-spread this.recipes = this.recipes.concat(this._getDevRecipes()); debug('StubServerApi::getInstalledRecipes resolves', this.recipes); @@ -425,8 +442,8 @@ export default class ServerApi { removeSync(join(recipesDirectory, recipeId, 'recipe.tar.gz')); return id; - } catch (err) { - console.error(err); + } catch (error) { + console.error(error); return false; } @@ -434,7 +451,9 @@ export default class ServerApi { // News async getLatestNews() { - const url = `${apiBase(true)}/news?platform=${osPlatform}&arch=${osArch}&version=${ferdiVersion}`; + const url = `${apiBase( + true, + )}/news?platform=${osPlatform}&arch=${osArch}&version=${ferdiVersion}`; const request = await sendAuthRequest(url); if (!request.ok) throw request; const data = await request.json(); @@ -494,7 +513,7 @@ export default class ServerApi { debug('ServerApi::getLegacyServices resolves', services); return services; } - } catch (err) { + } catch { console.error('ServerApi::getLegacyServices no config found'); } @@ -523,8 +542,8 @@ export default class ServerApi { } return new ServiceModel(service, recipe); - } catch (e) { - debug(e); + } catch (error) { + debug(error); return null; } } @@ -559,7 +578,7 @@ export default class ServerApi { return recipe; }), - ).catch(err => console.error("Can't load recipe", err)); + ).catch(error => console.error("Can't load recipe", error)); } _mapRecipePreviewModel(recipes) { @@ -567,8 +586,8 @@ export default class ServerApi { .map(recipe => { try { return new RecipePreviewModel(recipe); - } catch (e) { - console.error(e); + } catch (error) { + console.error(error); return null; } }) @@ -580,8 +599,8 @@ export default class ServerApi { .map(newsItem => { try { return new NewsModel(newsItem); - } catch (e) { - console.error(e); + } catch (error) { + console.error(error); return null; } }) @@ -591,22 +610,21 @@ export default class ServerApi { _getDevRecipes() { const recipesDirectory = getDevRecipeDirectory(); try { - const paths = readdirSync(recipesDirectory) - .filter( - file => - statSync(join(recipesDirectory, file)).isDirectory() && - file !== 'temp', - ); + const paths = readdirSync(recipesDirectory).filter( + file => + statSync(join(recipesDirectory, file)).isDirectory() && + file !== 'temp', + ); const recipes = paths .map(id => { let Recipe; try { - // eslint-disable-next-line + // eslint-disable-next-line import/no-dynamic-require Recipe = require(id)(RecipeModel); return new Recipe(loadRecipeConfig(id)); - } catch (err) { - console.error(err); + } catch (error) { + console.error(error); } return false; @@ -624,7 +642,7 @@ export default class ServerApi { }); return recipes; - } catch (err) { + } catch { debug('Could not load dev recipes'); return false; } diff --git a/src/api/utils/auth.js b/src/api/utils/auth.js index e493b2962..527c68840 100644 --- a/src/api/utils/auth.js +++ b/src/api/utils/auth.js @@ -1,7 +1,11 @@ import localStorage from 'mobx-localstorage'; import { ferdiLocale, ferdiVersion } from '../../environment'; -export const prepareAuthRequest = (options = { method: 'GET' }, auth = true) => { +export const prepareAuthRequest = ( + // eslint-disable-next-line unicorn/no-object-as-default-parameter + options = { method: 'GET' }, + auth = true, +) => { const request = Object.assign(options, { mode: 'cors', headers: { @@ -16,12 +20,13 @@ export const prepareAuthRequest = (options = { method: 'GET' }, auth = true) => }); if (auth) { - request.headers.Authorization = `Bearer ${localStorage.getItem('authToken')}`; + request.headers.Authorization = `Bearer ${localStorage.getItem( + 'authToken', + )}`; } return request; }; -export const sendAuthRequest = (url, options, auth) => ( - window.fetch(url, prepareAuthRequest(options, auth)) -); +export const sendAuthRequest = (url, options, auth) => + window.fetch(url, prepareAuthRequest(options, auth)); diff --git a/src/app.js b/src/app.js index e0d2dbc5a..8a1f99320 100644 --- a/src/app.js +++ b/src/app.js @@ -44,7 +44,7 @@ window.addEventListener('load', () => { ); - render(preparedApp, document.getElementById('root')); + render(preparedApp, document.querySelector('#root')); }, }; window.ferdi.render(); diff --git a/src/components/auth/Invite.js b/src/components/auth/Invite.js index 519691ede..df8980314 100644 --- a/src/components/auth/Invite.js +++ b/src/components/auth/Invite.js @@ -65,7 +65,7 @@ class Invite extends Component { { fields: { invite: [ - ...Array(3).fill({ + ...Array.from({ length: 3 }).fill({ fields: { name: { label: this.props.intl.formatMessage(messages.nameLabel), @@ -95,19 +95,19 @@ class Invite extends Component { this.props.intl, ); - document.querySelector('input:first-child').focus(); + document.querySelector('input:first-child')?.focus(); } submit(e) { e.preventDefault(); - this.form.submit({ + this.form?.submit({ onSuccess: form => { this.props.onSubmit({ invites: form.values().invite }); - this.form.clear(); + this.form?.clear(); // this.form.$('invite.0.name').focus(); // path accepted but does not focus ;( - document.querySelector('input:first-child').focus(); + document.querySelector('input:first-child')?.focus(); this.setState({ showSuccessInfo: true }); }, onError: () => {}, diff --git a/src/components/settings/SettingsLayout.js b/src/components/settings/SettingsLayout.js index 0574b3765..71250bd4d 100644 --- a/src/components/settings/SettingsLayout.js +++ b/src/components/settings/SettingsLayout.js @@ -29,6 +29,7 @@ class SettingsLayout extends Component { componentWillUnmount() { document.removeEventListener( 'keydown', + // eslint-disable-next-line unicorn/no-invalid-remove-event-listener this.handleKeyDown.bind(this), false, ); diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js index 9a9abeab4..7df6d5c78 100644 --- a/src/components/settings/services/EditServiceForm.js +++ b/src/components/settings/services/EditServiceForm.js @@ -183,8 +183,8 @@ class EditServiceForm extends Component { removeTrailingSlash: false, }); isValid = await recipe.validateUrl(values.customUrl); - } catch (err) { - console.warn('ValidateURL', err); + } catch (error) { + console.warn('ValidateURL', error); isValid = false; } } diff --git a/src/components/settings/services/ServicesDashboard.js b/src/components/settings/services/ServicesDashboard.js index 847f2ea06..9272b05c9 100644 --- a/src/components/settings/services/ServicesDashboard.js +++ b/src/components/settings/services/ServicesDashboard.js @@ -91,7 +91,7 @@ class ServicesDashboard extends Component {

{intl.formatMessage(messages.headline)}

- {(services.length !== 0 || searchNeedle) && !isLoading && ( + {(services.length > 0 || searchNeedle) && !isLoading && ( filterServices({ needle })} diff --git a/src/components/ui/ImageUpload.js b/src/components/ui/ImageUpload.js index 8ea31ca40..49aff389b 100644 --- a/src/components/ui/ImageUpload.js +++ b/src/components/ui/ImageUpload.js @@ -30,14 +30,14 @@ class ImageUpload extends Component { onDrop(acceptedFiles) { const { field } = this.props; - acceptedFiles.forEach(file => { + for (const file of acceptedFiles) { const imgPath = isWindows ? file.path.replace(/\\/g, '/') : file.path; this.setState({ path: imgPath, }); this.props.field.onDrop(file); - }); + } field.set(''); } diff --git a/src/components/ui/InfoBar.js b/src/components/ui/InfoBar.js index f5cbad48b..dc6be10da 100644 --- a/src/components/ui/InfoBar.js +++ b/src/components/ui/InfoBar.js @@ -5,7 +5,6 @@ import classnames from 'classnames'; import Loader from 'react-loader'; import { defineMessages, injectIntl } from 'react-intl'; -// import { oneOrManyChildElements } from '../../prop-types'; import Appear from './effects/Appear'; const messages = defineMessages({ @@ -18,7 +17,7 @@ const messages = defineMessages({ @observer class InfoBar extends Component { static propTypes = { - // eslint-disable-next-line + // eslint-disable-next-line react/forbid-prop-types children: PropTypes.any.isRequired, onClick: PropTypes.func, type: PropTypes.string, diff --git a/src/components/ui/Infobox.js b/src/components/ui/Infobox.js index 13ae2303b..9e34bf110 100644 --- a/src/components/ui/Infobox.js +++ b/src/components/ui/Infobox.js @@ -15,7 +15,8 @@ const messages = defineMessages({ @observer class Infobox extends Component { static propTypes = { - children: PropTypes.any.isRequired, // eslint-disable-line + // eslint-disable-next-line react/forbid-prop-types + children: PropTypes.any.isRequired, icon: PropTypes.string, type: PropTypes.string, ctaOnClick: PropTypes.func, diff --git a/src/components/ui/Modal/index.js b/src/components/ui/Modal/index.js index 9e6830b0c..3c7c66c59 100644 --- a/src/components/ui/Modal/index.js +++ b/src/components/ui/Modal/index.js @@ -54,7 +54,7 @@ class Modal extends Component { portal={portal} onRequestClose={close} shouldCloseOnOverlayClick={shouldCloseOnOverlayClick} - appElement={document.getElementById('root')} + appElement={document.querySelector('#root')} > {showClose && close && (