diff --git a/frontend/src/Series/Index/Select/Edit/EditSeriesModalContent.tsx b/frontend/src/Series/Index/Select/Edit/EditSeriesModalContent.tsx index 5eb8bcbf6..1f321b517 100644 --- a/frontend/src/Series/Index/Select/Edit/EditSeriesModalContent.tsx +++ b/frontend/src/Series/Index/Select/Edit/EditSeriesModalContent.tsx @@ -235,7 +235,7 @@ function EditSeriesModalContent(props: EditSeriesModalContentProps) { {translate('Cancel')} - {translate('Apply Changes')} + {translate('ApplyChanges')} diff --git a/frontend/src/Settings/DownloadClients/DownloadClientSettings.js b/frontend/src/Settings/DownloadClients/DownloadClientSettings.js index de955a326..aca9111b3 100644 --- a/frontend/src/Settings/DownloadClients/DownloadClientSettings.js +++ b/frontend/src/Settings/DownloadClients/DownloadClientSettings.js @@ -6,6 +6,7 @@ import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator'; import { icons } from 'Helpers/Props'; import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector'; +import translate from 'Utilities/String/translate'; import DownloadClientsConnector from './DownloadClients/DownloadClientsConnector'; import ManageDownloadClientsModal from './DownloadClients/Manage/ManageDownloadClientsModal'; import DownloadClientOptionsConnector from './Options/DownloadClientOptionsConnector'; @@ -85,7 +86,7 @@ class DownloadClientSettings extends Component { /> diff --git a/frontend/src/Settings/DownloadClients/DownloadClients/Manage/Edit/ManageDownloadClientsEditModalContent.tsx b/frontend/src/Settings/DownloadClients/DownloadClients/Manage/Edit/ManageDownloadClientsEditModalContent.tsx index 0ba86e862..458ee321e 100644 --- a/frontend/src/Settings/DownloadClients/DownloadClients/Manage/Edit/ManageDownloadClientsEditModalContent.tsx +++ b/frontend/src/Settings/DownloadClients/DownloadClients/Manage/Edit/ManageDownloadClientsEditModalContent.tsx @@ -27,9 +27,9 @@ interface ManageDownloadClientsEditModalContentProps { const NO_CHANGE = 'noChange'; const enableOptions = [ - { key: NO_CHANGE, value: 'No Change', disabled: true }, - { key: 'enabled', value: 'Enabled' }, - { key: 'disabled', value: 'Disabled' }, + { key: NO_CHANGE, value: translate('NoChange'), disabled: true }, + { key: 'enabled', value: translate('Enabled') }, + { key: 'disabled', value: translate('Disabled') }, ]; function ManageDownloadClientsEditModalContent( @@ -97,7 +97,9 @@ function ManageDownloadClientsEditModalContent( setRemoveFailedDownloads(value); break; default: - console.warn('EditDownloadClientsModalContent Unknown Input'); + console.warn( + `EditDownloadClientsModalContent Unknown Input: '${name}'` + ); } }, [] @@ -162,7 +164,7 @@ function ManageDownloadClientsEditModalContent( - {translate('{count} download clients selected', { + {translate('CountDownloadClientsSelected', { count: selectedCount, })} @@ -170,7 +172,7 @@ function ManageDownloadClientsEditModalContent( {translate('Cancel')} - {translate('Apply Changes')} + {translate('ApplyChanges')} diff --git a/frontend/src/Settings/DownloadClients/DownloadClients/Manage/ManageDownloadClientsModalContent.tsx b/frontend/src/Settings/DownloadClients/DownloadClients/Manage/ManageDownloadClientsModalContent.tsx index 1232803cc..5d9f434c0 100644 --- a/frontend/src/Settings/DownloadClients/DownloadClients/Manage/ManageDownloadClientsModalContent.tsx +++ b/frontend/src/Settings/DownloadClients/DownloadClients/Manage/ManageDownloadClientsModalContent.tsx @@ -1,6 +1,7 @@ import React, { useCallback, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { DownloadClientAppState } from 'App/State/SettingsAppState'; +import Alert from 'Components/Alert'; import Button from 'Components/Link/Button'; import SpinnerButton from 'Components/Link/SpinnerButton'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; @@ -20,6 +21,7 @@ import { import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector'; import { SelectStateInputProps } from 'typings/props'; import getErrorMessage from 'Utilities/Object/getErrorMessage'; +import translate from 'Utilities/String/translate'; import getSelectedIds from 'Utilities/Table/getSelectedIds'; import ManageDownloadClientsEditModal from './Edit/ManageDownloadClientsEditModal'; import ManageDownloadClientsModalRow from './ManageDownloadClientsModalRow'; @@ -34,37 +36,37 @@ type OnSelectedChangeCallback = React.ComponentProps< const COLUMNS = [ { name: 'name', - label: 'Name', + label: translate('Name'), isSortable: true, isVisible: true, }, { name: 'implementation', - label: 'Implementation', + label: translate('Implementation'), isSortable: true, isVisible: true, }, { name: 'enable', - label: 'Enabled', + label: translate('Enabled'), isSortable: true, isVisible: true, }, { name: 'priority', - label: 'Priority', + label: translate('Priority'), isSortable: true, isVisible: true, }, { name: 'removeCompletedDownloads', - label: 'Remove Completed', + label: translate('RemoveCompleted'), isSortable: true, isVisible: true, }, { name: 'removeFailedDownloads', - label: 'Remove Failed', + label: translate('RemoveFailed'), isSortable: true, isVisible: true, }, @@ -191,17 +193,24 @@ function ManageDownloadClientsModalContent( [items, setSelectState] ); - const errorMessage = getErrorMessage(error, 'Unable to load import lists.'); + const errorMessage = getErrorMessage( + error, + 'Unable to load download clients.' + ); const anySelected = selectedCount > 0; return ( - Manage Import Lists + {translate('ManageDownloadClients')} {isFetching ? : null} {error ? {errorMessage} : null} + {isPopulated && !error && !items.length && ( + {translate('NoDownloadClientsFound')} + )} + {isPopulated && !!items.length && !isFetching && !isFetching ? ( - Delete + {translate('Delete')} - Edit + {translate('Edit')} - Close + {translate('Close')} diff --git a/frontend/src/Settings/DownloadClients/DownloadClients/Manage/ManageDownloadClientsModalRow.tsx b/frontend/src/Settings/DownloadClients/DownloadClients/Manage/ManageDownloadClientsModalRow.tsx index e41b7ba24..5e1a62cb5 100644 --- a/frontend/src/Settings/DownloadClients/DownloadClients/Manage/ManageDownloadClientsModalRow.tsx +++ b/frontend/src/Settings/DownloadClients/DownloadClients/Manage/ManageDownloadClientsModalRow.tsx @@ -1,10 +1,13 @@ import React, { useCallback } from 'react'; +import Label from 'Components/Label'; import TableRowCell from 'Components/Table/Cells/TableRowCell'; import TableSelectCell from 'Components/Table/Cells/TableSelectCell'; import Column from 'Components/Table/Column'; import TableRow from 'Components/Table/TableRow'; import TagListConnector from 'Components/TagListConnector'; +import { kinds } from 'Helpers/Props'; import { SelectStateInputProps } from 'typings/props'; +import translate from 'Utilities/String/translate'; import styles from './ManageDownloadClientsModalRow.css'; interface ManageDownloadClientsModalRowProps { @@ -61,17 +64,19 @@ function ManageDownloadClientsModalRow( - {enable ? 'Yes' : 'No'} + + {enable ? translate('Yes') : translate('No')} + {priority} - {removeCompletedDownloads ? 'Yes' : 'No'} + {removeCompletedDownloads ? translate('Yes') : translate('No')} - {removeFailedDownloads ? 'Yes' : 'No'} + {removeFailedDownloads ? translate('Yes') : translate('No')} diff --git a/frontend/src/Settings/DownloadClients/DownloadClients/Manage/Tags/TagsModalContent.tsx b/frontend/src/Settings/DownloadClients/DownloadClients/Manage/Tags/TagsModalContent.tsx index e8885596f..23b52d50f 100644 --- a/frontend/src/Settings/DownloadClients/DownloadClients/Manage/Tags/TagsModalContent.tsx +++ b/frontend/src/Settings/DownloadClients/DownloadClients/Manage/Tags/TagsModalContent.tsx @@ -17,6 +17,7 @@ import ModalHeader from 'Components/Modal/ModalHeader'; import { inputTypes, kinds, sizes } from 'Helpers/Props'; import createTagsSelector from 'Store/Selectors/createTagsSelector'; import DownloadClient from 'typings/DownloadClient'; +import translate from 'Utilities/String/translate'; import styles from './TagsModalContent.css'; interface TagsModalContentProps { @@ -36,7 +37,7 @@ function TagsModalContent(props: TagsModalContentProps) { const [tags, setTags] = useState([]); const [applyTags, setApplyTags] = useState('add'); - const seriesTags = useMemo(() => { + const downloadClientsTags = useMemo(() => { const tags = ids.reduce((acc: number[], id) => { const s = allDownloadClients.items.find( (s: DownloadClient) => s.id === id @@ -71,19 +72,19 @@ function TagsModalContent(props: TagsModalContentProps) { }, [tags, applyTags, onApplyTagsPress]); const applyTagsOptions = [ - { key: 'add', value: 'Add' }, - { key: 'remove', value: 'Remove' }, - { key: 'replace', value: 'Replace' }, + { key: 'add', value: translate('Add') }, + { key: 'remove', value: translate('Remove') }, + { key: 'replace', value: translate('Replace') }, ]; return ( - Tags + {translate('Tags')} - Tags + {translate('Tags')} - Apply Tags + {translate('ApplyTags')} - Result + {translate('Result')} - {seriesTags.map((id) => { + {downloadClientsTags.map((id) => { const tag = tagList.find((t) => t.id === id); if (!tag) { @@ -129,7 +130,11 @@ function TagsModalContent(props: TagsModalContentProps) { return ( @@ -146,14 +151,14 @@ function TagsModalContent(props: TagsModalContentProps) { return null; } - if (seriesTags.indexOf(id) > -1) { + if (downloadClientsTags.indexOf(id) > -1) { return null; } return ( @@ -167,10 +172,10 @@ function TagsModalContent(props: TagsModalContentProps) { - Cancel + {translate('Cancel')} - Apply + {translate('Apply')} diff --git a/frontend/src/Settings/ImportLists/ImportListSettings.js b/frontend/src/Settings/ImportLists/ImportListSettings.js index 98a86bcea..16fead466 100644 --- a/frontend/src/Settings/ImportLists/ImportListSettings.js +++ b/frontend/src/Settings/ImportLists/ImportListSettings.js @@ -6,6 +6,7 @@ import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator'; import { icons } from 'Helpers/Props'; import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector'; +import translate from 'Utilities/String/translate'; import ImportListsExclusionsConnector from './ImportListExclusions/ImportListExclusionsConnector'; import ImportListsConnector from './ImportLists/ImportListsConnector'; import ManageImportListsModal from './ImportLists/Manage/ManageImportListsModal'; @@ -81,7 +82,7 @@ class ImportListSettings extends Component { /> diff --git a/frontend/src/Settings/ImportLists/ImportLists/Manage/Edit/ManageImportListsEditModalContent.tsx b/frontend/src/Settings/ImportLists/ImportLists/Manage/Edit/ManageImportListsEditModalContent.tsx index 937b15eb8..e5b28adf3 100644 --- a/frontend/src/Settings/ImportLists/ImportLists/Manage/Edit/ManageImportListsEditModalContent.tsx +++ b/frontend/src/Settings/ImportLists/ImportLists/Manage/Edit/ManageImportListsEditModalContent.tsx @@ -26,9 +26,9 @@ interface ManageImportListsEditModalContentProps { const NO_CHANGE = 'noChange'; const autoAddOptions = [ - { key: NO_CHANGE, value: 'No Change', disabled: true }, - { key: 'enabled', value: 'Enabled' }, - { key: 'disabled', value: 'Disabled' }, + { key: NO_CHANGE, value: translate('NoChange'), disabled: true }, + { key: 'enabled', value: translate('Enabled') }, + { key: 'disabled', value: translate('Disabled') }, ]; function ManageImportListsEditModalContent( @@ -87,7 +87,7 @@ function ManageImportListsEditModalContent( setRootFolderPath(value); break; default: - console.warn('EditImportListModalContent Unknown Input'); + console.warn(`EditImportListModalContent Unknown Input: '${name}'`); } }, [] @@ -142,7 +142,9 @@ function ManageImportListsEditModalContent( - {translate('{count} import lists selected', { count: selectedCount })} + {translate('CountImportListsSelected', { + count: selectedCount, + })} diff --git a/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalContent.tsx b/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalContent.tsx index 51b799bdf..fdcc20f8b 100644 --- a/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalContent.tsx +++ b/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalContent.tsx @@ -1,6 +1,7 @@ import React, { useCallback, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { ImportListAppState } from 'App/State/SettingsAppState'; +import Alert from 'Components/Alert'; import Button from 'Components/Link/Button'; import SpinnerButton from 'Components/Link/SpinnerButton'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; @@ -20,6 +21,7 @@ import { import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector'; import { SelectStateInputProps } from 'typings/props'; import getErrorMessage from 'Utilities/Object/getErrorMessage'; +import translate from 'Utilities/String/translate'; import getSelectedIds from 'Utilities/Table/getSelectedIds'; import ManageImportListsEditModal from './Edit/ManageImportListsEditModal'; import ManageImportListsModalRow from './ManageImportListsModalRow'; @@ -34,37 +36,37 @@ type OnSelectedChangeCallback = React.ComponentProps< const COLUMNS = [ { name: 'name', - label: 'Name', + label: translate('Name'), isSortable: true, isVisible: true, }, { name: 'implementation', - label: 'Implementation', + label: translate('Implementation'), isSortable: true, isVisible: true, }, { name: 'qualityProfileId', - label: 'Quality Profile', + label: translate('QualityProfile'), isSortable: true, isVisible: true, }, { name: 'rootFolderPath', - label: 'Root Folder', + label: translate('RootFolder'), isSortable: true, isVisible: true, }, { name: 'enableAutomaticAdd', - label: 'Auto Add', + label: translate('AutoAdd'), isSortable: true, isVisible: true, }, { name: 'tags', - label: 'Tags', + label: translate('Tags'), isSortable: true, isVisible: true, }, @@ -190,12 +192,16 @@ function ManageImportListsModalContent( return ( - Manage Import Lists + {translate('ManageImportLists')} {isFetching ? : null} {error ? {errorMessage} : null} + {isPopulated && !error && !items.length && ( + {translate('NoImportListsFound')} + )} + {isPopulated && !!items.length && !isFetching && !isFetching ? ( - Delete + {translate('Delete')} - Edit + {translate('Edit')} - Set Tags + {translate('SetTags')} - Close + {translate('Close')} diff --git a/frontend/src/Settings/ImportLists/ImportLists/Manage/Tags/TagsModalContent.tsx b/frontend/src/Settings/ImportLists/ImportLists/Manage/Tags/TagsModalContent.tsx index ad9ae4652..a39d0ca86 100644 --- a/frontend/src/Settings/ImportLists/ImportLists/Manage/Tags/TagsModalContent.tsx +++ b/frontend/src/Settings/ImportLists/ImportLists/Manage/Tags/TagsModalContent.tsx @@ -17,6 +17,7 @@ import ModalHeader from 'Components/Modal/ModalHeader'; import { inputTypes, kinds, sizes } from 'Helpers/Props'; import createTagsSelector from 'Store/Selectors/createTagsSelector'; import ImportList from 'typings/ImportList'; +import translate from 'Utilities/String/translate'; import styles from './TagsModalContent.css'; interface TagsModalContentProps { @@ -36,7 +37,7 @@ function TagsModalContent(props: TagsModalContentProps) { const [tags, setTags] = useState([]); const [applyTags, setApplyTags] = useState('add'); - const seriesTags = useMemo(() => { + const importListsTags = useMemo(() => { const tags = ids.reduce((acc: number[], id) => { const s = allImportLists.items.find((s: ImportList) => s.id === id); @@ -69,19 +70,19 @@ function TagsModalContent(props: TagsModalContentProps) { }, [tags, applyTags, onApplyTagsPress]); const applyTagsOptions = [ - { key: 'add', value: 'Add' }, - { key: 'remove', value: 'Remove' }, - { key: 'replace', value: 'Replace' }, + { key: 'add', value: translate('Add') }, + { key: 'remove', value: translate('Remove') }, + { key: 'replace', value: translate('Replace') }, ]; return ( - Tags + {translate('Tags')} - Tags + {translate('Tags')} - Apply Tags + {translate('ApplyTags')} - Result + {translate('Result')} - {seriesTags.map((id) => { + {importListsTags.map((id) => { const tag = tagList.find((t) => t.id === id); if (!tag) { @@ -127,7 +128,11 @@ function TagsModalContent(props: TagsModalContentProps) { return ( @@ -144,14 +149,14 @@ function TagsModalContent(props: TagsModalContentProps) { return null; } - if (seriesTags.indexOf(id) > -1) { + if (importListsTags.indexOf(id) > -1) { return null; } return ( @@ -165,10 +170,10 @@ function TagsModalContent(props: TagsModalContentProps) { - Cancel + {translate('Cancel')} - Apply + {translate('Apply')} diff --git a/frontend/src/Settings/Indexers/IndexerSettings.js b/frontend/src/Settings/Indexers/IndexerSettings.js index 7ab09b36b..e9675a993 100644 --- a/frontend/src/Settings/Indexers/IndexerSettings.js +++ b/frontend/src/Settings/Indexers/IndexerSettings.js @@ -6,6 +6,7 @@ import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator'; import { icons } from 'Helpers/Props'; import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector'; +import translate from 'Utilities/String/translate'; import IndexersConnector from './Indexers/IndexersConnector'; import ManageIndexersModal from './Indexers/Manage/ManageIndexersModal'; import IndexerOptionsConnector from './Options/IndexerOptionsConnector'; @@ -84,7 +85,7 @@ class IndexerSettings extends Component { /> diff --git a/frontend/src/Settings/Indexers/Indexers/Manage/Edit/ManageIndexersEditModalContent.tsx b/frontend/src/Settings/Indexers/Indexers/Manage/Edit/ManageIndexersEditModalContent.tsx index 984f3a150..c06207fbb 100644 --- a/frontend/src/Settings/Indexers/Indexers/Manage/Edit/ManageIndexersEditModalContent.tsx +++ b/frontend/src/Settings/Indexers/Indexers/Manage/Edit/ManageIndexersEditModalContent.tsx @@ -27,9 +27,9 @@ interface ManageIndexersEditModalContentProps { const NO_CHANGE = 'noChange'; const enableOptions = [ - { key: NO_CHANGE, value: 'No Change', disabled: true }, - { key: 'enabled', value: 'Enabled' }, - { key: 'disabled', value: 'Disabled' }, + { key: NO_CHANGE, value: translate('NoChange'), disabled: true }, + { key: 'enabled', value: translate('Enabled') }, + { key: 'disabled', value: translate('Disabled') }, ]; function ManageIndexersEditModalContent( @@ -97,7 +97,7 @@ function ManageIndexersEditModalContent( setPriority(value); break; default: - console.warn('EditIndexersModalContent Unknown Input'); + console.warn(`EditIndexersModalContent Unknown Input: '${name}'`); } }, [] @@ -111,7 +111,7 @@ function ManageIndexersEditModalContent( - {translate('EnableRss')} + {translate('EnableRSS')} - {translate('{count} indexers selected', { count: selectedCount })} + {translate('CountIndexersSelected', { + count: selectedCount, + })} {translate('Cancel')} - {translate('Apply Changes')} + {translate('ApplyChanges')} diff --git a/frontend/src/Settings/Indexers/Indexers/Manage/ManageIndexersModalContent.tsx b/frontend/src/Settings/Indexers/Indexers/Manage/ManageIndexersModalContent.tsx index e721a8193..20418c682 100644 --- a/frontend/src/Settings/Indexers/Indexers/Manage/ManageIndexersModalContent.tsx +++ b/frontend/src/Settings/Indexers/Indexers/Manage/ManageIndexersModalContent.tsx @@ -1,6 +1,7 @@ import React, { useCallback, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { IndexerAppState } from 'App/State/SettingsAppState'; +import Alert from 'Components/Alert'; import Button from 'Components/Link/Button'; import SpinnerButton from 'Components/Link/SpinnerButton'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; @@ -20,6 +21,7 @@ import { import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector'; import { SelectStateInputProps } from 'typings/props'; import getErrorMessage from 'Utilities/Object/getErrorMessage'; +import translate from 'Utilities/String/translate'; import getSelectedIds from 'Utilities/Table/getSelectedIds'; import ManageIndexersEditModal from './Edit/ManageIndexersEditModal'; import ManageIndexersModalRow from './ManageIndexersModalRow'; @@ -34,43 +36,43 @@ type OnSelectedChangeCallback = React.ComponentProps< const COLUMNS = [ { name: 'name', - label: 'Name', + label: translate('Name'), isSortable: true, isVisible: true, }, { name: 'implementation', - label: 'Implementation', + label: translate('Implementation'), isSortable: true, isVisible: true, }, { name: 'enableRss', - label: 'Enable RSS', + label: translate('EnableRSS'), isSortable: true, isVisible: true, }, { name: 'enableAutomaticSearch', - label: 'Enable Automatic Search', + label: translate('EnableAutomaticSearch'), isSortable: true, isVisible: true, }, { name: 'enableInteractiveSearch', - label: 'Enable Interactive Search', + label: translate('EnableInteractiveSearch'), isSortable: true, isVisible: true, }, { name: 'priority', - label: 'Priority', + label: translate('Priority'), isSortable: true, isVisible: true, }, { name: 'tags', - label: 'Tags', + label: translate('Tags'), isSortable: true, isVisible: true, }, @@ -189,17 +191,21 @@ function ManageIndexersModalContent(props: ManageIndexersModalContentProps) { [items, setSelectState] ); - const errorMessage = getErrorMessage(error, 'Unable to load import lists.'); + const errorMessage = getErrorMessage(error, 'Unable to load indexers.'); const anySelected = selectedCount > 0; return ( - Manage Import Lists + {translate('ManageIndexers')} {isFetching ? : null} {error ? {errorMessage} : null} + {isPopulated && !error && !items.length && ( + {translate('NoIndexersFound')} + )} + {isPopulated && !!items.length && !isFetching && !isFetching ? ( - Delete + {translate('Delete')} - Edit + {translate('Edit')} - Set Tags + {translate('SetTags')} - Close + {translate('Close')} diff --git a/frontend/src/Settings/Indexers/Indexers/Manage/ManageIndexersModalRow.tsx b/frontend/src/Settings/Indexers/Indexers/Manage/ManageIndexersModalRow.tsx index 10ea7ffaa..c888b84c4 100644 --- a/frontend/src/Settings/Indexers/Indexers/Manage/ManageIndexersModalRow.tsx +++ b/frontend/src/Settings/Indexers/Indexers/Manage/ManageIndexersModalRow.tsx @@ -1,10 +1,13 @@ import React, { useCallback } from 'react'; +import Label from 'Components/Label'; import TableRowCell from 'Components/Table/Cells/TableRowCell'; import TableSelectCell from 'Components/Table/Cells/TableSelectCell'; import Column from 'Components/Table/Column'; import TableRow from 'Components/Table/TableRow'; import TagListConnector from 'Components/TagListConnector'; +import { kinds } from 'Helpers/Props'; import { SelectStateInputProps } from 'typings/props'; +import translate from 'Utilities/String/translate'; import styles from './ManageIndexersModalRow.css'; interface ManageIndexersModalRowProps { @@ -59,15 +62,30 @@ function ManageIndexersModalRow(props: ManageIndexersModalRowProps) { - {enableRss ? 'Yes' : 'No'} + + {enableRss ? translate('Yes') : translate('No')} + - {enableAutomaticSearch ? 'Yes' : 'No'} + + {enableAutomaticSearch ? translate('Yes') : translate('No')} + - {enableInteractiveSearch ? 'Yes' : 'No'} + + {enableInteractiveSearch ? translate('Yes') : translate('No')} + {priority} diff --git a/frontend/src/Settings/Indexers/Indexers/Manage/Tags/TagsModalContent.tsx b/frontend/src/Settings/Indexers/Indexers/Manage/Tags/TagsModalContent.tsx index 1f681707c..3205c071a 100644 --- a/frontend/src/Settings/Indexers/Indexers/Manage/Tags/TagsModalContent.tsx +++ b/frontend/src/Settings/Indexers/Indexers/Manage/Tags/TagsModalContent.tsx @@ -17,6 +17,7 @@ import ModalHeader from 'Components/Modal/ModalHeader'; import { inputTypes, kinds, sizes } from 'Helpers/Props'; import createTagsSelector from 'Store/Selectors/createTagsSelector'; import Indexer from 'typings/Indexer'; +import translate from 'Utilities/String/translate'; import styles from './TagsModalContent.css'; interface TagsModalContentProps { @@ -36,7 +37,7 @@ function TagsModalContent(props: TagsModalContentProps) { const [tags, setTags] = useState([]); const [applyTags, setApplyTags] = useState('add'); - const seriesTags = useMemo(() => { + const indexersTags = useMemo(() => { const tags = ids.reduce((acc: number[], id) => { const s = allIndexers.items.find((s: Indexer) => s.id === id); @@ -69,19 +70,19 @@ function TagsModalContent(props: TagsModalContentProps) { }, [tags, applyTags, onApplyTagsPress]); const applyTagsOptions = [ - { key: 'add', value: 'Add' }, - { key: 'remove', value: 'Remove' }, - { key: 'replace', value: 'Replace' }, + { key: 'add', value: translate('Add') }, + { key: 'remove', value: translate('Remove') }, + { key: 'replace', value: translate('Replace') }, ]; return ( - Tags + {translate('Tags')} - Tags + {translate('Tags')} - Apply Tags + {translate('ApplyTags')} - Result + {translate('Result')} - {seriesTags.map((id) => { + {indexersTags.map((id) => { const tag = tagList.find((t) => t.id === id); if (!tag) { @@ -127,7 +128,11 @@ function TagsModalContent(props: TagsModalContentProps) { return ( @@ -144,14 +149,14 @@ function TagsModalContent(props: TagsModalContentProps) { return null; } - if (seriesTags.indexOf(id) > -1) { + if (indexersTags.indexOf(id) > -1) { return null; } return ( @@ -165,10 +170,10 @@ function TagsModalContent(props: TagsModalContentProps) { - Cancel + {translate('Cancel')} - Apply + {translate('Apply')} diff --git a/frontend/src/Store/Actions/Settings/downloadClients.js b/frontend/src/Store/Actions/Settings/downloadClients.js index 60f2fe435..d16dbd1e9 100644 --- a/frontend/src/Store/Actions/Settings/downloadClients.js +++ b/frontend/src/Store/Actions/Settings/downloadClients.js @@ -31,9 +31,8 @@ export const DELETE_DOWNLOAD_CLIENT = 'settings/downloadClients/deleteDownloadCl export const TEST_DOWNLOAD_CLIENT = 'settings/downloadClients/testDownloadClient'; export const CANCEL_TEST_DOWNLOAD_CLIENT = 'settings/downloadClients/cancelTestDownloadClient'; export const TEST_ALL_DOWNLOAD_CLIENTS = 'settings/downloadClients/testAllDownloadClients'; - -export const BULK_DELETE_DOWNLOAD_CLIENTS = 'settings/downloadClients/bulkDeleteDownloadClients'; export const BULK_EDIT_DOWNLOAD_CLIENTS = 'settings/downloadClients/bulkEditDownloadClients'; +export const BULK_DELETE_DOWNLOAD_CLIENTS = 'settings/downloadClients/bulkDeleteDownloadClients'; // // Action Creators @@ -48,9 +47,8 @@ export const deleteDownloadClient = createThunk(DELETE_DOWNLOAD_CLIENT); export const testDownloadClient = createThunk(TEST_DOWNLOAD_CLIENT); export const cancelTestDownloadClient = createThunk(CANCEL_TEST_DOWNLOAD_CLIENT); export const testAllDownloadClients = createThunk(TEST_ALL_DOWNLOAD_CLIENTS); - -export const bulkDeleteDownloadClients = createThunk(BULK_DELETE_DOWNLOAD_CLIENTS); export const bulkEditDownloadClients = createThunk(BULK_EDIT_DOWNLOAD_CLIENTS); +export const bulkDeleteDownloadClients = createThunk(BULK_DELETE_DOWNLOAD_CLIENTS); export const setDownloadClientValue = createAction(SET_DOWNLOAD_CLIENT_VALUE, (payload) => { return { @@ -106,8 +104,8 @@ export default { [TEST_DOWNLOAD_CLIENT]: createTestProviderHandler(section, '/downloadclient'), [CANCEL_TEST_DOWNLOAD_CLIENT]: createCancelTestProviderHandler(section), [TEST_ALL_DOWNLOAD_CLIENTS]: createTestAllProvidersHandler(section, '/downloadclient'), - [BULK_DELETE_DOWNLOAD_CLIENTS]: createBulkRemoveItemHandler(section, '/downloadclient/bulk'), - [BULK_EDIT_DOWNLOAD_CLIENTS]: createBulkEditItemHandler(section, '/downloadclient/bulk') + [BULK_EDIT_DOWNLOAD_CLIENTS]: createBulkEditItemHandler(section, '/downloadclient/bulk'), + [BULK_DELETE_DOWNLOAD_CLIENTS]: createBulkRemoveItemHandler(section, '/downloadclient/bulk') }, // diff --git a/frontend/src/Store/Actions/Settings/importLists.js b/frontend/src/Store/Actions/Settings/importLists.js index 1014cbe05..b21fb2df7 100644 --- a/frontend/src/Store/Actions/Settings/importLists.js +++ b/frontend/src/Store/Actions/Settings/importLists.js @@ -31,9 +31,8 @@ export const DELETE_IMPORT_LIST = 'settings/importlists/deleteImportList'; export const TEST_IMPORT_LIST = 'settings/importlists/testImportList'; export const CANCEL_TEST_IMPORT_LIST = 'settings/importlists/cancelTestImportList'; export const TEST_ALL_IMPORT_LISTS = 'settings/importlists/testAllImportLists'; - -export const BULK_DELETE_IMPORT_LISTS = 'settings/importlists/bulkDeleteImportLists'; export const BULK_EDIT_IMPORT_LISTS = 'settings/importlists/bulkEditImportLists'; +export const BULK_DELETE_IMPORT_LISTS = 'settings/importlists/bulkDeleteImportLists'; // // Action Creators @@ -48,9 +47,8 @@ export const deleteImportList = createThunk(DELETE_IMPORT_LIST); export const testImportList = createThunk(TEST_IMPORT_LIST); export const cancelTestImportList = createThunk(CANCEL_TEST_IMPORT_LIST); export const testAllImportLists = createThunk(TEST_ALL_IMPORT_LISTS); - -export const bulkDeleteImportLists = createThunk(BULK_DELETE_IMPORT_LISTS); export const bulkEditImportLists = createThunk(BULK_EDIT_IMPORT_LISTS); +export const bulkDeleteImportLists = createThunk(BULK_DELETE_IMPORT_LISTS); export const setImportListValue = createAction(SET_IMPORT_LIST_VALUE, (payload) => { return { @@ -105,8 +103,8 @@ export default { [TEST_IMPORT_LIST]: createTestProviderHandler(section, '/importlist'), [CANCEL_TEST_IMPORT_LIST]: createCancelTestProviderHandler(section), [TEST_ALL_IMPORT_LISTS]: createTestAllProvidersHandler(section, '/importlist'), - [BULK_DELETE_IMPORT_LISTS]: createBulkRemoveItemHandler(section, '/importlist/bulk'), - [BULK_EDIT_IMPORT_LISTS]: createBulkEditItemHandler(section, '/importlist/bulk') + [BULK_EDIT_IMPORT_LISTS]: createBulkEditItemHandler(section, '/importlist/bulk'), + [BULK_DELETE_IMPORT_LISTS]: createBulkRemoveItemHandler(section, '/importlist/bulk') }, // diff --git a/frontend/src/Store/Actions/Settings/indexers.js b/frontend/src/Store/Actions/Settings/indexers.js index 6433fbc7a..f4be09691 100644 --- a/frontend/src/Store/Actions/Settings/indexers.js +++ b/frontend/src/Store/Actions/Settings/indexers.js @@ -1,4 +1,6 @@ import { createAction } from 'redux-actions'; +import createBulkEditItemHandler from 'Store/Actions/Creators/createBulkEditItemHandler'; +import createBulkRemoveItemHandler from 'Store/Actions/Creators/createBulkRemoveItemHandler'; import createFetchHandler from 'Store/Actions/Creators/createFetchHandler'; import createFetchSchemaHandler from 'Store/Actions/Creators/createFetchSchemaHandler'; import createRemoveItemHandler from 'Store/Actions/Creators/createRemoveItemHandler'; @@ -11,8 +13,6 @@ import { createThunk } from 'Store/thunks'; import getSectionState from 'Utilities/State/getSectionState'; import selectProviderSchema from 'Utilities/State/selectProviderSchema'; import updateSectionState from 'Utilities/State/updateSectionState'; -import createBulkEditItemHandler from '../Creators/createBulkEditItemHandler'; -import createBulkRemoveItemHandler from '../Creators/createBulkRemoveItemHandler'; // // Variables @@ -34,9 +34,8 @@ export const DELETE_INDEXER = 'settings/indexers/deleteIndexer'; export const TEST_INDEXER = 'settings/indexers/testIndexer'; export const CANCEL_TEST_INDEXER = 'settings/indexers/cancelTestIndexer'; export const TEST_ALL_INDEXERS = 'settings/indexers/testAllIndexers'; - -export const BULK_DELETE_INDEXERS = 'settings/indexers/bulkDeleteIndexers'; export const BULK_EDIT_INDEXERS = 'settings/indexers/bulkEditIndexers'; +export const BULK_DELETE_INDEXERS = 'settings/indexers/bulkDeleteIndexers'; // // Action Creators @@ -52,9 +51,8 @@ export const deleteIndexer = createThunk(DELETE_INDEXER); export const testIndexer = createThunk(TEST_INDEXER); export const cancelTestIndexer = createThunk(CANCEL_TEST_INDEXER); export const testAllIndexers = createThunk(TEST_ALL_INDEXERS); - -export const bulkDeleteIndexers = createThunk(BULK_DELETE_INDEXERS); export const bulkEditIndexers = createThunk(BULK_EDIT_INDEXERS); +export const bulkDeleteIndexers = createThunk(BULK_DELETE_INDEXERS); export const setIndexerValue = createAction(SET_INDEXER_VALUE, (payload) => { return { @@ -110,9 +108,8 @@ export default { [TEST_INDEXER]: createTestProviderHandler(section, '/indexer'), [CANCEL_TEST_INDEXER]: createCancelTestProviderHandler(section), [TEST_ALL_INDEXERS]: createTestAllProvidersHandler(section, '/indexer'), - - [BULK_DELETE_INDEXERS]: createBulkRemoveItemHandler(section, '/indexer/bulk'), - [BULK_EDIT_INDEXERS]: createBulkEditItemHandler(section, '/indexer/bulk') + [BULK_EDIT_INDEXERS]: createBulkEditItemHandler(section, '/indexer/bulk'), + [BULK_DELETE_INDEXERS]: createBulkRemoveItemHandler(section, '/indexer/bulk') }, // diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index a5e5b2789..b5d6cc834 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -1,40 +1,63 @@ { + "Add": "Add", "Added": "Added", + "AddingTag": "Adding tag", "ApiKeyValidationHealthCheckMessage": "Please update your API key to be at least {0} characters long. You can do this via settings or the config file", "AppDataLocationHealthCheckMessage": "Updating will not be possible to prevent deleting AppData on Update", + "Apply": "Apply", "ApplyChanges": "Apply Changes", + "ApplyTags": "Apply Tags", + "ApplyTagsHelpTexts1": "How to apply tags to the selected indexers", + "ApplyTagsHelpTexts2": "Add: Add the tags the existing list of tags", + "ApplyTagsHelpTexts3": "Remove: Remove the entered tags", + "ApplyTagsHelpTexts4": "Replace: Replace the tags with the entered tags (enter no tags to clear all tags)", + "AutoAdd": "Auto Add", "AutomaticAdd": "Automatic Add", "BlocklistRelease": "Blocklist Release", "BlocklistReleaseHelpText": "Prevents Sonarr from automatically grabbing this release again", "BlocklistReleases": "Blocklist Releases", "Browser Reload Required": "Browser Reload Required", + "Cancel": "Cancel", "CloneCondition": "Clone Condition", "CloneCustomFormat": "Clone Custom Format", "Close": "Close", + "CountDownloadClientsSelected": "{count} download client(s) selected", + "CountImportListsSelected": "{count} import list(s) selected", + "CountIndexersSelected": "{count} indexer(s) selected", "CountSeasons": "{count} seasons", "Delete": "Delete", "DeleteCondition": "Delete Condition", "DeleteConditionMessageText": "Are you sure you want to delete the condition '{0}'?", "DeleteCustomFormat": "Delete Custom Format", "DeleteCustomFormatMessageText": "Are you sure you want to delete the custom format '{0}'?", + "DeleteSelectedDownloadClients": "Delete Download Client(s)", + "DeleteSelectedDownloadClientsMessageText": "Are you sure you want to delete {count} selected download client(s)?", + "DeleteSelectedImportLists": "Delete Import List(s)", + "DeleteSelectedImportListsMessageText": "Are you sure you want to delete {count} selected import list(s)?", + "DeleteSelectedIndexers": "Delete Indexer(s)", + "DeleteSelectedIndexersMessageText": "Are you sure you want to delete {count} selected indexer(s)?", + "Disabled": "Disabled", "DownloadClientCheckNoneAvailableHealthCheckMessage": "No download client is available", "DownloadClientCheckUnableToCommunicateWithHealthCheckMessage": "Unable to communicate with {0}.", "DownloadClientRootFolderHealthCheckMessage": "Download client {0} places downloads in the root folder {1}. You should not download to a root folder.", "DownloadClientSortingHealthCheckMessage": "Download client {0} has {1} sorting enabled for Sonarr's category. You should disable sorting in your download client to avoid import issues.", "DownloadClientStatusAllClientHealthCheckMessage": "All download clients are unavailable due to failures", "DownloadClientStatusSingleClientHealthCheckMessage": "Download clients unavailable due to failures: {0}", + "Edit": "Edit", "EditSelectedDownloadClients": "Edit Selected Download Clients", "EditSelectedImportLists": "Edit Selected Import Lists", "EditSelectedIndexers": "Edit Selected Indexers", "EditSeries": "Edit Series", "EnableAutomaticSearch": "Enable Automatic Search", "EnableInteractiveSearch": "Enable Interactive Search", - "EnableRss": "Enable Rss", + "EnableRSS": "Enable RSS", "Enabled": "Enabled", "Ended": "Ended", + "ExistingTag": "Existing tag", "ExportCustomFormat": "Export Custom Format", "HiddenClickToShow": "Hidden, click to show", "HideAdvanced": "Hide Advanced", + "Implementation": "Implementation", "ImportListRootFolderMissingRootHealthCheckMessage": "Missing root folder for import list(s): {0}", "ImportListRootFolderMultipleMissingRootsHealthCheckMessage": "Multiple root folders are missing for import lists: {0}", "ImportListStatusAllUnavailableHealthCheckMessage": "All lists are unavailable due to failures", @@ -54,11 +77,22 @@ "IndexerStatusUnavailableHealthCheckMessage": "Indexers unavailable due to failures: {0}", "Language": "Language", "Language that Sonarr will use for UI": "Language that Sonarr will use for UI", + "ManageClients": "Manage Clients", + "ManageDownloadClients": "Manage Download Clients", + "ManageImportLists": "Manage Import Lists", + "ManageIndexers": "Manage Indexers", + "ManageLists": "Manage Lists", "Monitored": "Monitored", "MountHealthCheckMessage": "Mount containing a series path is mounted read-only: ", + "Name": "Name", "Negated": "Negated", "Network": "Network", "NextAiring": "Next Airing", + "No": "No", + "NoChange": "No Change", + "NoDownloadClientsFound": "No download clients found", + "NoImportListsFound": "No import lists found", + "NoIndexersFound": "No indexers found", "NoSeasons": "No seasons", "OneSeason": "1 season", "OriginalLanguage": "Original Language", @@ -87,7 +121,9 @@ "RemotePathMappingRemoteDownloadClientHealthCheckMessage": "Remote download client {0} reported files in {1} but this directory does not appear to exist. Likely missing remote path mapping.", "RemotePathMappingWrongOSPathHealthCheckMessage": "Remote download client {0} places downloads in {1} but this is not a valid {2} path. Review your remote path mappings and download client settings.", "Remove": "Remove", + "RemoveCompleted": "Remove Completed", "RemoveCompletedDownloads": "Remove Completed Downloads", + "RemoveFailed": "Remove Failed", "RemoveFailedDownloads": "Remove Failed Downloads", "RemoveFromDownloadClient": "Remove From Download Client", "RemoveFromDownloadClientHelpTextWarning": "Removing will remove the download and the file(s) from the download client.", @@ -97,19 +133,25 @@ "RemoveSelectedItemsQueueMessageText": "Are you sure you want to remove {0} items from the queue?", "RemovedSeriesMultipleRemovedHealthCheckMessage": "Series {0} were removed from TheTVDB", "RemovedSeriesSingleRemovedHealthCheckMessage": "Series {0} was removed from TheTVDB", + "RemovingTag": "Removing tag", + "Replace": "Replace", "Required": "Required", + "Result": "Result", "RootFolder": "Root Folder", "RootFolderMissingHealthCheckMessage": "Missing root folder: {0}", "RootFolderMultipleMissingHealthCheckMessage": "Multiple root folders are missing: {0}", "SearchForMonitoredEpisodes": "Search for monitored episodes", + "SetTags": "Set Tags", "ShowAdvanced": "Show Advanced", "ShownClickToHide": "Shown, click to hide", "SizeOnDisk": "Size on disk", "SystemTimeHealthCheckMessage": "System time is off by more than 1 day. Scheduled tasks may not run correctly until the time is corrected", + "Tags": "Tags", "UI Language": "UI Language", "Unmonitored": "Unmonitored", "UpdateAvailableHealthCheckMessage": "New update is available", "UpdateStartupNotWritableHealthCheckMessage": "Cannot install update because startup folder '{0}' is not writable by the user '{1}'.", "UpdateStartupTranslocationHealthCheckMessage": "Cannot install update because startup folder '{0}' is in an App Translocation folder.", - "UpdateUINotWritableHealthCheckMessage": "Cannot install update because UI folder '{0}' is not writable by the user '{1}'." + "UpdateUINotWritableHealthCheckMessage": "Cannot install update because UI folder '{0}' is not writable by the user '{1}'.", + "Yes": "Yes" }