Convert Root Folders to Typescript
This commit is contained in:
parent
8bd91bd86b
commit
a5aab810d7
|
@ -10,6 +10,7 @@ import ImportList from 'typings/ImportList';
|
|||
import Indexer from 'typings/Indexer';
|
||||
import Notification from 'typings/Notification';
|
||||
import QualityProfile from 'typings/QualityProfile';
|
||||
import RootFolder from 'typings/RootFolder';
|
||||
import { UiSettings } from 'typings/UiSettings';
|
||||
|
||||
export interface DownloadClientAppState
|
||||
|
@ -35,6 +36,11 @@ export interface QualityProfilesAppState
|
|||
extends AppSectionState<QualityProfile>,
|
||||
AppSectionSchemaState<QualityProfile> {}
|
||||
|
||||
export interface RootFolderAppState
|
||||
extends AppSectionState<RootFolder>,
|
||||
AppSectionDeleteState,
|
||||
AppSectionSaveState {}
|
||||
|
||||
export type LanguageSettingsAppState = AppSectionState<Language>;
|
||||
export type UiSettingsAppState = AppSectionItemState<UiSettings>;
|
||||
|
||||
|
@ -45,6 +51,7 @@ interface SettingsAppState {
|
|||
languages: LanguageSettingsAppState;
|
||||
notifications: NotificationAppState;
|
||||
qualityProfiles: QualityProfilesAppState;
|
||||
rootFolders: RootFolderAppState;
|
||||
ui: UiSettingsAppState;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import Label from 'Components/Label';
|
||||
import IconButton from 'Components/Link/IconButton';
|
||||
import Link from 'Components/Link/Link';
|
||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import styles from './RootFolderRow.css';
|
||||
|
||||
function RootFolderRow(props) {
|
||||
const {
|
||||
id,
|
||||
path,
|
||||
accessible,
|
||||
freeSpace,
|
||||
unmappedFolders,
|
||||
onDeletePress
|
||||
} = props;
|
||||
|
||||
const isUnavailable = !accessible;
|
||||
|
||||
return (
|
||||
<TableRow>
|
||||
<TableRowCell>
|
||||
{
|
||||
isUnavailable ?
|
||||
<div className={styles.unavailablePath}>
|
||||
{path}
|
||||
|
||||
<Label
|
||||
className={styles.unavailableLabel}
|
||||
kind={kinds.DANGER}
|
||||
>
|
||||
Unavailable
|
||||
</Label>
|
||||
</div> :
|
||||
|
||||
<Link
|
||||
className={styles.link}
|
||||
to={`/add/import/${id}`}
|
||||
>
|
||||
{path}
|
||||
</Link>
|
||||
}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.freeSpace}>
|
||||
{(isUnavailable || isNaN(freeSpace)) ? '-' : formatBytes(freeSpace)}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.unmappedFolders}>
|
||||
{isUnavailable ? '-' : unmappedFolders.length}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.actions}>
|
||||
<IconButton
|
||||
title="Remove root folder"
|
||||
name={icons.REMOVE}
|
||||
onPress={onDeletePress}
|
||||
/>
|
||||
</TableRowCell>
|
||||
</TableRow>
|
||||
);
|
||||
}
|
||||
|
||||
RootFolderRow.propTypes = {
|
||||
id: PropTypes.number.isRequired,
|
||||
path: PropTypes.string.isRequired,
|
||||
accessible: PropTypes.bool.isRequired,
|
||||
freeSpace: PropTypes.number,
|
||||
unmappedFolders: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
onDeletePress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
RootFolderRow.defaultProps = {
|
||||
unmappedFolders: []
|
||||
};
|
||||
|
||||
export default RootFolderRow;
|
|
@ -0,0 +1,95 @@
|
|||
import React, { useCallback, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import Label from 'Components/Label';
|
||||
import IconButton from 'Components/Link/IconButton';
|
||||
import Link from 'Components/Link/Link';
|
||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import { deleteRootFolder } from 'Store/Actions/rootFolderActions';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './RootFolderRow.css';
|
||||
|
||||
interface RootFolderRowProps {
|
||||
id: number;
|
||||
path: string;
|
||||
accessible: boolean;
|
||||
freeSpace?: number;
|
||||
unmappedFolders: object[];
|
||||
}
|
||||
|
||||
function RootFolderRow(props: RootFolderRowProps) {
|
||||
const { id, path, accessible, freeSpace, unmappedFolders = [] } = props;
|
||||
|
||||
const isUnavailable = !accessible;
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||
|
||||
const onDeletePress = useCallback(() => {
|
||||
setIsDeleteModalOpen(true);
|
||||
}, [setIsDeleteModalOpen]);
|
||||
|
||||
const onDeleteModalClose = useCallback(() => {
|
||||
setIsDeleteModalOpen(false);
|
||||
}, [setIsDeleteModalOpen]);
|
||||
|
||||
const onConfirmDelete = useCallback(() => {
|
||||
dispatch(deleteRootFolder({ id }));
|
||||
|
||||
setIsDeleteModalOpen(false);
|
||||
}, [dispatch, id]);
|
||||
|
||||
return (
|
||||
<TableRow>
|
||||
<TableRowCell>
|
||||
{isUnavailable ? (
|
||||
<div className={styles.unavailablePath}>
|
||||
{path}
|
||||
|
||||
<Label className={styles.unavailableLabel} kind={kinds.DANGER}>
|
||||
{translate('Unavailable')}
|
||||
</Label>
|
||||
</div>
|
||||
) : (
|
||||
<Link className={styles.link} to={`/add/import/${id}`}>
|
||||
{path}
|
||||
</Link>
|
||||
)}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.freeSpace}>
|
||||
{isUnavailable || isNaN(Number(freeSpace))
|
||||
? '-'
|
||||
: formatBytes(freeSpace)}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.unmappedFolders}>
|
||||
{isUnavailable ? '-' : unmappedFolders.length}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.actions}>
|
||||
<IconButton
|
||||
title={translate('RemoveRootFolder')}
|
||||
name={icons.REMOVE}
|
||||
onPress={onDeletePress}
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
||||
<ConfirmModal
|
||||
isOpen={isDeleteModalOpen}
|
||||
kind={kinds.DANGER}
|
||||
title={translate('DeleteRootFolder')}
|
||||
message={translate('DeleteRootFolderMessageText', { path })}
|
||||
confirmLabel={translate('Delete')}
|
||||
onConfirm={onConfirmDelete}
|
||||
onCancel={onDeleteModalClose}
|
||||
/>
|
||||
</TableRow>
|
||||
);
|
||||
}
|
||||
|
||||
export default RootFolderRow;
|
|
@ -1,13 +0,0 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { deleteRootFolder } from 'Store/Actions/rootFolderActions';
|
||||
import RootFolderRow from './RootFolderRow';
|
||||
|
||||
function createMapDispatchToProps(dispatch, props) {
|
||||
return {
|
||||
onDeletePress() {
|
||||
dispatch(deleteRootFolder({ id: props.id }));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(null, createMapDispatchToProps)(RootFolderRow);
|
|
@ -1,83 +0,0 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import Alert from 'Components/Alert';
|
||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import RootFolderRowConnector from './RootFolderRowConnector';
|
||||
|
||||
const rootFolderColumns = [
|
||||
{
|
||||
name: 'path',
|
||||
label: 'Path',
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'freeSpace',
|
||||
label: 'Free Space',
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'unmappedFolders',
|
||||
label: 'Unmapped Folders',
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'actions',
|
||||
isVisible: true
|
||||
}
|
||||
];
|
||||
|
||||
function RootFolders(props) {
|
||||
const {
|
||||
isFetching,
|
||||
isPopulated,
|
||||
error,
|
||||
items
|
||||
} = props;
|
||||
|
||||
if (isFetching && !isPopulated) {
|
||||
return (
|
||||
<LoadingIndicator />
|
||||
);
|
||||
}
|
||||
|
||||
if (!isFetching && !!error) {
|
||||
return (
|
||||
<Alert kind={kinds.DANGER}>Unable to load root folders</Alert>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Table
|
||||
columns={rootFolderColumns}
|
||||
>
|
||||
<TableBody>
|
||||
{
|
||||
items.map((rootFolder) => {
|
||||
return (
|
||||
<RootFolderRowConnector
|
||||
key={rootFolder.id}
|
||||
id={rootFolder.id}
|
||||
path={rootFolder.path}
|
||||
accessible={rootFolder.accessible}
|
||||
freeSpace={rootFolder.freeSpace}
|
||||
unmappedFolders={rootFolder.unmappedFolders}
|
||||
/>
|
||||
);
|
||||
})
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
|
||||
RootFolders.propTypes = {
|
||||
isFetching: PropTypes.bool.isRequired,
|
||||
isPopulated: PropTypes.bool.isRequired,
|
||||
error: PropTypes.object,
|
||||
items: PropTypes.arrayOf(PropTypes.object).isRequired
|
||||
};
|
||||
|
||||
export default RootFolders;
|
|
@ -0,0 +1,82 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import Alert from 'Components/Alert';
|
||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import { fetchRootFolders } from 'Store/Actions/rootFolderActions';
|
||||
import createRootFoldersSelector from 'Store/Selectors/createRootFoldersSelector';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import RootFolderRow from './RootFolderRow';
|
||||
|
||||
const rootFolderColumns = [
|
||||
{
|
||||
name: 'path',
|
||||
get label() {
|
||||
return translate('Path');
|
||||
},
|
||||
isVisible: true,
|
||||
},
|
||||
{
|
||||
name: 'freeSpace',
|
||||
get label() {
|
||||
return translate('FreeSpace');
|
||||
},
|
||||
isVisible: true,
|
||||
},
|
||||
{
|
||||
name: 'unmappedFolders',
|
||||
get label() {
|
||||
return translate('UnmappedFolders');
|
||||
},
|
||||
isVisible: true,
|
||||
},
|
||||
{
|
||||
name: 'actions',
|
||||
isVisible: true,
|
||||
},
|
||||
];
|
||||
|
||||
function RootFolders() {
|
||||
const { isFetching, isPopulated, error, items } = useSelector(
|
||||
createRootFoldersSelector()
|
||||
);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchRootFolders());
|
||||
}, [dispatch]);
|
||||
|
||||
if (isFetching && !isPopulated) {
|
||||
return <LoadingIndicator />;
|
||||
}
|
||||
|
||||
if (!isFetching && !!error) {
|
||||
return (
|
||||
<Alert kind={kinds.DANGER}>{translate('UnableToLoadRootFolders')}</Alert>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Table columns={rootFolderColumns}>
|
||||
<TableBody>
|
||||
{items.map((rootFolder) => {
|
||||
return (
|
||||
<RootFolderRow
|
||||
key={rootFolder.id}
|
||||
id={rootFolder.id}
|
||||
path={rootFolder.path}
|
||||
accessible={rootFolder.accessible}
|
||||
freeSpace={rootFolder.freeSpace}
|
||||
unmappedFolders={rootFolder.unmappedFolders}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
|
||||
export default RootFolders;
|
|
@ -1,46 +0,0 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { fetchRootFolders } from 'Store/Actions/rootFolderActions';
|
||||
import RootFolders from './RootFolders';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.rootFolders,
|
||||
(rootFolders) => {
|
||||
return rootFolders;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
dispatchFetchRootFolders: fetchRootFolders
|
||||
};
|
||||
|
||||
class RootFoldersConnector extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatchFetchRootFolders();
|
||||
}
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
return (
|
||||
<RootFolders
|
||||
{...this.props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
RootFoldersConnector.propTypes = {
|
||||
dispatchFetchRootFolders: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(RootFoldersConnector);
|
|
@ -10,10 +10,11 @@ import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
|||
import PageContent from 'Components/Page/PageContent';
|
||||
import PageContentBody from 'Components/Page/PageContentBody';
|
||||
import { inputTypes, kinds, sizes } from 'Helpers/Props';
|
||||
import RootFoldersConnector from 'RootFolder/RootFoldersConnector';
|
||||
import RootFolders from 'RootFolder/RootFolders';
|
||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import NamingConnector from './Naming/NamingConnector';
|
||||
import AddRootFolderConnector from './RootFolder/AddRootFolderConnector';
|
||||
import AddRootFolder from './RootFolder/AddRootFolder';
|
||||
|
||||
const episodeTitleRequiredOptions = [
|
||||
{ key: 'always', value: 'Always' },
|
||||
|
@ -452,9 +453,9 @@ class MediaManagement extends Component {
|
|||
</Form> : null
|
||||
}
|
||||
|
||||
<FieldSet legend="Root Folders">
|
||||
<RootFoldersConnector />
|
||||
<AddRootFolderConnector />
|
||||
<FieldSet legend={translate('RootFolders')}>
|
||||
<RootFolders />
|
||||
<AddRootFolder />
|
||||
</FieldSet>
|
||||
</PageContentBody>
|
||||
</PageContent>
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import FileBrowserModal from 'Components/FileBrowser/FileBrowserModal';
|
||||
import Icon from 'Components/Icon';
|
||||
import Button from 'Components/Link/Button';
|
||||
import { icons, kinds, sizes } from 'Helpers/Props';
|
||||
import styles from './AddRootFolder.css';
|
||||
|
||||
class AddRootFolder extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
isAddNewRootFolderModalOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
onAddNewRootFolderPress = () => {
|
||||
this.setState({ isAddNewRootFolderModalOpen: true });
|
||||
};
|
||||
|
||||
onNewRootFolderSelect = ({ value }) => {
|
||||
this.props.onNewRootFolderSelect(value);
|
||||
};
|
||||
|
||||
onAddRootFolderModalClose = () => {
|
||||
this.setState({ isAddNewRootFolderModalOpen: false });
|
||||
};
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={styles.addRootFolderButtonContainer}>
|
||||
<Button
|
||||
kind={kinds.PRIMARY}
|
||||
size={sizes.LARGE}
|
||||
onPress={this.onAddNewRootFolderPress}
|
||||
>
|
||||
<Icon
|
||||
className={styles.importButtonIcon}
|
||||
name={icons.DRIVE}
|
||||
/>
|
||||
Add Root Folder
|
||||
</Button>
|
||||
|
||||
<FileBrowserModal
|
||||
isOpen={this.state.isAddNewRootFolderModalOpen}
|
||||
name="rootFolderPath"
|
||||
value=""
|
||||
onChange={this.onNewRootFolderSelect}
|
||||
onModalClose={this.onAddRootFolderModalClose}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AddRootFolder.propTypes = {
|
||||
onNewRootFolderSelect: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default AddRootFolder;
|
|
@ -0,0 +1,54 @@
|
|||
import React, { useCallback, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import FileBrowserModal from 'Components/FileBrowser/FileBrowserModal';
|
||||
import Icon from 'Components/Icon';
|
||||
import Button from 'Components/Link/Button';
|
||||
import { icons, kinds, sizes } from 'Helpers/Props';
|
||||
import { addRootFolder } from 'Store/Actions/rootFolderActions';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './AddRootFolder.css';
|
||||
|
||||
function AddRootFolder() {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [isAddNewRootFolderModalOpen, setIsAddNewRootFolderModalOpen] =
|
||||
useState(false);
|
||||
|
||||
const onAddNewRootFolderPress = useCallback(() => {
|
||||
setIsAddNewRootFolderModalOpen(true);
|
||||
}, [setIsAddNewRootFolderModalOpen]);
|
||||
|
||||
const onNewRootFolderSelect = useCallback(
|
||||
({ value }: { value: string }) => {
|
||||
dispatch(addRootFolder({ path: value }));
|
||||
},
|
||||
[dispatch]
|
||||
);
|
||||
|
||||
const onAddRootFolderModalClose = useCallback(() => {
|
||||
setIsAddNewRootFolderModalOpen(false);
|
||||
}, [setIsAddNewRootFolderModalOpen]);
|
||||
|
||||
return (
|
||||
<div className={styles.addRootFolderButtonContainer}>
|
||||
<Button
|
||||
kind={kinds.PRIMARY}
|
||||
size={sizes.LARGE}
|
||||
onPress={onAddNewRootFolderPress}
|
||||
>
|
||||
<Icon className={styles.importButtonIcon} name={icons.DRIVE} />
|
||||
{translate('AddRootFolder')}
|
||||
</Button>
|
||||
|
||||
<FileBrowserModal
|
||||
isOpen={isAddNewRootFolderModalOpen}
|
||||
name="rootFolderPath"
|
||||
value=""
|
||||
onChange={onNewRootFolderSelect}
|
||||
onModalClose={onAddRootFolderModalClose}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default AddRootFolder;
|
|
@ -1,13 +0,0 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { addRootFolder } from 'Store/Actions/rootFolderActions';
|
||||
import AddRootFolder from './AddRootFolder';
|
||||
|
||||
function createMapDispatchToProps(dispatch) {
|
||||
return {
|
||||
onNewRootFolderSelect(path) {
|
||||
dispatch(addRootFolder({ path }));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(null, createMapDispatchToProps)(AddRootFolder);
|
|
@ -0,0 +1,13 @@
|
|||
import { createSelector } from 'reselect';
|
||||
import { RootFolderAppState } from 'App/State/SettingsAppState';
|
||||
import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector';
|
||||
import RootFolder from 'typings/RootFolder';
|
||||
|
||||
export default function createRootFoldersSelector() {
|
||||
return createSelector(
|
||||
createSortedSectionSelector('rootFolders', (a: RootFolder, b: RootFolder) =>
|
||||
a.path.localeCompare(b.path)
|
||||
),
|
||||
(rootFolders: RootFolderAppState) => rootFolders
|
||||
);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import ModelBase from 'App/ModelBase';
|
||||
|
||||
interface RootFolder extends ModelBase {
|
||||
id: number;
|
||||
path: string;
|
||||
accessible: boolean;
|
||||
freeSpace?: number;
|
||||
unmappedFolders: object[];
|
||||
}
|
||||
|
||||
export default RootFolder;
|
|
@ -7,6 +7,7 @@
|
|||
"AddAutoTag": "Add Auto Tag",
|
||||
"AddCondition": "Add Condition",
|
||||
"AddNew": "Add New",
|
||||
"AddRootFolder": "Add Root Folder",
|
||||
"Added": "Added",
|
||||
"AddingTag": "Adding tag",
|
||||
"Age": "Age",
|
||||
|
@ -76,6 +77,8 @@
|
|||
"DeleteConditionMessageText": "Are you sure you want to delete the condition '{0}'?",
|
||||
"DeleteCustomFormat": "Delete Custom Format",
|
||||
"DeleteCustomFormatMessageText": "Are you sure you want to delete the custom format '{0}'?",
|
||||
"DeleteRootFolder": "Delete Root Folder",
|
||||
"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)?",
|
||||
"DeleteSelectedImportLists": "Delete Import List(s)",
|
||||
|
@ -295,6 +298,7 @@
|
|||
"RemoveFailedDownloads": "Remove Failed Downloads",
|
||||
"RemoveFromDownloadClient": "Remove From Download Client",
|
||||
"RemoveFromDownloadClientHelpTextWarning": "Removing will remove the download and the file(s) from the download client.",
|
||||
"RemoveRootFolder": "Remove root folder",
|
||||
"RemoveSelectedItem": "Remove Selected Item",
|
||||
"RemoveSelectedItemQueueMessageText": "Are you sure you want to remove 1 item from the queue?",
|
||||
"RemoveSelectedItems": "Remove Selected Items",
|
||||
|
@ -323,6 +327,7 @@
|
|||
"RootFolderMissingHealthCheckMessage": "Missing root folder: {0}",
|
||||
"RootFolderMultipleMissingHealthCheckMessage": "Multiple root folders are missing: {0}",
|
||||
"RootFolderPath": "Root Folder Path",
|
||||
"RootFolders": "Root Folders",
|
||||
"Runtime": "Runtime",
|
||||
"Save": "Save",
|
||||
"SceneNumbering": "Scene Numbering",
|
||||
|
@ -370,7 +375,10 @@
|
|||
"UI Language": "UI Language",
|
||||
"UnableToLoadAutoTagging": "Unable to load auto tagging",
|
||||
"UnableToLoadBackups": "Unable to load backups",
|
||||
"UnableToLoadRootFolders": "Unable to load root folders",
|
||||
"UnableToUpdateSonarrDirectly": "Unable to update Sonarr directly,",
|
||||
"Unavailable": "Unavailable",
|
||||
"UnmappedFolders": "Unmapped Folders",
|
||||
"Unmonitored": "Unmonitored",
|
||||
"UnmonitoredOnly": "Unmonitored Only",
|
||||
"UpdateAvailableHealthCheckMessage": "New update is available",
|
||||
|
|
Loading…
Reference in New Issue