mirror of
https://github.com/Sonarr/Sonarr.git
synced 2026-04-26 22:56:23 -04:00
Translate System pages
This commit is contained in:
@@ -9,6 +9,7 @@ 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 translate from 'Utilities/String/translate';
|
||||
import RestoreBackupModalConnector from './RestoreBackupModalConnector';
|
||||
import styles from './BackupRow.css';
|
||||
|
||||
@@ -75,14 +76,14 @@ class BackupRow extends Component {
|
||||
} = this.state;
|
||||
|
||||
let iconClassName = icons.SCHEDULED;
|
||||
let iconTooltip = 'Scheduled';
|
||||
let iconTooltip = translate('Scheduled');
|
||||
|
||||
if (type === 'manual') {
|
||||
iconClassName = icons.INTERACTIVE;
|
||||
iconTooltip = 'Manual';
|
||||
iconTooltip = translate('Manual');
|
||||
} else if (type === 'update') {
|
||||
iconClassName = icons.UPDATE;
|
||||
iconTooltip = 'Before update';
|
||||
iconTooltip = translate('BeforeUpdate');
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -115,12 +116,13 @@ class BackupRow extends Component {
|
||||
|
||||
<TableRowCell className={styles.actions}>
|
||||
<IconButton
|
||||
title={translate('RestoreBackup')}
|
||||
name={icons.RESTORE}
|
||||
onPress={this.onRestorePress}
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
title="Delete backup"
|
||||
title={translate('DeleteBackup')}
|
||||
name={icons.DELETE}
|
||||
onPress={this.onDeletePress}
|
||||
/>
|
||||
@@ -136,9 +138,11 @@ class BackupRow extends Component {
|
||||
<ConfirmModal
|
||||
isOpen={isConfirmDeleteModalOpen}
|
||||
kind={kinds.DANGER}
|
||||
title="Delete Backup"
|
||||
message={`Are you sure you want to delete the backup '${name}'?`}
|
||||
confirmLabel="Delete"
|
||||
title={translate('DeleteBackup')}
|
||||
message={translate('DeleteBackupMessageText', {
|
||||
name
|
||||
})}
|
||||
confirmLabel={translate('Delete')}
|
||||
onConfirm={this.onConfirmDeletePress}
|
||||
onCancel={this.onConfirmDeleteModalClose}
|
||||
/>
|
||||
|
||||
@@ -10,6 +10,7 @@ import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection';
|
||||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import BackupRow from './BackupRow';
|
||||
import RestoreBackupModalConnector from './RestoreBackupModalConnector';
|
||||
|
||||
@@ -20,17 +21,23 @@ const columns = [
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
label: 'Name',
|
||||
get label() {
|
||||
return translate('Name');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'size',
|
||||
label: 'Size',
|
||||
get label() {
|
||||
return translate('Size');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'time',
|
||||
label: 'Time',
|
||||
get label() {
|
||||
return translate('Time');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
@@ -81,18 +88,18 @@ class Backups extends Component {
|
||||
const noBackups = isPopulated && !items.length;
|
||||
|
||||
return (
|
||||
<PageContent title="Backups">
|
||||
<PageContent title={translate('Backups')}>
|
||||
<PageToolbar>
|
||||
<PageToolbarSection>
|
||||
<PageToolbarButton
|
||||
label="Backup Now"
|
||||
label={translate('BackupNow')}
|
||||
iconName={icons.BACKUP}
|
||||
isSpinning={backupExecuting}
|
||||
onPress={onBackupPress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Restore Backup"
|
||||
label={translate('RestoreBackup')}
|
||||
iconName={icons.RESTORE}
|
||||
onPress={this.onRestorePress}
|
||||
/>
|
||||
@@ -108,14 +115,14 @@ class Backups extends Component {
|
||||
{
|
||||
!isFetching && !!error &&
|
||||
<Alert kind={kinds.DANGER}>
|
||||
Unable to load backups
|
||||
{translate('UnableToLoadBackups')}
|
||||
</Alert>
|
||||
}
|
||||
|
||||
{
|
||||
noBackups &&
|
||||
<Alert kind={kinds.INFO}>
|
||||
No backups are available
|
||||
{translate('NoBackupsAreAvailable')}
|
||||
</Alert>
|
||||
}
|
||||
|
||||
|
||||
@@ -9,11 +9,12 @@ import ModalContent from 'Components/Modal/ModalContent';
|
||||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './RestoreBackupModalContent.css';
|
||||
|
||||
function getErrorMessage(error) {
|
||||
if (!error || !error.responseJSON || !error.responseJSON.message) {
|
||||
return 'Error restoring backup';
|
||||
return translate('ErrorRestoringBackup');
|
||||
}
|
||||
|
||||
return error.responseJSON.message;
|
||||
@@ -145,7 +146,9 @@ class RestoreBackupModalContent extends Component {
|
||||
|
||||
<ModalBody>
|
||||
{
|
||||
!!id && `Would you like to restore the backup '${name}'?`
|
||||
!!id && translate('WouldYouLikeToRestoreBackup', {
|
||||
name
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
@@ -167,7 +170,9 @@ class RestoreBackupModalContent extends Component {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>Restore</div>
|
||||
<div>
|
||||
{translate('Restore')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.step}>
|
||||
@@ -178,7 +183,9 @@ class RestoreBackupModalContent extends Component {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>Restart</div>
|
||||
<div>
|
||||
{translate('Restart')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.step}>
|
||||
@@ -189,18 +196,20 @@ class RestoreBackupModalContent extends Component {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>Reload</div>
|
||||
<div>
|
||||
{translate('Reload')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ModalBody>
|
||||
|
||||
<ModalFooter>
|
||||
<div className={styles.additionalInfo}>
|
||||
Note: Sonarr will automatically restart and reload the UI during the restore process.
|
||||
{translate('RestartReloadNote')}
|
||||
</div>
|
||||
|
||||
<Button onPress={onModalClose}>
|
||||
Cancel
|
||||
{translate('Cancel')}
|
||||
</Button>
|
||||
|
||||
<SpinnerButton
|
||||
@@ -209,7 +218,7 @@ class RestoreBackupModalContent extends Component {
|
||||
isSpinning={isRestoring}
|
||||
onPress={this.onRestorePress}
|
||||
>
|
||||
Restore
|
||||
{translate('Restore')}
|
||||
</SpinnerButton>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
|
||||
@@ -13,6 +13,7 @@ import TableBody from 'Components/Table/TableBody';
|
||||
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
|
||||
import TablePager from 'Components/Table/TablePager';
|
||||
import { align, icons, kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import LogsTableRow from './LogsTableRow';
|
||||
|
||||
function LogsTable(props) {
|
||||
@@ -33,11 +34,11 @@ function LogsTable(props) {
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<PageContent title="Logs">
|
||||
<PageContent title={translate('Logs')}>
|
||||
<PageToolbar>
|
||||
<PageToolbarSection>
|
||||
<PageToolbarButton
|
||||
label="Refresh"
|
||||
label={translate('Refresh')}
|
||||
iconName={icons.REFRESH}
|
||||
spinningName={icons.REFRESH}
|
||||
isSpinning={isFetching}
|
||||
@@ -45,7 +46,7 @@ function LogsTable(props) {
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Clear"
|
||||
label={translate('Clear')}
|
||||
iconName={icons.CLEAR}
|
||||
isSpinning={clearLogExecuting}
|
||||
onPress={onClearLogsPress}
|
||||
@@ -59,7 +60,7 @@ function LogsTable(props) {
|
||||
canModifyColumns={false}
|
||||
>
|
||||
<PageToolbarButton
|
||||
label="Options"
|
||||
label={translate('Options')}
|
||||
iconName={icons.TABLE}
|
||||
/>
|
||||
</TableOptionsModalWrapper>
|
||||
@@ -83,7 +84,7 @@ function LogsTable(props) {
|
||||
{
|
||||
isPopulated && !error && !items.length &&
|
||||
<Alert kind={kinds.INFO}>
|
||||
No events found
|
||||
{translate('NoEventsFound')}
|
||||
</Alert>
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import Scroller from 'Components/Scroller/Scroller';
|
||||
import { scrollDirections } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './LogsTableDetailsModal.css';
|
||||
|
||||
function LogsTableDetailsModal(props) {
|
||||
@@ -27,11 +28,13 @@ function LogsTableDetailsModal(props) {
|
||||
onModalClose={onModalClose}
|
||||
>
|
||||
<ModalHeader>
|
||||
Details
|
||||
{translate('Details')}
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody>
|
||||
<div>Message</div>
|
||||
<div>
|
||||
{translate('Message')}
|
||||
</div>
|
||||
|
||||
<Scroller
|
||||
className={styles.detailsText}
|
||||
@@ -43,7 +46,9 @@ function LogsTableDetailsModal(props) {
|
||||
{
|
||||
!!exception &&
|
||||
<div>
|
||||
<div>Exception</div>
|
||||
<div>
|
||||
{translate('Exception')}
|
||||
</div>
|
||||
<Scroller
|
||||
className={styles.detailsText}
|
||||
scrollDirection={scrollDirections.HORIZONTAL}
|
||||
@@ -56,7 +61,7 @@ function LogsTableDetailsModal(props) {
|
||||
|
||||
<ModalFooter>
|
||||
<Button onPress={onModalClose}>
|
||||
Close
|
||||
{translate('Close')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import Alert from 'Components/Alert';
|
||||
import Link from 'Components/Link/Link';
|
||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import PageContent from 'Components/Page/PageContent';
|
||||
import PageContentBody from 'Components/Page/PageContentBody';
|
||||
@@ -12,18 +11,24 @@ import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import InlineMarkdown from '../../../Components/Markdown/InlineMarkdown';
|
||||
import LogsNavMenu from '../LogsNavMenu';
|
||||
import LogFilesTableRow from './LogFilesTableRow';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
name: 'filename',
|
||||
label: 'Filename',
|
||||
get label() {
|
||||
return translate('Filename');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'lastWriteTime',
|
||||
label: 'Last Write Time',
|
||||
get label() {
|
||||
return translate('LastWriteTime');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
@@ -50,7 +55,7 @@ class LogFiles extends Component {
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<PageContent title="Log Files">
|
||||
<PageContent title={translate('LogFiles')}>
|
||||
<PageToolbar>
|
||||
<PageToolbarSection>
|
||||
<LogsNavMenu current={currentLogView} />
|
||||
@@ -58,7 +63,7 @@ class LogFiles extends Component {
|
||||
<PageToolbarSeparator />
|
||||
|
||||
<PageToolbarButton
|
||||
label="Refresh"
|
||||
label={translate('Refresh')}
|
||||
iconName={icons.REFRESH}
|
||||
spinningName={icons.REFRESH}
|
||||
isSpinning={isFetching}
|
||||
@@ -66,7 +71,7 @@ class LogFiles extends Component {
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Clear"
|
||||
label={translate('Clear')}
|
||||
iconName={icons.CLEAR}
|
||||
isSpinning={deleteFilesExecuting}
|
||||
onPress={onDeleteFilesPress}
|
||||
@@ -76,13 +81,15 @@ class LogFiles extends Component {
|
||||
<PageContentBody>
|
||||
<Alert>
|
||||
<div>
|
||||
Log files are located in: {location}
|
||||
{translate('LogFilesLocation', {
|
||||
location
|
||||
})}
|
||||
</div>
|
||||
|
||||
{
|
||||
currentLogView === 'Log Files' &&
|
||||
<div>
|
||||
The log level defaults to 'Info' and can be changed in <Link to="/settings/general">General Settings</Link>
|
||||
<InlineMarkdown data={translate('TheLogLevelDefault')} />
|
||||
</div>
|
||||
}
|
||||
</Alert>
|
||||
@@ -118,7 +125,7 @@ class LogFiles extends Component {
|
||||
{
|
||||
!isFetching && !items.length &&
|
||||
<Alert kind={kinds.INFO}>
|
||||
No log files
|
||||
{translate('NoLogFiles')}
|
||||
</Alert>
|
||||
}
|
||||
</PageContentBody>
|
||||
|
||||
@@ -7,6 +7,7 @@ import { executeCommand } from 'Store/Actions/commandActions';
|
||||
import { fetchLogFiles } from 'Store/Actions/systemActions';
|
||||
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
|
||||
import combinePath from 'Utilities/String/combinePath';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import LogFiles from './LogFiles';
|
||||
|
||||
function createMapStateToProps() {
|
||||
@@ -29,7 +30,7 @@ function createMapStateToProps() {
|
||||
isFetching,
|
||||
items,
|
||||
deleteFilesExecuting,
|
||||
currentLogView: 'Log Files',
|
||||
currentLogView: translate('LogFiles'),
|
||||
location: combinePath(isWindows, appData, ['logs'])
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import Link from 'Components/Link/Link';
|
||||
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
|
||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './LogFilesTableRow.css';
|
||||
|
||||
class LogFilesTableRow extends Component {
|
||||
@@ -32,7 +33,7 @@ class LogFilesTableRow extends Component {
|
||||
target="_blank"
|
||||
noRouter={true}
|
||||
>
|
||||
Download
|
||||
{translate('Download')}
|
||||
</Link>
|
||||
</TableRowCell>
|
||||
</TableRow>
|
||||
|
||||
@@ -4,6 +4,7 @@ import Menu from 'Components/Menu/Menu';
|
||||
import MenuButton from 'Components/Menu/MenuButton';
|
||||
import MenuContent from 'Components/Menu/MenuContent';
|
||||
import MenuItem from 'Components/Menu/MenuItem';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
class LogsNavMenu extends Component {
|
||||
|
||||
@@ -50,13 +51,13 @@ class LogsNavMenu extends Component {
|
||||
<MenuItem
|
||||
to={'/system/logs/files'}
|
||||
>
|
||||
Log Files
|
||||
{translate('LogFiles')}
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem
|
||||
to={'/system/logs/files/update'}
|
||||
>
|
||||
Updater Log Files
|
||||
{translate('UpdaterLogFiles')}
|
||||
</MenuItem>
|
||||
</MenuContent>
|
||||
</Menu>
|
||||
|
||||
@@ -5,6 +5,7 @@ import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'
|
||||
import FieldSet from 'Components/FieldSet';
|
||||
import InlineMarkdown from 'Components/Markdown/InlineMarkdown';
|
||||
import titleCase from 'Utilities/String/titleCase';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import StartTime from './StartTime';
|
||||
import styles from './About.css';
|
||||
|
||||
@@ -30,25 +31,32 @@ class About extends Component {
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<FieldSet legend="About">
|
||||
<FieldSet legend={translate('About')}>
|
||||
<DescriptionList className={styles.descriptionList}>
|
||||
<DescriptionListItem
|
||||
title="Version"
|
||||
title={translate('Version')}
|
||||
data={version}
|
||||
/>
|
||||
|
||||
{
|
||||
packageVersion &&
|
||||
<DescriptionListItem
|
||||
title="Package Version"
|
||||
data={(packageAuthor ? <span> {packageVersion} {' by '} <InlineMarkdown data={packageAuthor} /> </span> : packageVersion)}
|
||||
title={translate('PackageVersion')}
|
||||
data={(packageAuthor ?
|
||||
<InlineMarkdown data={translate('PackageVersionInfo', {
|
||||
packageVersion,
|
||||
packageAuthor
|
||||
})}
|
||||
/> :
|
||||
packageVersion
|
||||
)}
|
||||
/>
|
||||
}
|
||||
|
||||
{
|
||||
isNetCore &&
|
||||
<DescriptionListItem
|
||||
title=".Net Version"
|
||||
title={translate('DotNetVersion')}
|
||||
data={`Yes (${runtimeVersion})`}
|
||||
/>
|
||||
}
|
||||
@@ -56,28 +64,28 @@ class About extends Component {
|
||||
{
|
||||
isDocker &&
|
||||
<DescriptionListItem
|
||||
title="Docker"
|
||||
title={translate('Docker')}
|
||||
data={'Yes'}
|
||||
/>
|
||||
}
|
||||
|
||||
<DescriptionListItem
|
||||
title="AppData directory"
|
||||
title={translate('AppDataDirectory')}
|
||||
data={appData}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="Startup directory"
|
||||
title={translate('StartupDirectory')}
|
||||
data={startupPath}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="Mode"
|
||||
title={translate('Mode')}
|
||||
data={titleCase(mode)}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="Uptime"
|
||||
title={translate('Uptime')}
|
||||
data={
|
||||
<StartTime
|
||||
startTime={startTime}
|
||||
|
||||
@@ -9,22 +9,29 @@ import TableBody from 'Components/Table/TableBody';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import { kinds, sizes } from 'Helpers/Props';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './DiskSpace.css';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
name: 'path',
|
||||
label: 'Location',
|
||||
get label() {
|
||||
return translate('Location');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'freeSpace',
|
||||
label: 'Free Space',
|
||||
get label() {
|
||||
return translate('FreeSpace');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'totalSpace',
|
||||
label: 'Total Space',
|
||||
get label() {
|
||||
return translate('TotalSpace');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
@@ -45,7 +52,7 @@ class DiskSpace extends Component {
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<FieldSet legend="Disk Space">
|
||||
<FieldSet legend={translate('DiskSpace')}>
|
||||
{
|
||||
isFetching &&
|
||||
<LoadingIndicator />
|
||||
|
||||
@@ -11,6 +11,7 @@ import TableBody from 'Components/Table/TableBody';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import titleCase from 'Utilities/String/titleCase';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './Health.css';
|
||||
|
||||
function getInternalLink(source) {
|
||||
@@ -23,7 +24,7 @@ function getInternalLink(source) {
|
||||
return (
|
||||
<IconButton
|
||||
name={icons.SETTINGS}
|
||||
title="Settings"
|
||||
title={translate('Settings')}
|
||||
to="/settings/indexers"
|
||||
/>
|
||||
);
|
||||
@@ -33,7 +34,7 @@ function getInternalLink(source) {
|
||||
return (
|
||||
<IconButton
|
||||
name={icons.SETTINGS}
|
||||
title="Settings"
|
||||
title={translate('Settings')}
|
||||
to="/settings/downloadclients"
|
||||
/>
|
||||
);
|
||||
@@ -41,7 +42,7 @@ function getInternalLink(source) {
|
||||
return (
|
||||
<IconButton
|
||||
name={icons.SERIES_CONTINUING}
|
||||
title="Series Editor"
|
||||
title={translate('SeriesEditor')}
|
||||
to="/serieseditor"
|
||||
/>
|
||||
);
|
||||
@@ -49,7 +50,7 @@ function getInternalLink(source) {
|
||||
return (
|
||||
<IconButton
|
||||
name={icons.UPDATE}
|
||||
title="Updates"
|
||||
title={translate('Updates')}
|
||||
to="/system/updates"
|
||||
/>
|
||||
);
|
||||
@@ -64,7 +65,7 @@ function getTestLink(source, props) {
|
||||
return (
|
||||
<SpinnerIconButton
|
||||
name={icons.TEST}
|
||||
title="Test All"
|
||||
title={translate('TestAll')}
|
||||
isSpinning={props.isTestingAllIndexers}
|
||||
onPress={props.dispatchTestAllIndexers}
|
||||
/>
|
||||
@@ -74,7 +75,7 @@ function getTestLink(source, props) {
|
||||
return (
|
||||
<SpinnerIconButton
|
||||
name={icons.TEST}
|
||||
title="Test All"
|
||||
title={translate('TestAll')}
|
||||
isSpinning={props.isTestingAllDownloadClients}
|
||||
onPress={props.dispatchTestAllDownloadClients}
|
||||
/>
|
||||
@@ -93,12 +94,16 @@ const columns = [
|
||||
},
|
||||
{
|
||||
name: 'message',
|
||||
label: 'Message',
|
||||
get label() {
|
||||
return translate('Message');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'actions',
|
||||
label: 'Actions',
|
||||
get label() {
|
||||
return translate('Actions');
|
||||
},
|
||||
isVisible: true
|
||||
}
|
||||
];
|
||||
@@ -121,7 +126,7 @@ class Health extends Component {
|
||||
<FieldSet
|
||||
legend={
|
||||
<div className={styles.legend}>
|
||||
Health
|
||||
{translate('Health')}
|
||||
|
||||
{
|
||||
isFetching && isPopulated &&
|
||||
@@ -141,7 +146,7 @@ class Health extends Component {
|
||||
{
|
||||
!healthIssues &&
|
||||
<div className={styles.healthOk}>
|
||||
No issues with your configuration
|
||||
{translate('NoIssuesWithYourConfiguration')}
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -186,7 +191,7 @@ class Health extends Component {
|
||||
<IconButton
|
||||
name={icons.WIKI}
|
||||
to={item.wikiUrl}
|
||||
title="Read the Wiki for more information"
|
||||
title={translate('ReadTheWikiForMoreInformation')}
|
||||
/>
|
||||
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ import DescriptionListItemDescription from 'Components/DescriptionList/Descripti
|
||||
import DescriptionListItemTitle from 'Components/DescriptionList/DescriptionListItemTitle';
|
||||
import FieldSet from 'Components/FieldSet';
|
||||
import Link from 'Components/Link/Link';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
class MoreInfo extends Component {
|
||||
|
||||
@@ -12,34 +13,46 @@ class MoreInfo extends Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<FieldSet legend="More Info">
|
||||
<FieldSet legend={translate('MoreInfo')}>
|
||||
<DescriptionList>
|
||||
<DescriptionListItemTitle>Home page</DescriptionListItemTitle>
|
||||
<DescriptionListItemTitle>
|
||||
{translate('HomePage')}
|
||||
</DescriptionListItemTitle>
|
||||
<DescriptionListItemDescription>
|
||||
<Link to="https://sonarr.tv/">sonarr.tv</Link>
|
||||
</DescriptionListItemDescription>
|
||||
|
||||
<DescriptionListItemTitle>Wiki</DescriptionListItemTitle>
|
||||
<DescriptionListItemTitle>
|
||||
{translate('Wiki')}
|
||||
</DescriptionListItemTitle>
|
||||
<DescriptionListItemDescription>
|
||||
<Link to="https://wiki.servarr.com/sonarr">wiki.servarr.com/sonarr</Link>
|
||||
</DescriptionListItemDescription>
|
||||
|
||||
<DescriptionListItemTitle>Forums</DescriptionListItemTitle>
|
||||
<DescriptionListItemTitle>
|
||||
{translate('Forums')}
|
||||
</DescriptionListItemTitle>
|
||||
<DescriptionListItemDescription>
|
||||
<Link to="https://forums.sonarr.tv/">forums.sonarr.tv</Link>
|
||||
</DescriptionListItemDescription>
|
||||
|
||||
<DescriptionListItemTitle>Twitter</DescriptionListItemTitle>
|
||||
<DescriptionListItemTitle>
|
||||
{translate('Twitter')}
|
||||
</DescriptionListItemTitle>
|
||||
<DescriptionListItemDescription>
|
||||
<Link to="https://twitter.com/sonarrtv">@sonarrtv</Link>
|
||||
</DescriptionListItemDescription>
|
||||
|
||||
<DescriptionListItemTitle>Discord</DescriptionListItemTitle>
|
||||
<DescriptionListItemTitle>
|
||||
{translate('Discord')}
|
||||
</DescriptionListItemTitle>
|
||||
<DescriptionListItemDescription>
|
||||
<Link to="https://discord.sonarr.tv/">discord.sonarr.tv</Link>
|
||||
</DescriptionListItemDescription>
|
||||
|
||||
<DescriptionListItemTitle>IRC</DescriptionListItemTitle>
|
||||
<DescriptionListItemTitle>
|
||||
{translate('IRC')}
|
||||
</DescriptionListItemTitle>
|
||||
<DescriptionListItemDescription>
|
||||
<Link to="irc://irc.libera.chat/#sonarr">#sonarr on Libera</Link>
|
||||
</DescriptionListItemDescription>
|
||||
@@ -47,17 +60,23 @@ class MoreInfo extends Component {
|
||||
<Link to="https://web.libera.chat/?channels=#sonarr">Libera webchat</Link>
|
||||
</DescriptionListItemDescription>
|
||||
|
||||
<DescriptionListItemTitle>Donations</DescriptionListItemTitle>
|
||||
<DescriptionListItemTitle>
|
||||
{translate('Donations')}
|
||||
</DescriptionListItemTitle>
|
||||
<DescriptionListItemDescription>
|
||||
<Link to="https://sonarr.tv/donate">sonarr.tv/donate</Link>
|
||||
</DescriptionListItemDescription>
|
||||
|
||||
<DescriptionListItemTitle>Source</DescriptionListItemTitle>
|
||||
<DescriptionListItemTitle>
|
||||
{translate('Source')}
|
||||
</DescriptionListItemTitle>
|
||||
<DescriptionListItemDescription>
|
||||
<Link to="https://github.com/Sonarr/Sonarr/">github.com/Sonarr/Sonarr</Link>
|
||||
</DescriptionListItemDescription>
|
||||
|
||||
<DescriptionListItemTitle>Feature Requests</DescriptionListItemTitle>
|
||||
<DescriptionListItemTitle>
|
||||
{translate('FeatureRequests')}
|
||||
</DescriptionListItemTitle>
|
||||
<DescriptionListItemDescription>
|
||||
<Link to="https://forums.sonarr.tv/">forums.sonarr.tv</Link>
|
||||
</DescriptionListItemDescription>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import PageContent from 'Components/Page/PageContent';
|
||||
import PageContentBody from 'Components/Page/PageContentBody';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import AboutConnector from './About/AboutConnector';
|
||||
import DiskSpaceConnector from './DiskSpace/DiskSpaceConnector';
|
||||
import HealthConnector from './Health/HealthConnector';
|
||||
@@ -13,7 +14,7 @@ class Status extends Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<PageContent title="Status">
|
||||
<PageContent title={translate('Status')}>
|
||||
<PageContentBody>
|
||||
<HealthConnector />
|
||||
<DiskSpaceConnector />
|
||||
|
||||
@@ -11,6 +11,7 @@ import formatDate from 'Utilities/Date/formatDate';
|
||||
import formatDateTime from 'Utilities/Date/formatDateTime';
|
||||
import formatTimeSpan from 'Utilities/Date/formatTimeSpan';
|
||||
import titleCase from 'Utilities/String/titleCase';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './QueuedTaskRow.css';
|
||||
|
||||
function getStatusIconProps(status, message) {
|
||||
@@ -198,8 +199,8 @@ class QueuedTaskRow extends Component {
|
||||
</span>
|
||||
{
|
||||
clientUserAgent ?
|
||||
<span className={styles.userAgent} title="User-Agent provided by the app that called the API">
|
||||
from: {clientUserAgent}
|
||||
<span className={styles.userAgent} title={translate('TaskUserAgentTooltip')}>
|
||||
{translate('From')}: {clientUserAgent}
|
||||
</span> :
|
||||
null
|
||||
}
|
||||
@@ -236,7 +237,7 @@ class QueuedTaskRow extends Component {
|
||||
{
|
||||
status === 'queued' &&
|
||||
<IconButton
|
||||
title="Removed from task queue"
|
||||
title={translate('RemovedFromTaskQueue')}
|
||||
name={icons.REMOVE}
|
||||
onPress={this.onCancelPress}
|
||||
/>
|
||||
@@ -246,10 +247,10 @@ class QueuedTaskRow extends Component {
|
||||
<ConfirmModal
|
||||
isOpen={isCancelConfirmModalOpen}
|
||||
kind={kinds.DANGER}
|
||||
title="Cancel"
|
||||
message={'Are you sure you want to cancel this pending task?'}
|
||||
confirmLabel="Yes, Cancel"
|
||||
cancelLabel="No, Leave It"
|
||||
title={translate('Cancel')}
|
||||
message={translate('CancelPendingTask')}
|
||||
confirmLabel={translate('YesCancel')}
|
||||
cancelLabel={translate('NoLeaveIt')}
|
||||
onConfirm={onCancelPress}
|
||||
onCancel={this.onAbortCancel}
|
||||
/>
|
||||
|
||||
@@ -4,6 +4,7 @@ import FieldSet from 'Components/FieldSet';
|
||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import QueuedTaskRowConnector from './QueuedTaskRowConnector';
|
||||
|
||||
const columns = [
|
||||
@@ -14,27 +15,37 @@ const columns = [
|
||||
},
|
||||
{
|
||||
name: 'commandName',
|
||||
label: 'Name',
|
||||
get label() {
|
||||
return translate('Name');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'queued',
|
||||
label: 'Queued',
|
||||
get label() {
|
||||
return translate('Queued');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'started',
|
||||
label: 'Started',
|
||||
get label() {
|
||||
return translate('Started');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'ended',
|
||||
label: 'Ended',
|
||||
get label() {
|
||||
return translate('Ended');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'duration',
|
||||
label: 'Duration',
|
||||
get label() {
|
||||
return translate('Duration');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
@@ -51,7 +62,7 @@ function QueuedTasks(props) {
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<FieldSet legend="Queue">
|
||||
<FieldSet legend={translate('Queue')}>
|
||||
{
|
||||
isFetching && !isPopulated &&
|
||||
<LoadingIndicator />
|
||||
|
||||
@@ -4,32 +4,43 @@ import FieldSet from 'Components/FieldSet';
|
||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import ScheduledTaskRowConnector from './ScheduledTaskRowConnector';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
name: 'name',
|
||||
label: 'Name',
|
||||
get label() {
|
||||
return translate('Name');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'interval',
|
||||
label: 'Interval',
|
||||
get label() {
|
||||
return translate('Interval');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'lastExecution',
|
||||
label: 'Last Execution',
|
||||
get label() {
|
||||
return translate('LastExecution');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'lastDuration',
|
||||
label: 'Last Duration',
|
||||
get label() {
|
||||
return translate('LastDuration');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'nextExecution',
|
||||
label: 'Next Execution',
|
||||
get label() {
|
||||
return translate('NextExecution');
|
||||
},
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
@@ -46,7 +57,7 @@ function ScheduledTasks(props) {
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<FieldSet legend="Scheduled">
|
||||
<FieldSet legend={translate('Scheduled')}>
|
||||
{
|
||||
isFetching && !isPopulated &&
|
||||
<LoadingIndicator />
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import React from 'react';
|
||||
import PageContent from 'Components/Page/PageContent';
|
||||
import PageContentBody from 'Components/Page/PageContentBody';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import QueuedTasksConnector from './Queued/QueuedTasksConnector';
|
||||
import ScheduledTasksConnector from './Scheduled/ScheduledTasksConnector';
|
||||
|
||||
function Tasks() {
|
||||
return (
|
||||
<PageContent title="Tasks">
|
||||
<PageContent title={translate('Tasks')}>
|
||||
<PageContentBody>
|
||||
<ScheduledTasksConnector />
|
||||
<QueuedTasksConnector />
|
||||
|
||||
@@ -12,6 +12,7 @@ import PageContentBody from 'Components/Page/PageContentBody';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import formatDate from 'Utilities/Date/formatDate';
|
||||
import formatDateTime from 'Utilities/Date/formatDateTime';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import UpdateChanges from './UpdateChanges';
|
||||
import styles from './Updates.css';
|
||||
|
||||
@@ -43,15 +44,15 @@ class Updates extends Component {
|
||||
const hasUpdateToInstall = hasUpdates && _.some(items, { installable: true, latest: true });
|
||||
const noUpdateToInstall = hasUpdates && !hasUpdateToInstall;
|
||||
|
||||
const externalUpdaterPrefix = 'Unable to update Sonarr directly,';
|
||||
const externalUpdaterPrefix = translate('UnableToUpdateSonarrDirectly');
|
||||
const externalUpdaterMessages = {
|
||||
external: 'Sonarr is configured to use an external update mechanism',
|
||||
apt: 'use apt to install the update',
|
||||
docker: 'update the docker container to receive the update'
|
||||
external: translate('ExternalUpdater'),
|
||||
apt: translate('AptUpdater'),
|
||||
docker: translate('DockerUpdater')
|
||||
};
|
||||
|
||||
return (
|
||||
<PageContent title="Updates">
|
||||
<PageContent title={translate('Updates')}>
|
||||
<PageContentBody>
|
||||
{
|
||||
!isPopulated && !hasError &&
|
||||
@@ -61,7 +62,7 @@ class Updates extends Component {
|
||||
{
|
||||
noUpdates &&
|
||||
<Alert kind={kinds.INFO}>
|
||||
No updates are available
|
||||
{translate('NoUpdatesAreAvailable')}
|
||||
</Alert>
|
||||
}
|
||||
|
||||
@@ -76,7 +77,7 @@ class Updates extends Component {
|
||||
isSpinning={isInstallingUpdate}
|
||||
onPress={onInstallLatestPress}
|
||||
>
|
||||
Install Latest
|
||||
{translate('InstallLatest')}
|
||||
</SpinnerButton> :
|
||||
|
||||
<Fragment>
|
||||
@@ -112,7 +113,7 @@ class Updates extends Component {
|
||||
/>
|
||||
|
||||
<div className={styles.message}>
|
||||
The latest version of Sonarr is already installed
|
||||
{translate('OnLatestVersion')}
|
||||
</div>
|
||||
|
||||
{
|
||||
@@ -164,7 +165,7 @@ class Updates extends Component {
|
||||
kind={kinds.SUCCESS}
|
||||
title={formatDateTime(update.installedOn, longDateFormat, timeFormat)}
|
||||
>
|
||||
Currently Installed
|
||||
{translate('CurrentlyInstalled')}
|
||||
</Label> :
|
||||
null
|
||||
}
|
||||
@@ -176,7 +177,7 @@ class Updates extends Component {
|
||||
kind={kinds.INVERSE}
|
||||
title={formatDateTime(update.installedOn, longDateFormat, timeFormat)}
|
||||
>
|
||||
Previously Installed
|
||||
{translate('PreviouslyInstalled')}
|
||||
</Label> :
|
||||
null
|
||||
}
|
||||
@@ -184,19 +185,21 @@ class Updates extends Component {
|
||||
|
||||
{
|
||||
!hasChanges &&
|
||||
<div>Maintenance Release: See GitHub commit history for details.</div>
|
||||
<div>
|
||||
{translate('MaintenanceRelease')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
hasChanges &&
|
||||
<div className={styles.changes}>
|
||||
<UpdateChanges
|
||||
title="New"
|
||||
title={translate('New')}
|
||||
changes={update.changes.new}
|
||||
/>
|
||||
|
||||
<UpdateChanges
|
||||
title="Fixed"
|
||||
title={translate('Fixed')}
|
||||
changes={update.changes.fixed}
|
||||
/>
|
||||
</div>
|
||||
@@ -211,14 +214,14 @@ class Updates extends Component {
|
||||
{
|
||||
!!updatesError &&
|
||||
<div>
|
||||
Failed to fetch updates
|
||||
{translate('FailedToFetchUpdates')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
!!generalSettingsError &&
|
||||
<div>
|
||||
Failed to update settings
|
||||
{translate('FailedToUpdateSettings')}
|
||||
</div>
|
||||
}
|
||||
</PageContentBody>
|
||||
|
||||
Reference in New Issue
Block a user