mirror of https://github.com/lidarr/Lidarr
Initial pass for translations
This commit is contained in:
parent
93aa50b780
commit
a75a19698d
|
@ -14,6 +14,7 @@ import TablePager from 'Components/Table/TablePager';
|
|||
import { align, icons, kinds } from 'Helpers/Props';
|
||||
import getRemovedItems from 'Utilities/Object/getRemovedItems';
|
||||
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
||||
import removeOldSelectedState from 'Utilities/Table/removeOldSelectedState';
|
||||
import selectAll from 'Utilities/Table/selectAll';
|
||||
|
@ -120,11 +121,11 @@ class Blocklist extends Component {
|
|||
const selectedIds = this.getSelectedIds();
|
||||
|
||||
return (
|
||||
<PageContent title="Blocklist">
|
||||
<PageContent title={translate('Blocklist')}>
|
||||
<PageToolbar>
|
||||
<PageToolbarSection>
|
||||
<PageToolbarButton
|
||||
label="Remove Selected"
|
||||
label={translate('RemoveSelected')}
|
||||
iconName={icons.REMOVE}
|
||||
isDisabled={!selectedIds.length}
|
||||
isSpinning={isRemoving}
|
||||
|
@ -132,7 +133,7 @@ class Blocklist extends Component {
|
|||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Clear"
|
||||
label={translate('Clear')}
|
||||
iconName={icons.CLEAR}
|
||||
isSpinning={isClearingBlocklistExecuting}
|
||||
onPress={onClearBlocklistPress}
|
||||
|
@ -145,7 +146,7 @@ class Blocklist extends Component {
|
|||
columns={columns}
|
||||
>
|
||||
<PageToolbarButton
|
||||
label="Options"
|
||||
label={translate('Options')}
|
||||
iconName={icons.TABLE}
|
||||
/>
|
||||
</TableOptionsModalWrapper>
|
||||
|
@ -160,7 +161,9 @@ class Blocklist extends Component {
|
|||
|
||||
{
|
||||
!isAnyFetching && !!error &&
|
||||
<div>Unable to load blocklist</div>
|
||||
<div>
|
||||
{translate('UnableToLoadBlocklist')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -210,9 +213,9 @@ class Blocklist extends Component {
|
|||
<ConfirmModal
|
||||
isOpen={isConfirmRemoveModalOpen}
|
||||
kind={kinds.DANGER}
|
||||
title="Remove Selected"
|
||||
message={'Are you sure you want to remove the selected items from the blocklist?'}
|
||||
confirmLabel="Remove Selected"
|
||||
title={translate('RemoveSelected')}
|
||||
message={translate('RemoveSelectedMessageText')}
|
||||
confirmLabel={translate('RemoveSelected')}
|
||||
onConfirm={this.onRemoveSelectedConfirmed}
|
||||
onCancel={this.onConfirmRemoveModalClose}
|
||||
/>
|
||||
|
|
|
@ -8,6 +8,7 @@ import ModalBody from 'Components/Modal/ModalBody';
|
|||
import ModalContent from 'Components/Modal/ModalContent';
|
||||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
class BlocklistDetailsModal extends Component {
|
||||
|
||||
|
@ -39,19 +40,19 @@ class BlocklistDetailsModal extends Component {
|
|||
<ModalBody>
|
||||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
title="Name"
|
||||
title={translate('Name')}
|
||||
data={sourceTitle}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="Protocol"
|
||||
title={translate('Protocol')}
|
||||
data={protocol}
|
||||
/>
|
||||
|
||||
{
|
||||
!!message &&
|
||||
<DescriptionListItem
|
||||
title="Indexer"
|
||||
title={translate('Indexer')}
|
||||
data={indexer}
|
||||
/>
|
||||
}
|
||||
|
@ -59,7 +60,7 @@ class BlocklistDetailsModal extends Component {
|
|||
{
|
||||
!!message &&
|
||||
<DescriptionListItem
|
||||
title="Message"
|
||||
title={translate('Message')}
|
||||
data={message}
|
||||
/>
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
|||
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import BlocklistDetailsModal from './BlocklistDetailsModal';
|
||||
import styles from './BlocklistRow.css';
|
||||
|
||||
|
@ -141,7 +142,7 @@ class BlocklistRow extends Component {
|
|||
/>
|
||||
|
||||
<IconButton
|
||||
title="Remove from blocklist"
|
||||
title={translate('RemoveFromBlocklist')}
|
||||
name={icons.REMOVE}
|
||||
kind={kinds.DANGER}
|
||||
onPress={onRemovePress}
|
||||
|
|
|
@ -9,6 +9,7 @@ import Link from 'Components/Link/Link';
|
|||
import { icons } from 'Helpers/Props';
|
||||
import formatDateTime from 'Utilities/Date/formatDateTime';
|
||||
import formatAge from 'Utilities/Number/formatAge';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './HistoryDetails.css';
|
||||
|
||||
function getDetailedList(statusMessages) {
|
||||
|
@ -47,7 +48,9 @@ function formatMissing(value) {
|
|||
|
||||
function formatChange(oldValue, newValue) {
|
||||
return (
|
||||
<div> {formatMissing(oldValue)} <Icon name={icons.ARROW_RIGHT_NO_CIRCLE} size={12} /> {formatMissing(newValue)} </div>
|
||||
<div>
|
||||
{formatMissing(oldValue)} <Icon name={icons.ARROW_RIGHT_NO_CIRCLE} size={12} /> {formatMissing(newValue)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -77,14 +80,14 @@ function HistoryDetails(props) {
|
|||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
descriptionClassName={styles.description}
|
||||
title="Name"
|
||||
title={translate('Name')}
|
||||
data={sourceTitle}
|
||||
/>
|
||||
|
||||
{
|
||||
!!indexer &&
|
||||
<DescriptionListItem
|
||||
title="Indexer"
|
||||
title={translate('Indexer')}
|
||||
data={indexer}
|
||||
/>
|
||||
}
|
||||
|
@ -93,7 +96,7 @@ function HistoryDetails(props) {
|
|||
!!releaseGroup &&
|
||||
<DescriptionListItem
|
||||
descriptionClassName={styles.description}
|
||||
title="Release Group"
|
||||
title={translate('ReleaseGroup')}
|
||||
data={releaseGroup}
|
||||
/>
|
||||
}
|
||||
|
@ -114,7 +117,7 @@ function HistoryDetails(props) {
|
|||
{
|
||||
!!downloadClient &&
|
||||
<DescriptionListItem
|
||||
title="Download Client"
|
||||
title={translate('DownloadClient')}
|
||||
data={downloadClient}
|
||||
/>
|
||||
}
|
||||
|
@ -122,7 +125,7 @@ function HistoryDetails(props) {
|
|||
{
|
||||
!!downloadId &&
|
||||
<DescriptionListItem
|
||||
title="Grab ID"
|
||||
title={translate('GrabID')}
|
||||
data={downloadId}
|
||||
/>
|
||||
}
|
||||
|
@ -130,7 +133,7 @@ function HistoryDetails(props) {
|
|||
{
|
||||
!!indexer &&
|
||||
<DescriptionListItem
|
||||
title="Age (when grabbed)"
|
||||
title={translate('AgeWhenGrabbed')}
|
||||
data={formatAge(age, ageHours, ageMinutes)}
|
||||
/>
|
||||
}
|
||||
|
@ -138,7 +141,7 @@ function HistoryDetails(props) {
|
|||
{
|
||||
!!publishedDate &&
|
||||
<DescriptionListItem
|
||||
title="Published Date"
|
||||
title={translate('PublishedDate')}
|
||||
data={formatDateTime(publishedDate, shortDateFormat, timeFormat, { includeSeconds: true })}
|
||||
/>
|
||||
}
|
||||
|
@ -155,14 +158,14 @@ function HistoryDetails(props) {
|
|||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
descriptionClassName={styles.description}
|
||||
title="Name"
|
||||
title={translate('Name')}
|
||||
data={sourceTitle}
|
||||
/>
|
||||
|
||||
{
|
||||
!!message &&
|
||||
<DescriptionListItem
|
||||
title="Message"
|
||||
title={translate('Message')}
|
||||
data={message}
|
||||
/>
|
||||
}
|
||||
|
@ -180,7 +183,7 @@ function HistoryDetails(props) {
|
|||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
descriptionClassName={styles.description}
|
||||
title="Name"
|
||||
title={translate('Name')}
|
||||
data={sourceTitle}
|
||||
/>
|
||||
|
||||
|
@ -188,7 +191,7 @@ function HistoryDetails(props) {
|
|||
!!droppedPath &&
|
||||
<DescriptionListItem
|
||||
descriptionClassName={styles.description}
|
||||
title="Source"
|
||||
title={translate('Source')}
|
||||
data={droppedPath}
|
||||
/>
|
||||
}
|
||||
|
@ -197,7 +200,7 @@ function HistoryDetails(props) {
|
|||
!!importedPath &&
|
||||
<DescriptionListItem
|
||||
descriptionClassName={styles.description}
|
||||
title="Imported To"
|
||||
title={translate('ImportedTo')}
|
||||
data={importedPath}
|
||||
/>
|
||||
}
|
||||
|
@ -229,12 +232,12 @@ function HistoryDetails(props) {
|
|||
return (
|
||||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
title="Name"
|
||||
title={translate('Name')}
|
||||
data={sourceTitle}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="Reason"
|
||||
title={translate('Reason')}
|
||||
data={reasonMessage}
|
||||
/>
|
||||
</DescriptionList>
|
||||
|
@ -250,12 +253,12 @@ function HistoryDetails(props) {
|
|||
return (
|
||||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
title="Source Path"
|
||||
title={translate('SourcePath')}
|
||||
data={sourcePath}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="Destination Path"
|
||||
title={translate('DestinationPath')}
|
||||
data={path}
|
||||
/>
|
||||
</DescriptionList>
|
||||
|
@ -271,7 +274,7 @@ function HistoryDetails(props) {
|
|||
return (
|
||||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
title="Path"
|
||||
title={translate('Path')}
|
||||
data={sourceTitle}
|
||||
/>
|
||||
{
|
||||
|
@ -286,7 +289,7 @@ function HistoryDetails(props) {
|
|||
})
|
||||
}
|
||||
<DescriptionListItem
|
||||
title="Existing tags scrubbed"
|
||||
title={translate('ExistingTagsScrubbed')}
|
||||
data={tagsScrubbed === 'True' ? <Icon name={icons.CHECK} /> : <Icon name={icons.REMOVE} />}
|
||||
/>
|
||||
</DescriptionList>
|
||||
|
@ -301,14 +304,14 @@ function HistoryDetails(props) {
|
|||
return (
|
||||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
title="Name"
|
||||
title={translate('Name')}
|
||||
data={sourceTitle}
|
||||
/>
|
||||
|
||||
{
|
||||
!!statusMessages &&
|
||||
<DescriptionListItem
|
||||
title="Import failures"
|
||||
title={translate('ImportFailures')}
|
||||
data={getDetailedList(JSON.parse(statusMessages))}
|
||||
/>
|
||||
}
|
||||
|
@ -332,14 +335,14 @@ function HistoryDetails(props) {
|
|||
return (
|
||||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
title="Name"
|
||||
title={translate('Name')}
|
||||
data={sourceTitle}
|
||||
/>
|
||||
|
||||
{
|
||||
!!indexer &&
|
||||
<DescriptionListItem
|
||||
title="Indexer"
|
||||
title={translate('Indexer')}
|
||||
data={indexer}
|
||||
/>
|
||||
}
|
||||
|
@ -347,7 +350,7 @@ function HistoryDetails(props) {
|
|||
{
|
||||
!!releaseGroup &&
|
||||
<DescriptionListItem
|
||||
title="Release Group"
|
||||
title={translate('ReleaseGroup')}
|
||||
data={releaseGroup}
|
||||
/>
|
||||
}
|
||||
|
@ -368,7 +371,7 @@ function HistoryDetails(props) {
|
|||
{
|
||||
!!downloadClient &&
|
||||
<DescriptionListItem
|
||||
title="Download Client"
|
||||
title={translate('DownloadClient')}
|
||||
data={downloadClient}
|
||||
/>
|
||||
}
|
||||
|
@ -376,7 +379,7 @@ function HistoryDetails(props) {
|
|||
{
|
||||
!!downloadId &&
|
||||
<DescriptionListItem
|
||||
title="Grab ID"
|
||||
title={translate('GrabID')}
|
||||
data={downloadId}
|
||||
/>
|
||||
}
|
||||
|
@ -384,7 +387,7 @@ function HistoryDetails(props) {
|
|||
{
|
||||
!!indexer &&
|
||||
<DescriptionListItem
|
||||
title="Age (when grabbed)"
|
||||
title={translate('AgeWhenGrabbed')}
|
||||
data={formatAge(age, ageHours, ageMinutes)}
|
||||
/>
|
||||
}
|
||||
|
@ -392,7 +395,7 @@ function HistoryDetails(props) {
|
|||
{
|
||||
!!publishedDate &&
|
||||
<DescriptionListItem
|
||||
title="Published Date"
|
||||
title={translate('PublishedDate')}
|
||||
data={formatDateTime(publishedDate, shortDateFormat, timeFormat, { includeSeconds: true })}
|
||||
/>
|
||||
}
|
||||
|
@ -409,14 +412,14 @@ function HistoryDetails(props) {
|
|||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
descriptionClassName={styles.description}
|
||||
title="Name"
|
||||
title={translate('Name')}
|
||||
data={sourceTitle}
|
||||
/>
|
||||
|
||||
{
|
||||
!!message &&
|
||||
<DescriptionListItem
|
||||
title="Message"
|
||||
title={translate('Message')}
|
||||
data={message}
|
||||
/>
|
||||
}
|
||||
|
@ -428,7 +431,7 @@ function HistoryDetails(props) {
|
|||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
descriptionClassName={styles.description}
|
||||
title="Name"
|
||||
title={translate('Name')}
|
||||
data={sourceTitle}
|
||||
/>
|
||||
</DescriptionList>
|
||||
|
|
|
@ -13,6 +13,7 @@ import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptions
|
|||
import TablePager from 'Components/Table/TablePager';
|
||||
import { align, icons } from 'Helpers/Props';
|
||||
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import HistoryRowConnector from './HistoryRowConnector';
|
||||
|
||||
class History extends Component {
|
||||
|
@ -66,11 +67,11 @@ class History extends Component {
|
|||
const hasError = error || albumsError;
|
||||
|
||||
return (
|
||||
<PageContent title="History">
|
||||
<PageContent title={translate('History')}>
|
||||
<PageToolbar>
|
||||
<PageToolbarSection>
|
||||
<PageToolbarButton
|
||||
label="Refresh"
|
||||
label={translate('Refresh')}
|
||||
iconName={icons.REFRESH}
|
||||
isSpinning={isFetching}
|
||||
onPress={onFirstPagePress}
|
||||
|
@ -83,7 +84,7 @@ class History extends Component {
|
|||
columns={columns}
|
||||
>
|
||||
<PageToolbarButton
|
||||
label="Options"
|
||||
label={translate('Options')}
|
||||
iconName={icons.TABLE}
|
||||
/>
|
||||
</TableOptionsModalWrapper>
|
||||
|
@ -106,7 +107,9 @@ class History extends Component {
|
|||
|
||||
{
|
||||
!isFetchingAny && hasError &&
|
||||
<div>Unable to load history</div>
|
||||
<div>
|
||||
{translate('UnableToLoadHistory')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@ import TablePager from 'Components/Table/TablePager';
|
|||
import { align, icons } from 'Helpers/Props';
|
||||
import getRemovedItems from 'Utilities/Object/getRemovedItems';
|
||||
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
||||
import removeOldSelectedState from 'Utilities/Table/removeOldSelectedState';
|
||||
import selectAll from 'Utilities/Table/selectAll';
|
||||
|
@ -168,11 +169,11 @@ class Queue extends Component {
|
|||
const disableSelectedActions = selectedCount === 0;
|
||||
|
||||
return (
|
||||
<PageContent title="Queue">
|
||||
<PageContent title={translate('Queue')}>
|
||||
<PageToolbar>
|
||||
<PageToolbarSection>
|
||||
<PageToolbarButton
|
||||
label="Refresh"
|
||||
label={translate('Refresh')}
|
||||
iconName={icons.REFRESH}
|
||||
isSpinning={isRefreshing}
|
||||
onPress={onRefreshPress}
|
||||
|
@ -181,7 +182,7 @@ class Queue extends Component {
|
|||
<PageToolbarSeparator />
|
||||
|
||||
<PageToolbarButton
|
||||
label="Grab Selected"
|
||||
label={translate('GrabSelected')}
|
||||
iconName={icons.DOWNLOAD}
|
||||
isDisabled={disableSelectedActions || !isPendingSelected}
|
||||
isSpinning={isGrabbing}
|
||||
|
@ -189,7 +190,7 @@ class Queue extends Component {
|
|||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Remove Selected"
|
||||
label={translate('RemoveSelected')}
|
||||
iconName={icons.REMOVE}
|
||||
isDisabled={disableSelectedActions}
|
||||
isSpinning={isRemoving}
|
||||
|
@ -206,7 +207,7 @@ class Queue extends Component {
|
|||
optionsComponent={QueueOptionsConnector}
|
||||
>
|
||||
<PageToolbarButton
|
||||
label="Options"
|
||||
label={translate('Options')}
|
||||
iconName={icons.TABLE}
|
||||
/>
|
||||
</TableOptionsModalWrapper>
|
||||
|
|
|
@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|||
import React from 'react';
|
||||
import Icon from 'Components/Icon';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
function QueueDetails(props) {
|
||||
const {
|
||||
|
@ -23,7 +24,7 @@ function QueueDetails(props) {
|
|||
return (
|
||||
<Icon
|
||||
name={icons.PENDING}
|
||||
title={`Release will be processed ${moment(estimatedCompletionTime).fromNow()}`}
|
||||
title={translate('ReleaseWillBeProcessedInterp', [moment(estimatedCompletionTime).fromNow()])}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -34,7 +35,7 @@ function QueueDetails(props) {
|
|||
<Icon
|
||||
name={icons.DOWNLOAD}
|
||||
kind={kinds.DANGER}
|
||||
title={`Import failed: ${errorMessage}`}
|
||||
title={translate('ImportFailedInterp', [errorMessage])}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -47,7 +48,7 @@ function QueueDetails(props) {
|
|||
<Icon
|
||||
name={icons.DOWNLOADING}
|
||||
kind={kinds.DANGER}
|
||||
title={`Download failed: ${errorMessage}`}
|
||||
title={translate('DownloadFailedInterp', [errorMessage])}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -57,7 +58,7 @@ function QueueDetails(props) {
|
|||
<Icon
|
||||
name={icons.DOWNLOADING}
|
||||
kind={kinds.DANGER}
|
||||
title="Download failed: check download client for more details"
|
||||
title={translate('DownloadFailedCheckDownloadClientForMoreDetails')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -67,7 +68,7 @@ function QueueDetails(props) {
|
|||
<Icon
|
||||
name={icons.DOWNLOADING}
|
||||
kind={kinds.WARNING}
|
||||
title="Download warning: check download client for more details"
|
||||
title={translate('DownloadWarningCheckDownloadClientForMoreDetails')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -76,7 +77,7 @@ function QueueDetails(props) {
|
|||
return (
|
||||
<Icon
|
||||
name={icons.DOWNLOADING}
|
||||
title={`Album is downloading - ${progress.toFixed(1)}% ${title}`}
|
||||
title={translate('AlbumIsDownloadingInterp', [progress.toFixed(1), title])}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import FormGroup from 'Components/Form/FormGroup';
|
|||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||
import FormLabel from 'Components/Form/FormLabel';
|
||||
import { inputTypes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
class QueueOptions extends Component {
|
||||
|
||||
|
@ -54,13 +55,15 @@ class QueueOptions extends Component {
|
|||
return (
|
||||
<Fragment>
|
||||
<FormGroup>
|
||||
<FormLabel>Show Unknown Artist Items</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowUnknownArtistItems')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="includeUnknownArtistItems"
|
||||
value={includeUnknownArtistItems}
|
||||
helpText="Show items without a artist in the queue, this could include removed artists, movies or anything else in Lidarr's category"
|
||||
helpText={translate('IncludeUnknownArtistItemsHelpText')}
|
||||
onChange={this.onOptionChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
|
|
@ -16,6 +16,7 @@ import Popover from 'Components/Tooltip/Popover';
|
|||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||
import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import QueueStatusCell from './QueueStatusCell';
|
||||
import RemoveQueueItemModal from './RemoveQueueItemModal';
|
||||
import TimeleftCell from './TimeleftCell';
|
||||
|
@ -309,7 +310,7 @@ class QueueRow extends Component {
|
|||
kind={kinds.DANGER}
|
||||
/>
|
||||
}
|
||||
title="Manual Download"
|
||||
title={translate('ManualDownload')}
|
||||
body="This release failed parsing checks and was manually downloaded from an interactive search. Import is likely to fail."
|
||||
position={tooltipPositions.LEFT}
|
||||
/>
|
||||
|
@ -334,7 +335,7 @@ class QueueRow extends Component {
|
|||
}
|
||||
|
||||
<SpinnerIconButton
|
||||
title="Remove from queue"
|
||||
title={translate('RemoveFromQueue')}
|
||||
name={icons.REMOVE}
|
||||
isSpinning={isRemoving}
|
||||
onPress={this.onRemoveQueueItemPress}
|
||||
|
|
|
@ -4,6 +4,7 @@ import Icon from 'Components/Icon';
|
|||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import Popover from 'Components/Tooltip/Popover';
|
||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './QueueStatusCell.css';
|
||||
|
||||
function getDetailedPopoverBody(statusMessages) {
|
||||
|
@ -49,7 +50,7 @@ function QueueStatusCell(props) {
|
|||
// status === 'downloading'
|
||||
let iconName = icons.DOWNLOADING;
|
||||
let iconKind = kinds.DEFAULT;
|
||||
let title = 'Downloading';
|
||||
let title = translate('Downloading');
|
||||
|
||||
if (hasWarning) {
|
||||
iconKind = kinds.WARNING;
|
||||
|
|
|
@ -10,6 +10,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { inputTypes, kinds, sizes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
class RemoveQueueItemModal extends Component {
|
||||
|
||||
|
@ -95,26 +96,30 @@ class RemoveQueueItemModal extends Component {
|
|||
</div>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Remove From Download Client</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('RemoveFromDownloadClient')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="remove"
|
||||
value={remove}
|
||||
helpTextWarning="Removing will remove the download and the file(s) from the download client."
|
||||
helpTextWarning={translate('RemoveHelpTextWarning')}
|
||||
isDisabled={!canIgnore}
|
||||
onChange={this.onRemoveChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Blocklist Release</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('BlocklistRelease')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="blocklist"
|
||||
value={blocklist}
|
||||
helpText="Prevents Lidarr from automatically grabbing this release again"
|
||||
helpText={translate('BlocklistHelpText')}
|
||||
onChange={this.onBlocklistChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
@ -122,12 +127,14 @@ class RemoveQueueItemModal extends Component {
|
|||
{
|
||||
blocklist &&
|
||||
<FormGroup>
|
||||
<FormLabel>Skip Redownload</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('SkipRedownload')}
|
||||
</FormLabel>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="skipredownload"
|
||||
value={skipredownload}
|
||||
helpText="Prevents Lidarr from trying download an alternative release for this item"
|
||||
helpText={translate('SkipredownloadHelpText')}
|
||||
onChange={this.onSkipReDownloadChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
|
|
@ -10,6 +10,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { inputTypes, kinds, sizes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './RemoveQueueItemsModal.css';
|
||||
|
||||
class RemoveQueueItemsModal extends Component {
|
||||
|
@ -96,13 +97,15 @@ class RemoveQueueItemsModal extends Component {
|
|||
</div>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Remove From Download Client</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('RemoveFromDownloadClient')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="remove"
|
||||
value={remove}
|
||||
helpTextWarning="Removing will remove the download and the file(s) from the download client."
|
||||
helpTextWarning={translate('RemoveHelpTextWarning')}
|
||||
isDisabled={!canIgnore}
|
||||
onChange={this.onRemoveChange}
|
||||
/>
|
||||
|
@ -117,7 +120,7 @@ class RemoveQueueItemsModal extends Component {
|
|||
type={inputTypes.CHECK}
|
||||
name="blocklist"
|
||||
value={blocklist}
|
||||
helpText="Prevents Lidarr from automatically grabbing these files again"
|
||||
helpText={translate('BlocklistHelpText')}
|
||||
onChange={this.onBlocklistChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
@ -125,12 +128,14 @@ class RemoveQueueItemsModal extends Component {
|
|||
{
|
||||
blocklist &&
|
||||
<FormGroup>
|
||||
<FormLabel>Skip Redownload</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('SkipRedownload')}
|
||||
</FormLabel>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="skipredownload"
|
||||
value={skipredownload}
|
||||
helpText="Prevents Lidarr from trying download alternative releases for the removed items"
|
||||
helpText={translate('SkipredownloadHelpText')}
|
||||
onChange={this.onSkipReDownloadChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
|
|
@ -5,6 +5,7 @@ import formatTime from 'Utilities/Date/formatTime';
|
|||
import formatTimeSpan from 'Utilities/Date/formatTimeSpan';
|
||||
import getRelativeDate from 'Utilities/Date/getRelativeDate';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './TimeleftCell.css';
|
||||
|
||||
function TimeleftCell(props) {
|
||||
|
@ -26,7 +27,7 @@ function TimeleftCell(props) {
|
|||
return (
|
||||
<TableRowCell
|
||||
className={styles.timeleft}
|
||||
title={`Delaying download until ${date} at ${time}`}
|
||||
title={translate('DelayingDownloadUntilInterp', [date, time])}
|
||||
>
|
||||
-
|
||||
</TableRowCell>
|
||||
|
@ -40,7 +41,7 @@ function TimeleftCell(props) {
|
|||
return (
|
||||
<TableRowCell
|
||||
className={styles.timeleft}
|
||||
title={`Retrying download ${date} at ${time}`}
|
||||
title={translate('RetryingDownloadInterp', [date, time])}
|
||||
>
|
||||
-
|
||||
</TableRowCell>
|
||||
|
|
|
@ -1,43 +1,44 @@
|
|||
import React from 'react';
|
||||
import DescriptionList from 'Components/DescriptionList/DescriptionList';
|
||||
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
function ArtistMonitoringOptionsPopoverContent() {
|
||||
return (
|
||||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
title="All Albums"
|
||||
data="Monitor all albums except specials"
|
||||
title={translate('AllAlbums')}
|
||||
data={translate('AllAlbumsData')}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="Future Albums"
|
||||
data="Monitor albums that have not released yet"
|
||||
title={translate('FutureAlbums')}
|
||||
data={translate('FutureAlbumsData')}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="Missing Albums"
|
||||
data="Monitor albums that do not have files or have not released yet"
|
||||
title={translate('MissingAlbums')}
|
||||
data={translate('MissingAlbumsData')}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="Existing Albums"
|
||||
data="Monitor albums that have files or have not released yet"
|
||||
title={translate('ExistingAlbums')}
|
||||
data={translate('ExistingAlbumsData')}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="First Album"
|
||||
data="Monitor the first albums. All other albums will be ignored"
|
||||
title={translate('FirstAlbum')}
|
||||
data={translate('FirstAlbumData')}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="Latest Album"
|
||||
data="Monitor the latest albums and future albums"
|
||||
title={translate('LatestAlbum')}
|
||||
data={translate('LatestAlbumData')}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="None"
|
||||
data="No albums will be monitored"
|
||||
title={translate('None')}
|
||||
data={translate('NoneData')}
|
||||
/>
|
||||
</DescriptionList>
|
||||
);
|
||||
|
|
|
@ -10,6 +10,7 @@ import ModalFooter from 'Components/Modal/ModalFooter';
|
|||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { inputTypes, kinds } from 'Helpers/Props';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './DeleteAlbumModalContent.css';
|
||||
|
||||
class DeleteAlbumModalContent extends Component {
|
||||
|
@ -91,13 +92,15 @@ class DeleteAlbumModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Add List Exclusion</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('AddListExclusion')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="addImportListExclusion"
|
||||
value={addImportListExclusion}
|
||||
helpText="Prevent album from being added to Lidarr by Import Lists or Artist Refresh"
|
||||
helpText={translate('AddImportListExclusionHelpText')}
|
||||
kind={kinds.DANGER}
|
||||
onChange={this.onAddImportListExclusionChange}
|
||||
/>
|
||||
|
@ -106,14 +109,18 @@ class DeleteAlbumModalContent extends Component {
|
|||
{
|
||||
!addImportListExclusion &&
|
||||
<div className={styles.deleteFilesMessage}>
|
||||
<div>If you don't add an import list exclusion and the artist has a metadata profile other than 'None' then this album may be re-added during the next artist refresh.</div>
|
||||
<div>
|
||||
{translate('IfYouDontAddAnImportListExclusionAndTheArtistHasAMetadataProfileOtherThanNoneThenThisAlbumMayBeReaddedDuringTheNextArtistRefresh')}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
deleteFiles &&
|
||||
<div className={styles.deleteFilesMessage}>
|
||||
<div>The album's files will be deleted.</div>
|
||||
<div>
|
||||
{translate('TheAlbumsFilesWillBeDeleted')}
|
||||
</div>
|
||||
|
||||
{
|
||||
!!trackFileCount &&
|
||||
|
|
|
@ -27,6 +27,7 @@ import RetagPreviewModalConnector from 'Retag/RetagPreviewModalConnector';
|
|||
import fonts from 'Styles/Variables/fonts';
|
||||
import TrackFileEditorModal from 'TrackFile/Editor/TrackFileEditorModal';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import selectAll from 'Utilities/Table/selectAll';
|
||||
import toggleSelected from 'Utilities/Table/toggleSelected';
|
||||
import AlbumDetailsLinks from './AlbumDetailsLinks';
|
||||
|
@ -241,14 +242,14 @@ class AlbumDetails extends Component {
|
|||
<PageToolbar>
|
||||
<PageToolbarSection>
|
||||
<PageToolbarButton
|
||||
label="Search Album"
|
||||
label={translate('SearchAlbum')}
|
||||
iconName={icons.SEARCH}
|
||||
isSpinning={isSearching}
|
||||
onPress={onSearchPress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Interactive Search"
|
||||
label={translate('InteractiveSearch')}
|
||||
iconName={icons.INTERACTIVE}
|
||||
onPress={this.onInteractiveSearchPress}
|
||||
/>
|
||||
|
@ -256,28 +257,28 @@ class AlbumDetails extends Component {
|
|||
<PageToolbarSeparator />
|
||||
|
||||
<PageToolbarButton
|
||||
label="Preview Rename"
|
||||
label={translate('PreviewRename')}
|
||||
iconName={icons.ORGANIZE}
|
||||
isDisabled={!hasTrackFiles}
|
||||
onPress={this.onOrganizePress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Preview Retag"
|
||||
label={translate('PreviewRetag')}
|
||||
iconName={icons.RETAG}
|
||||
isDisabled={!hasTrackFiles}
|
||||
onPress={this.onRetagPress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Manage Tracks"
|
||||
label={translate('ManageTracks')}
|
||||
iconName={icons.TRACK_FILE}
|
||||
isDisabled={!hasTrackFiles}
|
||||
onPress={this.onManageTracksPress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="History"
|
||||
label={translate('History')}
|
||||
iconName={icons.HISTORY}
|
||||
onPress={this.onArtistHistoryPress}
|
||||
/>
|
||||
|
@ -285,13 +286,13 @@ class AlbumDetails extends Component {
|
|||
<PageToolbarSeparator />
|
||||
|
||||
<PageToolbarButton
|
||||
label="Edit"
|
||||
label={translate('Edit')}
|
||||
iconName={icons.EDIT}
|
||||
onPress={this.onEditAlbumPress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Delete"
|
||||
label={translate('Delete')}
|
||||
iconName={icons.DELETE}
|
||||
onPress={this.onDeleteAlbumPress}
|
||||
/>
|
||||
|
@ -299,7 +300,7 @@ class AlbumDetails extends Component {
|
|||
</PageToolbarSection>
|
||||
<PageToolbarSection alignContent={align.RIGHT}>
|
||||
<PageToolbarButton
|
||||
label={allExpanded ? 'Collapse All' : 'Expand All'}
|
||||
label={allExpanded ? translate('AllExpandedCollapseAll') : translate('AllExpandedExpandAll')}
|
||||
iconName={expandIcon}
|
||||
onPress={this.onExpandAllPress}
|
||||
/>
|
||||
|
@ -349,7 +350,7 @@ class AlbumDetails extends Component {
|
|||
className={styles.albumNavigationButton}
|
||||
name={icons.ARROW_LEFT}
|
||||
size={30}
|
||||
title={`Go to ${previousAlbum.title}`}
|
||||
title={translate('GoToInterp', [previousAlbum.title])}
|
||||
to={`/album/${previousAlbum.foreignAlbumId}`}
|
||||
/>
|
||||
|
||||
|
@ -357,7 +358,7 @@ class AlbumDetails extends Component {
|
|||
className={styles.albumNavigationButton}
|
||||
name={icons.ARROW_UP}
|
||||
size={30}
|
||||
title={`Go to ${artist.artistName}`}
|
||||
title={translate('GoToInterp', [artist.artistName])}
|
||||
to={`/artist/${artist.foreignArtistId}`}
|
||||
/>
|
||||
|
||||
|
@ -365,7 +366,7 @@ class AlbumDetails extends Component {
|
|||
className={styles.albumNavigationButton}
|
||||
name={icons.ARROW_RIGHT}
|
||||
size={30}
|
||||
title={`Go to ${nextAlbum.title}`}
|
||||
title={translate('GoToInterp', [nextAlbum.title])}
|
||||
to={`/album/${nextAlbum.foreignAlbumId}`}
|
||||
/>
|
||||
</div>
|
||||
|
@ -439,7 +440,7 @@ class AlbumDetails extends Component {
|
|||
!!albumType &&
|
||||
<Label
|
||||
className={styles.detailsLabel}
|
||||
title="Type"
|
||||
title={translate('Type')}
|
||||
size={sizes.LARGE}
|
||||
>
|
||||
<Icon
|
||||
|
@ -498,12 +499,16 @@ class AlbumDetails extends Component {
|
|||
|
||||
{
|
||||
!isFetching && albumsError &&
|
||||
<div>Loading albums failed</div>
|
||||
<div>
|
||||
{translate('LoadingAlbumsFailed')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
!isFetching && trackFilesError &&
|
||||
<div>Loading track files failed</div>
|
||||
<div>
|
||||
{translate('LoadingTrackFilesFailed')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -7,6 +7,7 @@ import Link from 'Components/Link/Link';
|
|||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import { icons, kinds, sizes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import TrackRowConnector from './TrackRowConnector';
|
||||
import styles from './AlbumDetailsMedium.css';
|
||||
|
||||
|
@ -120,7 +121,7 @@ class AlbumDetailsMedium extends Component {
|
|||
}
|
||||
|
||||
<Label
|
||||
title={`${totalTrackCount} tracks total. ${trackFileCount} tracks with files.`}
|
||||
title={translate('TotalTrackCountTracksTotalTrackFileCountTracksWithFilesInterp', [totalTrackCount, trackFileCount])}
|
||||
kind={getTrackCountKind(albumMonitored, trackFileCount, trackCount)}
|
||||
size={sizes.LARGE}
|
||||
>
|
||||
|
@ -137,7 +138,7 @@ class AlbumDetailsMedium extends Component {
|
|||
<Icon
|
||||
className={styles.expandButtonIcon}
|
||||
name={isExpanded ? icons.COLLAPSE : icons.EXPAND}
|
||||
title={isExpanded ? 'Hide tracks' : 'Show tracks'}
|
||||
title={isExpanded ? translate('IsExpandedHideTracks') : translate('IsExpandedShowTracks')}
|
||||
size={24}
|
||||
/>
|
||||
{
|
||||
|
@ -181,7 +182,7 @@ class AlbumDetailsMedium extends Component {
|
|||
<IconButton
|
||||
name={icons.COLLAPSE}
|
||||
size={20}
|
||||
title="Hide tracks"
|
||||
title={translate('HideTracks')}
|
||||
onPress={this.onExpandPress}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -9,6 +9,7 @@ import NotFound from 'Components/NotFound';
|
|||
import PageContent from 'Components/Page/PageContent';
|
||||
import PageContentBody from 'Components/Page/PageContentBody';
|
||||
import { clearAlbums, fetchAlbums } from 'Store/Actions/albumActions';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import AlbumDetailsConnector from './AlbumDetailsConnector';
|
||||
|
||||
function createMapStateToProps() {
|
||||
|
@ -94,7 +95,7 @@ class AlbumDetailsPageConnector extends Component {
|
|||
if (!foreignAlbumId) {
|
||||
return (
|
||||
<NotFound
|
||||
message="Sorry, that album cannot be found."
|
||||
message={translate('SorryThatAlbumCannotBeFound')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import ConfirmModal from 'Components/Modal/ConfirmModal';
|
|||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import FileDetailsModal from 'TrackFile/FileDetailsModal';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './TrackActionsCell.css';
|
||||
|
||||
class TrackActionsCell extends Component {
|
||||
|
@ -86,9 +87,9 @@ class TrackActionsCell extends Component {
|
|||
<ConfirmModal
|
||||
isOpen={isConfirmDeleteModalOpen}
|
||||
kind={kinds.DANGER}
|
||||
title="Delete Track File"
|
||||
message={`Are you sure you want to delete ${trackFilePath}?`}
|
||||
confirmLabel="Delete"
|
||||
title={translate('DeleteTrackFile')}
|
||||
message={translate('DeleteTrackFileMessageText', [trackFilePath])}
|
||||
confirmLabel={translate('Delete')}
|
||||
onConfirm={this.onConfirmDelete}
|
||||
onCancel={this.onConfirmDeleteModalClose}
|
||||
/>
|
||||
|
|
|
@ -11,6 +11,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { inputTypes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
class EditAlbumModalContent extends Component {
|
||||
|
||||
|
@ -59,36 +60,42 @@ class EditAlbumModalContent extends Component {
|
|||
{...otherProps}
|
||||
>
|
||||
<FormGroup>
|
||||
<FormLabel>Monitored</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Monitored')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="monitored"
|
||||
helpText="Lidarr will search for and download album"
|
||||
helpText={translate('MonitoredHelpText')}
|
||||
{...monitored}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Automatically Switch Release</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('AutomaticallySwitchRelease')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="anyReleaseOk"
|
||||
helpText="Lidarr will automatically switch to the release best matching downloaded tracks"
|
||||
helpText={translate('AnyReleaseOkHelpText')}
|
||||
{...anyReleaseOk}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel> Release</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Release')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.ALBUM_RELEASE_SELECT}
|
||||
name="releases"
|
||||
helpText="Change release for this album"
|
||||
helpText={translate('ReleasesHelpText')}
|
||||
isDisabled={anyReleaseOk.value && statistics.trackFileCount > 0}
|
||||
albumReleases={releases}
|
||||
onChange={onInputChange}
|
||||
|
|
|
@ -3,6 +3,7 @@ import React from 'react';
|
|||
import Icon from 'Components/Icon';
|
||||
import Popover from 'Components/Tooltip/Popover';
|
||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import SceneInfo from './SceneInfo';
|
||||
import styles from './EpisodeNumber.css';
|
||||
|
||||
|
@ -40,7 +41,7 @@ function EpisodeNumber(props) {
|
|||
}
|
||||
</span>
|
||||
}
|
||||
title="Scene Information"
|
||||
title={translate('SceneInformation')}
|
||||
body={
|
||||
<SceneInfo
|
||||
sceneSeasonNumber={sceneSeasonNumber}
|
||||
|
@ -70,7 +71,7 @@ function EpisodeNumber(props) {
|
|||
className={styles.warning}
|
||||
name={icons.WARNING}
|
||||
kind={kinds.WARNING}
|
||||
title="Scene number hasn't been verified yet"
|
||||
title={translate('SceneNumberHasntBeenVerifiedYet')}
|
||||
/>
|
||||
}
|
||||
|
||||
|
@ -80,7 +81,7 @@ function EpisodeNumber(props) {
|
|||
className={styles.warning}
|
||||
name={icons.WARNING}
|
||||
kind={kinds.WARNING}
|
||||
title="Episode does not have an absolute episode number"
|
||||
title={translate('EpisodeDoesNotHaveAnAbsoluteEpisodeNumber')}
|
||||
/>
|
||||
}
|
||||
</span>
|
||||
|
|
|
@ -5,6 +5,7 @@ import Icon from 'Components/Icon';
|
|||
import ProgressBar from 'Components/ProgressBar';
|
||||
import { icons, kinds, sizes } from 'Helpers/Props';
|
||||
import isBefore from 'Utilities/Date/isBefore';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import TrackQuality from './TrackQuality';
|
||||
import styles from './EpisodeStatus.css';
|
||||
|
||||
|
@ -35,7 +36,7 @@ function EpisodeStatus(props) {
|
|||
{...queueItem}
|
||||
progressBar={
|
||||
<ProgressBar
|
||||
title={`Album is downloading - ${progress.toFixed(1)}% ${queueItem.title}`}
|
||||
title={translate('AlbumIsDownloadingInterp', [progress.toFixed(1), queueItem.title])}
|
||||
progress={progress}
|
||||
kind={kinds.PURPLE}
|
||||
size={sizes.MEDIUM}
|
||||
|
@ -51,7 +52,7 @@ function EpisodeStatus(props) {
|
|||
<div className={styles.center}>
|
||||
<Icon
|
||||
name={icons.DOWNLOADING}
|
||||
title="Album is downloading"
|
||||
title={translate('AlbumIsDownloading')}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -67,7 +68,7 @@ function EpisodeStatus(props) {
|
|||
quality={quality}
|
||||
size={trackFile.size}
|
||||
isCutoffNotMet={isCutoffNotMet}
|
||||
title="Track Downloaded"
|
||||
title={translate('TrackDownloaded')}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -78,7 +79,7 @@ function EpisodeStatus(props) {
|
|||
<div className={styles.center}>
|
||||
<Icon
|
||||
name={icons.TBA}
|
||||
title="TBA"
|
||||
title={translate('TBA')}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -89,7 +90,7 @@ function EpisodeStatus(props) {
|
|||
<div className={styles.center}>
|
||||
<Icon
|
||||
name={icons.UNMONITORED}
|
||||
title="Album is not monitored"
|
||||
title={translate('AlbumIsNotMonitored')}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -100,7 +101,7 @@ function EpisodeStatus(props) {
|
|||
<div className={styles.center}>
|
||||
<Icon
|
||||
name={icons.MISSING}
|
||||
title="Track missing from disk"
|
||||
title={translate('TrackMissingFromDisk')}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -110,7 +111,7 @@ function EpisodeStatus(props) {
|
|||
<div className={styles.center}>
|
||||
<Icon
|
||||
name={icons.NOT_AIRED}
|
||||
title="Album has not aired"
|
||||
title={translate('AlbumHasNotAired')}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
|
|||
import React from 'react';
|
||||
import DescriptionList from 'Components/DescriptionList/DescriptionList';
|
||||
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './SceneInfo.css';
|
||||
|
||||
function SceneInfo(props) {
|
||||
|
@ -20,7 +21,7 @@ function SceneInfo(props) {
|
|||
<DescriptionListItem
|
||||
titleClassName={styles.title}
|
||||
descriptionClassName={styles.description}
|
||||
title="Season"
|
||||
title={translate('Season')}
|
||||
data={sceneSeasonNumber}
|
||||
/>
|
||||
}
|
||||
|
@ -30,7 +31,7 @@ function SceneInfo(props) {
|
|||
<DescriptionListItem
|
||||
titleClassName={styles.title}
|
||||
descriptionClassName={styles.description}
|
||||
title="Episode"
|
||||
title={translate('Episode')}
|
||||
data={sceneEpisodeNumber}
|
||||
/>
|
||||
}
|
||||
|
@ -40,7 +41,7 @@ function SceneInfo(props) {
|
|||
<DescriptionListItem
|
||||
titleClassName={styles.title}
|
||||
descriptionClassName={styles.description}
|
||||
title="Absolute"
|
||||
title={translate('Absolute')}
|
||||
data={sceneAbsoluteEpisodeNumber}
|
||||
/>
|
||||
}
|
||||
|
@ -50,7 +51,7 @@ function SceneInfo(props) {
|
|||
<DescriptionListItem
|
||||
titleClassName={styles.title}
|
||||
descriptionClassName={styles.description}
|
||||
title={alternateTitles.length === 1 ? 'Title' : 'Titles'}
|
||||
title={alternateTitles.length === 1 ? translate('AlternateTitleslength1Title') : translate('AlternateTitleslength1Titles')}
|
||||
data={
|
||||
<div>
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@ import VirtualTableRow from 'Components/Table/VirtualTableRow';
|
|||
import { align, sortDirections } from 'Helpers/Props';
|
||||
import getIndexOfFirstCharacter from 'Utilities/Array/getIndexOfFirstCharacter';
|
||||
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
||||
import selectAll from 'Utilities/Table/selectAll';
|
||||
import toggleSelected from 'Utilities/Table/toggleSelected';
|
||||
|
@ -330,7 +331,7 @@ class AlbumStudio extends Component {
|
|||
} = this.state;
|
||||
|
||||
return (
|
||||
<PageContent title="Album Studio">
|
||||
<PageContent title={translate('AlbumStudio')}>
|
||||
<PageToolbar>
|
||||
<PageToolbarSection />
|
||||
<PageToolbarSection alignContent={align.RIGHT}>
|
||||
|
|
|
@ -2,6 +2,7 @@ import classNames from 'classnames';
|
|||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import MonitorToggleButton from 'Components/MonitorToggleButton';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './AlbumStudioAlbum.css';
|
||||
|
||||
class AlbumStudioAlbum extends Component {
|
||||
|
@ -67,7 +68,7 @@ class AlbumStudioAlbum extends Component {
|
|||
percentOfTracks < 100 && monitored && styles.missingWanted,
|
||||
percentOfTracks === 100 && styles.allTracks
|
||||
)}
|
||||
title={`${trackFileCount}/${totalTrackCount} tracks downloaded`}
|
||||
title={translate('TrackFileCounttotalTrackCountTracksDownloadedInterp', [trackFileCount, totalTrackCount])}
|
||||
>
|
||||
{
|
||||
totalTrackCount === 0 ? '0/0' : `${trackFileCount}/${totalTrackCount}`
|
||||
|
|
|
@ -8,6 +8,7 @@ import ModalFooter from 'Components/Modal/ModalFooter';
|
|||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import UpdateChanges from 'System/Updates/UpdateChanges';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './AppUpdatedModalContent.css';
|
||||
|
||||
function AppUpdatedModalContent(props) {
|
||||
|
@ -49,12 +50,12 @@ function AppUpdatedModalContent(props) {
|
|||
</div>
|
||||
|
||||
<UpdateChanges
|
||||
title="New"
|
||||
title={translate('New')}
|
||||
changes={update.changes.new}
|
||||
/>
|
||||
|
||||
<UpdateChanges
|
||||
title="Fixed"
|
||||
title={translate('Fixed')}
|
||||
changes={update.changes.fixed}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -11,6 +11,7 @@ import ModalFooter from 'Components/Modal/ModalFooter';
|
|||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { icons, inputTypes, kinds } from 'Helpers/Props';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './DeleteArtistModalContent.css';
|
||||
|
||||
class DeleteArtistModalContent extends Component {
|
||||
|
@ -67,7 +68,7 @@ class DeleteArtistModalContent extends Component {
|
|||
const addImportListExclusion = this.state.addImportListExclusion;
|
||||
|
||||
let deleteFilesLabel = `Delete ${trackFileCount} Track Files`;
|
||||
let deleteFilesHelpText = 'Delete the track files and artist folder';
|
||||
let deleteFilesHelpText = translate('DeleteFilesHelpText');
|
||||
|
||||
if (trackFileCount === 0) {
|
||||
deleteFilesLabel = 'Delete Artist Folder';
|
||||
|
@ -106,13 +107,15 @@ class DeleteArtistModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Add List Exclusion</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('AddListExclusion')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="addImportListExclusion"
|
||||
value={addImportListExclusion}
|
||||
helpText="Prevent artist from being added to Lidarr by Import lists"
|
||||
helpText={translate('AddImportListExclusionHelpText')}
|
||||
kind={kinds.DANGER}
|
||||
onChange={this.onAddImportListExclusionChange}
|
||||
/>
|
||||
|
@ -121,7 +124,9 @@ class DeleteArtistModalContent extends Component {
|
|||
{
|
||||
deleteFiles &&
|
||||
<div className={styles.deleteFilesMessage}>
|
||||
<div>The artist folder <strong>{path}</strong> and all of its content will be deleted.</div>
|
||||
<div>
|
||||
{translate('TheArtistFolderStrongpathstrongAndAllOfItsContentWillBeDeleted')}
|
||||
</div>
|
||||
|
||||
{
|
||||
!!trackFileCount &&
|
||||
|
|
|
@ -10,6 +10,7 @@ import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
|||
import TableRow from 'Components/Table/TableRow';
|
||||
import { kinds, sizes } from 'Helpers/Props';
|
||||
import formatTimeSpan from 'Utilities/Date/formatTimeSpan';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './AlbumRow.css';
|
||||
|
||||
function getTrackCountKind(monitored, trackFileCount, trackCount) {
|
||||
|
@ -202,7 +203,7 @@ class AlbumRow extends Component {
|
|||
className={styles.status}
|
||||
>
|
||||
<Label
|
||||
title={`${totalTrackCount} tracks total. ${trackFileCount} tracks with files.`}
|
||||
title={translate('TotalTrackCountTracksTotalTrackFileCountTracksWithFilesInterp', [totalTrackCount, trackFileCount])}
|
||||
kind={getTrackCountKind(monitored, trackFileCount, trackCount)}
|
||||
size={sizes.MEDIUM}
|
||||
>
|
||||
|
|
|
@ -29,6 +29,7 @@ import QualityProfileNameConnector from 'Settings/Profiles/Quality/QualityProfil
|
|||
import fonts from 'Styles/Variables/fonts';
|
||||
import TrackFileEditorModal from 'TrackFile/Editor/TrackFileEditorModal';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import selectAll from 'Utilities/Table/selectAll';
|
||||
import toggleSelected from 'Utilities/Table/toggleSelected';
|
||||
import InteractiveImportModal from '../../InteractiveImport/InteractiveImportModal';
|
||||
|
@ -233,7 +234,7 @@ class ArtistDetails extends Component {
|
|||
const continuing = status === 'continuing';
|
||||
const endedString = artistType === 'Person' ? 'Deceased' : 'Ended';
|
||||
|
||||
let trackFilesCountMessage = 'No track files';
|
||||
let trackFilesCountMessage = translate('TrackFilesCountMessage');
|
||||
|
||||
if (trackFileCount === 1) {
|
||||
trackFilesCountMessage = '1 track file';
|
||||
|
@ -254,64 +255,64 @@ class ArtistDetails extends Component {
|
|||
<PageToolbar>
|
||||
<PageToolbarSection>
|
||||
<PageToolbarButton
|
||||
label="Refresh & Scan"
|
||||
label={translate('RefreshScan')}
|
||||
iconName={icons.REFRESH}
|
||||
spinningName={icons.REFRESH}
|
||||
title="Refresh information and scan disk"
|
||||
title={translate('RefreshInformationAndScanDisk')}
|
||||
isSpinning={isRefreshing}
|
||||
onPress={onRefreshPress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Search Monitored"
|
||||
label={translate('SearchMonitored')}
|
||||
iconName={icons.SEARCH}
|
||||
isDisabled={!monitored || !hasMonitoredAlbums || !hasAlbums}
|
||||
isSpinning={isSearching}
|
||||
title={hasMonitoredAlbums ? undefined : 'No monitored albums for this artist'}
|
||||
title={hasMonitoredAlbums ? undefined : translate('HasMonitoredAlbumsNoMonitoredAlbumsForThisArtist')}
|
||||
onPress={onSearchPress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Interactive Search"
|
||||
label={translate('InteractiveSearch')}
|
||||
iconName={icons.INTERACTIVE}
|
||||
isDisabled={!monitored || !hasMonitoredAlbums || !hasAlbums}
|
||||
isSpinning={isSearching}
|
||||
title={hasMonitoredAlbums ? undefined : 'No monitored albums for this artist'}
|
||||
title={hasMonitoredAlbums ? undefined : translate('HasMonitoredAlbumsNoMonitoredAlbumsForThisArtist')}
|
||||
onPress={this.onInteractiveSearchPress}
|
||||
/>
|
||||
|
||||
<PageToolbarSeparator />
|
||||
|
||||
<PageToolbarButton
|
||||
label="Preview Rename"
|
||||
label={translate('PreviewRename')}
|
||||
iconName={icons.ORGANIZE}
|
||||
isDisabled={!hasTrackFiles}
|
||||
onPress={this.onOrganizePress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Preview Retag"
|
||||
label={translate('PreviewRetag')}
|
||||
iconName={icons.RETAG}
|
||||
isDisabled={!hasTrackFiles}
|
||||
onPress={this.onRetagPress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Manage Tracks"
|
||||
label={translate('ManageTracks')}
|
||||
iconName={icons.TRACK_FILE}
|
||||
isDisabled={!hasTrackFiles}
|
||||
onPress={this.onManageTracksPress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="History"
|
||||
label={translate('History')}
|
||||
iconName={icons.HISTORY}
|
||||
isDisabled={!hasAlbums}
|
||||
onPress={this.onArtistHistoryPress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Manual Import"
|
||||
label={translate('ManualImport')}
|
||||
iconName={icons.INTERACTIVE}
|
||||
onPress={this.onInteractiveImportPress}
|
||||
/>
|
||||
|
@ -319,13 +320,13 @@ class ArtistDetails extends Component {
|
|||
<PageToolbarSeparator />
|
||||
|
||||
<PageToolbarButton
|
||||
label="Edit"
|
||||
label={translate('Edit')}
|
||||
iconName={icons.EDIT}
|
||||
onPress={this.onEditArtistPress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Delete"
|
||||
label={translate('Delete')}
|
||||
iconName={icons.DELETE}
|
||||
onPress={this.onDeleteArtistPress}
|
||||
/>
|
||||
|
@ -333,7 +334,7 @@ class ArtistDetails extends Component {
|
|||
|
||||
<PageToolbarSection alignContent={align.RIGHT}>
|
||||
<PageToolbarButton
|
||||
label={allExpanded ? 'Collapse All' : 'Expand All'}
|
||||
label={allExpanded ? translate('AllExpandedCollapseAll') : translate('AllExpandedExpandAll')}
|
||||
iconName={expandIcon}
|
||||
onPress={this.onExpandAllPress}
|
||||
/>
|
||||
|
@ -386,7 +387,7 @@ class ArtistDetails extends Component {
|
|||
size={20}
|
||||
/>
|
||||
}
|
||||
title="Alternate Titles"
|
||||
title={translate('AlternateTitles')}
|
||||
body={<ArtistAlternateTitles alternateTitles={alternateTitles} />}
|
||||
position={tooltipPositions.BOTTOM}
|
||||
/>
|
||||
|
@ -399,7 +400,7 @@ class ArtistDetails extends Component {
|
|||
className={styles.artistNavigationButton}
|
||||
name={icons.ARROW_LEFT}
|
||||
size={30}
|
||||
title={`Go to ${previousArtist.artistName}`}
|
||||
title={translate('GoToInterp', [previousArtist.artistName])}
|
||||
to={`/artist/${previousArtist.foreignArtistId}`}
|
||||
/>
|
||||
|
||||
|
@ -407,7 +408,7 @@ class ArtistDetails extends Component {
|
|||
className={styles.artistNavigationButton}
|
||||
name={icons.ARROW_UP}
|
||||
size={30}
|
||||
title={'Go to artist listing'}
|
||||
title={translate('GoToArtistListing')}
|
||||
to={{
|
||||
pathname: '/',
|
||||
state: { restoreScrollPosition: true }
|
||||
|
@ -418,7 +419,7 @@ class ArtistDetails extends Component {
|
|||
className={styles.artistNavigationButton}
|
||||
name={icons.ARROW_RIGHT}
|
||||
size={30}
|
||||
title={`Go to ${nextArtist.artistName}`}
|
||||
title={translate('GoToInterp', [nextArtist.artistName])}
|
||||
to={`/artist/${nextArtist.foreignArtistId}`}
|
||||
/>
|
||||
</div>
|
||||
|
@ -467,7 +468,7 @@ class ArtistDetails extends Component {
|
|||
|
||||
<Label
|
||||
className={styles.detailsLabel}
|
||||
title="Quality Profile"
|
||||
title={translate('QualityProfile')}
|
||||
size={sizes.LARGE}
|
||||
>
|
||||
<Icon
|
||||
|
@ -500,7 +501,7 @@ class ArtistDetails extends Component {
|
|||
|
||||
<Label
|
||||
className={styles.detailsLabel}
|
||||
title={continuing ? 'More albums are expected' : 'No additional albums are expected'}
|
||||
title={continuing ? translate('ContinuingMoreAlbumsAreExpected') : translate('ContinuingNoAdditionalAlbumsAreExpected')}
|
||||
size={sizes.LARGE}
|
||||
>
|
||||
<Icon
|
||||
|
@ -582,12 +583,16 @@ class ArtistDetails extends Component {
|
|||
|
||||
{
|
||||
!isFetching && albumsError &&
|
||||
<div>Loading albums failed</div>
|
||||
<div>
|
||||
{translate('LoadingAlbumsFailed')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
!isFetching && trackFilesError &&
|
||||
<div>Loading track files failed</div>
|
||||
<div>
|
||||
{translate('LoadingTrackFilesFailed')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@ import NotFound from 'Components/NotFound';
|
|||
import PageContent from 'Components/Page/PageContent';
|
||||
import PageContentBody from 'Components/Page/PageContentBody';
|
||||
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import ArtistDetailsConnector from './ArtistDetailsConnector';
|
||||
import styles from './ArtistDetails.css';
|
||||
|
||||
|
@ -92,7 +93,7 @@ class ArtistDetailsPageConnector extends Component {
|
|||
if (!foreignArtistId) {
|
||||
return (
|
||||
<NotFound
|
||||
message="Sorry, that artist cannot be found."
|
||||
message={translate('SorryThatArtistCannotBeFound')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import TableBody from 'Components/Table/TableBody';
|
|||
import { icons, sortDirections } from 'Helpers/Props';
|
||||
import OrganizePreviewModalConnector from 'Organize/OrganizePreviewModalConnector';
|
||||
import TrackFileEditorModal from 'TrackFile/Editor/TrackFileEditorModal';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import getToggledRange from 'Utilities/Table/getToggledRange';
|
||||
import AlbumRowConnector from './AlbumRowConnector';
|
||||
import styles from './ArtistDetailsSeason.css';
|
||||
|
@ -159,7 +160,7 @@ class ArtistDetailsSeason extends Component {
|
|||
<Icon
|
||||
className={styles.expandButtonIcon}
|
||||
name={isExpanded ? icons.COLLAPSE : icons.EXPAND}
|
||||
title={isExpanded ? 'Hide albums' : 'Show albums'}
|
||||
title={isExpanded ? translate('IsExpandedHideAlbums') : translate('IsExpandedShowAlbums')}
|
||||
size={24}
|
||||
/>
|
||||
|
||||
|
@ -209,7 +210,7 @@ class ArtistDetailsSeason extends Component {
|
|||
iconClassName={styles.collapseButtonIcon}
|
||||
name={icons.COLLAPSE}
|
||||
size={20}
|
||||
title="Hide albums"
|
||||
title={translate('HideAlbums')}
|
||||
onPress={this.onExpandPress}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -15,6 +15,7 @@ import ModalFooter from 'Components/Modal/ModalFooter';
|
|||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import Popover from 'Components/Tooltip/Popover';
|
||||
import { icons, inputTypes, kinds, tooltipPositions } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './EditArtistModalContent.css';
|
||||
|
||||
class EditArtistModalContent extends Component {
|
||||
|
@ -87,19 +88,23 @@ class EditArtistModalContent extends Component {
|
|||
<ModalBody>
|
||||
<Form {...otherProps}>
|
||||
<FormGroup>
|
||||
<FormLabel>Monitored</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Monitored')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="monitored"
|
||||
helpText="Download monitored albums from this artist"
|
||||
helpText={translate('MonitoredHelpText')}
|
||||
{...monitored}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Quality Profile</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('QualityProfile')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.QUALITY_PROFILE_SELECT}
|
||||
|
@ -122,7 +127,7 @@ class EditArtistModalContent extends Component {
|
|||
name={icons.INFO}
|
||||
/>
|
||||
}
|
||||
title="Metadata Profile"
|
||||
title={translate('MetadataProfile')}
|
||||
body={<ArtistMetadataProfilePopoverContent />}
|
||||
position={tooltipPositions.RIGHT}
|
||||
/>
|
||||
|
@ -132,7 +137,7 @@ class EditArtistModalContent extends Component {
|
|||
<FormInputGroup
|
||||
type={inputTypes.METADATA_PROFILE_SELECT}
|
||||
name="metadataProfileId"
|
||||
helpText="Changes will take place on next artist refresh"
|
||||
helpText={translate('MetadataProfileIdHelpText')}
|
||||
includeNone={true}
|
||||
{...metadataProfileId}
|
||||
onChange={onInputChange}
|
||||
|
@ -141,7 +146,9 @@ class EditArtistModalContent extends Component {
|
|||
}
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Path</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Path')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.PATH}
|
||||
|
@ -152,7 +159,9 @@ class EditArtistModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Tags</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Tags')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TAG}
|
||||
|
|
|
@ -14,6 +14,7 @@ import TableBody from 'Components/Table/TableBody';
|
|||
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
|
||||
import { align, icons, sortDirections } from 'Helpers/Props';
|
||||
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
||||
import selectAll from 'Utilities/Table/selectAll';
|
||||
import toggleSelected from 'Utilities/Table/toggleSelected';
|
||||
|
@ -143,7 +144,7 @@ class ArtistEditor extends Component {
|
|||
const selectedArtistIds = this.getSelectedIds();
|
||||
|
||||
return (
|
||||
<PageContent title="Artist Editor">
|
||||
<PageContent title={translate('ArtistEditor')}>
|
||||
<PageToolbar>
|
||||
<PageToolbarSection />
|
||||
<PageToolbarSection alignContent={align.RIGHT}>
|
||||
|
@ -152,7 +153,7 @@ class ArtistEditor extends Component {
|
|||
onTableOptionChange={onTableOptionChange}
|
||||
>
|
||||
<PageToolbarButton
|
||||
label="Options"
|
||||
label={translate('Options')}
|
||||
iconName={icons.TABLE}
|
||||
/>
|
||||
</TableOptionsModalWrapper>
|
||||
|
|
|
@ -8,6 +8,7 @@ import SelectInput from 'Components/Form/SelectInput';
|
|||
import SpinnerButton from 'Components/Link/SpinnerButton';
|
||||
import PageContentFooter from 'Components/Page/PageContentFooter';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import ArtistEditorFooterLabel from './ArtistEditorFooterLabel';
|
||||
import DeleteArtistModal from './Delete/DeleteArtistModal';
|
||||
import TagsModal from './Tags/TagsModal';
|
||||
|
@ -165,7 +166,7 @@ class ArtistEditorFooter extends Component {
|
|||
<PageContentFooter>
|
||||
<div className={styles.inputContainer}>
|
||||
<ArtistEditorFooterLabel
|
||||
label="Monitor Artist"
|
||||
label={translate('MonitorArtist')}
|
||||
isSaving={isSaving && monitored !== NO_CHANGE}
|
||||
/>
|
||||
|
||||
|
@ -196,7 +197,7 @@ class ArtistEditorFooter extends Component {
|
|||
className={styles.inputContainer}
|
||||
>
|
||||
<ArtistEditorFooterLabel
|
||||
label="Quality Profile"
|
||||
label={translate('QualityProfile')}
|
||||
isSaving={isSaving && qualityProfileId !== NO_CHANGE}
|
||||
/>
|
||||
|
||||
|
@ -218,7 +219,7 @@ class ArtistEditorFooter extends Component {
|
|||
className={styles.inputContainer}
|
||||
>
|
||||
<ArtistEditorFooterLabel
|
||||
label="Metadata Profile"
|
||||
label={translate('MetadataProfile')}
|
||||
isSaving={isSaving && metadataProfileId !== NO_CHANGE}
|
||||
/>
|
||||
|
||||
|
@ -240,7 +241,7 @@ class ArtistEditorFooter extends Component {
|
|||
className={styles.inputContainer}
|
||||
>
|
||||
<ArtistEditorFooterLabel
|
||||
label="Root Folder"
|
||||
label={translate('RootFolder')}
|
||||
isSaving={isSaving && rootFolderPath !== NO_CHANGE}
|
||||
/>
|
||||
|
||||
|
@ -263,7 +264,7 @@ class ArtistEditorFooter extends Component {
|
|||
<div className={styles.buttonContainer}>
|
||||
<div className={styles.buttonContainerContent}>
|
||||
<ArtistEditorFooterLabel
|
||||
label={`${selectedCount} Artist(s) Selected`}
|
||||
label={translate('SelectedCountArtistsSelectedInterp', [selectedCount])}
|
||||
isSaving={false}
|
||||
/>
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { inputTypes, kinds, sizes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './TagsModalContent.css';
|
||||
|
||||
class TagsModalContent extends Component {
|
||||
|
@ -74,7 +75,9 @@ class TagsModalContent extends Component {
|
|||
<ModalBody>
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<FormLabel>Tags</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Tags')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TAG}
|
||||
|
@ -85,7 +88,9 @@ class TagsModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Apply Tags</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ApplyTags')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.SELECT}
|
||||
|
@ -93,17 +98,19 @@ class TagsModalContent extends Component {
|
|||
value={applyTags}
|
||||
values={applyTagsOptions}
|
||||
helpTexts={[
|
||||
'How to apply tags to the selected artist',
|
||||
'Add: Add the tags the existing list of tags',
|
||||
'Remove: Remove the entered tags',
|
||||
'Replace: Replace the tags with the entered tags (enter no tags to clear all tags)'
|
||||
translate('ApplyTagsHelpTexts1'),
|
||||
translate('ApplyTagsHelpTexts2'),
|
||||
translate('ApplyTagsHelpTexts3'),
|
||||
translate('ApplyTagsHelpTexts4')
|
||||
]}
|
||||
onChange={this.onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Result</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Result')}
|
||||
</FormLabel>
|
||||
|
||||
<div className={styles.result}>
|
||||
{
|
||||
|
@ -120,7 +127,7 @@ class TagsModalContent extends Component {
|
|||
return (
|
||||
<Label
|
||||
key={tag.id}
|
||||
title={removeTag ? 'Removing tag' : 'Existing tag'}
|
||||
title={removeTag ? translate('RemoveTagRemovingTag') : translate('RemoveTagExistingTag')}
|
||||
kind={removeTag ? kinds.INVERSE : kinds.INFO}
|
||||
size={sizes.LARGE}
|
||||
>
|
||||
|
@ -146,7 +153,7 @@ class TagsModalContent extends Component {
|
|||
return (
|
||||
<Label
|
||||
key={tag.id}
|
||||
title={'Adding tag'}
|
||||
title={translate('AddingTag')}
|
||||
kind={kinds.SUCCESS}
|
||||
size={sizes.LARGE}
|
||||
>
|
||||
|
|
|
@ -8,6 +8,7 @@ import ModalFooter from 'Components/Modal/ModalFooter';
|
|||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import ArtistHistoryRowConnector from './ArtistHistoryRowConnector';
|
||||
|
||||
const columns = [
|
||||
|
@ -80,12 +81,16 @@ class ArtistHistoryModalContent extends Component {
|
|||
|
||||
{
|
||||
!isFetching && !!error &&
|
||||
<div>Unable to load history.</div>
|
||||
<div>
|
||||
{translate('UnableToLoadHistory')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
isPopulated && !hasItems && !error &&
|
||||
<div>No history.</div>
|
||||
<div>
|
||||
{translate('NoHistory')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@ import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
|||
import TableRow from 'Components/Table/TableRow';
|
||||
import Popover from 'Components/Tooltip/Popover';
|
||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './ArtistHistoryRow.css';
|
||||
|
||||
function getTitle(eventType) {
|
||||
|
@ -132,7 +133,7 @@ class ArtistHistoryRow extends Component {
|
|||
{
|
||||
eventType === 'grabbed' &&
|
||||
<IconButton
|
||||
title="Mark as failed"
|
||||
title={translate('MarkAsFailed')}
|
||||
name={icons.REMOVE}
|
||||
onPress={this.onMarkAsFailedPress}
|
||||
/>
|
||||
|
@ -142,9 +143,9 @@ class ArtistHistoryRow extends Component {
|
|||
<ConfirmModal
|
||||
isOpen={isMarkAsFailedModalOpen}
|
||||
kind={kinds.DANGER}
|
||||
title="Mark as Failed"
|
||||
message={`Are you sure you want to mark '${sourceTitle}' as failed?`}
|
||||
confirmLabel="Mark as Failed"
|
||||
title={translate('MarkAsFailed')}
|
||||
message={translate('MarkAsFailedMessageText', [sourceTitle])}
|
||||
confirmLabel={translate('MarkAsFailed')}
|
||||
onConfirm={this.onConfirmMarkAsFailed}
|
||||
onCancel={this.onMarkAsFailedModalClose}
|
||||
/>
|
||||
|
|
|
@ -14,6 +14,7 @@ import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptions
|
|||
import { align, icons, sortDirections } from 'Helpers/Props';
|
||||
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
||||
import hasDifferentItemsOrOrder from 'Utilities/Object/hasDifferentItemsOrOrder';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import ArtistIndexFooterConnector from './ArtistIndexFooterConnector';
|
||||
import ArtistIndexBannersConnector from './Banners/ArtistIndexBannersConnector';
|
||||
import ArtistIndexBannerOptionsModal from './Banners/Options/ArtistIndexBannerOptionsModal';
|
||||
|
@ -213,7 +214,7 @@ class ArtistIndex extends Component {
|
|||
<PageToolbar>
|
||||
<PageToolbarSection>
|
||||
<PageToolbarButton
|
||||
label="Update all"
|
||||
label={translate('UpdateAll')}
|
||||
iconName={icons.REFRESH}
|
||||
spinningName={icons.REFRESH}
|
||||
isSpinning={isRefreshingArtist}
|
||||
|
@ -221,7 +222,7 @@ class ArtistIndex extends Component {
|
|||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="RSS Sync"
|
||||
label={translate('RSSSync')}
|
||||
iconName={icons.RSS}
|
||||
isSpinning={isRssSyncExecuting}
|
||||
isDisabled={hasNoArtist}
|
||||
|
@ -242,7 +243,7 @@ class ArtistIndex extends Component {
|
|||
optionsComponent={ArtistIndexTableOptionsConnector}
|
||||
>
|
||||
<PageToolbarButton
|
||||
label="Options"
|
||||
label={translate('Options')}
|
||||
iconName={icons.TABLE}
|
||||
/>
|
||||
</TableOptionsModalWrapper> :
|
||||
|
@ -252,7 +253,7 @@ class ArtistIndex extends Component {
|
|||
{
|
||||
view === 'posters' ?
|
||||
<PageToolbarButton
|
||||
label="Options"
|
||||
label={translate('Options')}
|
||||
iconName={icons.POSTER}
|
||||
isDisabled={hasNoArtist}
|
||||
onPress={this.onPosterOptionsPress}
|
||||
|
@ -263,7 +264,7 @@ class ArtistIndex extends Component {
|
|||
{
|
||||
view === 'banners' ?
|
||||
<PageToolbarButton
|
||||
label="Options"
|
||||
label={translate('Options')}
|
||||
iconName={icons.POSTER}
|
||||
isDisabled={hasNoArtist}
|
||||
onPress={this.onBannerOptionsPress}
|
||||
|
@ -274,7 +275,7 @@ class ArtistIndex extends Component {
|
|||
{
|
||||
view === 'overview' ?
|
||||
<PageToolbarButton
|
||||
label="Options"
|
||||
label={translate('Options')}
|
||||
iconName={icons.OVERVIEW}
|
||||
isDisabled={hasNoArtist}
|
||||
onPress={this.onOverviewOptionsPress}
|
||||
|
|
|
@ -5,6 +5,7 @@ import { ColorImpairedConsumer } from 'App/ColorImpairedContext';
|
|||
import DescriptionList from 'Components/DescriptionList/DescriptionList';
|
||||
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './ArtistIndexFooter.css';
|
||||
|
||||
class ArtistIndexFooter extends PureComponent {
|
||||
|
@ -60,7 +61,9 @@ class ArtistIndexFooter extends PureComponent {
|
|||
enableColorImpairedMode && 'colorImpaired'
|
||||
)}
|
||||
/>
|
||||
<div>Continuing (All tracks downloaded)</div>
|
||||
<div>
|
||||
{translate('ContinuingAllTracksDownloaded')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.legendItem}>
|
||||
|
@ -70,7 +73,9 @@ class ArtistIndexFooter extends PureComponent {
|
|||
enableColorImpairedMode && 'colorImpaired'
|
||||
)}
|
||||
/>
|
||||
<div>Ended (All tracks downloaded)</div>
|
||||
<div>
|
||||
{translate('EndedAllTracksDownloaded')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.legendItem}>
|
||||
|
@ -80,7 +85,9 @@ class ArtistIndexFooter extends PureComponent {
|
|||
enableColorImpairedMode && 'colorImpaired'
|
||||
)}
|
||||
/>
|
||||
<div>Missing Tracks (Artist monitored)</div>
|
||||
<div>
|
||||
{translate('MissingTracksArtistMonitored')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.legendItem}>
|
||||
|
@ -90,55 +97,57 @@ class ArtistIndexFooter extends PureComponent {
|
|||
enableColorImpairedMode && 'colorImpaired'
|
||||
)}
|
||||
/>
|
||||
<div>Missing Tracks (Artist not monitored)</div>
|
||||
<div>
|
||||
{translate('MissingTracksArtistNotMonitored')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.statistics}>
|
||||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
title="Artist"
|
||||
title={translate('Artist')}
|
||||
data={count}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="Ended"
|
||||
title={translate('Ended')}
|
||||
data={ended}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="Continuing"
|
||||
title={translate('Continuing')}
|
||||
data={continuing}
|
||||
/>
|
||||
</DescriptionList>
|
||||
|
||||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
title="Monitored"
|
||||
title={translate('Monitored')}
|
||||
data={monitored}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="Unmonitored"
|
||||
title={translate('Unmonitored')}
|
||||
data={count - monitored}
|
||||
/>
|
||||
</DescriptionList>
|
||||
|
||||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
title="Tracks"
|
||||
title={translate('Tracks')}
|
||||
data={tracks}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="Files"
|
||||
title={translate('Files')}
|
||||
data={trackFiles}
|
||||
/>
|
||||
</DescriptionList>
|
||||
|
||||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
title="Total File Size"
|
||||
title={translate('TotalFileSize')}
|
||||
data={formatBytes(totalFileSize)}
|
||||
/>
|
||||
</DescriptionList>
|
||||
|
|
|
@ -10,6 +10,7 @@ import Link from 'Components/Link/Link';
|
|||
import SpinnerIconButton from 'Components/Link/SpinnerIconButton';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import getRelativeDate from 'Utilities/Date/getRelativeDate';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import ArtistIndexBannerInfo from './ArtistIndexBannerInfo';
|
||||
import styles from './ArtistIndexBanner.css';
|
||||
|
||||
|
@ -108,7 +109,7 @@ class ArtistIndexBanner extends Component {
|
|||
<SpinnerIconButton
|
||||
className={styles.action}
|
||||
name={icons.REFRESH}
|
||||
title="Refresh Artist"
|
||||
title={translate('RefreshArtist')}
|
||||
isSpinning={isRefreshingArtist}
|
||||
onPress={onRefreshArtistPress}
|
||||
/>
|
||||
|
@ -118,7 +119,7 @@ class ArtistIndexBanner extends Component {
|
|||
<SpinnerIconButton
|
||||
className={styles.action}
|
||||
name={icons.SEARCH}
|
||||
title="Search for monitored albums"
|
||||
title={translate('SearchForMonitoredAlbums')}
|
||||
isSpinning={isSearchingArtist}
|
||||
onPress={onSearchPress}
|
||||
/>
|
||||
|
@ -127,7 +128,7 @@ class ArtistIndexBanner extends Component {
|
|||
<IconButton
|
||||
className={styles.action}
|
||||
name={icons.EDIT}
|
||||
title="Edit Artist"
|
||||
title={translate('EditArtist')}
|
||||
onPress={this.onEditArtistPress}
|
||||
/>
|
||||
</Label>
|
||||
|
@ -136,7 +137,7 @@ class ArtistIndexBanner extends Component {
|
|||
status === 'ended' &&
|
||||
<div
|
||||
className={styles.ended}
|
||||
title="Ended"
|
||||
title={translate('Ended')}
|
||||
/>
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { inputTypes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
const bannerSizeOptions = [
|
||||
{ key: 'small', value: 'Small' },
|
||||
|
@ -114,7 +115,9 @@ class ArtistIndexBannerOptionsModalContent extends Component {
|
|||
<ModalBody>
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<FormLabel> Size</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Size')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.SELECT}
|
||||
|
@ -126,61 +129,71 @@ class ArtistIndexBannerOptionsModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Detailed Progress Bar</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('DetailedProgressBar')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="detailedProgressBar"
|
||||
value={detailedProgressBar}
|
||||
helpText="Show text on progess bar"
|
||||
helpText={translate('DetailedProgressBarHelpText')}
|
||||
onChange={this.onChangeBannerOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Name</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowName')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showTitle"
|
||||
value={showTitle}
|
||||
helpText="Show artist name under banner"
|
||||
helpText={translate('ShowTitleHelpText')}
|
||||
onChange={this.onChangeBannerOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Monitored</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowMonitored')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showMonitored"
|
||||
value={showMonitored}
|
||||
helpText="Show monitored status under banner"
|
||||
helpText={translate('ShowMonitoredHelpText')}
|
||||
onChange={this.onChangeBannerOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Quality Profile</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowQualityProfile')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showQualityProfile"
|
||||
value={showQualityProfile}
|
||||
helpText="Show quality profile under banner"
|
||||
helpText={translate('ShowQualityProfileHelpText')}
|
||||
onChange={this.onChangeBannerOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Search</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowSearch')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showSearchAction"
|
||||
value={showSearchAction}
|
||||
helpText="Show search button on hover"
|
||||
helpText={translate('ShowSearchActionHelpText')}
|
||||
onChange={this.onChangeBannerOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
|
|
@ -11,6 +11,7 @@ import SpinnerIconButton from 'Components/Link/SpinnerIconButton';
|
|||
import { icons } from 'Helpers/Props';
|
||||
import dimensions from 'Styles/Variables/dimensions';
|
||||
import fonts from 'Styles/Variables/fonts';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import ArtistIndexOverviewInfo from './ArtistIndexOverviewInfo';
|
||||
import styles from './ArtistIndexOverview.css';
|
||||
|
||||
|
@ -129,7 +130,7 @@ class ArtistIndexOverview extends Component {
|
|||
status === 'ended' &&
|
||||
<div
|
||||
className={styles.ended}
|
||||
title="Ended"
|
||||
title={translate('Ended')}
|
||||
/>
|
||||
}
|
||||
|
||||
|
@ -172,7 +173,7 @@ class ArtistIndexOverview extends Component {
|
|||
<div className={styles.actions}>
|
||||
<SpinnerIconButton
|
||||
name={icons.REFRESH}
|
||||
title="Refresh Artist"
|
||||
title={translate('RefreshArtist')}
|
||||
isSpinning={isRefreshingArtist}
|
||||
onPress={onRefreshArtistPress}
|
||||
/>
|
||||
|
@ -182,7 +183,7 @@ class ArtistIndexOverview extends Component {
|
|||
<SpinnerIconButton
|
||||
className={styles.action}
|
||||
name={icons.SEARCH}
|
||||
title="Search for monitored albums"
|
||||
title={translate('SearchForMonitoredAlbums')}
|
||||
isSpinning={isSearchingArtist}
|
||||
onPress={onSearchPress}
|
||||
/>
|
||||
|
@ -190,7 +191,7 @@ class ArtistIndexOverview extends Component {
|
|||
|
||||
<IconButton
|
||||
name={icons.EDIT}
|
||||
title="Edit Artist"
|
||||
title={translate('EditArtist')}
|
||||
onPress={this.onEditArtistPress}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -11,6 +11,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { inputTypes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
const posterSizeOptions = [
|
||||
{ key: 'small', value: 'Small' },
|
||||
|
@ -142,7 +143,9 @@ class ArtistIndexOverviewOptionsModalContent extends Component {
|
|||
<ModalBody>
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<FormLabel>Poster Size</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('PosterSize')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.SELECT}
|
||||
|
@ -154,19 +157,23 @@ class ArtistIndexOverviewOptionsModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Detailed Progress Bar</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('DetailedProgressBar')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="detailedProgressBar"
|
||||
value={detailedProgressBar}
|
||||
helpText="Show text on progess bar"
|
||||
helpText={translate('DetailedProgressBarHelpText')}
|
||||
onChange={this.onChangeOverviewOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Monitored</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowMonitored')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
@ -178,7 +185,9 @@ class ArtistIndexOverviewOptionsModalContent extends Component {
|
|||
|
||||
<FormGroup>
|
||||
|
||||
<FormLabel>Show Quality Profile</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowQualityProfile')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
@ -189,7 +198,9 @@ class ArtistIndexOverviewOptionsModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Last Album</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowLastAlbum')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
@ -200,7 +211,9 @@ class ArtistIndexOverviewOptionsModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Date Added</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowDateAdded')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
@ -211,7 +224,9 @@ class ArtistIndexOverviewOptionsModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Album Count</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowAlbumCount')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
@ -222,7 +237,9 @@ class ArtistIndexOverviewOptionsModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Path</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowPath')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
@ -233,7 +250,9 @@ class ArtistIndexOverviewOptionsModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Size on Disk</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowSizeOnDisk')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
@ -244,13 +263,15 @@ class ArtistIndexOverviewOptionsModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Search</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowSearch')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showSearchAction"
|
||||
value={showSearchAction}
|
||||
helpText="Show search button"
|
||||
helpText={translate('ShowSearchActionHelpText')}
|
||||
onChange={this.onChangeOverviewOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
|
|
@ -10,6 +10,7 @@ import Link from 'Components/Link/Link';
|
|||
import SpinnerIconButton from 'Components/Link/SpinnerIconButton';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import getRelativeDate from 'Utilities/Date/getRelativeDate';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import ArtistIndexPosterInfo from './ArtistIndexPosterInfo';
|
||||
import styles from './ArtistIndexPoster.css';
|
||||
|
||||
|
@ -122,7 +123,7 @@ class ArtistIndexPoster extends Component {
|
|||
<SpinnerIconButton
|
||||
className={styles.action}
|
||||
name={icons.REFRESH}
|
||||
title="Refresh Artist"
|
||||
title={translate('RefreshArtist')}
|
||||
isSpinning={isRefreshingArtist}
|
||||
onPress={onRefreshArtistPress}
|
||||
/>
|
||||
|
@ -132,7 +133,7 @@ class ArtistIndexPoster extends Component {
|
|||
<SpinnerIconButton
|
||||
className={styles.action}
|
||||
name={icons.SEARCH}
|
||||
title="Search for monitored albums"
|
||||
title={translate('SearchForMonitoredAlbums')}
|
||||
isSpinning={isSearchingArtist}
|
||||
onPress={onSearchPress}
|
||||
/>
|
||||
|
@ -141,7 +142,7 @@ class ArtistIndexPoster extends Component {
|
|||
<IconButton
|
||||
className={styles.action}
|
||||
name={icons.EDIT}
|
||||
title="Edit Artist"
|
||||
title={translate('EditArtist')}
|
||||
onPress={this.onEditArtistPress}
|
||||
/>
|
||||
</Label>
|
||||
|
@ -150,7 +151,7 @@ class ArtistIndexPoster extends Component {
|
|||
status === 'ended' &&
|
||||
<div
|
||||
className={styles.ended}
|
||||
title="Ended"
|
||||
title={translate('Ended')}
|
||||
/>
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { inputTypes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
const posterSizeOptions = [
|
||||
{ key: 'small', value: 'Small' },
|
||||
|
@ -114,7 +115,9 @@ class ArtistIndexPosterOptionsModalContent extends Component {
|
|||
<ModalBody>
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<FormLabel>Poster Size</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('PosterSize')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.SELECT}
|
||||
|
@ -126,61 +129,71 @@ class ArtistIndexPosterOptionsModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Detailed Progress Bar</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('DetailedProgressBar')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="detailedProgressBar"
|
||||
value={detailedProgressBar}
|
||||
helpText="Show text on progess bar"
|
||||
helpText={translate('DetailedProgressBarHelpText')}
|
||||
onChange={this.onChangePosterOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Name</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowName')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showTitle"
|
||||
value={showTitle}
|
||||
helpText="Show artist name under poster"
|
||||
helpText={translate('ShowTitleHelpText')}
|
||||
onChange={this.onChangePosterOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Monitored</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowMonitored')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showMonitored"
|
||||
value={showMonitored}
|
||||
helpText="Show monitored status under poster"
|
||||
helpText={translate('ShowMonitoredHelpText')}
|
||||
onChange={this.onChangePosterOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Quality Profile</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowQualityProfile')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showQualityProfile"
|
||||
value={showQualityProfile}
|
||||
helpText="Show quality profile under poster"
|
||||
helpText={translate('ShowQualityProfileHelpText')}
|
||||
onChange={this.onChangePosterOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Search</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowSearch')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showSearchAction"
|
||||
value={showSearchAction}
|
||||
helpText="Show search button on hover"
|
||||
helpText={translate('ShowSearchActionHelpText')}
|
||||
onChange={this.onChangePosterOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
|
|
@ -3,6 +3,7 @@ import React from 'react';
|
|||
import ProgressBar from 'Components/ProgressBar';
|
||||
import { sizes } from 'Helpers/Props';
|
||||
import getProgressBarKind from 'Utilities/Artist/getProgressBarKind';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './ArtistIndexProgressBar.css';
|
||||
|
||||
function ArtistIndexProgressBar(props) {
|
||||
|
@ -28,7 +29,7 @@ function ArtistIndexProgressBar(props) {
|
|||
size={detailedProgressBar ? sizes.MEDIUM : sizes.SMALL}
|
||||
showText={detailedProgressBar}
|
||||
text={text}
|
||||
title={`${trackFileCount} / ${trackCount} (Total: ${totalTrackCount})`}
|
||||
title={translate('TrackFileCountTrackCountTotalTotalTrackCountInterp', [trackFileCount, trackCount, totalTrackCount])}
|
||||
width={posterWidth}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -6,6 +6,7 @@ import IconButton from 'Components/Link/IconButton';
|
|||
import SpinnerIconButton from 'Components/Link/SpinnerIconButton';
|
||||
import VirtualTableRowCell from 'Components/Table/Cells/VirtualTableRowCell';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
class ArtistIndexActionsCell extends Component {
|
||||
|
||||
|
@ -65,14 +66,14 @@ class ArtistIndexActionsCell extends Component {
|
|||
>
|
||||
<SpinnerIconButton
|
||||
name={icons.REFRESH}
|
||||
title="Refresh Artist"
|
||||
title={translate('RefreshArtist')}
|
||||
isSpinning={isRefreshingArtist}
|
||||
onPress={onRefreshArtistPress}
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
name={icons.EDIT}
|
||||
title="Edit Artist"
|
||||
title={translate('EditArtist')}
|
||||
onPress={this.onEditArtistPress}
|
||||
/>
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import TagListConnector from 'Components/TagListConnector';
|
|||
import { icons } from 'Helpers/Props';
|
||||
import getProgressBarKind from 'Utilities/Artist/getProgressBarKind';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import ArtistStatusCell from './ArtistStatusCell';
|
||||
import hasGrowableColumns from './hasGrowableColumns';
|
||||
import styles from './ArtistIndexRow.css';
|
||||
|
@ -307,7 +308,7 @@ class ArtistIndexRow extends Component {
|
|||
kind={getProgressBarKind(status, monitored, progress)}
|
||||
showText={true}
|
||||
text={`${trackFileCount} / ${trackCount}`}
|
||||
title={`${trackFileCount} / ${trackCount} (Total: ${totalTrackCount})`}
|
||||
title={translate('TrackFileCountTrackCountTotalTotalTrackCountInterp', [trackFileCount, trackCount, totalTrackCount])}
|
||||
width={125}
|
||||
/>
|
||||
</VirtualTableRowCell>
|
||||
|
@ -396,7 +397,7 @@ class ArtistIndexRow extends Component {
|
|||
>
|
||||
<SpinnerIconButton
|
||||
name={icons.REFRESH}
|
||||
title="Refresh Artist"
|
||||
title={translate('RefreshArtist')}
|
||||
isSpinning={isRefreshingArtist}
|
||||
onPress={onRefreshArtistPress}
|
||||
/>
|
||||
|
@ -406,7 +407,7 @@ class ArtistIndexRow extends Component {
|
|||
<SpinnerIconButton
|
||||
className={styles.action}
|
||||
name={icons.SEARCH}
|
||||
title="Search for monitored albums"
|
||||
title={translate('SearchForMonitoredAlbums')}
|
||||
isSpinning={isSearchingArtist}
|
||||
onPress={onSearchPress}
|
||||
/>
|
||||
|
@ -414,7 +415,7 @@ class ArtistIndexRow extends Component {
|
|||
|
||||
<IconButton
|
||||
name={icons.EDIT}
|
||||
title="Edit Artist"
|
||||
title={translate('EditArtist')}
|
||||
onPress={this.onEditArtistPress}
|
||||
/>
|
||||
</VirtualTableRowCell>
|
||||
|
|
|
@ -4,6 +4,7 @@ import FormGroup from 'Components/Form/FormGroup';
|
|||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||
import FormLabel from 'Components/Form/FormLabel';
|
||||
import { inputTypes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
class ArtistIndexTableOptions extends Component {
|
||||
|
||||
|
@ -64,25 +65,29 @@ class ArtistIndexTableOptions extends Component {
|
|||
return (
|
||||
<Fragment>
|
||||
<FormGroup>
|
||||
<FormLabel>Show Banners</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowBanners')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showBanners"
|
||||
value={showBanners}
|
||||
helpText="Show banners instead of names"
|
||||
helpText={translate('ShowBannersHelpText')}
|
||||
onChange={this.onTableOptionChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Show Search</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ShowSearch')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showSearchAction"
|
||||
value={showSearchAction}
|
||||
helpText="Show search button on hover"
|
||||
helpText={translate('ShowSearchActionHelpText')}
|
||||
onChange={this.onTableOptionChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
|
|
@ -4,6 +4,7 @@ import Icon from 'Components/Icon';
|
|||
import MonitorToggleButton from 'Components/MonitorToggleButton';
|
||||
import VirtualTableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './ArtistStatusCell.css';
|
||||
|
||||
function ArtistStatusCell(props) {
|
||||
|
@ -36,7 +37,7 @@ function ArtistStatusCell(props) {
|
|||
<Icon
|
||||
className={styles.statusIcon}
|
||||
name={status === 'ended' ? icons.ARTIST_ENDED : icons.ARTIST_CONTINUING}
|
||||
title={status === 'ended' ? endedString : 'Continuing'}
|
||||
title={status === 'ended' ? endedString : translate('StatusEndedContinuing')}
|
||||
/>
|
||||
</Component>
|
||||
);
|
||||
|
|
|
@ -8,6 +8,7 @@ import Icon from 'Components/Icon';
|
|||
import Link from 'Components/Link/Link';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import formatTime from 'Utilities/Date/formatTime';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './AgendaEvent.css';
|
||||
|
||||
class AgendaEvent extends Component {
|
||||
|
@ -110,7 +111,7 @@ class AgendaEvent extends Component {
|
|||
!queueItem && grabbed &&
|
||||
<Icon
|
||||
name={icons.DOWNLOADING}
|
||||
title="Album is downloading"
|
||||
title={translate('AlbumIsDownloading')}
|
||||
/>
|
||||
}
|
||||
</Link>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import AgendaConnector from './Agenda/AgendaConnector';
|
||||
import * as calendarViews from './calendarViews';
|
||||
import CalendarDaysConnector from './Day/CalendarDaysConnector';
|
||||
|
@ -30,7 +31,9 @@ class Calendar extends Component {
|
|||
|
||||
{
|
||||
!isFetching && !!error &&
|
||||
<div>Unable to load the calendar</div>
|
||||
<div>
|
||||
{translate('UnableToLoadTheCalendar')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -12,6 +12,7 @@ import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection';
|
|||
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||
import { align, icons } from 'Helpers/Props';
|
||||
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import CalendarConnector from './CalendarConnector';
|
||||
import CalendarLinkModal from './iCal/CalendarLinkModal';
|
||||
import LegendConnector from './Legend/LegendConnector';
|
||||
|
@ -97,11 +98,11 @@ class CalendarPage extends Component {
|
|||
const isMeasured = this.state.width > 0;
|
||||
|
||||
return (
|
||||
<PageContent title="Calendar">
|
||||
<PageContent title={translate('Calendar')}>
|
||||
<PageToolbar>
|
||||
<PageToolbarSection>
|
||||
<PageToolbarButton
|
||||
label="iCal Link"
|
||||
label={translate('ICalLink')}
|
||||
iconName={icons.CALENDAR}
|
||||
onPress={this.onGetCalendarLinkPress}
|
||||
/>
|
||||
|
@ -109,14 +110,14 @@ class CalendarPage extends Component {
|
|||
<PageToolbarSeparator />
|
||||
|
||||
<PageToolbarButton
|
||||
label="RSS Sync"
|
||||
label={translate('RSSSync')}
|
||||
iconName={icons.RSS}
|
||||
isSpinning={isRssSyncExecuting}
|
||||
onPress={onRssSyncPress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
label="Search for Missing"
|
||||
label={translate('SearchForMissing')}
|
||||
iconName={icons.SEARCH}
|
||||
isDisabled={!missingAlbumIds.length}
|
||||
isSpinning={isSearchingForMissing}
|
||||
|
@ -126,7 +127,7 @@ class CalendarPage extends Component {
|
|||
|
||||
<PageToolbarSection alignContent={align.RIGHT}>
|
||||
<PageToolbarButton
|
||||
label="Options"
|
||||
label={translate('Options')}
|
||||
iconName={icons.POSTER}
|
||||
onPress={this.onOptionsPress}
|
||||
/>
|
||||
|
|
|
@ -6,6 +6,7 @@ import getStatusStyle from 'Calendar/getStatusStyle';
|
|||
import Icon from 'Components/Icon';
|
||||
import Link from 'Components/Link/Link';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import CalendarEventQueueDetails from './CalendarEventQueueDetails';
|
||||
import styles from './CalendarEvent.css';
|
||||
|
||||
|
@ -97,7 +98,7 @@ class CalendarEvent extends Component {
|
|||
<Icon
|
||||
className={styles.statusIcon}
|
||||
name={icons.DOWNLOADING}
|
||||
title="Album is downloading"
|
||||
title={translate('AlbumIsDownloading')}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -3,6 +3,7 @@ import React from 'react';
|
|||
import QueueDetails from 'Activity/Queue/QueueDetails';
|
||||
import CircularProgressBar from 'Components/CircularProgressBar';
|
||||
import colors from 'Styles/Variables/colors';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
function CalendarEventQueueDetails(props) {
|
||||
const {
|
||||
|
@ -25,7 +26,7 @@ function CalendarEventQueueDetails(props) {
|
|||
status={status}
|
||||
errorMessage={errorMessage}
|
||||
progressBar={
|
||||
<div title={`Album is downloading - ${progress.toFixed(1)}% ${title}`}>
|
||||
<div title={translate('AlbumIsDownloadingInterp', [progress.toFixed(1), title])}>
|
||||
<CircularProgressBar
|
||||
progress={progress}
|
||||
size={20}
|
||||
|
|
|
@ -12,6 +12,7 @@ import ModalFooter from 'Components/Modal/ModalFooter';
|
|||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { inputTypes } from 'Helpers/Props';
|
||||
import { firstDayOfWeekOptions, timeFormatOptions, weekColumnOptions } from 'Settings/UI/UISettings';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
class CalendarOptionsModalContent extends Component {
|
||||
|
||||
|
@ -110,38 +111,44 @@ class CalendarOptionsModalContent extends Component {
|
|||
</ModalHeader>
|
||||
|
||||
<ModalBody>
|
||||
<FieldSet legend="Local">
|
||||
<FieldSet legend={translate('Local')}>
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<FormLabel>Collapse Multiple Albums</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('CollapseMultipleAlbums')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="collapseMultipleAlbums"
|
||||
value={collapseMultipleAlbums}
|
||||
helpText="Collapse multiple albums releasing on the same day"
|
||||
helpText={translate('CollapseMultipleAlbumsHelpText')}
|
||||
onChange={this.onOptionInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Icon for Cutoff Unmet</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('IconForCutoffUnmet')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showCutoffUnmetIcon"
|
||||
value={showCutoffUnmetIcon}
|
||||
helpText="Show icon for files when the cutoff hasn't been met"
|
||||
helpText={translate('ShowCutoffUnmetIconHelpText')}
|
||||
onChange={this.onOptionInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
</FieldSet>
|
||||
|
||||
<FieldSet legend="Global">
|
||||
<FieldSet legend={translate('Global')}>
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<FormLabel>First Day of Week</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('FirstDayOfWeek')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.SELECT}
|
||||
|
@ -153,7 +160,9 @@ class CalendarOptionsModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Week Column Header</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('WeekColumnHeader')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.SELECT}
|
||||
|
@ -161,12 +170,14 @@ class CalendarOptionsModalContent extends Component {
|
|||
values={weekColumnOptions}
|
||||
value={calendarWeekColumnHeader}
|
||||
onChange={this.onGlobalInputChange}
|
||||
helpText="Shown above each column when week is the active view"
|
||||
helpText={translate('ShownAboveEachColumnWhenWeekIsTheActiveView')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Time Format</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('TimeFormat')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.SELECT}
|
||||
|
@ -176,13 +187,15 @@ class CalendarOptionsModalContent extends Component {
|
|||
onChange={this.onGlobalInputChange}
|
||||
/>
|
||||
</FormGroup><FormGroup>
|
||||
<FormLabel>Enable Color-Impaired Mode</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('EnableColorImpairedMode')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="enableColorImpairedMode"
|
||||
value={enableColorImpairedMode}
|
||||
helpText="Altered style to allow color-impaired users to better distinguish color coded information"
|
||||
helpText={translate('EnableColorImpairedModeHelpText')}
|
||||
onChange={this.onGlobalInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
|
|
@ -13,6 +13,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { icons, inputTypes, kinds, sizes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
function getUrls(state) {
|
||||
const {
|
||||
|
@ -113,49 +114,57 @@ class CalendarLinkModalContent extends Component {
|
|||
<ModalBody>
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<FormLabel>Include Unmonitored</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('IncludeUnmonitored')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="unmonitored"
|
||||
value={unmonitored}
|
||||
helpText="Include unmonitored albums in the iCal feed"
|
||||
helpText={translate('UnmonitoredHelpText')}
|
||||
onChange={this.onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Past Days</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('PastDays')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.NUMBER}
|
||||
name="pastDays"
|
||||
value={pastDays}
|
||||
helpText="Days for iCal feed to look into the past"
|
||||
helpText={translate('PastDaysHelpText')}
|
||||
onChange={this.onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Future Days</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('FutureDays')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.NUMBER}
|
||||
name="futureDays"
|
||||
value={futureDays}
|
||||
helpText="Days for iCal feed to look into the future"
|
||||
helpText={translate('FutureDaysHelpText')}
|
||||
onChange={this.onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Tags</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Tags')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TAG}
|
||||
name="tags"
|
||||
value={tags}
|
||||
helpText="Feed will only contain artists with at least one matching tag"
|
||||
helpText={translate('TagsHelpText')}
|
||||
onChange={this.onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
@ -163,14 +172,16 @@ class CalendarLinkModalContent extends Component {
|
|||
<FormGroup
|
||||
size={sizes.LARGE}
|
||||
>
|
||||
<FormLabel>iCal Feed</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ICalFeed')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
name="iCalHttpUrl"
|
||||
value={iCalHttpUrl}
|
||||
readOnly={true}
|
||||
helpText="Copy this URL to your client(s) or click to subscribe if your browser supports webcal"
|
||||
helpText={translate('ICalHttpUrlHelpText')}
|
||||
buttons={[
|
||||
<ClipboardButton
|
||||
key="copy"
|
||||
|
|
|
@ -14,6 +14,7 @@ import Scroller from 'Components/Scroller/Scroller';
|
|||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import { kinds, scrollDirections } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import FileBrowserRow from './FileBrowserRow';
|
||||
import styles from './FileBrowserModalContent.css';
|
||||
|
||||
|
@ -134,7 +135,7 @@ class FileBrowserModalContent extends Component {
|
|||
|
||||
<PathInput
|
||||
className={styles.pathInput}
|
||||
placeholder="Start typing or select a path below"
|
||||
placeholder={translate('StartTypingOrSelectAPathBelow')}
|
||||
hasFileBrowser={false}
|
||||
{...otherProps}
|
||||
value={this.state.currentPath}
|
||||
|
@ -148,7 +149,9 @@ class FileBrowserModalContent extends Component {
|
|||
>
|
||||
{
|
||||
!!error &&
|
||||
<div>Error loading contents</div>
|
||||
<div>
|
||||
{translate('ErrorLoadingContents')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@ import React, { Component } from 'react';
|
|||
import IconButton from 'Components/Link/IconButton';
|
||||
import SpinnerIconButton from 'Components/Link/SpinnerIconButton';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './CustomFilter.css';
|
||||
|
||||
class CustomFilter extends Component {
|
||||
|
@ -89,7 +90,7 @@ class CustomFilter extends Component {
|
|||
/>
|
||||
|
||||
<SpinnerIconButton
|
||||
title="Remove filter"
|
||||
title={translate('RemoveFilter')}
|
||||
name={icons.REMOVE}
|
||||
isSpinning={this.state.isDeleting}
|
||||
onPress={this.onRemovePress}
|
||||
|
|
|
@ -176,7 +176,7 @@ function FormInputGroup(props) {
|
|||
<Icon
|
||||
name={icons.UNSAVED_SETTING}
|
||||
className={styles.pendingChangesIcon}
|
||||
title="Change has not been saved yet"
|
||||
title={translate('ChangeHasNotBeenSavedYet')}
|
||||
/>
|
||||
}
|
||||
</div> */}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import PageContent from 'Components/Page/PageContent';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './NotFound.css';
|
||||
|
||||
function NotFound({ message }) {
|
||||
return (
|
||||
<PageContent title="MIA">
|
||||
<PageContent title={translate('MIA')}>
|
||||
<div className={styles.container}>
|
||||
<div className={styles.message}>
|
||||
{message}
|
||||
|
|
|
@ -15,6 +15,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { inputTypes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import TableOptionsColumn from './TableOptionsColumn';
|
||||
import TableOptionsColumnDragPreview from './TableOptionsColumnDragPreview';
|
||||
import TableOptionsColumnDragSource from './TableOptionsColumnDragSource';
|
||||
|
@ -144,13 +145,15 @@ class TableOptionsModal extends Component {
|
|||
{
|
||||
hasPageSize ?
|
||||
<FormGroup>
|
||||
<FormLabel>Page Size</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('PageSize')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.NUMBER}
|
||||
name="pageSize"
|
||||
value={pageSize || 0}
|
||||
helpText="Number of items to show on each page"
|
||||
helpText={translate('PageSizeHelpText')}
|
||||
errors={pageSizeError ? [{ message: pageSizeError }] : undefined}
|
||||
onChange={this.onPageSizeChange}
|
||||
/>
|
||||
|
@ -168,7 +171,9 @@ class TableOptionsModal extends Component {
|
|||
{
|
||||
canModifyColumns ?
|
||||
<FormGroup>
|
||||
<FormLabel>Columns</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Columns')}
|
||||
</FormLabel>
|
||||
|
||||
<div>
|
||||
<FormInputHelpText
|
||||
|
|
|
@ -11,6 +11,7 @@ import Scroller from 'Components/Scroller/Scroller';
|
|||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import { scrollDirections } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import SelectAlbumRow from './SelectAlbumRow';
|
||||
import styles from './SelectAlbumModalContent.css';
|
||||
|
||||
|
@ -87,7 +88,7 @@ class SelectAlbumModalContent extends Component {
|
|||
}
|
||||
<TextInput
|
||||
className={styles.filterInput}
|
||||
placeholder="Filter album"
|
||||
placeholder={translate('FilterPlaceHolder')}
|
||||
name="filter"
|
||||
value={filter}
|
||||
autoFocus={true}
|
||||
|
|
|
@ -5,6 +5,7 @@ import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellCo
|
|||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import { kinds, sizes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './SelectAlbumRow.css';
|
||||
|
||||
function getTrackCountKind(monitored, trackFileCount, trackCount) {
|
||||
|
@ -97,7 +98,7 @@ class SelectAlbumRow extends Component {
|
|||
key={name}
|
||||
>
|
||||
<Label
|
||||
title={`${totalTrackCount} tracks total. ${trackFileCount} tracks with files.`}
|
||||
title={translate('TotalTrackCountTracksTotalTrackFileCountTracksWithFilesInterp', [totalTrackCount, trackFileCount])}
|
||||
kind={getTrackCountKind(monitored, trackFileCount, trackCount)}
|
||||
size={sizes.MEDIUM}
|
||||
>
|
||||
|
|
|
@ -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 SelectArtistRow from './SelectArtistRow';
|
||||
import styles from './SelectArtistModalContent.css';
|
||||
|
||||
|
@ -55,7 +56,7 @@ class SelectArtistModalContent extends Component {
|
|||
>
|
||||
<TextInput
|
||||
className={styles.filterInput}
|
||||
placeholder="Filter artist"
|
||||
placeholder={translate('FilterPlaceHolder')}
|
||||
name="filter"
|
||||
value={filter}
|
||||
autoFocus={true}
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
@ -16,6 +16,7 @@ import SelectQualityModal from 'InteractiveImport/Quality/SelectQualityModal';
|
|||
import SelectTrackModal from 'InteractiveImport/Track/SelectTrackModal';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import InteractiveImportRowCellPlaceholder from './InteractiveImportRowCellPlaceholder';
|
||||
import styles from './InteractiveImportRow.css';
|
||||
|
||||
|
@ -197,7 +198,7 @@ class InteractiveImportRow extends Component {
|
|||
const pathCell = additionalFile ? (
|
||||
<Tooltip
|
||||
anchor={pathCellContents}
|
||||
tooltip='This file is already in your library for a release you are currently importing'
|
||||
tooltip={translate('AnchorTooltip')}
|
||||
position={tooltipPositions.TOP}
|
||||
/>
|
||||
) : pathCellContents;
|
||||
|
@ -221,7 +222,7 @@ class InteractiveImportRow extends Component {
|
|||
|
||||
<TableRowCellButton
|
||||
isDisabled={!allowArtistChange}
|
||||
title={allowArtistChange ? 'Click to change artist' : undefined}
|
||||
title={allowArtistChange ? translate('AllowArtistChangeClickToChangeArtist') : undefined}
|
||||
onPress={this.onSelectArtistPress}
|
||||
>
|
||||
{
|
||||
|
@ -231,7 +232,7 @@ class InteractiveImportRow extends Component {
|
|||
|
||||
<TableRowCellButton
|
||||
isDisabled={!artist}
|
||||
title={artist ? 'Click to change album' : undefined}
|
||||
title={artist ? translate('ArtistClickToChangeAlbum') : undefined}
|
||||
onPress={this.onSelectAlbumPress}
|
||||
>
|
||||
{
|
||||
|
@ -241,7 +242,7 @@ class InteractiveImportRow extends Component {
|
|||
|
||||
<TableRowCellButton
|
||||
isDisabled={!artist || !album}
|
||||
title={artist && album ? 'Click to change track' : undefined}
|
||||
title={artist && album ? translate('ArtistAlbumClickToChangeTrack') : undefined}
|
||||
onPress={this.onSelectTrackPress}
|
||||
>
|
||||
{
|
||||
|
@ -254,7 +255,7 @@ class InteractiveImportRow extends Component {
|
|||
|
||||
<TableRowCellButton
|
||||
className={styles.quality}
|
||||
title="Click to change quality"
|
||||
title={translate('ClickToChangeQuality')}
|
||||
onPress={this.onSelectQualityPress}
|
||||
>
|
||||
{
|
||||
|
@ -285,7 +286,7 @@ class InteractiveImportRow extends Component {
|
|||
kind={kinds.DANGER}
|
||||
/>
|
||||
}
|
||||
title="Release Rejected"
|
||||
title={translate('ReleaseRejected')}
|
||||
body={
|
||||
<ul>
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { inputTypes, kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
class SelectQualityModalContent extends Component {
|
||||
|
||||
|
@ -91,14 +92,18 @@ class SelectQualityModalContent extends Component {
|
|||
|
||||
{
|
||||
!isFetching && !!error &&
|
||||
<div>Unable to load qualities</div>
|
||||
<div>
|
||||
{translate('UnableToLoadQualities')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
isPopulated && !error &&
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<FormLabel>Quality</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Quality')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.SELECT}
|
||||
|
@ -110,7 +115,9 @@ class SelectQualityModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Proper</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Proper')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
@ -121,7 +128,9 @@ class SelectQualityModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Real</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Real')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
|
|
@ -6,6 +6,7 @@ import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
|||
import TableRowButton from 'Components/Table/TableRowButton';
|
||||
import Popover from 'Components/Tooltip/Popover';
|
||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
class SelectTrackRow extends Component {
|
||||
|
||||
|
@ -96,7 +97,7 @@ class SelectTrackRow extends Component {
|
|||
kind={iconKind}
|
||||
/>
|
||||
}
|
||||
title={'Track status'}
|
||||
title={translate('TrackStatus')}
|
||||
body={iconTip}
|
||||
position={tooltipPositions.LEFT}
|
||||
/>
|
||||
|
|
|
@ -13,6 +13,7 @@ import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
|||
import formatDateTime from 'Utilities/Date/formatDateTime';
|
||||
import formatAge from 'Utilities/Number/formatAge';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import Peers from './Peers';
|
||||
import styles from './InteractiveSearchRow.css';
|
||||
|
||||
|
@ -179,7 +180,7 @@ class InteractiveSearchRow extends Component {
|
|||
kind={kinds.DANGER}
|
||||
/>
|
||||
}
|
||||
title="Release Rejected"
|
||||
title={translate('ReleaseRejected')}
|
||||
body={
|
||||
<ul>
|
||||
{
|
||||
|
@ -213,9 +214,9 @@ class InteractiveSearchRow extends Component {
|
|||
<ConfirmModal
|
||||
isOpen={this.state.isConfirmGrabModalOpen}
|
||||
kind={kinds.WARNING}
|
||||
title="Grab Release"
|
||||
message={`Lidarr was unable to determine which artist and album this release was for. Lidarr may be unable to automatically import this release. Do you want to grab '${title}'?`}
|
||||
confirmLabel="Grab"
|
||||
title={translate('GrabRelease')}
|
||||
message={translate('GrabReleaseMessageText', [title])}
|
||||
confirmLabel={translate('Grab')}
|
||||
onConfirm={this.onGrabConfirm}
|
||||
onCancel={this.onGrabCancel}
|
||||
/>
|
||||
|
|
|
@ -9,6 +9,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
||||
import selectAll from 'Utilities/Table/selectAll';
|
||||
import toggleSelected from 'Utilities/Table/toggleSelected';
|
||||
|
@ -100,12 +101,16 @@ class OrganizePreviewModalContent extends Component {
|
|||
|
||||
{
|
||||
!isFetching && error &&
|
||||
<div>Error loading previews</div>
|
||||
<div>
|
||||
{translate('ErrorLoadingPreviews')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
!isFetching && isPopulated && !items.length &&
|
||||
<div>Success! My work is done, no files to rename.</div>
|
||||
<div>
|
||||
{translate('SuccessMyWorkIsDoneNoFilesToRename')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
||||
import selectAll from 'Utilities/Table/selectAll';
|
||||
import toggleSelected from 'Utilities/Table/toggleSelected';
|
||||
|
@ -99,12 +100,16 @@ class RetagPreviewModalContent extends Component {
|
|||
|
||||
{
|
||||
!isFetching && error &&
|
||||
<div>Error loading previews</div>
|
||||
<div>
|
||||
{translate('ErrorLoadingPreviews')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
!isFetching && ((isPopulated && !items.length)) &&
|
||||
<div>Success! My work is done, no files to retag.</div>
|
||||
<div>
|
||||
{translate('SuccessMyWorkIsDoneNoFilesToRetag')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@ import PageContent from 'Components/Page/PageContent';
|
|||
import PageContentBody from 'Components/Page/PageContentBody';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import AddNewAlbumSearchResultConnector from './Album/AddNewAlbumSearchResultConnector';
|
||||
import AddNewArtistSearchResultConnector from './Artist/AddNewArtistSearchResultConnector';
|
||||
import styles from './AddNewItem.css';
|
||||
|
@ -87,7 +88,7 @@ class AddNewItem extends Component {
|
|||
const isFetching = this.state.isFetching;
|
||||
|
||||
return (
|
||||
<PageContent title="Add New Item">
|
||||
<PageContent title={translate('AddNewItem')}>
|
||||
<PageContentBody>
|
||||
<div className={styles.searchContainer}>
|
||||
<div className={styles.searchIconContainer}>
|
||||
|
@ -101,7 +102,7 @@ class AddNewItem extends Component {
|
|||
className={styles.searchInput}
|
||||
name="searchBox"
|
||||
value={term}
|
||||
placeholder="eg. Breaking Benjamin, lidarr:854a1807-025b-42a8-ba8c-2a39717f1d25"
|
||||
placeholder={translate('SearchBoxPlaceHolder')}
|
||||
autoFocus={true}
|
||||
onChange={this.onSearchInputChange}
|
||||
/>
|
||||
|
|
|
@ -10,6 +10,7 @@ import Link from 'Components/Link/Link';
|
|||
import { icons, sizes } from 'Helpers/Props';
|
||||
import dimensions from 'Styles/Variables/dimensions';
|
||||
import fonts from 'Styles/Variables/fonts';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import AddNewAlbumModal from './AddNewAlbumModal';
|
||||
import styles from './AddNewAlbumSearchResult.css';
|
||||
|
||||
|
@ -130,7 +131,7 @@ class AddNewAlbumSearchResult extends Component {
|
|||
className={styles.alreadyExistsIcon}
|
||||
name={icons.CHECK_CIRCLE}
|
||||
size={36}
|
||||
title="Already in your library"
|
||||
title={translate('AlreadyInYourLibrary')}
|
||||
/> :
|
||||
null
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import Link from 'Components/Link/Link';
|
|||
import { icons, kinds, sizes } from 'Helpers/Props';
|
||||
import dimensions from 'Styles/Variables/dimensions';
|
||||
import fonts from 'Styles/Variables/fonts';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import AddNewArtistModal from './AddNewArtistModal';
|
||||
import styles from './AddNewArtistSearchResult.css';
|
||||
|
||||
|
@ -137,7 +138,7 @@ class AddNewArtistSearchResult extends Component {
|
|||
className={styles.alreadyExistsIcon}
|
||||
name={icons.CHECK_CIRCLE}
|
||||
size={36}
|
||||
title="Already in your library"
|
||||
title={translate('AlreadyInYourLibrary')}
|
||||
/> :
|
||||
null
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import FormLabel from 'Components/Form/FormLabel';
|
|||
import Icon from 'Components/Icon';
|
||||
import Popover from 'Components/Tooltip/Popover';
|
||||
import { icons, inputTypes, tooltipPositions } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './AddArtistOptionsForm.css';
|
||||
|
||||
class AddArtistOptionsForm extends Component {
|
||||
|
@ -43,7 +44,9 @@ class AddArtistOptionsForm extends Component {
|
|||
return (
|
||||
<Form {...otherProps}>
|
||||
<FormGroup>
|
||||
<FormLabel>Root Folder</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('RootFolder')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.ROOT_FOLDER_SELECT}
|
||||
|
@ -64,7 +67,7 @@ class AddArtistOptionsForm extends Component {
|
|||
name={icons.INFO}
|
||||
/>
|
||||
}
|
||||
title="Monitoring Options"
|
||||
title={translate('MonitoringOptions')}
|
||||
body={<ArtistMonitoringOptionsPopoverContent />}
|
||||
position={tooltipPositions.RIGHT}
|
||||
/>
|
||||
|
@ -79,7 +82,9 @@ class AddArtistOptionsForm extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Quality Profile</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('QualityProfile')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.QUALITY_PROFILE_SELECT}
|
||||
|
@ -102,7 +107,7 @@ class AddArtistOptionsForm extends Component {
|
|||
name={icons.INFO}
|
||||
/>
|
||||
}
|
||||
title="Metadata Profile"
|
||||
title={translate('MetadataProfile')}
|
||||
body={<ArtistMetadataProfilePopoverContent />}
|
||||
position={tooltipPositions.RIGHT}
|
||||
/>
|
||||
|
@ -119,7 +124,9 @@ class AddArtistOptionsForm extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Tags</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Tags')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TAG}
|
||||
|
|
|
@ -4,6 +4,7 @@ import React from 'react';
|
|||
import Icon from 'Components/Icon';
|
||||
import Link from 'Components/Link/Link';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './AdvancedSettingsButton.css';
|
||||
|
||||
function AdvancedSettingsButton(props) {
|
||||
|
@ -15,7 +16,7 @@ function AdvancedSettingsButton(props) {
|
|||
return (
|
||||
<Link
|
||||
className={styles.button}
|
||||
title={advancedSettings ? 'Shown, click to hide' : 'Hidden, click to show'}
|
||||
title={advancedSettings ? translate('AdvancedSettingsShownClickToHide') : translate('AdvancedSettingsHiddenClickToShow')}
|
||||
onPress={onAdvancedSettingsPress}
|
||||
>
|
||||
<Icon
|
||||
|
|
|
@ -6,6 +6,7 @@ import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
|||
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import DownloadClientsConnector from './DownloadClients/DownloadClientsConnector';
|
||||
import DownloadClientOptionsConnector from './Options/DownloadClientOptionsConnector';
|
||||
import RemotePathMappingsConnector from './RemotePathMappings/RemotePathMappingsConnector';
|
||||
|
@ -58,7 +59,7 @@ class DownloadClientSettings extends Component {
|
|||
} = this.state;
|
||||
|
||||
return (
|
||||
<PageContent title="Download Client Settings">
|
||||
<PageContent title={translate('DownloadClientSettings')}>
|
||||
<SettingsToolbarConnector
|
||||
isSaving={isSaving}
|
||||
hasPendingChanges={hasPendingChanges}
|
||||
|
@ -67,7 +68,7 @@ class DownloadClientSettings extends Component {
|
|||
<PageToolbarSeparator />
|
||||
|
||||
<PageToolbarButton
|
||||
label="Test All Clients"
|
||||
label={translate('TestAllClients')}
|
||||
iconName={icons.TEST}
|
||||
isSpinning={isTestingAll}
|
||||
onPress={dispatchTestAllDownloadClients}
|
||||
|
|
|
@ -9,6 +9,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import AddDownloadClientItem from './AddDownloadClientItem';
|
||||
import styles from './AddDownloadClientModalContent.css';
|
||||
|
||||
|
@ -42,7 +43,9 @@ class AddDownloadClientModalContent extends Component {
|
|||
|
||||
{
|
||||
!isSchemaFetching && !!schemaError &&
|
||||
<div>Unable to add a new downloadClient, please try again.</div>
|
||||
<div>
|
||||
{translate('UnableToAddANewDownloadClientPleaseTryAgain')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -50,11 +53,15 @@ class AddDownloadClientModalContent extends Component {
|
|||
<div>
|
||||
|
||||
<Alert kind={kinds.INFO}>
|
||||
<div>Lidarr supports any downloadClient that uses the Newznab standard, as well as other downloadClients listed below.</div>
|
||||
<div>For more information on the individual downloadClients, click on the info buttons.</div>
|
||||
<div>
|
||||
{translate('LidarrSupportsAnyDownloadClientThatUsesTheNewznabStandardAsWellAsOtherDownloadClientsListedBelow')}
|
||||
</div>
|
||||
<div>
|
||||
{translate('ForMoreInformationOnTheIndividualDownloadClientsClickOnTheInfoButtons')}
|
||||
</div>
|
||||
</Alert>
|
||||
|
||||
<FieldSet legend="Usenet">
|
||||
<FieldSet legend={translate('Usenet')}>
|
||||
<div className={styles.downloadClients}>
|
||||
{
|
||||
usenetDownloadClients.map((downloadClient) => {
|
||||
|
@ -71,7 +78,7 @@ class AddDownloadClientModalContent extends Component {
|
|||
</div>
|
||||
</FieldSet>
|
||||
|
||||
<FieldSet legend="Torrents">
|
||||
<FieldSet legend={translate('Torrents')}>
|
||||
<div className={styles.downloadClients}>
|
||||
{
|
||||
torrentDownloadClients.map((downloadClient) => {
|
||||
|
|
|
@ -4,6 +4,7 @@ import Card from 'Components/Card';
|
|||
import Label from 'Components/Label';
|
||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import EditDownloadClientModalConnector from './EditDownloadClientModalConnector';
|
||||
import styles from './DownloadClient.css';
|
||||
|
||||
|
@ -103,9 +104,9 @@ class DownloadClient extends Component {
|
|||
<ConfirmModal
|
||||
isOpen={this.state.isDeleteDownloadClientModalOpen}
|
||||
kind={kinds.DANGER}
|
||||
title="Delete Download Client"
|
||||
message={`Are you sure you want to delete the download client '${name}'?`}
|
||||
confirmLabel="Delete"
|
||||
title={translate('DeleteDownloadClient')}
|
||||
message={translate('DeleteDownloadClientMessageText', [name])}
|
||||
confirmLabel={translate('Delete')}
|
||||
onConfirm={this.onConfirmDeleteDownloadClient}
|
||||
onCancel={this.onDeleteDownloadClientModalClose}
|
||||
/>
|
||||
|
|
|
@ -5,6 +5,7 @@ import FieldSet from 'Components/FieldSet';
|
|||
import Icon from 'Components/Icon';
|
||||
import PageSectionContent from 'Components/Page/PageSectionContent';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import AddDownloadClientModal from './AddDownloadClientModal';
|
||||
import DownloadClient from './DownloadClient';
|
||||
import EditDownloadClientModalConnector from './EditDownloadClientModalConnector';
|
||||
|
@ -58,9 +59,9 @@ class DownloadClients extends Component {
|
|||
} = this.state;
|
||||
|
||||
return (
|
||||
<FieldSet legend="Download Clients">
|
||||
<FieldSet legend={translate('DownloadClients')}>
|
||||
<PageSectionContent
|
||||
errorMessage="Unable to load download clients"
|
||||
errorMessage={translate('UnableToLoadDownloadClients')}
|
||||
{...otherProps}
|
||||
>
|
||||
<div className={styles.downloadClients}>
|
||||
|
|
|
@ -14,6 +14,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { inputTypes, kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './EditDownloadClientModalContent.css';
|
||||
|
||||
class EditDownloadClientModalContent extends Component {
|
||||
|
@ -63,7 +64,9 @@ class EditDownloadClientModalContent extends Component {
|
|||
|
||||
{
|
||||
!isFetching && !!error &&
|
||||
<div>Unable to add a new download client, please try again.</div>
|
||||
<div>
|
||||
{translate('UnableToAddANewDownloadClientPleaseTryAgain')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -80,7 +83,9 @@ class EditDownloadClientModalContent extends Component {
|
|||
}
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Name</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Name')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
|
@ -91,7 +96,9 @@ class EditDownloadClientModalContent extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Enable</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Enable')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
@ -120,12 +127,14 @@ class EditDownloadClientModalContent extends Component {
|
|||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
>
|
||||
<FormLabel>Client Priority</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ClientPriority')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.NUMBER}
|
||||
name="priority"
|
||||
helpText="Prioritize multiple Download Clients. Round-Robin is used for clients with the same priority."
|
||||
helpText={translate('PriorityHelpText')}
|
||||
min={1}
|
||||
max={50}
|
||||
{...priority}
|
||||
|
|
|
@ -7,6 +7,7 @@ import FormInputGroup from 'Components/Form/FormInputGroup';
|
|||
import FormLabel from 'Components/Form/FormLabel';
|
||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import { inputTypes, sizes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
function DownloadClientOptions(props) {
|
||||
const {
|
||||
|
@ -27,21 +28,25 @@ function DownloadClientOptions(props) {
|
|||
|
||||
{
|
||||
!isFetching && error &&
|
||||
<div>Unable to load download client options</div>
|
||||
<div>
|
||||
{translate('UnableToLoadDownloadClientOptions')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
hasSettings && !isFetching && !error &&
|
||||
<div>
|
||||
<FieldSet legend="Completed Download Handling">
|
||||
<FieldSet legend={translate('CompletedDownloadHandling')}>
|
||||
<Form>
|
||||
<FormGroup size={sizes.MEDIUM}>
|
||||
<FormLabel>Enable</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Enable')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="enableCompletedDownloadHandling"
|
||||
helpText="Automatically import completed downloads from download client"
|
||||
helpText={translate('EnableCompletedDownloadHandlingHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...settings.enableCompletedDownloadHandling}
|
||||
/>
|
||||
|
@ -52,12 +57,14 @@ function DownloadClientOptions(props) {
|
|||
isAdvanced={true}
|
||||
size={sizes.MEDIUM}
|
||||
>
|
||||
<FormLabel>Remove</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Remove')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="removeCompletedDownloads"
|
||||
helpText="Remove imported downloads from download client history"
|
||||
helpText={translate('RemoveCompletedDownloadsHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...settings.removeCompletedDownloads}
|
||||
/>
|
||||
|
@ -66,16 +73,18 @@ function DownloadClientOptions(props) {
|
|||
</FieldSet>
|
||||
|
||||
<FieldSet
|
||||
legend="Failed Download Handling"
|
||||
legend={translate('FailedDownloadHandling')}
|
||||
>
|
||||
<Form>
|
||||
<FormGroup size={sizes.MEDIUM}>
|
||||
<FormLabel>Redownload</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Redownload')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="autoRedownloadFailed"
|
||||
helpText="Automatically search for and attempt to download a different release"
|
||||
helpText={translate('AutoRedownloadFailedHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...settings.autoRedownloadFailed}
|
||||
/>
|
||||
|
@ -86,12 +95,14 @@ function DownloadClientOptions(props) {
|
|||
isAdvanced={true}
|
||||
size={sizes.MEDIUM}
|
||||
>
|
||||
<FormLabel>Remove</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Remove')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="removeFailedDownloads"
|
||||
helpText="Remove failed downloads from download client history"
|
||||
helpText={translate('RemoveFailedDownloadsHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...settings.removeFailedDownloads}
|
||||
/>
|
||||
|
|
|
@ -13,6 +13,7 @@ import ModalFooter from 'Components/Modal/ModalFooter';
|
|||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { inputTypes, kinds } from 'Helpers/Props';
|
||||
import { stringSettingShape } from 'Helpers/Props/Shapes/settingShape';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './EditRemotePathMappingModalContent.css';
|
||||
|
||||
function EditRemotePathMappingModalContent(props) {
|
||||
|
@ -51,19 +52,23 @@ function EditRemotePathMappingModalContent(props) {
|
|||
|
||||
{
|
||||
!isFetching && !!error &&
|
||||
<div>Unable to add a new remote path mapping, please try again.</div>
|
||||
<div>
|
||||
{translate('UnableToAddANewRemotePathMappingPleaseTryAgain')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
!isFetching && !error &&
|
||||
<Form {...otherProps}>
|
||||
<FormGroup>
|
||||
<FormLabel>Host</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Host')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.SELECT}
|
||||
name="host"
|
||||
helpText="The same host you specified for the remote Download Client"
|
||||
helpText={translate('HostHelpText')}
|
||||
{...host}
|
||||
values={downloadClientHosts}
|
||||
onChange={onInputChange}
|
||||
|
@ -71,24 +76,28 @@ function EditRemotePathMappingModalContent(props) {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Remote Path</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('RemotePath')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
name="remotePath"
|
||||
helpText="Root path to the directory that the Download Client accesses"
|
||||
helpText={translate('RemotePathHelpText')}
|
||||
{...remotePath}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Local Path</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('LocalPath')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.PATH}
|
||||
name="localPath"
|
||||
helpText="Path that Lidarr should use to access the remote path locally"
|
||||
helpText={translate('LocalPathHelpText')}
|
||||
{...localPath}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
|
|
|
@ -5,6 +5,7 @@ import Icon from 'Components/Icon';
|
|||
import Link from 'Components/Link/Link';
|
||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import EditRemotePathMappingModalConnector from './EditRemotePathMappingModalConnector';
|
||||
import styles from './RemotePathMapping.css';
|
||||
|
||||
|
@ -87,9 +88,9 @@ class RemotePathMapping extends Component {
|
|||
<ConfirmModal
|
||||
isOpen={this.state.isDeleteRemotePathMappingModalOpen}
|
||||
kind={kinds.DANGER}
|
||||
title="Delete Delay Profile"
|
||||
message="Are you sure you want to delete this remote path mapping?"
|
||||
confirmLabel="Delete"
|
||||
title={translate('DeleteDelayProfile')}
|
||||
message={translate('DeleteDelayProfileMessageText')}
|
||||
confirmLabel={translate('Delete')}
|
||||
onConfirm={this.onConfirmDeleteRemotePathMapping}
|
||||
onCancel={this.onDeleteRemotePathMappingModalClose}
|
||||
/>
|
||||
|
|
|
@ -5,6 +5,7 @@ import Icon from 'Components/Icon';
|
|||
import Link from 'Components/Link/Link';
|
||||
import PageSectionContent from 'Components/Page/PageSectionContent';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import EditRemotePathMappingModalConnector from './EditRemotePathMappingModalConnector';
|
||||
import RemotePathMapping from './RemotePathMapping';
|
||||
import styles from './RemotePathMappings.css';
|
||||
|
@ -44,9 +45,9 @@ class RemotePathMappings extends Component {
|
|||
} = this.props;
|
||||
|
||||
return (
|
||||
<FieldSet legend="Remote Path Mappings">
|
||||
<FieldSet legend={translate('RemotePathMappings')}>
|
||||
<PageSectionContent
|
||||
errorMessage="Unable to load Remote Path Mappings"
|
||||
errorMessage={translate('UnableToLoadRemotePathMappings')}
|
||||
{...otherProps}
|
||||
>
|
||||
<div className={styles.remotePathMappingsHeader}>
|
||||
|
|
|
@ -5,6 +5,7 @@ import FormGroup from 'Components/Form/FormGroup';
|
|||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||
import FormLabel from 'Components/Form/FormLabel';
|
||||
import { inputTypes, sizes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
function AnalyticSettings(props) {
|
||||
const {
|
||||
|
@ -17,15 +18,17 @@ function AnalyticSettings(props) {
|
|||
} = settings;
|
||||
|
||||
return (
|
||||
<FieldSet legend="Analytics">
|
||||
<FieldSet legend={translate('Analytics')}>
|
||||
<FormGroup size={sizes.MEDIUM}>
|
||||
<FormLabel>Send Anonymous Usage Data</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('SendAnonymousUsageData')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="analyticsEnabled"
|
||||
helpText="Send anonymous usage and error information to Lidarr's servers. This includes information on your browser, which Lidarr WebUI pages you use, error reporting as well as OS and runtime version. We will use this information to prioritize features and bug fixes."
|
||||
helpTextWarning="Requires restart to take effect"
|
||||
helpText={translate('AnalyticsEnabledHelpText')}
|
||||
helpTextWarning={translate('AnalyticsEnabledHelpTextWarning')}
|
||||
onChange={onInputChange}
|
||||
{...analyticsEnabled}
|
||||
/>
|
||||
|
|
|
@ -5,6 +5,7 @@ import FormGroup from 'Components/Form/FormGroup';
|
|||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||
import FormLabel from 'Components/Form/FormLabel';
|
||||
import { inputTypes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
function BackupSettings(props) {
|
||||
const {
|
||||
|
@ -24,17 +25,19 @@ function BackupSettings(props) {
|
|||
}
|
||||
|
||||
return (
|
||||
<FieldSet legend="Backups">
|
||||
<FieldSet legend={translate('Backups')}>
|
||||
<FormGroup
|
||||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
>
|
||||
<FormLabel>Folder</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Folder')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.PATH}
|
||||
name="backupFolder"
|
||||
helpText="Relative paths will be under Lidarr's AppData directory"
|
||||
helpText={translate('BackupFolderHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...backupFolder}
|
||||
/>
|
||||
|
@ -44,13 +47,15 @@ function BackupSettings(props) {
|
|||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
>
|
||||
<FormLabel>Interval</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Interval')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.NUMBER}
|
||||
name="backupInterval"
|
||||
unit="days"
|
||||
helpText="Interval to backup the Lidarr DB and settings"
|
||||
helpText={translate('BackupIntervalHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...backupInterval}
|
||||
/>
|
||||
|
@ -60,13 +65,15 @@ function BackupSettings(props) {
|
|||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
>
|
||||
<FormLabel>Retention</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Retention')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.NUMBER}
|
||||
name="backupRetention"
|
||||
unit="days"
|
||||
helpText="Automatic backups older than the retention period will be cleaned up automatically"
|
||||
helpText={translate('BackupRetentionHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...backupRetention}
|
||||
/>
|
||||
|
|
|
@ -8,6 +8,7 @@ import PageContent from 'Components/Page/PageContent';
|
|||
import PageContentBody from 'Components/Page/PageContentBody';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import AnalyticSettings from './AnalyticSettings';
|
||||
import BackupSettings from './BackupSettings';
|
||||
import HostSettings from './HostSettings';
|
||||
|
@ -110,7 +111,7 @@ class GeneralSettings extends Component {
|
|||
} = this.props;
|
||||
|
||||
return (
|
||||
<PageContent title="General Settings">
|
||||
<PageContent title={translate('GeneralSettings')}>
|
||||
<SettingsToolbarConnector
|
||||
{...otherProps}
|
||||
/>
|
||||
|
@ -123,7 +124,9 @@ class GeneralSettings extends Component {
|
|||
|
||||
{
|
||||
!isFetching && error &&
|
||||
<div>Unable to load General settings</div>
|
||||
<div>
|
||||
{translate('UnableToLoadGeneralSettings')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -183,12 +186,12 @@ class GeneralSettings extends Component {
|
|||
<ConfirmModal
|
||||
isOpen={this.state.isRestartRequiredModalOpen}
|
||||
kind={kinds.DANGER}
|
||||
title="Restart Lidarr"
|
||||
title={translate('RestartLidarr')}
|
||||
message={
|
||||
`Lidarr requires a restart to apply changes, do you want to restart now? ${isWindowsService ? 'Depending which user is running the Lidarr service you may need to restart Lidarr as admin once before the service will start automatically.' : ''}`
|
||||
}
|
||||
cancelLabel="I'll restart later"
|
||||
confirmLabel="Restart Now"
|
||||
cancelLabel={translate('IllRestartLater')}
|
||||
confirmLabel={translate('RestartNow')}
|
||||
onConfirm={this.onConfirmRestart}
|
||||
onCancel={this.onCloseRestartRequiredModalOpen}
|
||||
/>
|
||||
|
|
|
@ -5,6 +5,7 @@ import FormGroup from 'Components/Form/FormGroup';
|
|||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||
import FormLabel from 'Components/Form/FormLabel';
|
||||
import { inputTypes, sizes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
function HostSettings(props) {
|
||||
const {
|
||||
|
@ -27,25 +28,29 @@ function HostSettings(props) {
|
|||
} = settings;
|
||||
|
||||
return (
|
||||
<FieldSet legend="Host">
|
||||
<FieldSet legend={translate('Host')}>
|
||||
<FormGroup
|
||||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
>
|
||||
<FormLabel>Bind Address</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('BindAddress')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
name="bindAddress"
|
||||
helpText="Valid IP4 address or '*' for all interfaces"
|
||||
helpTextWarning="Requires restart to take effect"
|
||||
helpText={translate('BindAddressHelpText')}
|
||||
helpTextWarning={translate('BindAddressHelpTextWarning')}
|
||||
onChange={onInputChange}
|
||||
{...bindAddress}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Port Number</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('PortNumber')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.NUMBER}
|
||||
|
@ -53,20 +58,22 @@ function HostSettings(props) {
|
|||
min={1}
|
||||
max={65535}
|
||||
autocomplete="off"
|
||||
helpTextWarning="Requires restart to take effect"
|
||||
helpTextWarning={translate('RequiresRestartToTakeEffect')}
|
||||
onChange={onInputChange}
|
||||
{...port}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>URL Base</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('URLBase')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
name="urlBase"
|
||||
helpText="For reverse proxy support, default is empty"
|
||||
helpTextWarning="Requires restart to take effect"
|
||||
helpText={translate('UrlBaseHelpText')}
|
||||
helpTextWarning={translate('UrlBaseHelpTextWarning')}
|
||||
onChange={onInputChange}
|
||||
{...urlBase}
|
||||
/>
|
||||
|
@ -77,12 +84,14 @@ function HostSettings(props) {
|
|||
isAdvanced={true}
|
||||
size={sizes.MEDIUM}
|
||||
>
|
||||
<FormLabel>Enable SSL</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('EnableSSL')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="enableSsl"
|
||||
helpText=" Requires restart running as administrator to take effect"
|
||||
helpText={translate('EnableSslHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...enableSsl}
|
||||
/>
|
||||
|
@ -94,14 +103,16 @@ function HostSettings(props) {
|
|||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
>
|
||||
<FormLabel>SSL Port</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('SSLPort')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.NUMBER}
|
||||
name="sslPort"
|
||||
min={1}
|
||||
max={65535}
|
||||
helpTextWarning="Requires restart to take effect"
|
||||
helpTextWarning={translate('SslPortHelpTextWarning')}
|
||||
onChange={onInputChange}
|
||||
{...sslPort}
|
||||
/>
|
||||
|
@ -115,13 +126,15 @@ function HostSettings(props) {
|
|||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
>
|
||||
<FormLabel>SSL Cert Path</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('SSLCertPath')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
name="sslCertPath"
|
||||
helpText="Path to pfx file"
|
||||
helpTextWarning="Requires restart to take effect"
|
||||
helpText={translate('SslCertPathHelpText')}
|
||||
helpTextWarning={translate('SslCertPathHelpTextWarning')}
|
||||
onChange={onInputChange}
|
||||
{...sslCertPath}
|
||||
/>
|
||||
|
@ -135,13 +148,15 @@ function HostSettings(props) {
|
|||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
>
|
||||
<FormLabel>SSL Cert Password</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('SSLCertPassword')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.PASSWORD}
|
||||
name="sslCertPassword"
|
||||
helpText="Password for pfx file"
|
||||
helpTextWarning="Requires restart to take effect"
|
||||
helpText={translate('SslCertPasswordHelpText')}
|
||||
helpTextWarning={translate('SslCertPasswordHelpTextWarning')}
|
||||
onChange={onInputChange}
|
||||
{...sslCertPassword}
|
||||
/>
|
||||
|
@ -152,12 +167,14 @@ function HostSettings(props) {
|
|||
{
|
||||
isWindows && mode !== 'service' &&
|
||||
<FormGroup size={sizes.MEDIUM}>
|
||||
<FormLabel>Open browser on start</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('OpenBrowserOnStart')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="launchBrowser"
|
||||
helpText=" Open a web browser and navigate to Lidarr homepage on app start."
|
||||
helpText={translate('LaunchBrowserHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...launchBrowser}
|
||||
/>
|
||||
|
|
|
@ -5,6 +5,7 @@ import FormGroup from 'Components/Form/FormGroup';
|
|||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||
import FormLabel from 'Components/Form/FormLabel';
|
||||
import { inputTypes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
const logLevelOptions = [
|
||||
{ key: 'info', value: 'Info' },
|
||||
|
@ -23,15 +24,17 @@ function LoggingSettings(props) {
|
|||
} = settings;
|
||||
|
||||
return (
|
||||
<FieldSet legend="Logging">
|
||||
<FieldSet legend={translate('Logging')}>
|
||||
<FormGroup>
|
||||
<FormLabel>Log Level</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('LogLevel')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.SELECT}
|
||||
name="logLevel"
|
||||
values={logLevelOptions}
|
||||
helpTextWarning={logLevel.value === 'trace' ? 'Trace logging should only be enabled temporarily' : undefined}
|
||||
helpTextWarning={logLevel.value === 'trace' ? translate('LogLevelvalueTraceTraceLoggingShouldOnlyBeEnabledTemporarily') : undefined}
|
||||
onChange={onInputChange}
|
||||
{...logLevel}
|
||||
/>
|
||||
|
|
|
@ -5,6 +5,7 @@ import FormGroup from 'Components/Form/FormGroup';
|
|||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||
import FormLabel from 'Components/Form/FormLabel';
|
||||
import { inputTypes, sizes } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
function ProxySettings(props) {
|
||||
const {
|
||||
|
@ -30,9 +31,11 @@ function ProxySettings(props) {
|
|||
];
|
||||
|
||||
return (
|
||||
<FieldSet legend="Proxy">
|
||||
<FieldSet legend={translate('Proxy')}>
|
||||
<FormGroup size={sizes.MEDIUM}>
|
||||
<FormLabel>Use Proxy</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('UseProxy')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
@ -46,7 +49,9 @@ function ProxySettings(props) {
|
|||
proxyEnabled.value &&
|
||||
<div>
|
||||
<FormGroup>
|
||||
<FormLabel>Proxy Type</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ProxyType')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.SELECT}
|
||||
|
@ -58,7 +63,9 @@ function ProxySettings(props) {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Hostname</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Hostname')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
|
@ -69,7 +76,9 @@ function ProxySettings(props) {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Port</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Port')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.NUMBER}
|
||||
|
@ -82,43 +91,51 @@ function ProxySettings(props) {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Username')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
name="proxyUsername"
|
||||
helpText="You only need to enter a username and password if one is required. Leave them blank otherwise."
|
||||
helpText={translate('ProxyUsernameHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...proxyUsername}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Password</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Password')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.PASSWORD}
|
||||
name="proxyPassword"
|
||||
helpText="You only need to enter a username and password if one is required. Leave them blank otherwise."
|
||||
helpText={translate('ProxyPasswordHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...proxyPassword}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Ignored Addresses</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('IgnoredAddresses')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
name="proxyBypassFilter"
|
||||
helpText="Use ',' as a separator, and '*.' as a wildcard for subdomains"
|
||||
helpText={translate('ProxyBypassFilterHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...proxyBypassFilter}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup size={sizes.MEDIUM}>
|
||||
<FormLabel>Bypass Proxy for Local Addresses</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('BypassProxyForLocalAddresses')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
|
|
@ -9,6 +9,7 @@ import Icon from 'Components/Icon';
|
|||
import ClipboardButton from 'Components/Link/ClipboardButton';
|
||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||
import { icons, inputTypes, kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
const authenticationMethodOptions = [
|
||||
{ key: 'none', value: 'None' },
|
||||
|
@ -76,15 +77,17 @@ class SecuritySettings extends Component {
|
|||
const authenticationEnabled = authenticationMethod && authenticationMethod.value !== 'none';
|
||||
|
||||
return (
|
||||
<FieldSet legend="Security">
|
||||
<FieldSet legend={translate('Security')}>
|
||||
<FormGroup>
|
||||
<FormLabel>Authentication</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Authentication')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.SELECT}
|
||||
name="authenticationMethod"
|
||||
values={authenticationMethodOptions}
|
||||
helpText="Require Username and Password to access Lidarr"
|
||||
helpText={translate('AuthenticationMethodHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...authenticationMethod}
|
||||
/>
|
||||
|
@ -93,7 +96,9 @@ class SecuritySettings extends Component {
|
|||
{
|
||||
authenticationEnabled &&
|
||||
<FormGroup>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Username')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
|
@ -107,7 +112,9 @@ class SecuritySettings extends Component {
|
|||
{
|
||||
authenticationEnabled &&
|
||||
<FormGroup>
|
||||
<FormLabel>Password</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Password')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.PASSWORD}
|
||||
|
@ -119,13 +126,15 @@ class SecuritySettings extends Component {
|
|||
}
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>API Key</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('APIKey')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
name="apiKey"
|
||||
readOnly={true}
|
||||
helpTextWarning="Requires restart to take effect"
|
||||
helpTextWarning={translate('ApiKeyHelpTextWarning')}
|
||||
buttons={[
|
||||
<ClipboardButton
|
||||
key="copy"
|
||||
|
@ -151,13 +160,15 @@ class SecuritySettings extends Component {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Certificate Validation</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('CertificateValidation')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.SELECT}
|
||||
name="certificateValidation"
|
||||
values={certificateValidationOptions}
|
||||
helpText="Change how strict HTTPS certification validation is"
|
||||
helpText={translate('CertificateValidationHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...certificateValidation}
|
||||
/>
|
||||
|
@ -166,9 +177,9 @@ class SecuritySettings extends Component {
|
|||
<ConfirmModal
|
||||
isOpen={this.state.isConfirmApiKeyResetModalOpen}
|
||||
kind={kinds.DANGER}
|
||||
title="Reset API Key"
|
||||
message="Are you sure you want to reset your API Key?"
|
||||
confirmLabel="Reset"
|
||||
title={translate('ResetAPIKey')}
|
||||
message={translate('ResetAPIKeyMessageText')}
|
||||
confirmLabel={translate('Reset')}
|
||||
onConfirm={this.onConfirmResetApiKey}
|
||||
onCancel={this.onCloseResetApiKeyModal}
|
||||
/>
|
||||
|
|
|
@ -6,6 +6,7 @@ import FormInputGroup from 'Components/Form/FormInputGroup';
|
|||
import FormLabel from 'Components/Form/FormLabel';
|
||||
import { inputTypes, sizes } from 'Helpers/Props';
|
||||
import titleCase from 'Utilities/String/titleCase';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
function UpdateSettings(props) {
|
||||
const {
|
||||
|
@ -45,24 +46,28 @@ function UpdateSettings(props) {
|
|||
|
||||
if (isDocker) {
|
||||
return (
|
||||
<FieldSet legend="Updates">
|
||||
<div>Updating is disabled inside a docker container. Update the container image instead.</div>
|
||||
<FieldSet legend={translate('Updates')}>
|
||||
<div>
|
||||
{translate('UpdatingIsDisabledInsideADockerContainerUpdateTheContainerImageInstead')}
|
||||
</div>
|
||||
</FieldSet>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<FieldSet legend="Updates">
|
||||
<FieldSet legend={translate('Updates')}>
|
||||
<FormGroup
|
||||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
>
|
||||
<FormLabel>Branch</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Branch')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
name="branch"
|
||||
helpText={usingExternalUpdateMechanism ? 'Branch used by external update mechanism' : 'Branch to use to update Lidarr'}
|
||||
helpText={usingExternalUpdateMechanism ? translate('UsingExternalUpdateMechanismBranchUsedByExternalUpdateMechanism') : translate('UsingExternalUpdateMechanismBranchToUseToUpdateLidarr')}
|
||||
helpLink="https://wiki.servarr.com/lidarr/faq#how-do-i-update-lidarr"
|
||||
{...branch}
|
||||
onChange={onInputChange}
|
||||
|
@ -78,12 +83,14 @@ function UpdateSettings(props) {
|
|||
isAdvanced={true}
|
||||
size={sizes.MEDIUM}
|
||||
>
|
||||
<FormLabel>Automatic</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Automatic')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="updateAutomatically"
|
||||
helpText="Automatically download and install updates. You will still be able to install from System: Updates"
|
||||
helpText={translate('UpdateAutomaticallyHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...updateAutomatically}
|
||||
/>
|
||||
|
@ -93,13 +100,15 @@ function UpdateSettings(props) {
|
|||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
>
|
||||
<FormLabel>Mechanism</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Mechanism')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.SELECT}
|
||||
name="updateMechanism"
|
||||
values={updateOptions}
|
||||
helpText="Use Lidarr's built-in updater or a script"
|
||||
helpText={translate('UpdateMechanismHelpText')}
|
||||
helpLink="https://wiki.servarr.com/lidarr/faq#how-do-i-update-lidarr"
|
||||
onChange={onInputChange}
|
||||
{...updateMechanism}
|
||||
|
@ -112,12 +121,14 @@ function UpdateSettings(props) {
|
|||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
>
|
||||
<FormLabel>Script Path</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('ScriptPath')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
name="updateScriptPath"
|
||||
helpText="Path to a custom script that takes an extracted update package and handle the remainder of the update process"
|
||||
helpText={translate('UpdateScriptPathHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...updateScriptPath}
|
||||
/>
|
||||
|
|
|
@ -13,6 +13,7 @@ import ModalFooter from 'Components/Modal/ModalFooter';
|
|||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { inputTypes, kinds } from 'Helpers/Props';
|
||||
import { stringSettingShape } from 'Helpers/Props/Shapes/settingShape';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './EditImportListExclusionModalContent.css';
|
||||
|
||||
function EditImportListExclusionModalContent(props) {
|
||||
|
@ -49,7 +50,9 @@ function EditImportListExclusionModalContent(props) {
|
|||
|
||||
{
|
||||
!isFetching && !!error &&
|
||||
<div>Unable to add a new import list exclusion, please try again.</div>
|
||||
<div>
|
||||
{translate('UnableToAddANewImportListExclusionPleaseTryAgain')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -58,24 +61,28 @@ function EditImportListExclusionModalContent(props) {
|
|||
{...otherProps}
|
||||
>
|
||||
<FormGroup>
|
||||
<FormLabel>Entity Name</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('EntityName')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
name="artistName"
|
||||
helpText="The name of the artist/album to exclude (can be anything meaningful)"
|
||||
helpText={translate('ArtistNameHelpText')}
|
||||
{...artistName}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Musicbrainz Id</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('MusicbrainzId')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
name="foreignId"
|
||||
helpText="The Musicbrainz Id of the artist/album to exclude"
|
||||
helpText={translate('ForeignIdHelpText')}
|
||||
{...foreignId}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
|
|
|
@ -5,6 +5,7 @@ import Icon from 'Components/Icon';
|
|||
import Link from 'Components/Link/Link';
|
||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import EditImportListExclusionModalConnector from './EditImportListExclusionModalConnector';
|
||||
import styles from './ImportListExclusion.css';
|
||||
|
||||
|
@ -85,9 +86,9 @@ class ImportListExclusion extends Component {
|
|||
<ConfirmModal
|
||||
isOpen={this.state.isDeleteImportListExclusionModalOpen}
|
||||
kind={kinds.DANGER}
|
||||
title="Delete Import List Exclusion"
|
||||
message="Are you sure you want to delete this import list exclusion?"
|
||||
confirmLabel="Delete"
|
||||
title={translate('DeleteImportListExclusion')}
|
||||
message={translate('DeleteImportListExclusionMessageText')}
|
||||
confirmLabel={translate('Delete')}
|
||||
onConfirm={this.onConfirmDeleteImportListExclusion}
|
||||
onCancel={this.onDeleteImportListExclusionModalClose}
|
||||
/>
|
||||
|
|
|
@ -5,6 +5,7 @@ import Icon from 'Components/Icon';
|
|||
import Link from 'Components/Link/Link';
|
||||
import PageSectionContent from 'Components/Page/PageSectionContent';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import EditImportListExclusionModalConnector from './EditImportListExclusionModalConnector';
|
||||
import ImportListExclusion from './ImportListExclusion';
|
||||
import styles from './ImportListExclusions.css';
|
||||
|
@ -44,9 +45,9 @@ class ImportListExclusions extends Component {
|
|||
} = this.props;
|
||||
|
||||
return (
|
||||
<FieldSet legend="Import List Exclusions">
|
||||
<FieldSet legend={translate('ImportListExclusions')}>
|
||||
<PageSectionContent
|
||||
errorMessage="Unable to load Import List Exclusions"
|
||||
errorMessage={translate('UnableToLoadImportListExclusions')}
|
||||
{...otherProps}
|
||||
>
|
||||
<div className={styles.importListExclusionsHeader}>
|
||||
|
|
|
@ -6,6 +6,7 @@ import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
|||
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import ImportListsExclusionsConnector from './ImportListExclusions/ImportListExclusionsConnector';
|
||||
import ImportListsConnector from './ImportLists/ImportListsConnector';
|
||||
|
||||
|
@ -54,7 +55,7 @@ class ImportListSettings extends Component {
|
|||
} = this.state;
|
||||
|
||||
return (
|
||||
<PageContent title="Import List Settings">
|
||||
<PageContent title={translate('ImportListSettings')}>
|
||||
<SettingsToolbarConnector
|
||||
isSaving={isSaving}
|
||||
hasPendingChanges={hasPendingChanges}
|
||||
|
@ -63,7 +64,7 @@ class ImportListSettings extends Component {
|
|||
<PageToolbarSeparator />
|
||||
|
||||
<PageToolbarButton
|
||||
label="Test All Lists"
|
||||
label={translate('TestAllLists')}
|
||||
iconName={icons.TEST}
|
||||
isSpinning={isTestingAll}
|
||||
onPress={dispatchTestAllImportLists}
|
||||
|
|
|
@ -10,6 +10,7 @@ import ModalFooter from 'Components/Modal/ModalFooter';
|
|||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import titleCase from 'Utilities/String/titleCase';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import AddImportListItem from './AddImportListItem';
|
||||
import styles from './AddImportListModalContent.css';
|
||||
|
||||
|
@ -42,7 +43,9 @@ class AddImportListModalContent extends Component {
|
|||
|
||||
{
|
||||
!isSchemaFetching && !!schemaError &&
|
||||
<div>Unable to add a new list, please try again.</div>
|
||||
<div>
|
||||
{translate('UnableToAddANewListPleaseTryAgain')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -50,8 +53,12 @@ class AddImportListModalContent extends Component {
|
|||
<div>
|
||||
|
||||
<Alert kind={kinds.INFO}>
|
||||
<div>Lidarr supports multiple lists for importing Albums and Artists into the database.</div>
|
||||
<div>For more information on the individual lists, click on the info buttons.</div>
|
||||
<div>
|
||||
{translate('LidarrSupportsMultipleListsForImportingAlbumsAndArtistsIntoTheDatabase')}
|
||||
</div>
|
||||
<div>
|
||||
{translate('ForMoreInformationOnTheIndividualListsClickOnTheInfoButtons')}
|
||||
</div>
|
||||
</Alert>
|
||||
{
|
||||
Object.keys(listGroups).map((key) => {
|
||||
|
|
|
@ -18,23 +18,24 @@ import ModalFooter from 'Components/Modal/ModalFooter';
|
|||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import Popover from 'Components/Tooltip/Popover';
|
||||
import { icons, inputTypes, kinds, tooltipPositions } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './EditImportListModalContent.css';
|
||||
|
||||
function ImportListMonitoringOptionsPopoverContent() {
|
||||
return (
|
||||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
title="None"
|
||||
title={translate('None')}
|
||||
data="Do not monitor artists or albums"
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="Specific Album"
|
||||
title={translate('SpecificAlbum')}
|
||||
data="Monitor artists but only monitor albums explicitly included in the list"
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title="All Artist Albums"
|
||||
title={translate('AllArtistAlbums')}
|
||||
data="Monitor artists and all albums for each artist included on the import list"
|
||||
/>
|
||||
</DescriptionList>
|
||||
|
@ -94,7 +95,9 @@ function EditImportListModalContent(props) {
|
|||
|
||||
{
|
||||
!isFetching && !!error &&
|
||||
<div>Unable to add a new list, please try again.</div>
|
||||
<div>
|
||||
{translate('UnableToAddANewListPleaseTryAgain')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -110,7 +113,9 @@ function EditImportListModalContent(props) {
|
|||
</Alert>
|
||||
}
|
||||
<FormGroup>
|
||||
<FormLabel>Name</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('Name')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
|
@ -121,12 +126,14 @@ function EditImportListModalContent(props) {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Enable Automatic Add</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('EnableAutomaticAdd')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="enableAutomaticAdd"
|
||||
helpText={'Add artist/albums to Lidarr when syncs are performed via the UI or by Lidarr'}
|
||||
helpText={translate('EnableAutomaticAddHelpText')}
|
||||
{...enableAutomaticAdd}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
|
@ -143,7 +150,7 @@ function EditImportListModalContent(props) {
|
|||
name={icons.INFO}
|
||||
/>
|
||||
}
|
||||
title="Monitoring Options"
|
||||
title={translate('MonitoringOptions')}
|
||||
body={<ImportListMonitoringOptionsPopoverContent />}
|
||||
position={tooltipPositions.RIGHT}
|
||||
/>
|
||||
|
@ -153,43 +160,49 @@ function EditImportListModalContent(props) {
|
|||
type={inputTypes.SELECT}
|
||||
name="shouldMonitor"
|
||||
values={monitorOptions}
|
||||
helpText={'Monitor artists and albums added from this list'}
|
||||
helpText={translate('ShouldMonitorHelpText')}
|
||||
{...shouldMonitor}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Root Folder</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('RootFolder')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.ROOT_FOLDER_SELECT}
|
||||
name="rootFolderPath"
|
||||
helpText={'Root Folder list items will be added to'}
|
||||
helpText={translate('RootFolderPathHelpText')}
|
||||
{...rootFolderPath}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Quality Profile</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('QualityProfile')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.QUALITY_PROFILE_SELECT}
|
||||
name="qualityProfileId"
|
||||
helpText={'Quality Profile list items should be added with'}
|
||||
helpText={translate('QualityProfileIdHelpText')}
|
||||
{...qualityProfileId}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup className={showMetadataProfile ? undefined : styles.hideMetadataProfile}>
|
||||
<FormLabel>Metadata Profile</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('MetadataProfile')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.METADATA_PROFILE_SELECT}
|
||||
name="metadataProfileId"
|
||||
helpText={'Metadata Profile list items should be added with'}
|
||||
helpText={translate('MetadataProfileIdHelpText')}
|
||||
{...metadataProfileId}
|
||||
includeNone={true}
|
||||
onChange={onInputChange}
|
||||
|
@ -197,12 +210,14 @@ function EditImportListModalContent(props) {
|
|||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Lidarr Tags</FormLabel>
|
||||
<FormLabel>
|
||||
{translate('LidarrTags')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TAG}
|
||||
name="tags"
|
||||
helpText="Add artists from this list with these tags"
|
||||
helpText={translate('TagsHelpText')}
|
||||
{...tags}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue