New: Add translations for managing bulk indexers, lists and clients
This commit is contained in:
parent
45336389e6
commit
e641c57ad9
|
@ -235,7 +235,7 @@ function EditSeriesModalContent(props: EditSeriesModalContentProps) {
|
||||||
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
||||||
|
|
||||||
<Button onPress={onSavePressWrapper}>
|
<Button onPress={onSavePressWrapper}>
|
||||||
{translate('Apply Changes')}
|
{translate('ApplyChanges')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
|
|
|
@ -6,6 +6,7 @@ import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
||||||
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||||
import { icons } from 'Helpers/Props';
|
import { icons } from 'Helpers/Props';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
import DownloadClientsConnector from './DownloadClients/DownloadClientsConnector';
|
import DownloadClientsConnector from './DownloadClients/DownloadClientsConnector';
|
||||||
import ManageDownloadClientsModal from './DownloadClients/Manage/ManageDownloadClientsModal';
|
import ManageDownloadClientsModal from './DownloadClients/Manage/ManageDownloadClientsModal';
|
||||||
import DownloadClientOptionsConnector from './Options/DownloadClientOptionsConnector';
|
import DownloadClientOptionsConnector from './Options/DownloadClientOptionsConnector';
|
||||||
|
@ -85,7 +86,7 @@ class DownloadClientSettings extends Component {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PageToolbarButton
|
<PageToolbarButton
|
||||||
label="Manage Clients"
|
label={translate('ManageClients')}
|
||||||
iconName={icons.MANAGE}
|
iconName={icons.MANAGE}
|
||||||
onPress={this.onManageDownloadClientsPress}
|
onPress={this.onManageDownloadClientsPress}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -27,9 +27,9 @@ interface ManageDownloadClientsEditModalContentProps {
|
||||||
const NO_CHANGE = 'noChange';
|
const NO_CHANGE = 'noChange';
|
||||||
|
|
||||||
const enableOptions = [
|
const enableOptions = [
|
||||||
{ key: NO_CHANGE, value: 'No Change', disabled: true },
|
{ key: NO_CHANGE, value: translate('NoChange'), disabled: true },
|
||||||
{ key: 'enabled', value: 'Enabled' },
|
{ key: 'enabled', value: translate('Enabled') },
|
||||||
{ key: 'disabled', value: 'Disabled' },
|
{ key: 'disabled', value: translate('Disabled') },
|
||||||
];
|
];
|
||||||
|
|
||||||
function ManageDownloadClientsEditModalContent(
|
function ManageDownloadClientsEditModalContent(
|
||||||
|
@ -97,7 +97,9 @@ function ManageDownloadClientsEditModalContent(
|
||||||
setRemoveFailedDownloads(value);
|
setRemoveFailedDownloads(value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.warn('EditDownloadClientsModalContent Unknown Input');
|
console.warn(
|
||||||
|
`EditDownloadClientsModalContent Unknown Input: '${name}'`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
|
@ -162,7 +164,7 @@ function ManageDownloadClientsEditModalContent(
|
||||||
|
|
||||||
<ModalFooter className={styles.modalFooter}>
|
<ModalFooter className={styles.modalFooter}>
|
||||||
<div className={styles.selected}>
|
<div className={styles.selected}>
|
||||||
{translate('{count} download clients selected', {
|
{translate('CountDownloadClientsSelected', {
|
||||||
count: selectedCount,
|
count: selectedCount,
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
@ -170,7 +172,7 @@ function ManageDownloadClientsEditModalContent(
|
||||||
<div>
|
<div>
|
||||||
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
||||||
|
|
||||||
<Button onPress={save}>{translate('Apply Changes')}</Button>
|
<Button onPress={save}>{translate('ApplyChanges')}</Button>
|
||||||
</div>
|
</div>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React, { useCallback, useMemo, useState } from 'react';
|
import React, { useCallback, useMemo, useState } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { DownloadClientAppState } from 'App/State/SettingsAppState';
|
import { DownloadClientAppState } from 'App/State/SettingsAppState';
|
||||||
|
import Alert from 'Components/Alert';
|
||||||
import Button from 'Components/Link/Button';
|
import Button from 'Components/Link/Button';
|
||||||
import SpinnerButton from 'Components/Link/SpinnerButton';
|
import SpinnerButton from 'Components/Link/SpinnerButton';
|
||||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||||
|
@ -20,6 +21,7 @@ import {
|
||||||
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
||||||
import { SelectStateInputProps } from 'typings/props';
|
import { SelectStateInputProps } from 'typings/props';
|
||||||
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
||||||
import ManageDownloadClientsEditModal from './Edit/ManageDownloadClientsEditModal';
|
import ManageDownloadClientsEditModal from './Edit/ManageDownloadClientsEditModal';
|
||||||
import ManageDownloadClientsModalRow from './ManageDownloadClientsModalRow';
|
import ManageDownloadClientsModalRow from './ManageDownloadClientsModalRow';
|
||||||
|
@ -34,37 +36,37 @@ type OnSelectedChangeCallback = React.ComponentProps<
|
||||||
const COLUMNS = [
|
const COLUMNS = [
|
||||||
{
|
{
|
||||||
name: 'name',
|
name: 'name',
|
||||||
label: 'Name',
|
label: translate('Name'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'implementation',
|
name: 'implementation',
|
||||||
label: 'Implementation',
|
label: translate('Implementation'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'enable',
|
name: 'enable',
|
||||||
label: 'Enabled',
|
label: translate('Enabled'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'priority',
|
name: 'priority',
|
||||||
label: 'Priority',
|
label: translate('Priority'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'removeCompletedDownloads',
|
name: 'removeCompletedDownloads',
|
||||||
label: 'Remove Completed',
|
label: translate('RemoveCompleted'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'removeFailedDownloads',
|
name: 'removeFailedDownloads',
|
||||||
label: 'Remove Failed',
|
label: translate('RemoveFailed'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
|
@ -191,17 +193,24 @@ function ManageDownloadClientsModalContent(
|
||||||
[items, setSelectState]
|
[items, setSelectState]
|
||||||
);
|
);
|
||||||
|
|
||||||
const errorMessage = getErrorMessage(error, 'Unable to load import lists.');
|
const errorMessage = getErrorMessage(
|
||||||
|
error,
|
||||||
|
'Unable to load download clients.'
|
||||||
|
);
|
||||||
const anySelected = selectedCount > 0;
|
const anySelected = selectedCount > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalContent onModalClose={onModalClose}>
|
<ModalContent onModalClose={onModalClose}>
|
||||||
<ModalHeader>Manage Import Lists</ModalHeader>
|
<ModalHeader>{translate('ManageDownloadClients')}</ModalHeader>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
{isFetching ? <LoadingIndicator /> : null}
|
{isFetching ? <LoadingIndicator /> : null}
|
||||||
|
|
||||||
{error ? <div>{errorMessage}</div> : null}
|
{error ? <div>{errorMessage}</div> : null}
|
||||||
|
|
||||||
|
{isPopulated && !error && !items.length && (
|
||||||
|
<Alert kind={kinds.INFO}>{translate('NoDownloadClientsFound')}</Alert>
|
||||||
|
)}
|
||||||
|
|
||||||
{isPopulated && !!items.length && !isFetching && !isFetching ? (
|
{isPopulated && !!items.length && !isFetching && !isFetching ? (
|
||||||
<Table
|
<Table
|
||||||
columns={COLUMNS}
|
columns={COLUMNS}
|
||||||
|
@ -236,7 +245,7 @@ function ManageDownloadClientsModalContent(
|
||||||
isDisabled={!anySelected}
|
isDisabled={!anySelected}
|
||||||
onPress={onDeletePress}
|
onPress={onDeletePress}
|
||||||
>
|
>
|
||||||
Delete
|
{translate('Delete')}
|
||||||
</SpinnerButton>
|
</SpinnerButton>
|
||||||
|
|
||||||
<SpinnerButton
|
<SpinnerButton
|
||||||
|
@ -244,7 +253,7 @@ function ManageDownloadClientsModalContent(
|
||||||
isDisabled={!anySelected}
|
isDisabled={!anySelected}
|
||||||
onPress={onEditPress}
|
onPress={onEditPress}
|
||||||
>
|
>
|
||||||
Edit
|
{translate('Edit')}
|
||||||
</SpinnerButton>
|
</SpinnerButton>
|
||||||
|
|
||||||
<SpinnerButton
|
<SpinnerButton
|
||||||
|
@ -256,7 +265,7 @@ function ManageDownloadClientsModalContent(
|
||||||
</SpinnerButton>
|
</SpinnerButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button onPress={onModalClose}>Close</Button>
|
<Button onPress={onModalClose}>{translate('Close')}</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
|
|
||||||
<ManageDownloadClientsEditModal
|
<ManageDownloadClientsEditModal
|
||||||
|
@ -276,9 +285,11 @@ function ManageDownloadClientsModalContent(
|
||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
isOpen={isDeleteModalOpen}
|
isOpen={isDeleteModalOpen}
|
||||||
kind={kinds.DANGER}
|
kind={kinds.DANGER}
|
||||||
title="Delete Download Clients(s)"
|
title={translate('DeleteSelectedDownloadClients')}
|
||||||
message={`Are you sure you want to delete ${selectedIds.length} download clients(s)?`}
|
message={translate('DeleteSelectedDownloadClientsMessageText', {
|
||||||
confirmLabel="Delete"
|
count: selectedIds.length,
|
||||||
|
})}
|
||||||
|
confirmLabel={translate('Delete')}
|
||||||
onConfirm={onConfirmDelete}
|
onConfirm={onConfirmDelete}
|
||||||
onCancel={onDeleteModalClose}
|
onCancel={onDeleteModalClose}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
|
import Label from 'Components/Label';
|
||||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
||||||
import Column from 'Components/Table/Column';
|
import Column from 'Components/Table/Column';
|
||||||
import TableRow from 'Components/Table/TableRow';
|
import TableRow from 'Components/Table/TableRow';
|
||||||
import TagListConnector from 'Components/TagListConnector';
|
import TagListConnector from 'Components/TagListConnector';
|
||||||
|
import { kinds } from 'Helpers/Props';
|
||||||
import { SelectStateInputProps } from 'typings/props';
|
import { SelectStateInputProps } from 'typings/props';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
import styles from './ManageDownloadClientsModalRow.css';
|
import styles from './ManageDownloadClientsModalRow.css';
|
||||||
|
|
||||||
interface ManageDownloadClientsModalRowProps {
|
interface ManageDownloadClientsModalRowProps {
|
||||||
|
@ -61,17 +64,19 @@ function ManageDownloadClientsModalRow(
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
<TableRowCell className={styles.enable}>
|
<TableRowCell className={styles.enable}>
|
||||||
{enable ? 'Yes' : 'No'}
|
<Label kind={enable ? kinds.SUCCESS : kinds.DISABLED} outline={!enable}>
|
||||||
|
{enable ? translate('Yes') : translate('No')}
|
||||||
|
</Label>
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
<TableRowCell className={styles.priority}>{priority}</TableRowCell>
|
<TableRowCell className={styles.priority}>{priority}</TableRowCell>
|
||||||
|
|
||||||
<TableRowCell className={styles.removeCompletedDownloads}>
|
<TableRowCell className={styles.removeCompletedDownloads}>
|
||||||
{removeCompletedDownloads ? 'Yes' : 'No'}
|
{removeCompletedDownloads ? translate('Yes') : translate('No')}
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
<TableRowCell className={styles.removeFailedDownloads}>
|
<TableRowCell className={styles.removeFailedDownloads}>
|
||||||
{removeFailedDownloads ? 'Yes' : 'No'}
|
{removeFailedDownloads ? translate('Yes') : translate('No')}
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
<TableRowCell className={styles.tags}>
|
<TableRowCell className={styles.tags}>
|
||||||
|
|
|
@ -17,6 +17,7 @@ import ModalHeader from 'Components/Modal/ModalHeader';
|
||||||
import { inputTypes, kinds, sizes } from 'Helpers/Props';
|
import { inputTypes, kinds, sizes } from 'Helpers/Props';
|
||||||
import createTagsSelector from 'Store/Selectors/createTagsSelector';
|
import createTagsSelector from 'Store/Selectors/createTagsSelector';
|
||||||
import DownloadClient from 'typings/DownloadClient';
|
import DownloadClient from 'typings/DownloadClient';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
import styles from './TagsModalContent.css';
|
import styles from './TagsModalContent.css';
|
||||||
|
|
||||||
interface TagsModalContentProps {
|
interface TagsModalContentProps {
|
||||||
|
@ -36,7 +37,7 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
const [tags, setTags] = useState<number[]>([]);
|
const [tags, setTags] = useState<number[]>([]);
|
||||||
const [applyTags, setApplyTags] = useState('add');
|
const [applyTags, setApplyTags] = useState('add');
|
||||||
|
|
||||||
const seriesTags = useMemo(() => {
|
const downloadClientsTags = useMemo(() => {
|
||||||
const tags = ids.reduce((acc: number[], id) => {
|
const tags = ids.reduce((acc: number[], id) => {
|
||||||
const s = allDownloadClients.items.find(
|
const s = allDownloadClients.items.find(
|
||||||
(s: DownloadClient) => s.id === id
|
(s: DownloadClient) => s.id === id
|
||||||
|
@ -71,19 +72,19 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
}, [tags, applyTags, onApplyTagsPress]);
|
}, [tags, applyTags, onApplyTagsPress]);
|
||||||
|
|
||||||
const applyTagsOptions = [
|
const applyTagsOptions = [
|
||||||
{ key: 'add', value: 'Add' },
|
{ key: 'add', value: translate('Add') },
|
||||||
{ key: 'remove', value: 'Remove' },
|
{ key: 'remove', value: translate('Remove') },
|
||||||
{ key: 'replace', value: 'Replace' },
|
{ key: 'replace', value: translate('Replace') },
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalContent onModalClose={onModalClose}>
|
<ModalContent onModalClose={onModalClose}>
|
||||||
<ModalHeader>Tags</ModalHeader>
|
<ModalHeader>{translate('Tags')}</ModalHeader>
|
||||||
|
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<Form>
|
<Form>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>Tags</FormLabel>
|
<FormLabel>{translate('Tags')}</FormLabel>
|
||||||
|
|
||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.TAG}
|
type={inputTypes.TAG}
|
||||||
|
@ -94,7 +95,7 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>Apply Tags</FormLabel>
|
<FormLabel>{translate('ApplyTags')}</FormLabel>
|
||||||
|
|
||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.SELECT}
|
type={inputTypes.SELECT}
|
||||||
|
@ -102,20 +103,20 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
value={applyTags}
|
value={applyTags}
|
||||||
values={applyTagsOptions}
|
values={applyTagsOptions}
|
||||||
helpTexts={[
|
helpTexts={[
|
||||||
'How to apply tags to the selected download clients(s)',
|
translate('ApplyTagsHelpTexts1'),
|
||||||
'Add: Add the tags the existing list of tags',
|
translate('ApplyTagsHelpTexts2'),
|
||||||
'Remove: Remove the entered tags',
|
translate('ApplyTagsHelpTexts3'),
|
||||||
'Replace: Replace the tags with the entered tags (enter no tags to clear all tags)',
|
translate('ApplyTagsHelpTexts4'),
|
||||||
]}
|
]}
|
||||||
onChange={onApplyTagsChange}
|
onChange={onApplyTagsChange}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>Result</FormLabel>
|
<FormLabel>{translate('Result')}</FormLabel>
|
||||||
|
|
||||||
<div className={styles.result}>
|
<div className={styles.result}>
|
||||||
{seriesTags.map((id) => {
|
{downloadClientsTags.map((id) => {
|
||||||
const tag = tagList.find((t) => t.id === id);
|
const tag = tagList.find((t) => t.id === id);
|
||||||
|
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
|
@ -129,7 +130,11 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
return (
|
return (
|
||||||
<Label
|
<Label
|
||||||
key={tag.id}
|
key={tag.id}
|
||||||
title={removeTag ? 'Removing tag' : 'Existing tag'}
|
title={
|
||||||
|
removeTag
|
||||||
|
? translate('RemovingTag')
|
||||||
|
: translate('ExistingTag')
|
||||||
|
}
|
||||||
kind={removeTag ? kinds.INVERSE : kinds.INFO}
|
kind={removeTag ? kinds.INVERSE : kinds.INFO}
|
||||||
size={sizes.LARGE}
|
size={sizes.LARGE}
|
||||||
>
|
>
|
||||||
|
@ -146,14 +151,14 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seriesTags.indexOf(id) > -1) {
|
if (downloadClientsTags.indexOf(id) > -1) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Label
|
<Label
|
||||||
key={tag.id}
|
key={tag.id}
|
||||||
title={'Adding tag'}
|
title={translate('AddingTag')}
|
||||||
kind={kinds.SUCCESS}
|
kind={kinds.SUCCESS}
|
||||||
size={sizes.LARGE}
|
size={sizes.LARGE}
|
||||||
>
|
>
|
||||||
|
@ -167,10 +172,10 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button onPress={onModalClose}>Cancel</Button>
|
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
||||||
|
|
||||||
<Button kind={kinds.PRIMARY} onPress={onApplyPress}>
|
<Button kind={kinds.PRIMARY} onPress={onApplyPress}>
|
||||||
Apply
|
{translate('Apply')}
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|
|
@ -6,6 +6,7 @@ import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
||||||
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||||
import { icons } from 'Helpers/Props';
|
import { icons } from 'Helpers/Props';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
import ImportListsExclusionsConnector from './ImportListExclusions/ImportListExclusionsConnector';
|
import ImportListsExclusionsConnector from './ImportListExclusions/ImportListExclusionsConnector';
|
||||||
import ImportListsConnector from './ImportLists/ImportListsConnector';
|
import ImportListsConnector from './ImportLists/ImportListsConnector';
|
||||||
import ManageImportListsModal from './ImportLists/Manage/ManageImportListsModal';
|
import ManageImportListsModal from './ImportLists/Manage/ManageImportListsModal';
|
||||||
|
@ -81,7 +82,7 @@ class ImportListSettings extends Component {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PageToolbarButton
|
<PageToolbarButton
|
||||||
label="Manage Lists"
|
label={translate('ManageLists')}
|
||||||
iconName={icons.MANAGE}
|
iconName={icons.MANAGE}
|
||||||
onPress={this.onManageImportListsPress}
|
onPress={this.onManageImportListsPress}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -26,9 +26,9 @@ interface ManageImportListsEditModalContentProps {
|
||||||
const NO_CHANGE = 'noChange';
|
const NO_CHANGE = 'noChange';
|
||||||
|
|
||||||
const autoAddOptions = [
|
const autoAddOptions = [
|
||||||
{ key: NO_CHANGE, value: 'No Change', disabled: true },
|
{ key: NO_CHANGE, value: translate('NoChange'), disabled: true },
|
||||||
{ key: 'enabled', value: 'Enabled' },
|
{ key: 'enabled', value: translate('Enabled') },
|
||||||
{ key: 'disabled', value: 'Disabled' },
|
{ key: 'disabled', value: translate('Disabled') },
|
||||||
];
|
];
|
||||||
|
|
||||||
function ManageImportListsEditModalContent(
|
function ManageImportListsEditModalContent(
|
||||||
|
@ -87,7 +87,7 @@ function ManageImportListsEditModalContent(
|
||||||
setRootFolderPath(value);
|
setRootFolderPath(value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.warn('EditImportListModalContent Unknown Input');
|
console.warn(`EditImportListModalContent Unknown Input: '${name}'`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
|
@ -142,7 +142,9 @@ function ManageImportListsEditModalContent(
|
||||||
|
|
||||||
<ModalFooter className={styles.modalFooter}>
|
<ModalFooter className={styles.modalFooter}>
|
||||||
<div className={styles.selected}>
|
<div className={styles.selected}>
|
||||||
{translate('{count} import lists selected', { count: selectedCount })}
|
{translate('CountImportListsSelected', {
|
||||||
|
count: selectedCount,
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React, { useCallback, useMemo, useState } from 'react';
|
import React, { useCallback, useMemo, useState } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { ImportListAppState } from 'App/State/SettingsAppState';
|
import { ImportListAppState } from 'App/State/SettingsAppState';
|
||||||
|
import Alert from 'Components/Alert';
|
||||||
import Button from 'Components/Link/Button';
|
import Button from 'Components/Link/Button';
|
||||||
import SpinnerButton from 'Components/Link/SpinnerButton';
|
import SpinnerButton from 'Components/Link/SpinnerButton';
|
||||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||||
|
@ -20,6 +21,7 @@ import {
|
||||||
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
||||||
import { SelectStateInputProps } from 'typings/props';
|
import { SelectStateInputProps } from 'typings/props';
|
||||||
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
||||||
import ManageImportListsEditModal from './Edit/ManageImportListsEditModal';
|
import ManageImportListsEditModal from './Edit/ManageImportListsEditModal';
|
||||||
import ManageImportListsModalRow from './ManageImportListsModalRow';
|
import ManageImportListsModalRow from './ManageImportListsModalRow';
|
||||||
|
@ -34,37 +36,37 @@ type OnSelectedChangeCallback = React.ComponentProps<
|
||||||
const COLUMNS = [
|
const COLUMNS = [
|
||||||
{
|
{
|
||||||
name: 'name',
|
name: 'name',
|
||||||
label: 'Name',
|
label: translate('Name'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'implementation',
|
name: 'implementation',
|
||||||
label: 'Implementation',
|
label: translate('Implementation'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'qualityProfileId',
|
name: 'qualityProfileId',
|
||||||
label: 'Quality Profile',
|
label: translate('QualityProfile'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'rootFolderPath',
|
name: 'rootFolderPath',
|
||||||
label: 'Root Folder',
|
label: translate('RootFolder'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'enableAutomaticAdd',
|
name: 'enableAutomaticAdd',
|
||||||
label: 'Auto Add',
|
label: translate('AutoAdd'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'tags',
|
name: 'tags',
|
||||||
label: 'Tags',
|
label: translate('Tags'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
|
@ -190,12 +192,16 @@ function ManageImportListsModalContent(
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalContent onModalClose={onModalClose}>
|
<ModalContent onModalClose={onModalClose}>
|
||||||
<ModalHeader>Manage Import Lists</ModalHeader>
|
<ModalHeader>{translate('ManageImportLists')}</ModalHeader>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
{isFetching ? <LoadingIndicator /> : null}
|
{isFetching ? <LoadingIndicator /> : null}
|
||||||
|
|
||||||
{error ? <div>{errorMessage}</div> : null}
|
{error ? <div>{errorMessage}</div> : null}
|
||||||
|
|
||||||
|
{isPopulated && !error && !items.length && (
|
||||||
|
<Alert kind={kinds.INFO}>{translate('NoImportListsFound')}</Alert>
|
||||||
|
)}
|
||||||
|
|
||||||
{isPopulated && !!items.length && !isFetching && !isFetching ? (
|
{isPopulated && !!items.length && !isFetching && !isFetching ? (
|
||||||
<Table
|
<Table
|
||||||
columns={COLUMNS}
|
columns={COLUMNS}
|
||||||
|
@ -230,7 +236,7 @@ function ManageImportListsModalContent(
|
||||||
isDisabled={!anySelected}
|
isDisabled={!anySelected}
|
||||||
onPress={onDeletePress}
|
onPress={onDeletePress}
|
||||||
>
|
>
|
||||||
Delete
|
{translate('Delete')}
|
||||||
</SpinnerButton>
|
</SpinnerButton>
|
||||||
|
|
||||||
<SpinnerButton
|
<SpinnerButton
|
||||||
|
@ -238,7 +244,7 @@ function ManageImportListsModalContent(
|
||||||
isDisabled={!anySelected}
|
isDisabled={!anySelected}
|
||||||
onPress={onEditPress}
|
onPress={onEditPress}
|
||||||
>
|
>
|
||||||
Edit
|
{translate('Edit')}
|
||||||
</SpinnerButton>
|
</SpinnerButton>
|
||||||
|
|
||||||
<SpinnerButton
|
<SpinnerButton
|
||||||
|
@ -246,11 +252,11 @@ function ManageImportListsModalContent(
|
||||||
isDisabled={!anySelected}
|
isDisabled={!anySelected}
|
||||||
onPress={onTagsPress}
|
onPress={onTagsPress}
|
||||||
>
|
>
|
||||||
Set Tags
|
{translate('SetTags')}
|
||||||
</SpinnerButton>
|
</SpinnerButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button onPress={onModalClose}>Close</Button>
|
<Button onPress={onModalClose}>{translate('Close')}</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
|
|
||||||
<ManageImportListsEditModal
|
<ManageImportListsEditModal
|
||||||
|
@ -270,9 +276,11 @@ function ManageImportListsModalContent(
|
||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
isOpen={isDeleteModalOpen}
|
isOpen={isDeleteModalOpen}
|
||||||
kind={kinds.DANGER}
|
kind={kinds.DANGER}
|
||||||
title="Delete Import List(s)"
|
title={translate('DeleteSelectedImportLists')}
|
||||||
message={`Are you sure you want to delete ${selectedIds.length} import list(s)?`}
|
message={translate('DeleteSelectedImportListsMessageText', {
|
||||||
confirmLabel="Delete"
|
count: selectedIds.length,
|
||||||
|
})}
|
||||||
|
confirmLabel={translate('Delete')}
|
||||||
onConfirm={onConfirmDelete}
|
onConfirm={onConfirmDelete}
|
||||||
onCancel={onDeleteModalClose}
|
onCancel={onDeleteModalClose}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -17,6 +17,7 @@ import ModalHeader from 'Components/Modal/ModalHeader';
|
||||||
import { inputTypes, kinds, sizes } from 'Helpers/Props';
|
import { inputTypes, kinds, sizes } from 'Helpers/Props';
|
||||||
import createTagsSelector from 'Store/Selectors/createTagsSelector';
|
import createTagsSelector from 'Store/Selectors/createTagsSelector';
|
||||||
import ImportList from 'typings/ImportList';
|
import ImportList from 'typings/ImportList';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
import styles from './TagsModalContent.css';
|
import styles from './TagsModalContent.css';
|
||||||
|
|
||||||
interface TagsModalContentProps {
|
interface TagsModalContentProps {
|
||||||
|
@ -36,7 +37,7 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
const [tags, setTags] = useState<number[]>([]);
|
const [tags, setTags] = useState<number[]>([]);
|
||||||
const [applyTags, setApplyTags] = useState('add');
|
const [applyTags, setApplyTags] = useState('add');
|
||||||
|
|
||||||
const seriesTags = useMemo(() => {
|
const importListsTags = useMemo(() => {
|
||||||
const tags = ids.reduce((acc: number[], id) => {
|
const tags = ids.reduce((acc: number[], id) => {
|
||||||
const s = allImportLists.items.find((s: ImportList) => s.id === id);
|
const s = allImportLists.items.find((s: ImportList) => s.id === id);
|
||||||
|
|
||||||
|
@ -69,19 +70,19 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
}, [tags, applyTags, onApplyTagsPress]);
|
}, [tags, applyTags, onApplyTagsPress]);
|
||||||
|
|
||||||
const applyTagsOptions = [
|
const applyTagsOptions = [
|
||||||
{ key: 'add', value: 'Add' },
|
{ key: 'add', value: translate('Add') },
|
||||||
{ key: 'remove', value: 'Remove' },
|
{ key: 'remove', value: translate('Remove') },
|
||||||
{ key: 'replace', value: 'Replace' },
|
{ key: 'replace', value: translate('Replace') },
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalContent onModalClose={onModalClose}>
|
<ModalContent onModalClose={onModalClose}>
|
||||||
<ModalHeader>Tags</ModalHeader>
|
<ModalHeader>{translate('Tags')}</ModalHeader>
|
||||||
|
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<Form>
|
<Form>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>Tags</FormLabel>
|
<FormLabel>{translate('Tags')}</FormLabel>
|
||||||
|
|
||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.TAG}
|
type={inputTypes.TAG}
|
||||||
|
@ -92,7 +93,7 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>Apply Tags</FormLabel>
|
<FormLabel>{translate('ApplyTags')}</FormLabel>
|
||||||
|
|
||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.SELECT}
|
type={inputTypes.SELECT}
|
||||||
|
@ -100,20 +101,20 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
value={applyTags}
|
value={applyTags}
|
||||||
values={applyTagsOptions}
|
values={applyTagsOptions}
|
||||||
helpTexts={[
|
helpTexts={[
|
||||||
'How to apply tags to the selected list',
|
translate('ApplyTagsHelpTexts1'),
|
||||||
'Add: Add the tags the existing list of tags',
|
translate('ApplyTagsHelpTexts2'),
|
||||||
'Remove: Remove the entered tags',
|
translate('ApplyTagsHelpTexts3'),
|
||||||
'Replace: Replace the tags with the entered tags (enter no tags to clear all tags)',
|
translate('ApplyTagsHelpTexts4'),
|
||||||
]}
|
]}
|
||||||
onChange={onApplyTagsChange}
|
onChange={onApplyTagsChange}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>Result</FormLabel>
|
<FormLabel>{translate('Result')}</FormLabel>
|
||||||
|
|
||||||
<div className={styles.result}>
|
<div className={styles.result}>
|
||||||
{seriesTags.map((id) => {
|
{importListsTags.map((id) => {
|
||||||
const tag = tagList.find((t) => t.id === id);
|
const tag = tagList.find((t) => t.id === id);
|
||||||
|
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
|
@ -127,7 +128,11 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
return (
|
return (
|
||||||
<Label
|
<Label
|
||||||
key={tag.id}
|
key={tag.id}
|
||||||
title={removeTag ? 'Removing tag' : 'Existing tag'}
|
title={
|
||||||
|
removeTag
|
||||||
|
? translate('RemovingTag')
|
||||||
|
: translate('ExistingTag')
|
||||||
|
}
|
||||||
kind={removeTag ? kinds.INVERSE : kinds.INFO}
|
kind={removeTag ? kinds.INVERSE : kinds.INFO}
|
||||||
size={sizes.LARGE}
|
size={sizes.LARGE}
|
||||||
>
|
>
|
||||||
|
@ -144,14 +149,14 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seriesTags.indexOf(id) > -1) {
|
if (importListsTags.indexOf(id) > -1) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Label
|
<Label
|
||||||
key={tag.id}
|
key={tag.id}
|
||||||
title={'Adding tag'}
|
title={translate('AddingTag')}
|
||||||
kind={kinds.SUCCESS}
|
kind={kinds.SUCCESS}
|
||||||
size={sizes.LARGE}
|
size={sizes.LARGE}
|
||||||
>
|
>
|
||||||
|
@ -165,10 +170,10 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button onPress={onModalClose}>Cancel</Button>
|
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
||||||
|
|
||||||
<Button kind={kinds.PRIMARY} onPress={onApplyPress}>
|
<Button kind={kinds.PRIMARY} onPress={onApplyPress}>
|
||||||
Apply
|
{translate('Apply')}
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|
|
@ -6,6 +6,7 @@ import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
||||||
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||||
import { icons } from 'Helpers/Props';
|
import { icons } from 'Helpers/Props';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
import IndexersConnector from './Indexers/IndexersConnector';
|
import IndexersConnector from './Indexers/IndexersConnector';
|
||||||
import ManageIndexersModal from './Indexers/Manage/ManageIndexersModal';
|
import ManageIndexersModal from './Indexers/Manage/ManageIndexersModal';
|
||||||
import IndexerOptionsConnector from './Options/IndexerOptionsConnector';
|
import IndexerOptionsConnector from './Options/IndexerOptionsConnector';
|
||||||
|
@ -84,7 +85,7 @@ class IndexerSettings extends Component {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PageToolbarButton
|
<PageToolbarButton
|
||||||
label="Manage Indexers"
|
label={translate('ManageIndexers')}
|
||||||
iconName={icons.MANAGE}
|
iconName={icons.MANAGE}
|
||||||
onPress={this.onManageIndexersPress}
|
onPress={this.onManageIndexersPress}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -27,9 +27,9 @@ interface ManageIndexersEditModalContentProps {
|
||||||
const NO_CHANGE = 'noChange';
|
const NO_CHANGE = 'noChange';
|
||||||
|
|
||||||
const enableOptions = [
|
const enableOptions = [
|
||||||
{ key: NO_CHANGE, value: 'No Change', disabled: true },
|
{ key: NO_CHANGE, value: translate('NoChange'), disabled: true },
|
||||||
{ key: 'enabled', value: 'Enabled' },
|
{ key: 'enabled', value: translate('Enabled') },
|
||||||
{ key: 'disabled', value: 'Disabled' },
|
{ key: 'disabled', value: translate('Disabled') },
|
||||||
];
|
];
|
||||||
|
|
||||||
function ManageIndexersEditModalContent(
|
function ManageIndexersEditModalContent(
|
||||||
|
@ -97,7 +97,7 @@ function ManageIndexersEditModalContent(
|
||||||
setPriority(value);
|
setPriority(value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.warn('EditIndexersModalContent Unknown Input');
|
console.warn(`EditIndexersModalContent Unknown Input: '${name}'`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
|
@ -111,7 +111,7 @@ function ManageIndexersEditModalContent(
|
||||||
|
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>{translate('EnableRss')}</FormLabel>
|
<FormLabel>{translate('EnableRSS')}</FormLabel>
|
||||||
|
|
||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.SELECT}
|
type={inputTypes.SELECT}
|
||||||
|
@ -162,13 +162,15 @@ function ManageIndexersEditModalContent(
|
||||||
|
|
||||||
<ModalFooter className={styles.modalFooter}>
|
<ModalFooter className={styles.modalFooter}>
|
||||||
<div className={styles.selected}>
|
<div className={styles.selected}>
|
||||||
{translate('{count} indexers selected', { count: selectedCount })}
|
{translate('CountIndexersSelected', {
|
||||||
|
count: selectedCount,
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
||||||
|
|
||||||
<Button onPress={save}>{translate('Apply Changes')}</Button>
|
<Button onPress={save}>{translate('ApplyChanges')}</Button>
|
||||||
</div>
|
</div>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React, { useCallback, useMemo, useState } from 'react';
|
import React, { useCallback, useMemo, useState } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { IndexerAppState } from 'App/State/SettingsAppState';
|
import { IndexerAppState } from 'App/State/SettingsAppState';
|
||||||
|
import Alert from 'Components/Alert';
|
||||||
import Button from 'Components/Link/Button';
|
import Button from 'Components/Link/Button';
|
||||||
import SpinnerButton from 'Components/Link/SpinnerButton';
|
import SpinnerButton from 'Components/Link/SpinnerButton';
|
||||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||||
|
@ -20,6 +21,7 @@ import {
|
||||||
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
||||||
import { SelectStateInputProps } from 'typings/props';
|
import { SelectStateInputProps } from 'typings/props';
|
||||||
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
||||||
import ManageIndexersEditModal from './Edit/ManageIndexersEditModal';
|
import ManageIndexersEditModal from './Edit/ManageIndexersEditModal';
|
||||||
import ManageIndexersModalRow from './ManageIndexersModalRow';
|
import ManageIndexersModalRow from './ManageIndexersModalRow';
|
||||||
|
@ -34,43 +36,43 @@ type OnSelectedChangeCallback = React.ComponentProps<
|
||||||
const COLUMNS = [
|
const COLUMNS = [
|
||||||
{
|
{
|
||||||
name: 'name',
|
name: 'name',
|
||||||
label: 'Name',
|
label: translate('Name'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'implementation',
|
name: 'implementation',
|
||||||
label: 'Implementation',
|
label: translate('Implementation'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'enableRss',
|
name: 'enableRss',
|
||||||
label: 'Enable RSS',
|
label: translate('EnableRSS'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'enableAutomaticSearch',
|
name: 'enableAutomaticSearch',
|
||||||
label: 'Enable Automatic Search',
|
label: translate('EnableAutomaticSearch'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'enableInteractiveSearch',
|
name: 'enableInteractiveSearch',
|
||||||
label: 'Enable Interactive Search',
|
label: translate('EnableInteractiveSearch'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'priority',
|
name: 'priority',
|
||||||
label: 'Priority',
|
label: translate('Priority'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'tags',
|
name: 'tags',
|
||||||
label: 'Tags',
|
label: translate('Tags'),
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
|
@ -189,17 +191,21 @@ function ManageIndexersModalContent(props: ManageIndexersModalContentProps) {
|
||||||
[items, setSelectState]
|
[items, setSelectState]
|
||||||
);
|
);
|
||||||
|
|
||||||
const errorMessage = getErrorMessage(error, 'Unable to load import lists.');
|
const errorMessage = getErrorMessage(error, 'Unable to load indexers.');
|
||||||
const anySelected = selectedCount > 0;
|
const anySelected = selectedCount > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalContent onModalClose={onModalClose}>
|
<ModalContent onModalClose={onModalClose}>
|
||||||
<ModalHeader>Manage Import Lists</ModalHeader>
|
<ModalHeader>{translate('ManageIndexers')}</ModalHeader>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
{isFetching ? <LoadingIndicator /> : null}
|
{isFetching ? <LoadingIndicator /> : null}
|
||||||
|
|
||||||
{error ? <div>{errorMessage}</div> : null}
|
{error ? <div>{errorMessage}</div> : null}
|
||||||
|
|
||||||
|
{isPopulated && !error && !items.length && (
|
||||||
|
<Alert kind={kinds.INFO}>{translate('NoIndexersFound')}</Alert>
|
||||||
|
)}
|
||||||
|
|
||||||
{isPopulated && !!items.length && !isFetching && !isFetching ? (
|
{isPopulated && !!items.length && !isFetching && !isFetching ? (
|
||||||
<Table
|
<Table
|
||||||
columns={COLUMNS}
|
columns={COLUMNS}
|
||||||
|
@ -234,7 +240,7 @@ function ManageIndexersModalContent(props: ManageIndexersModalContentProps) {
|
||||||
isDisabled={!anySelected}
|
isDisabled={!anySelected}
|
||||||
onPress={onDeletePress}
|
onPress={onDeletePress}
|
||||||
>
|
>
|
||||||
Delete
|
{translate('Delete')}
|
||||||
</SpinnerButton>
|
</SpinnerButton>
|
||||||
|
|
||||||
<SpinnerButton
|
<SpinnerButton
|
||||||
|
@ -242,7 +248,7 @@ function ManageIndexersModalContent(props: ManageIndexersModalContentProps) {
|
||||||
isDisabled={!anySelected}
|
isDisabled={!anySelected}
|
||||||
onPress={onEditPress}
|
onPress={onEditPress}
|
||||||
>
|
>
|
||||||
Edit
|
{translate('Edit')}
|
||||||
</SpinnerButton>
|
</SpinnerButton>
|
||||||
|
|
||||||
<SpinnerButton
|
<SpinnerButton
|
||||||
|
@ -250,11 +256,11 @@ function ManageIndexersModalContent(props: ManageIndexersModalContentProps) {
|
||||||
isDisabled={!anySelected}
|
isDisabled={!anySelected}
|
||||||
onPress={onTagsPress}
|
onPress={onTagsPress}
|
||||||
>
|
>
|
||||||
Set Tags
|
{translate('SetTags')}
|
||||||
</SpinnerButton>
|
</SpinnerButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button onPress={onModalClose}>Close</Button>
|
<Button onPress={onModalClose}>{translate('Close')}</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
|
|
||||||
<ManageIndexersEditModal
|
<ManageIndexersEditModal
|
||||||
|
@ -274,9 +280,11 @@ function ManageIndexersModalContent(props: ManageIndexersModalContentProps) {
|
||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
isOpen={isDeleteModalOpen}
|
isOpen={isDeleteModalOpen}
|
||||||
kind={kinds.DANGER}
|
kind={kinds.DANGER}
|
||||||
title="Delete Import List(s)"
|
title={translate('DeleteSelectedIndexers')}
|
||||||
message={`Are you sure you want to delete ${selectedIds.length} import list(s)?`}
|
message={translate('DeleteSelectedIndexersMessageText', {
|
||||||
confirmLabel="Delete"
|
count: selectedIds.length,
|
||||||
|
})}
|
||||||
|
confirmLabel={translate('Delete')}
|
||||||
onConfirm={onConfirmDelete}
|
onConfirm={onConfirmDelete}
|
||||||
onCancel={onDeleteModalClose}
|
onCancel={onDeleteModalClose}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
|
import Label from 'Components/Label';
|
||||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
||||||
import Column from 'Components/Table/Column';
|
import Column from 'Components/Table/Column';
|
||||||
import TableRow from 'Components/Table/TableRow';
|
import TableRow from 'Components/Table/TableRow';
|
||||||
import TagListConnector from 'Components/TagListConnector';
|
import TagListConnector from 'Components/TagListConnector';
|
||||||
|
import { kinds } from 'Helpers/Props';
|
||||||
import { SelectStateInputProps } from 'typings/props';
|
import { SelectStateInputProps } from 'typings/props';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
import styles from './ManageIndexersModalRow.css';
|
import styles from './ManageIndexersModalRow.css';
|
||||||
|
|
||||||
interface ManageIndexersModalRowProps {
|
interface ManageIndexersModalRowProps {
|
||||||
|
@ -59,15 +62,30 @@ function ManageIndexersModalRow(props: ManageIndexersModalRowProps) {
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
<TableRowCell className={styles.enableRss}>
|
<TableRowCell className={styles.enableRss}>
|
||||||
{enableRss ? 'Yes' : 'No'}
|
<Label
|
||||||
|
kind={enableRss ? kinds.SUCCESS : kinds.DISABLED}
|
||||||
|
outline={!enableRss}
|
||||||
|
>
|
||||||
|
{enableRss ? translate('Yes') : translate('No')}
|
||||||
|
</Label>
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
<TableRowCell className={styles.enableAutomaticSearch}>
|
<TableRowCell className={styles.enableAutomaticSearch}>
|
||||||
{enableAutomaticSearch ? 'Yes' : 'No'}
|
<Label
|
||||||
|
kind={enableAutomaticSearch ? kinds.SUCCESS : kinds.DISABLED}
|
||||||
|
outline={!enableAutomaticSearch}
|
||||||
|
>
|
||||||
|
{enableAutomaticSearch ? translate('Yes') : translate('No')}
|
||||||
|
</Label>
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
<TableRowCell className={styles.enableInteractiveSearch}>
|
<TableRowCell className={styles.enableInteractiveSearch}>
|
||||||
{enableInteractiveSearch ? 'Yes' : 'No'}
|
<Label
|
||||||
|
kind={enableInteractiveSearch ? kinds.SUCCESS : kinds.DISABLED}
|
||||||
|
outline={!enableInteractiveSearch}
|
||||||
|
>
|
||||||
|
{enableInteractiveSearch ? translate('Yes') : translate('No')}
|
||||||
|
</Label>
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
<TableRowCell className={styles.priority}>{priority}</TableRowCell>
|
<TableRowCell className={styles.priority}>{priority}</TableRowCell>
|
||||||
|
|
|
@ -17,6 +17,7 @@ import ModalHeader from 'Components/Modal/ModalHeader';
|
||||||
import { inputTypes, kinds, sizes } from 'Helpers/Props';
|
import { inputTypes, kinds, sizes } from 'Helpers/Props';
|
||||||
import createTagsSelector from 'Store/Selectors/createTagsSelector';
|
import createTagsSelector from 'Store/Selectors/createTagsSelector';
|
||||||
import Indexer from 'typings/Indexer';
|
import Indexer from 'typings/Indexer';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
import styles from './TagsModalContent.css';
|
import styles from './TagsModalContent.css';
|
||||||
|
|
||||||
interface TagsModalContentProps {
|
interface TagsModalContentProps {
|
||||||
|
@ -36,7 +37,7 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
const [tags, setTags] = useState<number[]>([]);
|
const [tags, setTags] = useState<number[]>([]);
|
||||||
const [applyTags, setApplyTags] = useState('add');
|
const [applyTags, setApplyTags] = useState('add');
|
||||||
|
|
||||||
const seriesTags = useMemo(() => {
|
const indexersTags = useMemo(() => {
|
||||||
const tags = ids.reduce((acc: number[], id) => {
|
const tags = ids.reduce((acc: number[], id) => {
|
||||||
const s = allIndexers.items.find((s: Indexer) => s.id === id);
|
const s = allIndexers.items.find((s: Indexer) => s.id === id);
|
||||||
|
|
||||||
|
@ -69,19 +70,19 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
}, [tags, applyTags, onApplyTagsPress]);
|
}, [tags, applyTags, onApplyTagsPress]);
|
||||||
|
|
||||||
const applyTagsOptions = [
|
const applyTagsOptions = [
|
||||||
{ key: 'add', value: 'Add' },
|
{ key: 'add', value: translate('Add') },
|
||||||
{ key: 'remove', value: 'Remove' },
|
{ key: 'remove', value: translate('Remove') },
|
||||||
{ key: 'replace', value: 'Replace' },
|
{ key: 'replace', value: translate('Replace') },
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalContent onModalClose={onModalClose}>
|
<ModalContent onModalClose={onModalClose}>
|
||||||
<ModalHeader>Tags</ModalHeader>
|
<ModalHeader>{translate('Tags')}</ModalHeader>
|
||||||
|
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<Form>
|
<Form>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>Tags</FormLabel>
|
<FormLabel>{translate('Tags')}</FormLabel>
|
||||||
|
|
||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.TAG}
|
type={inputTypes.TAG}
|
||||||
|
@ -92,7 +93,7 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>Apply Tags</FormLabel>
|
<FormLabel>{translate('ApplyTags')}</FormLabel>
|
||||||
|
|
||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.SELECT}
|
type={inputTypes.SELECT}
|
||||||
|
@ -100,20 +101,20 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
value={applyTags}
|
value={applyTags}
|
||||||
values={applyTagsOptions}
|
values={applyTagsOptions}
|
||||||
helpTexts={[
|
helpTexts={[
|
||||||
'How to apply tags to the selected indexer(s)',
|
translate('ApplyTagsHelpTexts1'),
|
||||||
'Add: Add the tags the existing list of tags',
|
translate('ApplyTagsHelpTexts2'),
|
||||||
'Remove: Remove the entered tags',
|
translate('ApplyTagsHelpTexts3'),
|
||||||
'Replace: Replace the tags with the entered tags (enter no tags to clear all tags)',
|
translate('ApplyTagsHelpTexts4'),
|
||||||
]}
|
]}
|
||||||
onChange={onApplyTagsChange}
|
onChange={onApplyTagsChange}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>Result</FormLabel>
|
<FormLabel>{translate('Result')}</FormLabel>
|
||||||
|
|
||||||
<div className={styles.result}>
|
<div className={styles.result}>
|
||||||
{seriesTags.map((id) => {
|
{indexersTags.map((id) => {
|
||||||
const tag = tagList.find((t) => t.id === id);
|
const tag = tagList.find((t) => t.id === id);
|
||||||
|
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
|
@ -127,7 +128,11 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
return (
|
return (
|
||||||
<Label
|
<Label
|
||||||
key={tag.id}
|
key={tag.id}
|
||||||
title={removeTag ? 'Removing tag' : 'Existing tag'}
|
title={
|
||||||
|
removeTag
|
||||||
|
? translate('RemovingTag')
|
||||||
|
: translate('ExistingTag')
|
||||||
|
}
|
||||||
kind={removeTag ? kinds.INVERSE : kinds.INFO}
|
kind={removeTag ? kinds.INVERSE : kinds.INFO}
|
||||||
size={sizes.LARGE}
|
size={sizes.LARGE}
|
||||||
>
|
>
|
||||||
|
@ -144,14 +149,14 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seriesTags.indexOf(id) > -1) {
|
if (indexersTags.indexOf(id) > -1) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Label
|
<Label
|
||||||
key={tag.id}
|
key={tag.id}
|
||||||
title={'Adding tag'}
|
title={translate('AddingTag')}
|
||||||
kind={kinds.SUCCESS}
|
kind={kinds.SUCCESS}
|
||||||
size={sizes.LARGE}
|
size={sizes.LARGE}
|
||||||
>
|
>
|
||||||
|
@ -165,10 +170,10 @@ function TagsModalContent(props: TagsModalContentProps) {
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button onPress={onModalClose}>Cancel</Button>
|
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
||||||
|
|
||||||
<Button kind={kinds.PRIMARY} onPress={onApplyPress}>
|
<Button kind={kinds.PRIMARY} onPress={onApplyPress}>
|
||||||
Apply
|
{translate('Apply')}
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|
|
@ -31,9 +31,8 @@ export const DELETE_DOWNLOAD_CLIENT = 'settings/downloadClients/deleteDownloadCl
|
||||||
export const TEST_DOWNLOAD_CLIENT = 'settings/downloadClients/testDownloadClient';
|
export const TEST_DOWNLOAD_CLIENT = 'settings/downloadClients/testDownloadClient';
|
||||||
export const CANCEL_TEST_DOWNLOAD_CLIENT = 'settings/downloadClients/cancelTestDownloadClient';
|
export const CANCEL_TEST_DOWNLOAD_CLIENT = 'settings/downloadClients/cancelTestDownloadClient';
|
||||||
export const TEST_ALL_DOWNLOAD_CLIENTS = 'settings/downloadClients/testAllDownloadClients';
|
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_EDIT_DOWNLOAD_CLIENTS = 'settings/downloadClients/bulkEditDownloadClients';
|
||||||
|
export const BULK_DELETE_DOWNLOAD_CLIENTS = 'settings/downloadClients/bulkDeleteDownloadClients';
|
||||||
|
|
||||||
//
|
//
|
||||||
// Action Creators
|
// Action Creators
|
||||||
|
@ -48,9 +47,8 @@ export const deleteDownloadClient = createThunk(DELETE_DOWNLOAD_CLIENT);
|
||||||
export const testDownloadClient = createThunk(TEST_DOWNLOAD_CLIENT);
|
export const testDownloadClient = createThunk(TEST_DOWNLOAD_CLIENT);
|
||||||
export const cancelTestDownloadClient = createThunk(CANCEL_TEST_DOWNLOAD_CLIENT);
|
export const cancelTestDownloadClient = createThunk(CANCEL_TEST_DOWNLOAD_CLIENT);
|
||||||
export const testAllDownloadClients = createThunk(TEST_ALL_DOWNLOAD_CLIENTS);
|
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 bulkEditDownloadClients = createThunk(BULK_EDIT_DOWNLOAD_CLIENTS);
|
||||||
|
export const bulkDeleteDownloadClients = createThunk(BULK_DELETE_DOWNLOAD_CLIENTS);
|
||||||
|
|
||||||
export const setDownloadClientValue = createAction(SET_DOWNLOAD_CLIENT_VALUE, (payload) => {
|
export const setDownloadClientValue = createAction(SET_DOWNLOAD_CLIENT_VALUE, (payload) => {
|
||||||
return {
|
return {
|
||||||
|
@ -106,8 +104,8 @@ export default {
|
||||||
[TEST_DOWNLOAD_CLIENT]: createTestProviderHandler(section, '/downloadclient'),
|
[TEST_DOWNLOAD_CLIENT]: createTestProviderHandler(section, '/downloadclient'),
|
||||||
[CANCEL_TEST_DOWNLOAD_CLIENT]: createCancelTestProviderHandler(section),
|
[CANCEL_TEST_DOWNLOAD_CLIENT]: createCancelTestProviderHandler(section),
|
||||||
[TEST_ALL_DOWNLOAD_CLIENTS]: createTestAllProvidersHandler(section, '/downloadclient'),
|
[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')
|
||||||
},
|
},
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -31,9 +31,8 @@ export const DELETE_IMPORT_LIST = 'settings/importlists/deleteImportList';
|
||||||
export const TEST_IMPORT_LIST = 'settings/importlists/testImportList';
|
export const TEST_IMPORT_LIST = 'settings/importlists/testImportList';
|
||||||
export const CANCEL_TEST_IMPORT_LIST = 'settings/importlists/cancelTestImportList';
|
export const CANCEL_TEST_IMPORT_LIST = 'settings/importlists/cancelTestImportList';
|
||||||
export const TEST_ALL_IMPORT_LISTS = 'settings/importlists/testAllImportLists';
|
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_EDIT_IMPORT_LISTS = 'settings/importlists/bulkEditImportLists';
|
||||||
|
export const BULK_DELETE_IMPORT_LISTS = 'settings/importlists/bulkDeleteImportLists';
|
||||||
|
|
||||||
//
|
//
|
||||||
// Action Creators
|
// Action Creators
|
||||||
|
@ -48,9 +47,8 @@ export const deleteImportList = createThunk(DELETE_IMPORT_LIST);
|
||||||
export const testImportList = createThunk(TEST_IMPORT_LIST);
|
export const testImportList = createThunk(TEST_IMPORT_LIST);
|
||||||
export const cancelTestImportList = createThunk(CANCEL_TEST_IMPORT_LIST);
|
export const cancelTestImportList = createThunk(CANCEL_TEST_IMPORT_LIST);
|
||||||
export const testAllImportLists = createThunk(TEST_ALL_IMPORT_LISTS);
|
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 bulkEditImportLists = createThunk(BULK_EDIT_IMPORT_LISTS);
|
||||||
|
export const bulkDeleteImportLists = createThunk(BULK_DELETE_IMPORT_LISTS);
|
||||||
|
|
||||||
export const setImportListValue = createAction(SET_IMPORT_LIST_VALUE, (payload) => {
|
export const setImportListValue = createAction(SET_IMPORT_LIST_VALUE, (payload) => {
|
||||||
return {
|
return {
|
||||||
|
@ -105,8 +103,8 @@ export default {
|
||||||
[TEST_IMPORT_LIST]: createTestProviderHandler(section, '/importlist'),
|
[TEST_IMPORT_LIST]: createTestProviderHandler(section, '/importlist'),
|
||||||
[CANCEL_TEST_IMPORT_LIST]: createCancelTestProviderHandler(section),
|
[CANCEL_TEST_IMPORT_LIST]: createCancelTestProviderHandler(section),
|
||||||
[TEST_ALL_IMPORT_LISTS]: createTestAllProvidersHandler(section, '/importlist'),
|
[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')
|
||||||
},
|
},
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import { createAction } from 'redux-actions';
|
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 createFetchHandler from 'Store/Actions/Creators/createFetchHandler';
|
||||||
import createFetchSchemaHandler from 'Store/Actions/Creators/createFetchSchemaHandler';
|
import createFetchSchemaHandler from 'Store/Actions/Creators/createFetchSchemaHandler';
|
||||||
import createRemoveItemHandler from 'Store/Actions/Creators/createRemoveItemHandler';
|
import createRemoveItemHandler from 'Store/Actions/Creators/createRemoveItemHandler';
|
||||||
|
@ -11,8 +13,6 @@ import { createThunk } from 'Store/thunks';
|
||||||
import getSectionState from 'Utilities/State/getSectionState';
|
import getSectionState from 'Utilities/State/getSectionState';
|
||||||
import selectProviderSchema from 'Utilities/State/selectProviderSchema';
|
import selectProviderSchema from 'Utilities/State/selectProviderSchema';
|
||||||
import updateSectionState from 'Utilities/State/updateSectionState';
|
import updateSectionState from 'Utilities/State/updateSectionState';
|
||||||
import createBulkEditItemHandler from '../Creators/createBulkEditItemHandler';
|
|
||||||
import createBulkRemoveItemHandler from '../Creators/createBulkRemoveItemHandler';
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Variables
|
// Variables
|
||||||
|
@ -34,9 +34,8 @@ export const DELETE_INDEXER = 'settings/indexers/deleteIndexer';
|
||||||
export const TEST_INDEXER = 'settings/indexers/testIndexer';
|
export const TEST_INDEXER = 'settings/indexers/testIndexer';
|
||||||
export const CANCEL_TEST_INDEXER = 'settings/indexers/cancelTestIndexer';
|
export const CANCEL_TEST_INDEXER = 'settings/indexers/cancelTestIndexer';
|
||||||
export const TEST_ALL_INDEXERS = 'settings/indexers/testAllIndexers';
|
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_EDIT_INDEXERS = 'settings/indexers/bulkEditIndexers';
|
||||||
|
export const BULK_DELETE_INDEXERS = 'settings/indexers/bulkDeleteIndexers';
|
||||||
|
|
||||||
//
|
//
|
||||||
// Action Creators
|
// Action Creators
|
||||||
|
@ -52,9 +51,8 @@ export const deleteIndexer = createThunk(DELETE_INDEXER);
|
||||||
export const testIndexer = createThunk(TEST_INDEXER);
|
export const testIndexer = createThunk(TEST_INDEXER);
|
||||||
export const cancelTestIndexer = createThunk(CANCEL_TEST_INDEXER);
|
export const cancelTestIndexer = createThunk(CANCEL_TEST_INDEXER);
|
||||||
export const testAllIndexers = createThunk(TEST_ALL_INDEXERS);
|
export const testAllIndexers = createThunk(TEST_ALL_INDEXERS);
|
||||||
|
|
||||||
export const bulkDeleteIndexers = createThunk(BULK_DELETE_INDEXERS);
|
|
||||||
export const bulkEditIndexers = createThunk(BULK_EDIT_INDEXERS);
|
export const bulkEditIndexers = createThunk(BULK_EDIT_INDEXERS);
|
||||||
|
export const bulkDeleteIndexers = createThunk(BULK_DELETE_INDEXERS);
|
||||||
|
|
||||||
export const setIndexerValue = createAction(SET_INDEXER_VALUE, (payload) => {
|
export const setIndexerValue = createAction(SET_INDEXER_VALUE, (payload) => {
|
||||||
return {
|
return {
|
||||||
|
@ -110,9 +108,8 @@ export default {
|
||||||
[TEST_INDEXER]: createTestProviderHandler(section, '/indexer'),
|
[TEST_INDEXER]: createTestProviderHandler(section, '/indexer'),
|
||||||
[CANCEL_TEST_INDEXER]: createCancelTestProviderHandler(section),
|
[CANCEL_TEST_INDEXER]: createCancelTestProviderHandler(section),
|
||||||
[TEST_ALL_INDEXERS]: createTestAllProvidersHandler(section, '/indexer'),
|
[TEST_ALL_INDEXERS]: createTestAllProvidersHandler(section, '/indexer'),
|
||||||
|
[BULK_EDIT_INDEXERS]: createBulkEditItemHandler(section, '/indexer/bulk'),
|
||||||
[BULK_DELETE_INDEXERS]: createBulkRemoveItemHandler(section, '/indexer/bulk'),
|
[BULK_DELETE_INDEXERS]: createBulkRemoveItemHandler(section, '/indexer/bulk')
|
||||||
[BULK_EDIT_INDEXERS]: createBulkEditItemHandler(section, '/indexer/bulk')
|
|
||||||
},
|
},
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,40 +1,63 @@
|
||||||
{
|
{
|
||||||
|
"Add": "Add",
|
||||||
"Added": "Added",
|
"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",
|
"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",
|
"AppDataLocationHealthCheckMessage": "Updating will not be possible to prevent deleting AppData on Update",
|
||||||
|
"Apply": "Apply",
|
||||||
"ApplyChanges": "Apply Changes",
|
"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",
|
"AutomaticAdd": "Automatic Add",
|
||||||
"BlocklistRelease": "Blocklist Release",
|
"BlocklistRelease": "Blocklist Release",
|
||||||
"BlocklistReleaseHelpText": "Prevents Sonarr from automatically grabbing this release again",
|
"BlocklistReleaseHelpText": "Prevents Sonarr from automatically grabbing this release again",
|
||||||
"BlocklistReleases": "Blocklist Releases",
|
"BlocklistReleases": "Blocklist Releases",
|
||||||
"Browser Reload Required": "Browser Reload Required",
|
"Browser Reload Required": "Browser Reload Required",
|
||||||
|
"Cancel": "Cancel",
|
||||||
"CloneCondition": "Clone Condition",
|
"CloneCondition": "Clone Condition",
|
||||||
"CloneCustomFormat": "Clone Custom Format",
|
"CloneCustomFormat": "Clone Custom Format",
|
||||||
"Close": "Close",
|
"Close": "Close",
|
||||||
|
"CountDownloadClientsSelected": "{count} download client(s) selected",
|
||||||
|
"CountImportListsSelected": "{count} import list(s) selected",
|
||||||
|
"CountIndexersSelected": "{count} indexer(s) selected",
|
||||||
"CountSeasons": "{count} seasons",
|
"CountSeasons": "{count} seasons",
|
||||||
"Delete": "Delete",
|
"Delete": "Delete",
|
||||||
"DeleteCondition": "Delete Condition",
|
"DeleteCondition": "Delete Condition",
|
||||||
"DeleteConditionMessageText": "Are you sure you want to delete the condition '{0}'?",
|
"DeleteConditionMessageText": "Are you sure you want to delete the condition '{0}'?",
|
||||||
"DeleteCustomFormat": "Delete Custom Format",
|
"DeleteCustomFormat": "Delete Custom Format",
|
||||||
"DeleteCustomFormatMessageText": "Are you sure you want to delete the custom format '{0}'?",
|
"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",
|
"DownloadClientCheckNoneAvailableHealthCheckMessage": "No download client is available",
|
||||||
"DownloadClientCheckUnableToCommunicateWithHealthCheckMessage": "Unable to communicate with {0}.",
|
"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.",
|
"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.",
|
"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",
|
"DownloadClientStatusAllClientHealthCheckMessage": "All download clients are unavailable due to failures",
|
||||||
"DownloadClientStatusSingleClientHealthCheckMessage": "Download clients unavailable due to failures: {0}",
|
"DownloadClientStatusSingleClientHealthCheckMessage": "Download clients unavailable due to failures: {0}",
|
||||||
|
"Edit": "Edit",
|
||||||
"EditSelectedDownloadClients": "Edit Selected Download Clients",
|
"EditSelectedDownloadClients": "Edit Selected Download Clients",
|
||||||
"EditSelectedImportLists": "Edit Selected Import Lists",
|
"EditSelectedImportLists": "Edit Selected Import Lists",
|
||||||
"EditSelectedIndexers": "Edit Selected Indexers",
|
"EditSelectedIndexers": "Edit Selected Indexers",
|
||||||
"EditSeries": "Edit Series",
|
"EditSeries": "Edit Series",
|
||||||
"EnableAutomaticSearch": "Enable Automatic Search",
|
"EnableAutomaticSearch": "Enable Automatic Search",
|
||||||
"EnableInteractiveSearch": "Enable Interactive Search",
|
"EnableInteractiveSearch": "Enable Interactive Search",
|
||||||
"EnableRss": "Enable Rss",
|
"EnableRSS": "Enable RSS",
|
||||||
"Enabled": "Enabled",
|
"Enabled": "Enabled",
|
||||||
"Ended": "Ended",
|
"Ended": "Ended",
|
||||||
|
"ExistingTag": "Existing tag",
|
||||||
"ExportCustomFormat": "Export Custom Format",
|
"ExportCustomFormat": "Export Custom Format",
|
||||||
"HiddenClickToShow": "Hidden, click to show",
|
"HiddenClickToShow": "Hidden, click to show",
|
||||||
"HideAdvanced": "Hide Advanced",
|
"HideAdvanced": "Hide Advanced",
|
||||||
|
"Implementation": "Implementation",
|
||||||
"ImportListRootFolderMissingRootHealthCheckMessage": "Missing root folder for import list(s): {0}",
|
"ImportListRootFolderMissingRootHealthCheckMessage": "Missing root folder for import list(s): {0}",
|
||||||
"ImportListRootFolderMultipleMissingRootsHealthCheckMessage": "Multiple root folders are missing for import lists: {0}",
|
"ImportListRootFolderMultipleMissingRootsHealthCheckMessage": "Multiple root folders are missing for import lists: {0}",
|
||||||
"ImportListStatusAllUnavailableHealthCheckMessage": "All lists are unavailable due to failures",
|
"ImportListStatusAllUnavailableHealthCheckMessage": "All lists are unavailable due to failures",
|
||||||
|
@ -54,11 +77,22 @@
|
||||||
"IndexerStatusUnavailableHealthCheckMessage": "Indexers unavailable due to failures: {0}",
|
"IndexerStatusUnavailableHealthCheckMessage": "Indexers unavailable due to failures: {0}",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language that Sonarr will use for UI": "Language that Sonarr will use for UI",
|
"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",
|
"Monitored": "Monitored",
|
||||||
"MountHealthCheckMessage": "Mount containing a series path is mounted read-only: ",
|
"MountHealthCheckMessage": "Mount containing a series path is mounted read-only: ",
|
||||||
|
"Name": "Name",
|
||||||
"Negated": "Negated",
|
"Negated": "Negated",
|
||||||
"Network": "Network",
|
"Network": "Network",
|
||||||
"NextAiring": "Next Airing",
|
"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",
|
"NoSeasons": "No seasons",
|
||||||
"OneSeason": "1 season",
|
"OneSeason": "1 season",
|
||||||
"OriginalLanguage": "Original Language",
|
"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.",
|
"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.",
|
"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",
|
"Remove": "Remove",
|
||||||
|
"RemoveCompleted": "Remove Completed",
|
||||||
"RemoveCompletedDownloads": "Remove Completed Downloads",
|
"RemoveCompletedDownloads": "Remove Completed Downloads",
|
||||||
|
"RemoveFailed": "Remove Failed",
|
||||||
"RemoveFailedDownloads": "Remove Failed Downloads",
|
"RemoveFailedDownloads": "Remove Failed Downloads",
|
||||||
"RemoveFromDownloadClient": "Remove From Download Client",
|
"RemoveFromDownloadClient": "Remove From Download Client",
|
||||||
"RemoveFromDownloadClientHelpTextWarning": "Removing will remove the download and the file(s) from the 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?",
|
"RemoveSelectedItemsQueueMessageText": "Are you sure you want to remove {0} items from the queue?",
|
||||||
"RemovedSeriesMultipleRemovedHealthCheckMessage": "Series {0} were removed from TheTVDB",
|
"RemovedSeriesMultipleRemovedHealthCheckMessage": "Series {0} were removed from TheTVDB",
|
||||||
"RemovedSeriesSingleRemovedHealthCheckMessage": "Series {0} was removed from TheTVDB",
|
"RemovedSeriesSingleRemovedHealthCheckMessage": "Series {0} was removed from TheTVDB",
|
||||||
|
"RemovingTag": "Removing tag",
|
||||||
|
"Replace": "Replace",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
|
"Result": "Result",
|
||||||
"RootFolder": "Root Folder",
|
"RootFolder": "Root Folder",
|
||||||
"RootFolderMissingHealthCheckMessage": "Missing root folder: {0}",
|
"RootFolderMissingHealthCheckMessage": "Missing root folder: {0}",
|
||||||
"RootFolderMultipleMissingHealthCheckMessage": "Multiple root folders are missing: {0}",
|
"RootFolderMultipleMissingHealthCheckMessage": "Multiple root folders are missing: {0}",
|
||||||
"SearchForMonitoredEpisodes": "Search for monitored episodes",
|
"SearchForMonitoredEpisodes": "Search for monitored episodes",
|
||||||
|
"SetTags": "Set Tags",
|
||||||
"ShowAdvanced": "Show Advanced",
|
"ShowAdvanced": "Show Advanced",
|
||||||
"ShownClickToHide": "Shown, click to hide",
|
"ShownClickToHide": "Shown, click to hide",
|
||||||
"SizeOnDisk": "Size on disk",
|
"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",
|
"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",
|
"UI Language": "UI Language",
|
||||||
"Unmonitored": "Unmonitored",
|
"Unmonitored": "Unmonitored",
|
||||||
"UpdateAvailableHealthCheckMessage": "New update is available",
|
"UpdateAvailableHealthCheckMessage": "New update is available",
|
||||||
"UpdateStartupNotWritableHealthCheckMessage": "Cannot install update because startup folder '{0}' is not writable by the user '{1}'.",
|
"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.",
|
"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"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue