Add translations to frontend/InteractiveImport
This commit is contained in:
parent
16d95ea6bf
commit
060b66aa39
|
@ -71,7 +71,7 @@ interface SelectEpisodeModalContentProps {
|
|||
isAnime: boolean;
|
||||
sortKey?: string;
|
||||
sortDirection?: string;
|
||||
modalTitle?: string;
|
||||
modalTitle: string;
|
||||
onEpisodesSelect(selectedEpisodes: SelectedEpisode[]): unknown;
|
||||
onModalClose(): unknown;
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ function SelectEpisodeModalContent(props: SelectEpisodeModalContentProps) {
|
|||
const dispatch = useDispatch();
|
||||
|
||||
const filterEpisodeNumber = parseInt(filter);
|
||||
const errorMessage = getErrorMessage(error, 'Unable to load episodes');
|
||||
const errorMessage = getErrorMessage(error, translate('EpisodesLoadError'));
|
||||
const selectedCount = selectedIds.length;
|
||||
const selectedEpisodesCount = getSelectedIds(selectedState).length;
|
||||
const selectionIsValid =
|
||||
|
@ -197,13 +197,15 @@ function SelectEpisodeModalContent(props: SelectEpisodeModalContentProps) {
|
|||
if (!details) {
|
||||
details =
|
||||
selectedCount > 1
|
||||
? `${selectedCount} selected files`
|
||||
: `${selectedCount} selected file`;
|
||||
? translate('CountSelectedFiles', { selectedCount })
|
||||
: translate('CountSelectedFile', { selectedCount });
|
||||
}
|
||||
|
||||
return (
|
||||
<ModalContent onModalClose={onModalClose}>
|
||||
<ModalHeader>{modalTitle} - Select Episode(s)</ModalHeader>
|
||||
<ModalHeader>
|
||||
{translate('SelectEpisodesModalTitle', { modalTitle })}
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody
|
||||
className={styles.modalBody}
|
||||
|
@ -211,7 +213,7 @@ function SelectEpisodeModalContent(props: SelectEpisodeModalContentProps) {
|
|||
>
|
||||
<TextInput
|
||||
className={styles.filterInput}
|
||||
placeholder="Filter episodes by title or number"
|
||||
placeholder={translate('FilterEpisodesPlaceholder')}
|
||||
name="filter"
|
||||
value={filter}
|
||||
autoFocus={true}
|
||||
|
@ -256,7 +258,7 @@ function SelectEpisodeModalContent(props: SelectEpisodeModalContentProps) {
|
|||
) : null}
|
||||
|
||||
{isPopulated && !items.length
|
||||
? 'No episodes were found for the selected season'
|
||||
? translate('NoEpisodesFoundForSelectedSeason')
|
||||
: null}
|
||||
</Scroller>
|
||||
</ModalBody>
|
||||
|
@ -265,14 +267,14 @@ function SelectEpisodeModalContent(props: SelectEpisodeModalContentProps) {
|
|||
<div className={styles.details}>{details}</div>
|
||||
|
||||
<div className={styles.buttons}>
|
||||
<Button onPress={onModalClose}>Cancel</Button>
|
||||
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
||||
|
||||
<Button
|
||||
kind={kinds.SUCCESS}
|
||||
isDisabled={!selectionIsValid}
|
||||
onPress={onEpisodesSelectWrapper}
|
||||
>
|
||||
Select Episodes
|
||||
{translate('SelectEpisodes')}
|
||||
</Button>
|
||||
</div>
|
||||
</ModalFooter>
|
||||
|
|
|
@ -100,7 +100,7 @@ function InteractiveImportSelectFolderModalContent(
|
|||
return (
|
||||
<ModalContent onModalClose={onModalClose}>
|
||||
<ModalHeader>
|
||||
{modalTitle} - {translate('SelectFolder')}
|
||||
{translate('SelectFolderModalTitle', { modalTitle })}
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody>
|
||||
|
|
|
@ -5,6 +5,7 @@ import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellCo
|
|||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import TableRowButton from 'Components/Table/TableRowButton';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './RecentFolderRow.css';
|
||||
|
||||
class RecentFolderRow extends Component {
|
||||
|
@ -44,7 +45,7 @@ class RecentFolderRow extends Component {
|
|||
|
||||
<TableRowCell className={styles.actions}>
|
||||
<IconButton
|
||||
title="Remove"
|
||||
title={translate('Remove')}
|
||||
name={icons.REMOVE}
|
||||
onPress={this.onRemovePress}
|
||||
/>
|
||||
|
|
|
@ -147,9 +147,19 @@ const COLUMNS = [
|
|||
];
|
||||
|
||||
const importModeOptions = [
|
||||
{ key: 'chooseImportMode', value: 'Choose Import Mode', disabled: true },
|
||||
{ key: 'move', value: 'Move Files' },
|
||||
{ key: 'copy', value: 'Hardlink/Copy Files' },
|
||||
{
|
||||
key: 'chooseImportMode',
|
||||
value: () => translate('ChooseImportMode'),
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: 'move',
|
||||
value: () => translate('MoveFiles'),
|
||||
},
|
||||
{
|
||||
key: 'copy',
|
||||
value: () => translate('HardlinkCopyFiles'),
|
||||
},
|
||||
];
|
||||
|
||||
function isSameEpisodeFile(
|
||||
|
@ -260,12 +270,31 @@ function InteractiveImportModalContent(
|
|||
useState<string | null>(null);
|
||||
const [selectState, setSelectState] = useSelectState();
|
||||
const [bulkSelectOptions, setBulkSelectOptions] = useState([
|
||||
{ key: 'select', value: 'Select...', disabled: true },
|
||||
{ key: 'season', value: 'Select Season' },
|
||||
{ key: 'episode', value: 'Select Episode(s)' },
|
||||
{ key: 'quality', value: 'Select Quality' },
|
||||
{ key: 'releaseGroup', value: 'Select Release Group' },
|
||||
{ key: 'language', value: 'Select Language' },
|
||||
{
|
||||
key: 'select',
|
||||
value: translate('SelectDropdown'),
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: 'season',
|
||||
value: translate('SelectSeason'),
|
||||
},
|
||||
{
|
||||
key: 'episode',
|
||||
value: translate('SelectEpisodes'),
|
||||
},
|
||||
{
|
||||
key: 'quality',
|
||||
value: translate('SelectQuality'),
|
||||
},
|
||||
{
|
||||
key: 'releaseGroup',
|
||||
value: translate('SelectReleaseGroup'),
|
||||
},
|
||||
{
|
||||
key: 'language',
|
||||
value: translate('SelectLanguage'),
|
||||
},
|
||||
]);
|
||||
const { allSelected, allUnselected, selectedState } = selectState;
|
||||
const previousIsDeleting = usePrevious(isDeleting);
|
||||
|
@ -296,7 +325,7 @@ function InteractiveImportModalContent(
|
|||
|
||||
newBulkSelectOptions.splice(1, 0, {
|
||||
key: 'series',
|
||||
value: 'Select Series',
|
||||
value: translate('SelectSeries'),
|
||||
});
|
||||
|
||||
setBulkSelectOptions(newBulkSelectOptions);
|
||||
|
@ -410,7 +439,9 @@ function InteractiveImportModalContent(
|
|||
const files: InteractiveImportCommandOptions[] = [];
|
||||
|
||||
if (finalImportMode === 'chooseImportMode') {
|
||||
setInteractiveImportErrorMessage('An import mode must be selected');
|
||||
setInteractiveImportErrorMessage(
|
||||
translate('InteractiveImportNoImportMode')
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -431,35 +462,35 @@ function InteractiveImportModalContent(
|
|||
|
||||
if (!series) {
|
||||
setInteractiveImportErrorMessage(
|
||||
'Series must be chosen for each selected file'
|
||||
translate('InteractiveImportNoSeries')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNaN(seasonNumber)) {
|
||||
setInteractiveImportErrorMessage(
|
||||
'Season must be chosen for each selected file'
|
||||
translate('InteractiveImportNoSeason')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!episodes || !episodes.length) {
|
||||
setInteractiveImportErrorMessage(
|
||||
'One or more episodes must be chosen for each selected file'
|
||||
translate('InteractiveImportNoEpisode')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!quality) {
|
||||
setInteractiveImportErrorMessage(
|
||||
'Quality must be chosen for each selected file'
|
||||
translate('InteractiveImportNoQuality')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!languages) {
|
||||
setInteractiveImportErrorMessage(
|
||||
'Language(s) must be chosen for each selected file'
|
||||
translate('InteractiveImportNoLanguage')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -699,7 +730,7 @@ function InteractiveImportModalContent(
|
|||
|
||||
const errorMessage = getErrorMessage(
|
||||
error,
|
||||
'Unable to load manual import items'
|
||||
translate('InteractiveImportLoadError')
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -716,7 +747,9 @@ function InteractiveImportModalContent(
|
|||
<Icon name={icons.FILTER} size={22} />
|
||||
|
||||
<div className={styles.filterText}>
|
||||
{filterExistingFiles ? 'Unmapped Files Only' : 'All Files'}
|
||||
{filterExistingFiles
|
||||
? translate('UnmappedFilesOnly')
|
||||
: translate('AllFiles')}
|
||||
</div>
|
||||
</MenuButton>
|
||||
|
||||
|
@ -726,7 +759,7 @@ function InteractiveImportModalContent(
|
|||
isSelected={!filterExistingFiles}
|
||||
onPress={onFilterExistingFilesChange}
|
||||
>
|
||||
All Files
|
||||
{translate('AllFiles')}
|
||||
</SelectedMenuItem>
|
||||
|
||||
<SelectedMenuItem
|
||||
|
@ -734,7 +767,7 @@ function InteractiveImportModalContent(
|
|||
isSelected={filterExistingFiles}
|
||||
onPress={onFilterExistingFilesChange}
|
||||
>
|
||||
Unmapped Files Only
|
||||
{translate('UnmappedFilesOnly')}
|
||||
</SelectedMenuItem>
|
||||
</MenuContent>
|
||||
</Menu>
|
||||
|
@ -777,7 +810,7 @@ function InteractiveImportModalContent(
|
|||
) : null}
|
||||
|
||||
{isPopulated && !items.length && !isFetching
|
||||
? 'No video files were found in the selected folder'
|
||||
? translate('InteractiveImportNoFilesFound')
|
||||
: null}
|
||||
</ModalBody>
|
||||
|
||||
|
@ -793,7 +826,7 @@ function InteractiveImportModalContent(
|
|||
}
|
||||
onPress={onDeleteSelectedPress}
|
||||
>
|
||||
Delete
|
||||
{translate('Delete')}
|
||||
</SpinnerButton>
|
||||
) : null}
|
||||
|
||||
|
@ -831,7 +864,7 @@ function InteractiveImportModalContent(
|
|||
isDisabled={!selectedIds.length || !!invalidRowsSelected.length}
|
||||
onPress={onImportSelectedPress}
|
||||
>
|
||||
Import
|
||||
{translate('Import')}
|
||||
</Button>
|
||||
</div>
|
||||
</ModalFooter>
|
||||
|
@ -891,9 +924,9 @@ function InteractiveImportModalContent(
|
|||
<ConfirmModal
|
||||
isOpen={isConfirmDeleteModalOpen}
|
||||
kind={kinds.DANGER}
|
||||
title="Delete Selected Episode Files"
|
||||
message={'Are you sure you want to delete the selected episode files?'}
|
||||
confirmLabel="Delete"
|
||||
title={translate('DeleteSelectedEpisodeFiles')}
|
||||
message={translate('DeleteSelectedEpisodeFilesHelpText')}
|
||||
confirmLabel={translate('Delete')}
|
||||
onConfirm={onConfirmDelete}
|
||||
onCancel={onConfirmDeleteModalClose}
|
||||
/>
|
||||
|
|
|
@ -348,7 +348,9 @@ function InteractiveImportRow(props: InteractiveImportRowProps) {
|
|||
{isSeriesColumnVisible ? (
|
||||
<TableRowCellButton
|
||||
isDisabled={!allowSeriesChange}
|
||||
title={allowSeriesChange ? 'Click to change series' : undefined}
|
||||
title={
|
||||
allowSeriesChange ? translate('ClickToChangeSeries') : undefined
|
||||
}
|
||||
onPress={onSelectSeriesPress}
|
||||
>
|
||||
{showSeriesPlaceholder ? (
|
||||
|
@ -361,7 +363,7 @@ function InteractiveImportRow(props: InteractiveImportRowProps) {
|
|||
|
||||
<TableRowCellButton
|
||||
isDisabled={!series}
|
||||
title={series ? 'Click to change season' : undefined}
|
||||
title={series ? translate('ClickToChangeSeason') : undefined}
|
||||
onPress={onSelectSeasonPress}
|
||||
>
|
||||
{showSeasonNumberPlaceholder ? (
|
||||
|
@ -379,7 +381,7 @@ function InteractiveImportRow(props: InteractiveImportRowProps) {
|
|||
isDisabled={!series || requiresSeasonNumber}
|
||||
title={
|
||||
series && !requiresSeasonNumber
|
||||
? 'Click to change episode'
|
||||
? translate('ClickToChangeEpisode')
|
||||
: undefined
|
||||
}
|
||||
onPress={onSelectEpisodePress}
|
||||
|
@ -392,7 +394,7 @@ function InteractiveImportRow(props: InteractiveImportRowProps) {
|
|||
</TableRowCellButton>
|
||||
|
||||
<TableRowCellButton
|
||||
title="Click to change release group"
|
||||
title={translate('ClickToChangeReleaseGroup')}
|
||||
onPress={onSelectReleaseGroupPress}
|
||||
>
|
||||
{showReleaseGroupPlaceholder ? (
|
||||
|
@ -404,7 +406,7 @@ function InteractiveImportRow(props: InteractiveImportRowProps) {
|
|||
|
||||
<TableRowCellButton
|
||||
className={styles.quality}
|
||||
title="Click to change quality"
|
||||
title={translate('ClickToChangeQuality')}
|
||||
onPress={onSelectQualityPress}
|
||||
>
|
||||
{showQualityPlaceholder && <InteractiveImportRowCellPlaceholder />}
|
||||
|
@ -416,7 +418,7 @@ function InteractiveImportRow(props: InteractiveImportRowProps) {
|
|||
|
||||
<TableRowCellButton
|
||||
className={styles.languages}
|
||||
title="Click to change language"
|
||||
title={translate('ClickToChangeLanguage')}
|
||||
onPress={onSelectLanguagePress}
|
||||
>
|
||||
{showLanguagePlaceholder && <InteractiveImportRowCellPlaceholder />}
|
||||
|
@ -450,7 +452,7 @@ function InteractiveImportRow(props: InteractiveImportRowProps) {
|
|||
{rejections.length ? (
|
||||
<Popover
|
||||
anchor={<Icon name={icons.DANGER} kind={kinds.DANGER} />}
|
||||
title="Release Rejected"
|
||||
title={translate('ReleaseRejected')}
|
||||
body={
|
||||
<ul>
|
||||
{rejections.map((rejection, index) => {
|
||||
|
|
|
@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useState } from 'react';
|
|||
import Modal from 'Components/Modal/Modal';
|
||||
import usePrevious from 'Helpers/Hooks/usePrevious';
|
||||
import { sizes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import InteractiveImportSelectFolderModalContent from './Folder/InteractiveImportSelectFolderModalContent';
|
||||
import InteractiveImportModalContent from './Interactive/InteractiveImportModalContent';
|
||||
|
||||
|
@ -18,7 +19,7 @@ function InteractiveImportModal(props: InteractiveImportModalProps) {
|
|||
isOpen,
|
||||
folder,
|
||||
downloadId,
|
||||
modalTitle = 'Manual Import',
|
||||
modalTitle = translate('ManualImport'),
|
||||
onModalClose,
|
||||
...otherProps
|
||||
} = props;
|
||||
|
|
|
@ -16,6 +16,7 @@ import ModalHeader from 'Components/Modal/ModalHeader';
|
|||
import { inputTypes, kinds, sizes } from 'Helpers/Props';
|
||||
import Language from 'Language/Language';
|
||||
import createLanguagesSelector from 'Store/Selectors/createLanguagesSelector';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './SelectLanguageModalContent.css';
|
||||
|
||||
interface SelectLanguageModalContentProps {
|
||||
|
@ -78,13 +79,15 @@ function SelectLanguageModalContent(props: SelectLanguageModalContentProps) {
|
|||
|
||||
return (
|
||||
<ModalContent onModalClose={onModalClose}>
|
||||
<ModalHeader>{modalTitle} - Select Language</ModalHeader>
|
||||
<ModalHeader>
|
||||
{translate('SelectLanguageModalTitle', { modalTitle })}
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody>
|
||||
{isFetching ? <LoadingIndicator /> : null}
|
||||
|
||||
{!isFetching && error ? (
|
||||
<Alert kind={kinds.DANGER}>Unable to load Languages</Alert>
|
||||
<Alert kind={kinds.DANGER}>{translate('LanguagesLoadError')}</Alert>
|
||||
) : null}
|
||||
|
||||
{isPopulated && !error ? (
|
||||
|
@ -111,10 +114,10 @@ function SelectLanguageModalContent(props: SelectLanguageModalContentProps) {
|
|||
</ModalBody>
|
||||
|
||||
<ModalFooter>
|
||||
<Button onPress={onModalClose}>Cancel</Button>
|
||||
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
||||
|
||||
<Button kind={kinds.SUCCESS} onPress={onLanguagesSelectWrapper}>
|
||||
Select Languages
|
||||
{translate('SelectLanguages')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
|
|
|
@ -19,6 +19,7 @@ import Quality, { QualityModel } from 'Quality/Quality';
|
|||
import { fetchQualityProfileSchema } from 'Store/Actions/settingsActions';
|
||||
import { CheckInputChanged } from 'typings/inputs';
|
||||
import getQualities from 'Utilities/Quality/getQualities';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
interface QualitySchemaState {
|
||||
isFetching: boolean;
|
||||
|
@ -128,13 +129,13 @@ function SelectQualityModalContent(props: SelectQualityModalContentProps) {
|
|||
{isFetching && <LoadingIndicator />}
|
||||
|
||||
{!isFetching && error ? (
|
||||
<Alert kind={kinds.DANGER}>Unable to load qualities</Alert>
|
||||
<Alert kind={kinds.DANGER}>{translate('QualitiesLoadError')}</Alert>
|
||||
) : null}
|
||||
|
||||
{isPopulated && !error ? (
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<FormLabel>Quality</FormLabel>
|
||||
<FormLabel>{translate('Quality')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.SELECT}
|
||||
|
@ -146,7 +147,7 @@ function SelectQualityModalContent(props: SelectQualityModalContentProps) {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Proper</FormLabel>
|
||||
<FormLabel>{translate('Proper')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
@ -157,7 +158,7 @@ function SelectQualityModalContent(props: SelectQualityModalContentProps) {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Real</FormLabel>
|
||||
<FormLabel>{translate('Real')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
@ -174,7 +175,7 @@ function SelectQualityModalContent(props: SelectQualityModalContentProps) {
|
|||
<Button onPress={onModalClose}>Cancel</Button>
|
||||
|
||||
<Button kind={kinds.SUCCESS} onPress={onQualitySelectWrapper}>
|
||||
Select Quality
|
||||
{translate('SelectQuality')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
|
|
|
@ -9,6 +9,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { inputTypes, kinds, scrollDirections } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './SelectReleaseGroupModalContent.css';
|
||||
|
||||
interface SelectReleaseGroupModalContentProps {
|
||||
|
@ -37,7 +38,9 @@ function SelectReleaseGroupModalContent(
|
|||
|
||||
return (
|
||||
<ModalContent onModalClose={onModalClose}>
|
||||
<ModalHeader>{modalTitle} - Set Release Group</ModalHeader>
|
||||
<ModalHeader>
|
||||
{translate('SetReleaseGroupModalTitle', { modalTitle })}
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody
|
||||
className={styles.modalBody}
|
||||
|
@ -45,7 +48,7 @@ function SelectReleaseGroupModalContent(
|
|||
>
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<FormLabel>Release Group</FormLabel>
|
||||
<FormLabel>{translate('ReleaseGroup')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
|
@ -59,10 +62,10 @@ function SelectReleaseGroupModalContent(
|
|||
</ModalBody>
|
||||
|
||||
<ModalFooter>
|
||||
<Button onPress={onModalClose}>Cancel</Button>
|
||||
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
||||
|
||||
<Button kind={kinds.SUCCESS} onPress={onReleaseGroupSelectWrapper}>
|
||||
Set Release Group
|
||||
{translate('SetReleaseGroup')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
|
|
|
@ -7,6 +7,7 @@ import ModalFooter from 'Components/Modal/ModalFooter';
|
|||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { Season } from 'Series/Series';
|
||||
import { createSeriesSelectorForHook } from 'Store/Selectors/createSeriesSelector';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import SelectSeasonRow from './SelectSeasonRow';
|
||||
|
||||
interface SelectSeasonModalContentProps {
|
||||
|
@ -25,7 +26,9 @@ function SelectSeasonModalContent(props: SelectSeasonModalContentProps) {
|
|||
|
||||
return (
|
||||
<ModalContent onModalClose={onModalClose}>
|
||||
<ModalHeader>{modalTitle} - Select Season</ModalHeader>
|
||||
<ModalHeader>
|
||||
{translate('SelectSeasonModalTitle', { modalTitle })}
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody>
|
||||
{seasons.map((item) => {
|
||||
|
@ -40,7 +43,7 @@ function SelectSeasonModalContent(props: SelectSeasonModalContentProps) {
|
|||
</ModalBody>
|
||||
|
||||
<ModalFooter>
|
||||
<Button onPress={onModalClose}>Cancel</Button>
|
||||
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import Link from 'Components/Link/Link';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './SelectSeasonRow.css';
|
||||
|
||||
interface SelectSeasonRowProps {
|
||||
|
@ -20,7 +21,9 @@ function SelectSeasonRow(props: SelectSeasonRowProps) {
|
|||
component="div"
|
||||
onPress={onSeasonSelectWrapper}
|
||||
>
|
||||
{seasonNumber === 0 ? 'Specials' : `Season ${seasonNumber}`}
|
||||
{seasonNumber === 0
|
||||
? translate('Specials')
|
||||
: translate('SeasonNumberToken', { seasonNumber })}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import Scroller from 'Components/Scroller/Scroller';
|
|||
import { scrollDirections } from 'Helpers/Props';
|
||||
import Series from 'Series/Series';
|
||||
import createAllSeriesSelector from 'Store/Selectors/createAllSeriesSelector';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import SelectSeriesRow from './SelectSeriesRow';
|
||||
import styles from './SelectSeriesModalContent.css';
|
||||
|
||||
|
@ -61,7 +62,7 @@ function SelectSeriesModalContent(props: SelectSeriesModalContentProps) {
|
|||
>
|
||||
<TextInput
|
||||
className={styles.filterInput}
|
||||
placeholder="Filter series"
|
||||
placeholder={translate('FilterSeriesPlaceholder')}
|
||||
name="filter"
|
||||
value={filter}
|
||||
autoFocus={true}
|
||||
|
@ -83,7 +84,7 @@ function SelectSeriesModalContent(props: SelectSeriesModalContentProps) {
|
|||
</ModalBody>
|
||||
|
||||
<ModalFooter>
|
||||
<Button onPress={onModalClose}>Cancel</Button>
|
||||
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
);
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
"AirsTimeOn": "{time} on {networkLabel}",
|
||||
"AirsTomorrowOn": "Tomorrow at {time} on {networkLabel}",
|
||||
"All": "All",
|
||||
"AllFiles": "All Files",
|
||||
"AllResultsAreHiddenByTheAppliedFilter": "All results are hidden by the applied filter",
|
||||
"AllSeriesInRootFolderHaveBeenImported": "All series in {path} have been imported",
|
||||
"AllTitles": "All Titles",
|
||||
|
@ -166,10 +167,17 @@
|
|||
"ChmodFolderHelpText": "Octal, applied during import/rename to media folders and files (without execute bits)",
|
||||
"ChmodFolderHelpTextWarning": "This only works if the user running sonarr is the owner of the file. It's better to ensure the download client sets the permissions properly.",
|
||||
"ChooseAnotherFolder": "Choose another folder",
|
||||
"ChooseImportMode": "Choose Import Mode",
|
||||
"ChownGroup": "chown Group",
|
||||
"ChownGroupHelpText": "Group name or gid. Use gid for remote file systems.",
|
||||
"ChownGroupHelpTextWarning": "This only works if the user running sonarr is the owner of the file. It's better to ensure the download client uses the same group as sonarr.",
|
||||
"Clear": "Clear",
|
||||
"ClickToChangeEpisode": "Click to change episode",
|
||||
"ClickToChangeLanguage": "Click to change language",
|
||||
"ClickToChangeQuality": "Click to change quality",
|
||||
"ClickToChangeReleaseGroup": "Click to change release group",
|
||||
"ClickToChangeSeason": "Click to change season",
|
||||
"ClickToChangeSeries": "Click to change series",
|
||||
"ClientPriority": "Client Priority",
|
||||
"Clone": "Clone",
|
||||
"CloneAutoTag": "Clone Auto Tag",
|
||||
|
@ -205,6 +213,8 @@
|
|||
"CountImportListsSelected": "{count} import list(s) selected",
|
||||
"CountIndexersSelected": "{count} indexer(s) selected",
|
||||
"CountSeasons": "{count} Seasons",
|
||||
"CountSelectedFile": "{selectedCount} selected file",
|
||||
"CountSelectedFiles": "{selectedCount} selected files",
|
||||
"CreateEmptySeriesFolders": "Create Empty Series Folders",
|
||||
"CreateEmptySeriesFoldersHelpText": "Create missing series folders during disk scan",
|
||||
"CreateGroup": "Create Group",
|
||||
|
@ -277,6 +287,8 @@
|
|||
"DeleteRootFolderMessageText": "Are you sure you want to delete the root folder '{path}'?",
|
||||
"DeleteSelectedDownloadClients": "Delete Download Client(s)",
|
||||
"DeleteSelectedDownloadClientsMessageText": "Are you sure you want to delete {count} selected download client(s)?",
|
||||
"DeleteSelectedEpisodeFiles": "Delete Selected Episode Files",
|
||||
"DeleteSelectedEpisodeFilesHelpText": "Are you sure you want to delete the selected episode files?",
|
||||
"DeleteSelectedImportLists": "Delete Import List(s)",
|
||||
"DeleteSelectedImportListsMessageText": "Are you sure you want to delete {count} selected import list(s)?",
|
||||
"DeleteSelectedIndexers": "Delete Indexer(s)",
|
||||
|
@ -401,6 +413,7 @@
|
|||
"EpisodeTitleRequired": "Episode Title Required",
|
||||
"EpisodeTitleRequiredHelpText": "Prevent importing for up to 48 hours if the episode title is in the naming format and the episode title is TBA",
|
||||
"Episodes": "Episodes",
|
||||
"EpisodesLoadError": "Unable to load episodes",
|
||||
"Error": "Error",
|
||||
"ErrorLoadingContent": "There was an error loading this content",
|
||||
"ErrorLoadingContents": "Error loading contents",
|
||||
|
@ -445,6 +458,7 @@
|
|||
"FilterDoesNotEndWith": "does not end with",
|
||||
"FilterDoesNotStartWith": "does not start with",
|
||||
"FilterEndsWith": "ends with",
|
||||
"FilterEpisodesPlaceholder": "Filter episodes by title or number",
|
||||
"FilterEqual": "equal",
|
||||
"FilterGreaterThan": "greater than",
|
||||
"FilterGreaterThanOrEqual": "greater than or equal",
|
||||
|
@ -459,6 +473,7 @@
|
|||
"FilterNotEqual": "not equal",
|
||||
"FilterNotInLast": "not in the last",
|
||||
"FilterNotInNext": "not in the next",
|
||||
"FilterSeriesPlaceholder": "Filter series",
|
||||
"FilterStartsWith": "starts with",
|
||||
"FinaleTooltip": "Series or season finale",
|
||||
"FirstDayOfWeek": "First Day of Week",
|
||||
|
@ -484,6 +499,7 @@
|
|||
"Grabbed": "Grabbed",
|
||||
"GrabbedHistoryTooltip": "Episode grabbed from {indexer} and sent to {downloadClient}",
|
||||
"Group": "Group",
|
||||
"HardlinkCopyFiles": "Hardlink/Copy Files",
|
||||
"HasMissingSeason": "Has Missing Season",
|
||||
"Health": "Health",
|
||||
"Here": "here",
|
||||
|
@ -577,6 +593,14 @@
|
|||
"InstanceName": "Instance Name",
|
||||
"InstanceNameHelpText": "Instance name in tab and for Syslog app name",
|
||||
"InteractiveImport": "Interactive Import",
|
||||
"InteractiveImportLoadError": "Unable to load manual import items",
|
||||
"InteractiveImportNoEpisode": "One or more episodes must be chosen for each selected file",
|
||||
"InteractiveImportNoFilesFound": "No video files were found in the selected folder",
|
||||
"InteractiveImportNoImportMode": "An import mode must be selected",
|
||||
"InteractiveImportNoLanguage": "Language(s) must be chosen for each selected file",
|
||||
"InteractiveImportNoQuality": "Quality must be chosen for each selected file",
|
||||
"InteractiveImportNoSeason": "Season must be chosen for each selected file",
|
||||
"InteractiveImportNoSeries": "Series must be chosen for each selected file",
|
||||
"InteractiveSearch": "Interactive Search",
|
||||
"Interval": "Interval",
|
||||
"InvalidFormat": "Invalid Format",
|
||||
|
@ -629,6 +653,7 @@
|
|||
"ManageIndexers": "Manage Indexers",
|
||||
"ManageLists": "Manage Lists",
|
||||
"Manual": "Manual",
|
||||
"ManualImport": "Manual Import",
|
||||
"ManualImportItemsLoadError": "Unable to load manual import items",
|
||||
"MappedNetworkDrivesWindowsService": "Mapped network drives are not available when running as a Windows Service, see the [FAQ](https://wiki.servarr.com/sonarr/faq#why-cant-sonarr-see-my-files-on-a-remote-server) for more information.",
|
||||
"MarkAsFailed": "Mark as Failed",
|
||||
|
@ -701,6 +726,7 @@
|
|||
"MoreInfo": "More Info",
|
||||
"MountHealthCheckMessage": "Mount containing a series path is mounted read-only: ",
|
||||
"MoveAutomatically": "Move Automatically",
|
||||
"MoveFiles": "Move Files",
|
||||
"MultiEpisode": "Multi Episode",
|
||||
"MultiEpisodeInvalidFormat": "Multi Episode: Invalid Format",
|
||||
"MultiEpisodeStyle": "Multi Episode Style",
|
||||
|
@ -730,6 +756,7 @@
|
|||
"NoDownloadClientsFound": "No download clients found",
|
||||
"NoEpisodeHistory": "No episode history",
|
||||
"NoEpisodeOverview": "No episode overview",
|
||||
"NoEpisodesFoundForSelectedSeason": "No episodes were found for the selected season",
|
||||
"NoEventsFound": "No events found",
|
||||
"NoHistoryBlocklist": "No history blocklist",
|
||||
"NoHistoryFound": "No history found",
|
||||
|
@ -877,6 +904,7 @@
|
|||
"ReleaseProfileTagHelpText": "Release profiles will apply to series with at least one matching tag. Leave blank to apply to all series",
|
||||
"ReleaseProfiles": "Release Profiles",
|
||||
"ReleaseProfilesLoadError": "Unable to load Release Profiles",
|
||||
"ReleaseRejected": "Release Rejected",
|
||||
"ReleaseTitle": "Release Title",
|
||||
"Reload": "Reload",
|
||||
"RemotePath": "Remote Path",
|
||||
|
@ -1007,13 +1035,26 @@
|
|||
"SeasonFolder": "Season Folder",
|
||||
"SeasonFolderFormat": "Season Folder Format",
|
||||
"SeasonNumber": "Season Number",
|
||||
"SeasonNumberToken": "Season {seasonNumber}",
|
||||
"SeasonPack": "Season Pack",
|
||||
"SeasonPremiere": "Season Premiere",
|
||||
"SeasonPremieresOnly": "Season Premieres Only",
|
||||
"Seasons": "Seasons",
|
||||
"Security": "Security",
|
||||
"Seeders": "Seeders",
|
||||
"SelectDropdown": "Select...",
|
||||
"SelectEpisodes": "Select Episode(s)",
|
||||
"SelectEpisodesModalTitle": "{modalTitle} - Select Episode(s)",
|
||||
"SelectFolder": "Select Folder",
|
||||
"SelectFolderModalTitle": "{modalTitle} - Select Folder",
|
||||
"SelectLanguage": "Select Language",
|
||||
"SelectLanguageModalTitle": "{modalTitle} - Select Language",
|
||||
"SelectLanguages": "Select Languages",
|
||||
"SelectQuality": "Select Quality",
|
||||
"SelectReleaseGroup": "Select Release Group",
|
||||
"SelectSeason": "Select Season",
|
||||
"SelectSeasonModalTitle": "{modalTitle} - Select Season",
|
||||
"SelectSeries": "Select Series",
|
||||
"SendAnonymousUsageData": "Send Anonymous Usage Data",
|
||||
"Series": "Series",
|
||||
"SeriesAndEpisodeInformationIsProvidedByTheTVDB": "Series and episode information is provided by TheTVDB.com. [Please consider supporting them](https://www.thetvdb.com/subscribe).",
|
||||
|
@ -1034,6 +1075,8 @@
|
|||
"SetPermissions": "Set Permissions",
|
||||
"SetPermissionsLinuxHelpText": "Should chmod be run when files are imported/renamed?",
|
||||
"SetPermissionsLinuxHelpTextWarning": "If you're unsure what these settings do, do not alter them.",
|
||||
"SetReleaseGroup": "Set Release Group",
|
||||
"SetReleaseGroupModalTitle": "{modalTitle} - Set Release Group",
|
||||
"SetTags": "Set Tags",
|
||||
"Settings": "Settings",
|
||||
"ShortDateFormat": "Short Date Format",
|
||||
|
@ -1069,6 +1112,7 @@
|
|||
"Space": "Space",
|
||||
"Special": "Special",
|
||||
"SpecialEpisode": "Special Episode",
|
||||
"Specials": "Specials",
|
||||
"SpecialsFolderFormat": "Specials Folder Format",
|
||||
"SslCertPassword": "SSL Cert Password",
|
||||
"SslCertPasswordHelpText": "Password for pfx file",
|
||||
|
@ -1168,6 +1212,7 @@
|
|||
"Unknown": "Unknown",
|
||||
"UnknownEventTooltip": "Unknown event",
|
||||
"Unlimited": "Unlimited",
|
||||
"UnmappedFilesOnly": "Unmapped Files Only",
|
||||
"UnmappedFolders": "Unmapped Folders",
|
||||
"UnmonitorDeletedEpisodes": "Unmonitor Deleted Episodes",
|
||||
"UnmonitorDeletedEpisodesHelpText": "Episodes deleted from disk are automatically unmonitored in Sonarr",
|
||||
|
|
Loading…
Reference in New Issue