New: Custom Format Language Condition
This commit is contained in:
parent
52760e0908
commit
89b0b04e08
|
@ -1,4 +1,4 @@
|
||||||
.language,
|
.languages,
|
||||||
.quality {
|
.quality {
|
||||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
||||||
import TableRow from 'Components/Table/TableRow';
|
import TableRow from 'Components/Table/TableRow';
|
||||||
import EpisodeFormats from 'Episode/EpisodeFormats';
|
import EpisodeFormats from 'Episode/EpisodeFormats';
|
||||||
import EpisodeLanguage from 'Episode/EpisodeLanguage';
|
import EpisodeLanguages from 'Episode/EpisodeLanguages';
|
||||||
import EpisodeQuality from 'Episode/EpisodeQuality';
|
import EpisodeQuality from 'Episode/EpisodeQuality';
|
||||||
import { icons, kinds } from 'Helpers/Props';
|
import { icons, kinds } from 'Helpers/Props';
|
||||||
import SeriesTitleLink from 'Series/SeriesTitleLink';
|
import SeriesTitleLink from 'Series/SeriesTitleLink';
|
||||||
|
@ -45,7 +45,7 @@ class BlocklistRow extends Component {
|
||||||
id,
|
id,
|
||||||
series,
|
series,
|
||||||
sourceTitle,
|
sourceTitle,
|
||||||
language,
|
languages,
|
||||||
quality,
|
quality,
|
||||||
customFormats,
|
customFormats,
|
||||||
date,
|
date,
|
||||||
|
@ -96,14 +96,14 @@ class BlocklistRow extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name === 'language') {
|
if (name === 'languages') {
|
||||||
return (
|
return (
|
||||||
<TableRowCell
|
<TableRowCell
|
||||||
key={name}
|
key={name}
|
||||||
className={styles.language}
|
className={styles.languages}
|
||||||
>
|
>
|
||||||
<EpisodeLanguage
|
<EpisodeLanguages
|
||||||
language={language}
|
languages={languages}
|
||||||
/>
|
/>
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
);
|
);
|
||||||
|
@ -195,7 +195,7 @@ BlocklistRow.propTypes = {
|
||||||
id: PropTypes.number.isRequired,
|
id: PropTypes.number.isRequired,
|
||||||
series: PropTypes.object.isRequired,
|
series: PropTypes.object.isRequired,
|
||||||
sourceTitle: PropTypes.string.isRequired,
|
sourceTitle: PropTypes.string.isRequired,
|
||||||
language: PropTypes.object.isRequired,
|
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
quality: PropTypes.object.isRequired,
|
quality: PropTypes.object.isRequired,
|
||||||
customFormats: PropTypes.arrayOf(PropTypes.object).isRequired,
|
customFormats: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
date: PropTypes.string.isRequired,
|
date: PropTypes.string.isRequired,
|
||||||
|
|
|
@ -6,7 +6,7 @@ import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import TableRow from 'Components/Table/TableRow';
|
import TableRow from 'Components/Table/TableRow';
|
||||||
import episodeEntities from 'Episode/episodeEntities';
|
import episodeEntities from 'Episode/episodeEntities';
|
||||||
import EpisodeFormats from 'Episode/EpisodeFormats';
|
import EpisodeFormats from 'Episode/EpisodeFormats';
|
||||||
import EpisodeLanguage from 'Episode/EpisodeLanguage';
|
import EpisodeLanguages from 'Episode/EpisodeLanguages';
|
||||||
import EpisodeQuality from 'Episode/EpisodeQuality';
|
import EpisodeQuality from 'Episode/EpisodeQuality';
|
||||||
import EpisodeTitleLink from 'Episode/EpisodeTitleLink';
|
import EpisodeTitleLink from 'Episode/EpisodeTitleLink';
|
||||||
import SeasonEpisodeNumber from 'Episode/SeasonEpisodeNumber';
|
import SeasonEpisodeNumber from 'Episode/SeasonEpisodeNumber';
|
||||||
|
@ -59,7 +59,7 @@ class HistoryRow extends Component {
|
||||||
episodeId,
|
episodeId,
|
||||||
series,
|
series,
|
||||||
episode,
|
episode,
|
||||||
language,
|
languages,
|
||||||
languageCutoffNotMet,
|
languageCutoffNotMet,
|
||||||
quality,
|
quality,
|
||||||
customFormats,
|
customFormats,
|
||||||
|
@ -144,11 +144,11 @@ class HistoryRow extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name === 'language') {
|
if (name === 'languages') {
|
||||||
return (
|
return (
|
||||||
<TableRowCell key={name}>
|
<TableRowCell key={name}>
|
||||||
<EpisodeLanguage
|
<EpisodeLanguages
|
||||||
language={language}
|
languages={languages}
|
||||||
isCutoffMet={languageCutoffNotMet}
|
isCutoffMet={languageCutoffNotMet}
|
||||||
/>
|
/>
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
@ -278,7 +278,7 @@ HistoryRow.propTypes = {
|
||||||
episodeId: PropTypes.number,
|
episodeId: PropTypes.number,
|
||||||
series: PropTypes.object.isRequired,
|
series: PropTypes.object.isRequired,
|
||||||
episode: PropTypes.object,
|
episode: PropTypes.object,
|
||||||
language: PropTypes.object.isRequired,
|
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
languageCutoffNotMet: PropTypes.bool.isRequired,
|
languageCutoffNotMet: PropTypes.bool.isRequired,
|
||||||
quality: PropTypes.object.isRequired,
|
quality: PropTypes.object.isRequired,
|
||||||
customFormats: PropTypes.arrayOf(PropTypes.object),
|
customFormats: PropTypes.arrayOf(PropTypes.object),
|
||||||
|
|
|
@ -9,7 +9,7 @@ import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
||||||
import TableRow from 'Components/Table/TableRow';
|
import TableRow from 'Components/Table/TableRow';
|
||||||
import EpisodeFormats from 'Episode/EpisodeFormats';
|
import EpisodeFormats from 'Episode/EpisodeFormats';
|
||||||
import EpisodeLanguage from 'Episode/EpisodeLanguage';
|
import EpisodeLanguages from 'Episode/EpisodeLanguages';
|
||||||
import EpisodeQuality from 'Episode/EpisodeQuality';
|
import EpisodeQuality from 'Episode/EpisodeQuality';
|
||||||
import EpisodeTitleLink from 'Episode/EpisodeTitleLink';
|
import EpisodeTitleLink from 'Episode/EpisodeTitleLink';
|
||||||
import SeasonEpisodeNumber from 'Episode/SeasonEpisodeNumber';
|
import SeasonEpisodeNumber from 'Episode/SeasonEpisodeNumber';
|
||||||
|
@ -88,7 +88,7 @@ class QueueRow extends Component {
|
||||||
errorMessage,
|
errorMessage,
|
||||||
series,
|
series,
|
||||||
episode,
|
episode,
|
||||||
language,
|
languages,
|
||||||
quality,
|
quality,
|
||||||
customFormats,
|
customFormats,
|
||||||
protocol,
|
protocol,
|
||||||
|
@ -225,11 +225,11 @@ class QueueRow extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name === 'language') {
|
if (name === 'languages') {
|
||||||
return (
|
return (
|
||||||
<TableRowCell key={name}>
|
<TableRowCell key={name}>
|
||||||
<EpisodeLanguage
|
<EpisodeLanguages
|
||||||
language={language}
|
languages={languages}
|
||||||
/>
|
/>
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
);
|
);
|
||||||
|
@ -410,7 +410,7 @@ QueueRow.propTypes = {
|
||||||
errorMessage: PropTypes.string,
|
errorMessage: PropTypes.string,
|
||||||
series: PropTypes.object,
|
series: PropTypes.object,
|
||||||
episode: PropTypes.object,
|
episode: PropTypes.object,
|
||||||
language: PropTypes.object.isRequired,
|
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
quality: PropTypes.object.isRequired,
|
quality: PropTypes.object.isRequired,
|
||||||
customFormats: PropTypes.arrayOf(PropTypes.object),
|
customFormats: PropTypes.arrayOf(PropTypes.object),
|
||||||
protocol: PropTypes.string.isRequired,
|
protocol: PropTypes.string.isRequired,
|
||||||
|
|
|
@ -57,12 +57,6 @@
|
||||||
composes: button from '~Components/Link/SpinnerButton.css';
|
composes: button from '~Components/Link/SpinnerButton.css';
|
||||||
}
|
}
|
||||||
|
|
||||||
.hideLanguageProfile {
|
|
||||||
composes: group from '~Components/Form/FormGroup.css';
|
|
||||||
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: $breakpointSmall) {
|
@media only screen and (max-width: $breakpointSmall) {
|
||||||
.modalFooter {
|
.modalFooter {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
|
@ -47,10 +47,6 @@ class AddNewSeriesModalContent extends Component {
|
||||||
this.props.onInputChange({ name: 'qualityProfileId', value: parseInt(value) });
|
this.props.onInputChange({ name: 'qualityProfileId', value: parseInt(value) });
|
||||||
};
|
};
|
||||||
|
|
||||||
onLanguageProfileIdChange = ({ value }) => {
|
|
||||||
this.props.onInputChange({ name: 'languageProfileId', value: parseInt(value) });
|
|
||||||
};
|
|
||||||
|
|
||||||
onAddSeriesPress = () => {
|
onAddSeriesPress = () => {
|
||||||
const {
|
const {
|
||||||
seriesType
|
seriesType
|
||||||
|
@ -74,14 +70,12 @@ class AddNewSeriesModalContent extends Component {
|
||||||
rootFolderPath,
|
rootFolderPath,
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId,
|
qualityProfileId,
|
||||||
languageProfileId,
|
|
||||||
seriesType,
|
seriesType,
|
||||||
seasonFolder,
|
seasonFolder,
|
||||||
searchForMissingEpisodes,
|
searchForMissingEpisodes,
|
||||||
searchForCutoffUnmetEpisodes,
|
searchForCutoffUnmetEpisodes,
|
||||||
folder,
|
folder,
|
||||||
tags,
|
tags,
|
||||||
showLanguageProfile,
|
|
||||||
isSmallScreen,
|
isSmallScreen,
|
||||||
isWindows,
|
isWindows,
|
||||||
onModalClose,
|
onModalClose,
|
||||||
|
@ -180,17 +174,6 @@ class AddNewSeriesModalContent extends Component {
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup className={showLanguageProfile ? undefined : styles.hideLanguageProfile}>
|
|
||||||
<FormLabel>Language Profile</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.LANGUAGE_PROFILE_SELECT}
|
|
||||||
name="languageProfileId"
|
|
||||||
onChange={this.onLanguageProfileIdChange}
|
|
||||||
{...languageProfileId}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>
|
<FormLabel>
|
||||||
Series Type
|
Series Type
|
||||||
|
@ -299,14 +282,12 @@ AddNewSeriesModalContent.propTypes = {
|
||||||
rootFolderPath: PropTypes.object,
|
rootFolderPath: PropTypes.object,
|
||||||
monitor: PropTypes.object.isRequired,
|
monitor: PropTypes.object.isRequired,
|
||||||
qualityProfileId: PropTypes.object,
|
qualityProfileId: PropTypes.object,
|
||||||
languageProfileId: PropTypes.object,
|
|
||||||
seriesType: PropTypes.object.isRequired,
|
seriesType: PropTypes.object.isRequired,
|
||||||
seasonFolder: PropTypes.object.isRequired,
|
seasonFolder: PropTypes.object.isRequired,
|
||||||
searchForMissingEpisodes: PropTypes.object.isRequired,
|
searchForMissingEpisodes: PropTypes.object.isRequired,
|
||||||
searchForCutoffUnmetEpisodes: PropTypes.object.isRequired,
|
searchForCutoffUnmetEpisodes: PropTypes.object.isRequired,
|
||||||
folder: PropTypes.string.isRequired,
|
folder: PropTypes.string.isRequired,
|
||||||
tags: PropTypes.object.isRequired,
|
tags: PropTypes.object.isRequired,
|
||||||
showLanguageProfile: PropTypes.bool.isRequired,
|
|
||||||
isSmallScreen: PropTypes.bool.isRequired,
|
isSmallScreen: PropTypes.bool.isRequired,
|
||||||
isWindows: PropTypes.bool.isRequired,
|
isWindows: PropTypes.bool.isRequired,
|
||||||
onModalClose: PropTypes.func.isRequired,
|
onModalClose: PropTypes.func.isRequired,
|
||||||
|
|
|
@ -11,10 +11,9 @@ import AddNewSeriesModalContent from './AddNewSeriesModalContent';
|
||||||
function createMapStateToProps() {
|
function createMapStateToProps() {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
(state) => state.addSeries,
|
(state) => state.addSeries,
|
||||||
(state) => state.settings.languageProfiles,
|
|
||||||
createDimensionsSelector(),
|
createDimensionsSelector(),
|
||||||
createSystemStatusSelector(),
|
createSystemStatusSelector(),
|
||||||
(addSeriesState, languageProfiles, dimensions, systemStatus) => {
|
(addSeriesState, dimensions, systemStatus) => {
|
||||||
const {
|
const {
|
||||||
isAdding,
|
isAdding,
|
||||||
addError,
|
addError,
|
||||||
|
@ -30,7 +29,6 @@ function createMapStateToProps() {
|
||||||
return {
|
return {
|
||||||
isAdding,
|
isAdding,
|
||||||
addError,
|
addError,
|
||||||
showLanguageProfile: languageProfiles.items.length > 1,
|
|
||||||
isSmallScreen: dimensions.isSmallScreen,
|
isSmallScreen: dimensions.isSmallScreen,
|
||||||
validationErrors,
|
validationErrors,
|
||||||
validationWarnings,
|
validationWarnings,
|
||||||
|
@ -61,7 +59,6 @@ class AddNewSeriesModalContentConnector extends Component {
|
||||||
rootFolderPath,
|
rootFolderPath,
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId,
|
qualityProfileId,
|
||||||
languageProfileId,
|
|
||||||
seasonFolder,
|
seasonFolder,
|
||||||
searchForMissingEpisodes,
|
searchForMissingEpisodes,
|
||||||
searchForCutoffUnmetEpisodes,
|
searchForCutoffUnmetEpisodes,
|
||||||
|
@ -73,7 +70,6 @@ class AddNewSeriesModalContentConnector extends Component {
|
||||||
rootFolderPath: rootFolderPath.value,
|
rootFolderPath: rootFolderPath.value,
|
||||||
monitor: monitor.value,
|
monitor: monitor.value,
|
||||||
qualityProfileId: qualityProfileId.value,
|
qualityProfileId: qualityProfileId.value,
|
||||||
languageProfileId: languageProfileId.value,
|
|
||||||
seriesType,
|
seriesType,
|
||||||
seasonFolder: seasonFolder.value,
|
seasonFolder: seasonFolder.value,
|
||||||
searchForMissingEpisodes: searchForMissingEpisodes.value,
|
searchForMissingEpisodes: searchForMissingEpisodes.value,
|
||||||
|
@ -101,7 +97,6 @@ AddNewSeriesModalContentConnector.propTypes = {
|
||||||
rootFolderPath: PropTypes.object,
|
rootFolderPath: PropTypes.object,
|
||||||
monitor: PropTypes.object.isRequired,
|
monitor: PropTypes.object.isRequired,
|
||||||
qualityProfileId: PropTypes.object,
|
qualityProfileId: PropTypes.object,
|
||||||
languageProfileId: PropTypes.object,
|
|
||||||
seriesType: PropTypes.object.isRequired,
|
seriesType: PropTypes.object.isRequired,
|
||||||
seasonFolder: PropTypes.object.isRequired,
|
seasonFolder: PropTypes.object.isRequired,
|
||||||
searchForMissingEpisodes: PropTypes.object.isRequired,
|
searchForMissingEpisodes: PropTypes.object.isRequired,
|
||||||
|
|
|
@ -84,8 +84,7 @@ class ImportSeries extends Component {
|
||||||
rootFoldersFetching,
|
rootFoldersFetching,
|
||||||
rootFoldersPopulated,
|
rootFoldersPopulated,
|
||||||
rootFoldersError,
|
rootFoldersError,
|
||||||
unmappedFolders,
|
unmappedFolders
|
||||||
showLanguageProfile
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -135,7 +134,6 @@ class ImportSeries extends Component {
|
||||||
allUnselected={allUnselected}
|
allUnselected={allUnselected}
|
||||||
selectedState={selectedState}
|
selectedState={selectedState}
|
||||||
scroller={scroller}
|
scroller={scroller}
|
||||||
showLanguageProfile={showLanguageProfile}
|
|
||||||
onSelectAllChange={this.onSelectAllChange}
|
onSelectAllChange={this.onSelectAllChange}
|
||||||
onSelectedChange={this.onSelectedChange}
|
onSelectedChange={this.onSelectedChange}
|
||||||
onRemoveSelectedStateItem={this.onRemoveSelectedStateItem}
|
onRemoveSelectedStateItem={this.onRemoveSelectedStateItem}
|
||||||
|
@ -150,7 +148,6 @@ class ImportSeries extends Component {
|
||||||
!!unmappedFolders.length ?
|
!!unmappedFolders.length ?
|
||||||
<ImportSeriesFooterConnector
|
<ImportSeriesFooterConnector
|
||||||
selectedIds={this.getSelectedIds()}
|
selectedIds={this.getSelectedIds()}
|
||||||
showLanguageProfile={showLanguageProfile}
|
|
||||||
onInputChange={this.onInputChange}
|
onInputChange={this.onInputChange}
|
||||||
onImportPress={this.onImportPress}
|
onImportPress={this.onImportPress}
|
||||||
/> :
|
/> :
|
||||||
|
@ -169,7 +166,6 @@ ImportSeries.propTypes = {
|
||||||
rootFoldersError: PropTypes.object,
|
rootFoldersError: PropTypes.object,
|
||||||
unmappedFolders: PropTypes.arrayOf(PropTypes.object),
|
unmappedFolders: PropTypes.arrayOf(PropTypes.object),
|
||||||
items: PropTypes.arrayOf(PropTypes.object),
|
items: PropTypes.arrayOf(PropTypes.object),
|
||||||
showLanguageProfile: PropTypes.bool.isRequired,
|
|
||||||
onInputChange: PropTypes.func.isRequired,
|
onInputChange: PropTypes.func.isRequired,
|
||||||
onImportPress: PropTypes.func.isRequired
|
onImportPress: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,14 +16,12 @@ function createMapStateToProps() {
|
||||||
(state) => state.addSeries,
|
(state) => state.addSeries,
|
||||||
(state) => state.importSeries,
|
(state) => state.importSeries,
|
||||||
(state) => state.settings.qualityProfiles,
|
(state) => state.settings.qualityProfiles,
|
||||||
(state) => state.settings.languageProfiles,
|
|
||||||
(
|
(
|
||||||
match,
|
match,
|
||||||
rootFolders,
|
rootFolders,
|
||||||
addSeries,
|
addSeries,
|
||||||
importSeriesState,
|
importSeriesState,
|
||||||
qualityProfiles,
|
qualityProfiles
|
||||||
languageProfiles
|
|
||||||
) => {
|
) => {
|
||||||
const {
|
const {
|
||||||
isFetching: rootFoldersFetching,
|
isFetching: rootFoldersFetching,
|
||||||
|
@ -40,10 +38,7 @@ function createMapStateToProps() {
|
||||||
rootFoldersPopulated,
|
rootFoldersPopulated,
|
||||||
rootFoldersError,
|
rootFoldersError,
|
||||||
qualityProfiles: qualityProfiles.items,
|
qualityProfiles: qualityProfiles.items,
|
||||||
languageProfiles: languageProfiles.items,
|
defaultQualityProfileId: addSeries.defaults.qualityProfileId
|
||||||
showLanguageProfile: languageProfiles.items.length > 1,
|
|
||||||
defaultQualityProfileId: addSeries.defaults.qualityProfileId,
|
|
||||||
defaultLanguageProfileId: addSeries.defaults.languageProfileId
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (items.length) {
|
if (items.length) {
|
||||||
|
@ -78,9 +73,7 @@ class ImportSeriesConnector extends Component {
|
||||||
const {
|
const {
|
||||||
rootFolderId,
|
rootFolderId,
|
||||||
qualityProfiles,
|
qualityProfiles,
|
||||||
languageProfiles,
|
|
||||||
defaultQualityProfileId,
|
defaultQualityProfileId,
|
||||||
defaultLanguageProfileId,
|
|
||||||
dispatchFetchRootFolders,
|
dispatchFetchRootFolders,
|
||||||
dispatchSetAddSeriesDefault
|
dispatchSetAddSeriesDefault
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
@ -98,14 +91,6 @@ class ImportSeriesConnector extends Component {
|
||||||
setDefaultPayload.qualityProfileId = qualityProfiles[0].id;
|
setDefaultPayload.qualityProfileId = qualityProfiles[0].id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
|
||||||
!defaultLanguageProfileId ||
|
|
||||||
!languageProfiles.some((p) => p.id === defaultLanguageProfileId)
|
|
||||||
) {
|
|
||||||
setDefaults = true;
|
|
||||||
setDefaultPayload.languageProfileId = languageProfiles[0].id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setDefaults) {
|
if (setDefaults) {
|
||||||
dispatchSetAddSeriesDefault(setDefaultPayload);
|
dispatchSetAddSeriesDefault(setDefaultPayload);
|
||||||
}
|
}
|
||||||
|
@ -157,9 +142,7 @@ ImportSeriesConnector.propTypes = {
|
||||||
rootFoldersFetching: PropTypes.bool.isRequired,
|
rootFoldersFetching: PropTypes.bool.isRequired,
|
||||||
rootFoldersPopulated: PropTypes.bool.isRequired,
|
rootFoldersPopulated: PropTypes.bool.isRequired,
|
||||||
qualityProfiles: PropTypes.arrayOf(PropTypes.object).isRequired,
|
qualityProfiles: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
languageProfiles: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
||||||
defaultQualityProfileId: PropTypes.number.isRequired,
|
defaultQualityProfileId: PropTypes.number.isRequired,
|
||||||
defaultLanguageProfileId: PropTypes.number.isRequired,
|
|
||||||
dispatchSetImportSeriesValue: PropTypes.func.isRequired,
|
dispatchSetImportSeriesValue: PropTypes.func.isRequired,
|
||||||
dispatchImportSeries: PropTypes.func.isRequired,
|
dispatchImportSeries: PropTypes.func.isRequired,
|
||||||
dispatchClearImportSeries: PropTypes.func.isRequired,
|
dispatchClearImportSeries: PropTypes.func.isRequired,
|
||||||
|
|
|
@ -25,7 +25,6 @@ class ImportSeriesFooter extends Component {
|
||||||
const {
|
const {
|
||||||
defaultMonitor,
|
defaultMonitor,
|
||||||
defaultQualityProfileId,
|
defaultQualityProfileId,
|
||||||
defaultLanguageProfileId,
|
|
||||||
defaultSeasonFolder,
|
defaultSeasonFolder,
|
||||||
defaultSeriesType
|
defaultSeriesType
|
||||||
} = props;
|
} = props;
|
||||||
|
@ -33,7 +32,6 @@ class ImportSeriesFooter extends Component {
|
||||||
this.state = {
|
this.state = {
|
||||||
monitor: defaultMonitor,
|
monitor: defaultMonitor,
|
||||||
qualityProfileId: defaultQualityProfileId,
|
qualityProfileId: defaultQualityProfileId,
|
||||||
languageProfileId: defaultLanguageProfileId,
|
|
||||||
seriesType: defaultSeriesType,
|
seriesType: defaultSeriesType,
|
||||||
seasonFolder: defaultSeasonFolder
|
seasonFolder: defaultSeasonFolder
|
||||||
};
|
};
|
||||||
|
@ -43,12 +41,10 @@ class ImportSeriesFooter extends Component {
|
||||||
const {
|
const {
|
||||||
defaultMonitor,
|
defaultMonitor,
|
||||||
defaultQualityProfileId,
|
defaultQualityProfileId,
|
||||||
defaultLanguageProfileId,
|
|
||||||
defaultSeriesType,
|
defaultSeriesType,
|
||||||
defaultSeasonFolder,
|
defaultSeasonFolder,
|
||||||
isMonitorMixed,
|
isMonitorMixed,
|
||||||
isQualityProfileIdMixed,
|
isQualityProfileIdMixed,
|
||||||
isLanguageProfileIdMixed,
|
|
||||||
isSeriesTypeMixed,
|
isSeriesTypeMixed,
|
||||||
isSeasonFolderMixed
|
isSeasonFolderMixed
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
@ -56,7 +52,6 @@ class ImportSeriesFooter extends Component {
|
||||||
const {
|
const {
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId,
|
qualityProfileId,
|
||||||
languageProfileId,
|
|
||||||
seriesType,
|
seriesType,
|
||||||
seasonFolder
|
seasonFolder
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
@ -75,12 +70,6 @@ class ImportSeriesFooter extends Component {
|
||||||
newState.qualityProfileId = defaultQualityProfileId;
|
newState.qualityProfileId = defaultQualityProfileId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLanguageProfileIdMixed && languageProfileId !== MIXED) {
|
|
||||||
newState.languageProfileId = MIXED;
|
|
||||||
} else if (!isLanguageProfileIdMixed && languageProfileId !== defaultLanguageProfileId) {
|
|
||||||
newState.languageProfileId = defaultLanguageProfileId;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSeriesTypeMixed && seriesType !== MIXED) {
|
if (isSeriesTypeMixed && seriesType !== MIXED) {
|
||||||
newState.seriesType = MIXED;
|
newState.seriesType = MIXED;
|
||||||
} else if (!isSeriesTypeMixed && seriesType !== defaultSeriesType) {
|
} else if (!isSeriesTypeMixed && seriesType !== defaultSeriesType) {
|
||||||
|
@ -116,10 +105,8 @@ class ImportSeriesFooter extends Component {
|
||||||
isLookingUpSeries,
|
isLookingUpSeries,
|
||||||
isMonitorMixed,
|
isMonitorMixed,
|
||||||
isQualityProfileIdMixed,
|
isQualityProfileIdMixed,
|
||||||
isLanguageProfileIdMixed,
|
|
||||||
isSeriesTypeMixed,
|
isSeriesTypeMixed,
|
||||||
hasUnsearchedItems,
|
hasUnsearchedItems,
|
||||||
showLanguageProfile,
|
|
||||||
importError,
|
importError,
|
||||||
onImportPress,
|
onImportPress,
|
||||||
onLookupPress,
|
onLookupPress,
|
||||||
|
@ -129,7 +116,6 @@ class ImportSeriesFooter extends Component {
|
||||||
const {
|
const {
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId,
|
qualityProfileId,
|
||||||
languageProfileId,
|
|
||||||
seriesType,
|
seriesType,
|
||||||
seasonFolder
|
seasonFolder
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
@ -166,24 +152,6 @@ class ImportSeriesFooter extends Component {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
|
||||||
showLanguageProfile &&
|
|
||||||
<div className={styles.inputContainer}>
|
|
||||||
<div className={styles.label}>
|
|
||||||
Language Profile
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.LANGUAGE_PROFILE_SELECT}
|
|
||||||
name="languageProfileId"
|
|
||||||
value={languageProfileId}
|
|
||||||
isDisabled={!selectedCount}
|
|
||||||
includeMixed={isLanguageProfileIdMixed}
|
|
||||||
onChange={this.onInputChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
<div className={styles.inputContainer}>
|
<div className={styles.inputContainer}>
|
||||||
<div className={styles.label}>
|
<div className={styles.label}>
|
||||||
Series Type
|
Series Type
|
||||||
|
@ -308,16 +276,13 @@ ImportSeriesFooter.propTypes = {
|
||||||
isLookingUpSeries: PropTypes.bool.isRequired,
|
isLookingUpSeries: PropTypes.bool.isRequired,
|
||||||
defaultMonitor: PropTypes.string.isRequired,
|
defaultMonitor: PropTypes.string.isRequired,
|
||||||
defaultQualityProfileId: PropTypes.number,
|
defaultQualityProfileId: PropTypes.number,
|
||||||
defaultLanguageProfileId: PropTypes.number,
|
|
||||||
defaultSeriesType: PropTypes.string.isRequired,
|
defaultSeriesType: PropTypes.string.isRequired,
|
||||||
defaultSeasonFolder: PropTypes.bool.isRequired,
|
defaultSeasonFolder: PropTypes.bool.isRequired,
|
||||||
isMonitorMixed: PropTypes.bool.isRequired,
|
isMonitorMixed: PropTypes.bool.isRequired,
|
||||||
isQualityProfileIdMixed: PropTypes.bool.isRequired,
|
isQualityProfileIdMixed: PropTypes.bool.isRequired,
|
||||||
isLanguageProfileIdMixed: PropTypes.bool.isRequired,
|
|
||||||
isSeriesTypeMixed: PropTypes.bool.isRequired,
|
isSeriesTypeMixed: PropTypes.bool.isRequired,
|
||||||
isSeasonFolderMixed: PropTypes.bool.isRequired,
|
isSeasonFolderMixed: PropTypes.bool.isRequired,
|
||||||
hasUnsearchedItems: PropTypes.bool.isRequired,
|
hasUnsearchedItems: PropTypes.bool.isRequired,
|
||||||
showLanguageProfile: PropTypes.bool.isRequired,
|
|
||||||
importError: PropTypes.object,
|
importError: PropTypes.object,
|
||||||
onInputChange: PropTypes.func.isRequired,
|
onInputChange: PropTypes.func.isRequired,
|
||||||
onImportPress: PropTypes.func.isRequired,
|
onImportPress: PropTypes.func.isRequired,
|
||||||
|
|
|
@ -19,7 +19,6 @@ function createMapStateToProps() {
|
||||||
const {
|
const {
|
||||||
monitor: defaultMonitor,
|
monitor: defaultMonitor,
|
||||||
qualityProfileId: defaultQualityProfileId,
|
qualityProfileId: defaultQualityProfileId,
|
||||||
languageProfileId: defaultLanguageProfileId,
|
|
||||||
seriesType: defaultSeriesType,
|
seriesType: defaultSeriesType,
|
||||||
seasonFolder: defaultSeasonFolder
|
seasonFolder: defaultSeasonFolder
|
||||||
} = addSeries.defaults;
|
} = addSeries.defaults;
|
||||||
|
@ -33,7 +32,6 @@ function createMapStateToProps() {
|
||||||
|
|
||||||
const isMonitorMixed = isMixed(items, selectedIds, defaultMonitor, 'monitor');
|
const isMonitorMixed = isMixed(items, selectedIds, defaultMonitor, 'monitor');
|
||||||
const isQualityProfileIdMixed = isMixed(items, selectedIds, defaultQualityProfileId, 'qualityProfileId');
|
const isQualityProfileIdMixed = isMixed(items, selectedIds, defaultQualityProfileId, 'qualityProfileId');
|
||||||
const isLanguageProfileIdMixed = isMixed(items, selectedIds, defaultLanguageProfileId, 'languageProfileId');
|
|
||||||
const isSeriesTypeMixed = isMixed(items, selectedIds, defaultSeriesType, 'seriesType');
|
const isSeriesTypeMixed = isMixed(items, selectedIds, defaultSeriesType, 'seriesType');
|
||||||
const isSeasonFolderMixed = isMixed(items, selectedIds, defaultSeasonFolder, 'seasonFolder');
|
const isSeasonFolderMixed = isMixed(items, selectedIds, defaultSeasonFolder, 'seasonFolder');
|
||||||
const hasUnsearchedItems = !isLookingUpSeries && items.some((item) => !item.isPopulated);
|
const hasUnsearchedItems = !isLookingUpSeries && items.some((item) => !item.isPopulated);
|
||||||
|
@ -44,12 +42,10 @@ function createMapStateToProps() {
|
||||||
isImporting,
|
isImporting,
|
||||||
defaultMonitor,
|
defaultMonitor,
|
||||||
defaultQualityProfileId,
|
defaultQualityProfileId,
|
||||||
defaultLanguageProfileId,
|
|
||||||
defaultSeriesType,
|
defaultSeriesType,
|
||||||
defaultSeasonFolder,
|
defaultSeasonFolder,
|
||||||
isMonitorMixed,
|
isMonitorMixed,
|
||||||
isQualityProfileIdMixed,
|
isQualityProfileIdMixed,
|
||||||
isLanguageProfileIdMixed,
|
|
||||||
isSeriesTypeMixed,
|
isSeriesTypeMixed,
|
||||||
isSeasonFolderMixed,
|
isSeasonFolderMixed,
|
||||||
importError,
|
importError,
|
||||||
|
|
|
@ -11,8 +11,7 @@
|
||||||
min-width: 185px;
|
min-width: 185px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.qualityProfile,
|
.qualityProfile {
|
||||||
.languageProfile {
|
|
||||||
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
||||||
|
|
||||||
flex: 0 1 250px;
|
flex: 0 1 250px;
|
||||||
|
|
|
@ -12,7 +12,6 @@ import styles from './ImportSeriesHeader.css';
|
||||||
|
|
||||||
function ImportSeriesHeader(props) {
|
function ImportSeriesHeader(props) {
|
||||||
const {
|
const {
|
||||||
showLanguageProfile,
|
|
||||||
allSelected,
|
allSelected,
|
||||||
allUnselected,
|
allUnselected,
|
||||||
onSelectAllChange
|
onSelectAllChange
|
||||||
|
@ -59,16 +58,6 @@ function ImportSeriesHeader(props) {
|
||||||
Quality Profile
|
Quality Profile
|
||||||
</VirtualTableHeaderCell>
|
</VirtualTableHeaderCell>
|
||||||
|
|
||||||
{
|
|
||||||
showLanguageProfile &&
|
|
||||||
<VirtualTableHeaderCell
|
|
||||||
className={styles.languageProfile}
|
|
||||||
name="languageProfileId"
|
|
||||||
>
|
|
||||||
Language Profile
|
|
||||||
</VirtualTableHeaderCell>
|
|
||||||
}
|
|
||||||
|
|
||||||
<VirtualTableHeaderCell
|
<VirtualTableHeaderCell
|
||||||
className={styles.seriesType}
|
className={styles.seriesType}
|
||||||
name="seriesType"
|
name="seriesType"
|
||||||
|
@ -106,7 +95,6 @@ function ImportSeriesHeader(props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ImportSeriesHeader.propTypes = {
|
ImportSeriesHeader.propTypes = {
|
||||||
showLanguageProfile: PropTypes.bool.isRequired,
|
|
||||||
allSelected: PropTypes.bool.isRequired,
|
allSelected: PropTypes.bool.isRequired,
|
||||||
allUnselected: PropTypes.bool.isRequired,
|
allUnselected: PropTypes.bool.isRequired,
|
||||||
onSelectAllChange: PropTypes.func.isRequired
|
onSelectAllChange: PropTypes.func.isRequired
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
min-width: 185px;
|
min-width: 185px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.qualityProfile,
|
.qualityProfile {
|
||||||
.languageProfile {
|
|
||||||
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
||||||
|
|
||||||
flex: 0 1 250px;
|
flex: 0 1 250px;
|
||||||
|
@ -44,9 +43,3 @@
|
||||||
flex: 0 1 400px;
|
flex: 0 1 400px;
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hideLanguageProfile {
|
|
||||||
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
|
||||||
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,12 +12,10 @@ function ImportSeriesRow(props) {
|
||||||
id,
|
id,
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId,
|
qualityProfileId,
|
||||||
languageProfileId,
|
|
||||||
seasonFolder,
|
seasonFolder,
|
||||||
seriesType,
|
seriesType,
|
||||||
selectedSeries,
|
selectedSeries,
|
||||||
isExistingSeries,
|
isExistingSeries,
|
||||||
showLanguageProfile,
|
|
||||||
isSelected,
|
isSelected,
|
||||||
onSelectedChange,
|
onSelectedChange,
|
||||||
onInputChange
|
onInputChange
|
||||||
|
@ -55,17 +53,6 @@ function ImportSeriesRow(props) {
|
||||||
/>
|
/>
|
||||||
</VirtualTableRowCell>
|
</VirtualTableRowCell>
|
||||||
|
|
||||||
<VirtualTableRowCell
|
|
||||||
className={showLanguageProfile ? styles.languageProfile : styles.hideLanguageProfile}
|
|
||||||
>
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.LANGUAGE_PROFILE_SELECT}
|
|
||||||
name="languageProfileId"
|
|
||||||
value={languageProfileId}
|
|
||||||
onChange={onInputChange}
|
|
||||||
/>
|
|
||||||
</VirtualTableRowCell>
|
|
||||||
|
|
||||||
<VirtualTableRowCell className={styles.seriesType}>
|
<VirtualTableRowCell className={styles.seriesType}>
|
||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.SERIES_TYPE_SELECT}
|
type={inputTypes.SERIES_TYPE_SELECT}
|
||||||
|
@ -99,13 +86,11 @@ ImportSeriesRow.propTypes = {
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
monitor: PropTypes.string.isRequired,
|
monitor: PropTypes.string.isRequired,
|
||||||
qualityProfileId: PropTypes.number.isRequired,
|
qualityProfileId: PropTypes.number.isRequired,
|
||||||
languageProfileId: PropTypes.number.isRequired,
|
|
||||||
seriesType: PropTypes.string.isRequired,
|
seriesType: PropTypes.string.isRequired,
|
||||||
seasonFolder: PropTypes.bool.isRequired,
|
seasonFolder: PropTypes.bool.isRequired,
|
||||||
selectedSeries: PropTypes.object,
|
selectedSeries: PropTypes.object,
|
||||||
isExistingSeries: PropTypes.bool.isRequired,
|
isExistingSeries: PropTypes.bool.isRequired,
|
||||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
showLanguageProfile: PropTypes.bool.isRequired,
|
|
||||||
isSelected: PropTypes.bool,
|
isSelected: PropTypes.bool,
|
||||||
onSelectedChange: PropTypes.func.isRequired,
|
onSelectedChange: PropTypes.func.isRequired,
|
||||||
onInputChange: PropTypes.func.isRequired
|
onInputChange: PropTypes.func.isRequired
|
||||||
|
|
|
@ -16,7 +16,6 @@ class ImportSeriesTable extends Component {
|
||||||
unmappedFolders,
|
unmappedFolders,
|
||||||
defaultMonitor,
|
defaultMonitor,
|
||||||
defaultQualityProfileId,
|
defaultQualityProfileId,
|
||||||
defaultLanguageProfileId,
|
|
||||||
defaultSeriesType,
|
defaultSeriesType,
|
||||||
defaultSeasonFolder,
|
defaultSeasonFolder,
|
||||||
onSeriesLookup,
|
onSeriesLookup,
|
||||||
|
@ -26,7 +25,6 @@ class ImportSeriesTable extends Component {
|
||||||
const values = {
|
const values = {
|
||||||
monitor: defaultMonitor,
|
monitor: defaultMonitor,
|
||||||
qualityProfileId: defaultQualityProfileId,
|
qualityProfileId: defaultQualityProfileId,
|
||||||
languageProfileId: defaultLanguageProfileId,
|
|
||||||
seriesType: defaultSeriesType,
|
seriesType: defaultSeriesType,
|
||||||
seasonFolder: defaultSeasonFolder
|
seasonFolder: defaultSeasonFolder
|
||||||
};
|
};
|
||||||
|
@ -106,7 +104,6 @@ class ImportSeriesTable extends Component {
|
||||||
rootFolderId,
|
rootFolderId,
|
||||||
items,
|
items,
|
||||||
selectedState,
|
selectedState,
|
||||||
showLanguageProfile,
|
|
||||||
onSelectedChange
|
onSelectedChange
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
@ -120,7 +117,6 @@ class ImportSeriesTable extends Component {
|
||||||
<ImportSeriesRowConnector
|
<ImportSeriesRowConnector
|
||||||
key={item.id}
|
key={item.id}
|
||||||
rootFolderId={rootFolderId}
|
rootFolderId={rootFolderId}
|
||||||
showLanguageProfile={showLanguageProfile}
|
|
||||||
isSelected={selectedState[item.id]}
|
isSelected={selectedState[item.id]}
|
||||||
onSelectedChange={onSelectedChange}
|
onSelectedChange={onSelectedChange}
|
||||||
id={item.id}
|
id={item.id}
|
||||||
|
@ -139,7 +135,6 @@ class ImportSeriesTable extends Component {
|
||||||
allUnselected,
|
allUnselected,
|
||||||
isSmallScreen,
|
isSmallScreen,
|
||||||
scroller,
|
scroller,
|
||||||
showLanguageProfile,
|
|
||||||
selectedState,
|
selectedState,
|
||||||
onSelectAllChange
|
onSelectAllChange
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
@ -158,7 +153,6 @@ class ImportSeriesTable extends Component {
|
||||||
rowRenderer={this.rowRenderer}
|
rowRenderer={this.rowRenderer}
|
||||||
header={
|
header={
|
||||||
<ImportSeriesHeader
|
<ImportSeriesHeader
|
||||||
showLanguageProfile={showLanguageProfile}
|
|
||||||
allSelected={allSelected}
|
allSelected={allSelected}
|
||||||
allUnselected={allUnselected}
|
allUnselected={allUnselected}
|
||||||
onSelectAllChange={onSelectAllChange}
|
onSelectAllChange={onSelectAllChange}
|
||||||
|
@ -176,7 +170,6 @@ ImportSeriesTable.propTypes = {
|
||||||
unmappedFolders: PropTypes.arrayOf(PropTypes.object),
|
unmappedFolders: PropTypes.arrayOf(PropTypes.object),
|
||||||
defaultMonitor: PropTypes.string.isRequired,
|
defaultMonitor: PropTypes.string.isRequired,
|
||||||
defaultQualityProfileId: PropTypes.number,
|
defaultQualityProfileId: PropTypes.number,
|
||||||
defaultLanguageProfileId: PropTypes.number,
|
|
||||||
defaultSeriesType: PropTypes.string.isRequired,
|
defaultSeriesType: PropTypes.string.isRequired,
|
||||||
defaultSeasonFolder: PropTypes.bool.isRequired,
|
defaultSeasonFolder: PropTypes.bool.isRequired,
|
||||||
allSelected: PropTypes.bool.isRequired,
|
allSelected: PropTypes.bool.isRequired,
|
||||||
|
@ -185,7 +178,6 @@ ImportSeriesTable.propTypes = {
|
||||||
isSmallScreen: PropTypes.bool.isRequired,
|
isSmallScreen: PropTypes.bool.isRequired,
|
||||||
allSeries: PropTypes.arrayOf(PropTypes.object),
|
allSeries: PropTypes.arrayOf(PropTypes.object),
|
||||||
scroller: PropTypes.instanceOf(Element).isRequired,
|
scroller: PropTypes.instanceOf(Element).isRequired,
|
||||||
showLanguageProfile: PropTypes.bool.isRequired,
|
|
||||||
onSelectAllChange: PropTypes.func.isRequired,
|
onSelectAllChange: PropTypes.func.isRequired,
|
||||||
onSelectedChange: PropTypes.func.isRequired,
|
onSelectedChange: PropTypes.func.isRequired,
|
||||||
onRemoveSelectedStateItem: PropTypes.func.isRequired,
|
onRemoveSelectedStateItem: PropTypes.func.isRequired,
|
||||||
|
|
|
@ -14,7 +14,6 @@ function createMapStateToProps() {
|
||||||
return {
|
return {
|
||||||
defaultMonitor: addSeries.defaults.monitor,
|
defaultMonitor: addSeries.defaults.monitor,
|
||||||
defaultQualityProfileId: addSeries.defaults.qualityProfileId,
|
defaultQualityProfileId: addSeries.defaults.qualityProfileId,
|
||||||
defaultLanguageProfileId: addSeries.defaults.languageProfileId,
|
|
||||||
defaultSeriesType: addSeries.defaults.seriesType,
|
defaultSeriesType: addSeries.defaults.seriesType,
|
||||||
defaultSeasonFolder: addSeries.defaults.seasonFolder,
|
defaultSeasonFolder: addSeries.defaults.seasonFolder,
|
||||||
items: importSeries.items,
|
items: importSeries.items,
|
||||||
|
|
|
@ -175,19 +175,6 @@ class AgendaEvent extends Component {
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
showCutoffUnmetIcon &&
|
|
||||||
!!episodeFile &&
|
|
||||||
episodeFile.languageCutoffNotMet &&
|
|
||||||
!episodeFile.qualityCutoffNotMet &&
|
|
||||||
<Icon
|
|
||||||
className={styles.statusIcon}
|
|
||||||
name={icons.EPISODE_FILE}
|
|
||||||
kind={kinds.WARNING}
|
|
||||||
title="Language cutoff has not been met"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
episodeNumber === 1 && seasonNumber > 0 &&
|
episodeNumber === 1 && seasonNumber > 0 &&
|
||||||
<Icon
|
<Icon
|
||||||
|
|
|
@ -152,20 +152,6 @@ class CalendarEvent extends Component {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
showCutoffUnmetIcon &&
|
|
||||||
!!episodeFile &&
|
|
||||||
episodeFile.languageCutoffNotMet &&
|
|
||||||
!episodeFile.qualityCutoffNotMet ?
|
|
||||||
<Icon
|
|
||||||
className={styles.statusIcon}
|
|
||||||
name={icons.EPISODE_FILE}
|
|
||||||
kind={fullColorEvents ? kinds.DEFAULT : kinds.WARNING}
|
|
||||||
title="Language cutoff has not been met"
|
|
||||||
/> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
episodeNumber === 1 && seasonNumber > 0 ?
|
episodeNumber === 1 && seasonNumber > 0 ?
|
||||||
<Icon
|
<Icon
|
||||||
|
|
|
@ -47,7 +47,7 @@ function Legend(props) {
|
||||||
name="Cutoff Not Met"
|
name="Cutoff Not Met"
|
||||||
icon={icons.EPISODE_FILE}
|
icon={icons.EPISODE_FILE}
|
||||||
kind={fullColorEvents ? kinds.DEFAULT : kinds.WARNING}
|
kind={fullColorEvents ? kinds.DEFAULT : kinds.WARNING}
|
||||||
tooltip="Quality or language cutoff has not been met"
|
tooltip="Quality cutoff has not been met"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import BoolFilterBuilderRowValue from './BoolFilterBuilderRowValue';
|
||||||
import DateFilterBuilderRowValue from './DateFilterBuilderRowValue';
|
import DateFilterBuilderRowValue from './DateFilterBuilderRowValue';
|
||||||
import FilterBuilderRowValueConnector from './FilterBuilderRowValueConnector';
|
import FilterBuilderRowValueConnector from './FilterBuilderRowValueConnector';
|
||||||
import IndexerFilterBuilderRowValueConnector from './IndexerFilterBuilderRowValueConnector';
|
import IndexerFilterBuilderRowValueConnector from './IndexerFilterBuilderRowValueConnector';
|
||||||
import LanguageProfileFilterBuilderRowValueConnector from './LanguageProfileFilterBuilderRowValueConnector';
|
|
||||||
import ProtocolFilterBuilderRowValue from './ProtocolFilterBuilderRowValue';
|
import ProtocolFilterBuilderRowValue from './ProtocolFilterBuilderRowValue';
|
||||||
import QualityFilterBuilderRowValueConnector from './QualityFilterBuilderRowValueConnector';
|
import QualityFilterBuilderRowValueConnector from './QualityFilterBuilderRowValueConnector';
|
||||||
import QualityProfileFilterBuilderRowValueConnector from './QualityProfileFilterBuilderRowValueConnector';
|
import QualityProfileFilterBuilderRowValueConnector from './QualityProfileFilterBuilderRowValueConnector';
|
||||||
|
@ -61,9 +60,6 @@ function getRowValueConnector(selectedFilterBuilderProp) {
|
||||||
case filterBuilderValueTypes.INDEXER:
|
case filterBuilderValueTypes.INDEXER:
|
||||||
return IndexerFilterBuilderRowValueConnector;
|
return IndexerFilterBuilderRowValueConnector;
|
||||||
|
|
||||||
case filterBuilderValueTypes.LANGUAGE_PROFILE:
|
|
||||||
return LanguageProfileFilterBuilderRowValueConnector;
|
|
||||||
|
|
||||||
case filterBuilderValueTypes.PROTOCOL:
|
case filterBuilderValueTypes.PROTOCOL:
|
||||||
return ProtocolFilterBuilderRowValue;
|
return ProtocolFilterBuilderRowValue;
|
||||||
|
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { createSelector } from 'reselect';
|
|
||||||
import FilterBuilderRowValue from './FilterBuilderRowValue';
|
|
||||||
|
|
||||||
function createMapStateToProps() {
|
|
||||||
return createSelector(
|
|
||||||
(state) => state.settings.languageProfiles,
|
|
||||||
(languageProfiles) => {
|
|
||||||
const tagList = languageProfiles.items.map((languageProfile) => {
|
|
||||||
const {
|
|
||||||
id,
|
|
||||||
name
|
|
||||||
} = languageProfile;
|
|
||||||
|
|
||||||
return {
|
|
||||||
id,
|
|
||||||
name
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
tagList
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(createMapStateToProps)(FilterBuilderRowValue);
|
|
|
@ -12,7 +12,6 @@ import EnhancedSelectInputConnector from './EnhancedSelectInputConnector';
|
||||||
import FormInputHelpText from './FormInputHelpText';
|
import FormInputHelpText from './FormInputHelpText';
|
||||||
import IndexerSelectInputConnector from './IndexerSelectInputConnector';
|
import IndexerSelectInputConnector from './IndexerSelectInputConnector';
|
||||||
import KeyValueListInput from './KeyValueListInput';
|
import KeyValueListInput from './KeyValueListInput';
|
||||||
import LanguageProfileSelectInputConnector from './LanguageProfileSelectInputConnector';
|
|
||||||
import MonitorEpisodesSelectInput from './MonitorEpisodesSelectInput';
|
import MonitorEpisodesSelectInput from './MonitorEpisodesSelectInput';
|
||||||
import NumberInput from './NumberInput';
|
import NumberInput from './NumberInput';
|
||||||
import OAuthInputConnector from './OAuthInputConnector';
|
import OAuthInputConnector from './OAuthInputConnector';
|
||||||
|
@ -64,9 +63,6 @@ function getComponent(type) {
|
||||||
case inputTypes.QUALITY_PROFILE_SELECT:
|
case inputTypes.QUALITY_PROFILE_SELECT:
|
||||||
return QualityProfileSelectInputConnector;
|
return QualityProfileSelectInputConnector;
|
||||||
|
|
||||||
case inputTypes.LANGUAGE_PROFILE_SELECT:
|
|
||||||
return LanguageProfileSelectInputConnector;
|
|
||||||
|
|
||||||
case inputTypes.INDEXER_SELECT:
|
case inputTypes.INDEXER_SELECT:
|
||||||
return IndexerSelectInputConnector;
|
return IndexerSelectInputConnector;
|
||||||
|
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
import _ from 'lodash';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { createSelector } from 'reselect';
|
|
||||||
import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector';
|
|
||||||
import sortByName from 'Utilities/Array/sortByName';
|
|
||||||
import SelectInput from './SelectInput';
|
|
||||||
|
|
||||||
function createMapStateToProps() {
|
|
||||||
return createSelector(
|
|
||||||
createSortedSectionSelector('settings.languageProfiles', sortByName),
|
|
||||||
(state, { includeNoChange }) => includeNoChange,
|
|
||||||
(state, { includeMixed }) => includeMixed,
|
|
||||||
(languageProfiles, includeNoChange, includeMixed) => {
|
|
||||||
const values = _.map(languageProfiles.items, (languageProfile) => {
|
|
||||||
return {
|
|
||||||
key: languageProfile.id,
|
|
||||||
value: languageProfile.name
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
if (includeNoChange) {
|
|
||||||
values.unshift({
|
|
||||||
key: 'noChange',
|
|
||||||
value: 'No Change',
|
|
||||||
disabled: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includeMixed) {
|
|
||||||
values.unshift({
|
|
||||||
key: 'mixed',
|
|
||||||
value: '(Mixed)',
|
|
||||||
disabled: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
values
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class LanguageProfileSelectInputConnector extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
const {
|
|
||||||
name,
|
|
||||||
value,
|
|
||||||
values
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
if (!value || !_.some(values, (option) => parseInt(option.key) === value)) {
|
|
||||||
const firstValue = _.find(values, (option) => !isNaN(parseInt(option.key)));
|
|
||||||
|
|
||||||
if (firstValue) {
|
|
||||||
this.onChange({ name, value: firstValue.key });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onChange = ({ name, value }) => {
|
|
||||||
this.props.onChange({ name, value: parseInt(value) });
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<SelectInput
|
|
||||||
{...this.props}
|
|
||||||
onChange={this.onChange}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LanguageProfileSelectInputConnector.propTypes = {
|
|
||||||
name: PropTypes.string.isRequired,
|
|
||||||
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
||||||
values: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
||||||
includeNoChange: PropTypes.bool.isRequired,
|
|
||||||
onChange: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
LanguageProfileSelectInputConnector.defaultProps = {
|
|
||||||
includeNoChange: false
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(createMapStateToProps)(LanguageProfileSelectInputConnector);
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import EnhancedSelectInput from './EnhancedSelectInput';
|
||||||
|
|
||||||
|
function createMapStateToProps() {
|
||||||
|
return createSelector(
|
||||||
|
(state, { values }) => values,
|
||||||
|
( languages ) => {
|
||||||
|
|
||||||
|
const minId = languages.reduce((min, v) => (v.key < 1 ? v.key : min), languages[0].key);
|
||||||
|
|
||||||
|
const values = languages.map(({ key, value }) => {
|
||||||
|
return {
|
||||||
|
key,
|
||||||
|
value,
|
||||||
|
dividerAfter: minId < 1 ? key === minId : false
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
values
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class LanguageSelectInputConnector extends Component {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Render
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EnhancedSelectInput
|
||||||
|
{...this.props}
|
||||||
|
onChange={this.props.onChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LanguageSelectInputConnector.propTypes = {
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
value: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.number]).isRequired,
|
||||||
|
values: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
|
onChange: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(createMapStateToProps)(LanguageSelectInputConnector);
|
|
@ -11,7 +11,6 @@ function ErrorPage(props) {
|
||||||
customFiltersError,
|
customFiltersError,
|
||||||
tagsError,
|
tagsError,
|
||||||
qualityProfilesError,
|
qualityProfilesError,
|
||||||
languageProfilesError,
|
|
||||||
uiSettingsError,
|
uiSettingsError,
|
||||||
systemStatusError
|
systemStatusError
|
||||||
} = props;
|
} = props;
|
||||||
|
@ -28,8 +27,6 @@ function ErrorPage(props) {
|
||||||
errorMessage = getErrorMessage(tagsError, 'Failed to load tags from API');
|
errorMessage = getErrorMessage(tagsError, 'Failed to load tags from API');
|
||||||
} else if (qualityProfilesError) {
|
} else if (qualityProfilesError) {
|
||||||
errorMessage = getErrorMessage(qualityProfilesError, 'Failed to load quality profiles from API');
|
errorMessage = getErrorMessage(qualityProfilesError, 'Failed to load quality profiles from API');
|
||||||
} else if (languageProfilesError) {
|
|
||||||
errorMessage = getErrorMessage(languageProfilesError, 'Failed to load language profiles from API');
|
|
||||||
} else if (uiSettingsError) {
|
} else if (uiSettingsError) {
|
||||||
errorMessage = getErrorMessage(uiSettingsError, 'Failed to load UI settings from API');
|
errorMessage = getErrorMessage(uiSettingsError, 'Failed to load UI settings from API');
|
||||||
} else if (systemStatusError) {
|
} else if (systemStatusError) {
|
||||||
|
@ -56,7 +53,6 @@ ErrorPage.propTypes = {
|
||||||
customFiltersError: PropTypes.object,
|
customFiltersError: PropTypes.object,
|
||||||
tagsError: PropTypes.object,
|
tagsError: PropTypes.object,
|
||||||
qualityProfilesError: PropTypes.object,
|
qualityProfilesError: PropTypes.object,
|
||||||
languageProfilesError: PropTypes.object,
|
|
||||||
uiSettingsError: PropTypes.object,
|
uiSettingsError: PropTypes.object,
|
||||||
systemStatusError: PropTypes.object
|
systemStatusError: PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { createSelector } from 'reselect';
|
||||||
import { saveDimensions, setIsSidebarVisible } from 'Store/Actions/appActions';
|
import { saveDimensions, setIsSidebarVisible } from 'Store/Actions/appActions';
|
||||||
import { fetchCustomFilters } from 'Store/Actions/customFilterActions';
|
import { fetchCustomFilters } from 'Store/Actions/customFilterActions';
|
||||||
import { fetchSeries } from 'Store/Actions/seriesActions';
|
import { fetchSeries } from 'Store/Actions/seriesActions';
|
||||||
import { fetchImportLists, fetchLanguageProfiles, fetchQualityProfiles, fetchUISettings } from 'Store/Actions/settingsActions';
|
import { fetchImportLists, fetchLanguages, fetchQualityProfiles, fetchUISettings } from 'Store/Actions/settingsActions';
|
||||||
import { fetchStatus } from 'Store/Actions/systemActions';
|
import { fetchStatus } from 'Store/Actions/systemActions';
|
||||||
import { fetchTags } from 'Store/Actions/tagActions';
|
import { fetchTags } from 'Store/Actions/tagActions';
|
||||||
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
|
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
|
||||||
|
@ -49,7 +49,7 @@ const selectIsPopulated = createSelector(
|
||||||
(state) => state.tags.isPopulated,
|
(state) => state.tags.isPopulated,
|
||||||
(state) => state.settings.ui.isPopulated,
|
(state) => state.settings.ui.isPopulated,
|
||||||
(state) => state.settings.qualityProfiles.isPopulated,
|
(state) => state.settings.qualityProfiles.isPopulated,
|
||||||
(state) => state.settings.languageProfiles.isPopulated,
|
(state) => state.settings.languages.isPopulated,
|
||||||
(state) => state.settings.importLists.isPopulated,
|
(state) => state.settings.importLists.isPopulated,
|
||||||
(state) => state.system.status.isPopulated,
|
(state) => state.system.status.isPopulated,
|
||||||
(
|
(
|
||||||
|
@ -58,7 +58,7 @@ const selectIsPopulated = createSelector(
|
||||||
tagsIsPopulated,
|
tagsIsPopulated,
|
||||||
uiSettingsIsPopulated,
|
uiSettingsIsPopulated,
|
||||||
qualityProfilesIsPopulated,
|
qualityProfilesIsPopulated,
|
||||||
languageProfilesIsPopulated,
|
languagesIsPopulated,
|
||||||
importListsIsPopulated,
|
importListsIsPopulated,
|
||||||
systemStatusIsPopulated
|
systemStatusIsPopulated
|
||||||
) => {
|
) => {
|
||||||
|
@ -68,7 +68,7 @@ const selectIsPopulated = createSelector(
|
||||||
tagsIsPopulated &&
|
tagsIsPopulated &&
|
||||||
uiSettingsIsPopulated &&
|
uiSettingsIsPopulated &&
|
||||||
qualityProfilesIsPopulated &&
|
qualityProfilesIsPopulated &&
|
||||||
languageProfilesIsPopulated &&
|
languagesIsPopulated &&
|
||||||
importListsIsPopulated &&
|
importListsIsPopulated &&
|
||||||
systemStatusIsPopulated
|
systemStatusIsPopulated
|
||||||
);
|
);
|
||||||
|
@ -81,7 +81,7 @@ const selectErrors = createSelector(
|
||||||
(state) => state.tags.error,
|
(state) => state.tags.error,
|
||||||
(state) => state.settings.ui.error,
|
(state) => state.settings.ui.error,
|
||||||
(state) => state.settings.qualityProfiles.error,
|
(state) => state.settings.qualityProfiles.error,
|
||||||
(state) => state.settings.languageProfiles.error,
|
(state) => state.settings.languages.error,
|
||||||
(state) => state.settings.importLists.error,
|
(state) => state.settings.importLists.error,
|
||||||
(state) => state.system.status.error,
|
(state) => state.system.status.error,
|
||||||
(
|
(
|
||||||
|
@ -90,7 +90,7 @@ const selectErrors = createSelector(
|
||||||
tagsError,
|
tagsError,
|
||||||
uiSettingsError,
|
uiSettingsError,
|
||||||
qualityProfilesError,
|
qualityProfilesError,
|
||||||
languageProfilesError,
|
languagesError,
|
||||||
importListsError,
|
importListsError,
|
||||||
systemStatusError
|
systemStatusError
|
||||||
) => {
|
) => {
|
||||||
|
@ -100,7 +100,7 @@ const selectErrors = createSelector(
|
||||||
tagsError ||
|
tagsError ||
|
||||||
uiSettingsError ||
|
uiSettingsError ||
|
||||||
qualityProfilesError ||
|
qualityProfilesError ||
|
||||||
languageProfilesError ||
|
languagesError ||
|
||||||
importListsError ||
|
importListsError ||
|
||||||
systemStatusError
|
systemStatusError
|
||||||
);
|
);
|
||||||
|
@ -112,7 +112,7 @@ const selectErrors = createSelector(
|
||||||
tagsError,
|
tagsError,
|
||||||
uiSettingsError,
|
uiSettingsError,
|
||||||
qualityProfilesError,
|
qualityProfilesError,
|
||||||
languageProfilesError,
|
languagesError,
|
||||||
importListsError,
|
importListsError,
|
||||||
systemStatusError
|
systemStatusError
|
||||||
};
|
};
|
||||||
|
@ -161,8 +161,8 @@ function createMapDispatchToProps(dispatch, props) {
|
||||||
dispatchFetchQualityProfiles() {
|
dispatchFetchQualityProfiles() {
|
||||||
dispatch(fetchQualityProfiles());
|
dispatch(fetchQualityProfiles());
|
||||||
},
|
},
|
||||||
dispatchFetchLanguageProfiles() {
|
dispatchFetchLanguages() {
|
||||||
dispatch(fetchLanguageProfiles());
|
dispatch(fetchLanguages());
|
||||||
},
|
},
|
||||||
dispatchFetchImportLists() {
|
dispatchFetchImportLists() {
|
||||||
dispatch(fetchImportLists());
|
dispatch(fetchImportLists());
|
||||||
|
@ -201,7 +201,7 @@ class PageConnector extends Component {
|
||||||
this.props.dispatchFetchCustomFilters();
|
this.props.dispatchFetchCustomFilters();
|
||||||
this.props.dispatchFetchTags();
|
this.props.dispatchFetchTags();
|
||||||
this.props.dispatchFetchQualityProfiles();
|
this.props.dispatchFetchQualityProfiles();
|
||||||
this.props.dispatchFetchLanguageProfiles();
|
this.props.dispatchFetchLanguages();
|
||||||
this.props.dispatchFetchImportLists();
|
this.props.dispatchFetchImportLists();
|
||||||
this.props.dispatchFetchUISettings();
|
this.props.dispatchFetchUISettings();
|
||||||
this.props.dispatchFetchStatus();
|
this.props.dispatchFetchStatus();
|
||||||
|
@ -225,7 +225,7 @@ class PageConnector extends Component {
|
||||||
dispatchFetchSeries,
|
dispatchFetchSeries,
|
||||||
dispatchFetchTags,
|
dispatchFetchTags,
|
||||||
dispatchFetchQualityProfiles,
|
dispatchFetchQualityProfiles,
|
||||||
dispatchFetchLanguageProfiles,
|
dispatchFetchLanguages,
|
||||||
dispatchFetchImportLists,
|
dispatchFetchImportLists,
|
||||||
dispatchFetchUISettings,
|
dispatchFetchUISettings,
|
||||||
dispatchFetchStatus,
|
dispatchFetchStatus,
|
||||||
|
@ -264,7 +264,7 @@ PageConnector.propTypes = {
|
||||||
dispatchFetchCustomFilters: PropTypes.func.isRequired,
|
dispatchFetchCustomFilters: PropTypes.func.isRequired,
|
||||||
dispatchFetchTags: PropTypes.func.isRequired,
|
dispatchFetchTags: PropTypes.func.isRequired,
|
||||||
dispatchFetchQualityProfiles: PropTypes.func.isRequired,
|
dispatchFetchQualityProfiles: PropTypes.func.isRequired,
|
||||||
dispatchFetchLanguageProfiles: PropTypes.func.isRequired,
|
dispatchFetchLanguages: PropTypes.func.isRequired,
|
||||||
dispatchFetchImportLists: PropTypes.func.isRequired,
|
dispatchFetchImportLists: PropTypes.func.isRequired,
|
||||||
dispatchFetchUISettings: PropTypes.func.isRequired,
|
dispatchFetchUISettings: PropTypes.func.isRequired,
|
||||||
dispatchFetchStatus: PropTypes.func.isRequired,
|
dispatchFetchStatus: PropTypes.func.isRequired,
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
import Label from 'Components/Label';
|
|
||||||
import { kinds } from 'Helpers/Props';
|
|
||||||
|
|
||||||
function EpisodeLanguage(props) {
|
|
||||||
const {
|
|
||||||
className,
|
|
||||||
language,
|
|
||||||
isCutoffNotMet
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
if (!language) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Label
|
|
||||||
className={className}
|
|
||||||
kind={isCutoffNotMet ? kinds.INVERSE : kinds.DEFAULT}
|
|
||||||
>
|
|
||||||
{language.name}
|
|
||||||
</Label>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
EpisodeLanguage.propTypes = {
|
|
||||||
className: PropTypes.string,
|
|
||||||
language: PropTypes.object,
|
|
||||||
isCutoffNotMet: PropTypes.bool
|
|
||||||
};
|
|
||||||
|
|
||||||
EpisodeLanguage.defaultProps = {
|
|
||||||
isCutoffNotMet: true
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EpisodeLanguage;
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import Label from 'Components/Label';
|
||||||
|
import Popover from 'Components/Tooltip/Popover';
|
||||||
|
import { kinds, tooltipPositions } from 'Helpers/Props';
|
||||||
|
|
||||||
|
function EpisodeLanguages(props) {
|
||||||
|
const {
|
||||||
|
className,
|
||||||
|
languages,
|
||||||
|
isCutoffNotMet
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
if (!languages) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (languages.length === 1) {
|
||||||
|
return (
|
||||||
|
<Label
|
||||||
|
className={className}
|
||||||
|
kind={isCutoffNotMet ? kinds.INVERSE : kinds.DEFAULT}
|
||||||
|
>
|
||||||
|
{languages[0].name}
|
||||||
|
</Label>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popover
|
||||||
|
className={className}
|
||||||
|
anchor={
|
||||||
|
<Label
|
||||||
|
className={className}
|
||||||
|
kind={isCutoffNotMet ? kinds.INVERSE : kinds.DEFAULT}
|
||||||
|
>
|
||||||
|
Multi-Languages
|
||||||
|
</Label>
|
||||||
|
}
|
||||||
|
title={'Languages'}
|
||||||
|
body={
|
||||||
|
<ul>
|
||||||
|
{
|
||||||
|
languages.map((language) => {
|
||||||
|
return (
|
||||||
|
<li key={language.id}>
|
||||||
|
{language.name}
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
}
|
||||||
|
position={tooltipPositions.LEFT}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
EpisodeLanguages.propTypes = {
|
||||||
|
className: PropTypes.string,
|
||||||
|
languages: PropTypes.arrayOf(PropTypes.object),
|
||||||
|
isCutoffNotMet: PropTypes.bool
|
||||||
|
};
|
||||||
|
|
||||||
|
EpisodeLanguages.defaultProps = {
|
||||||
|
isCutoffNotMet: true
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EpisodeLanguages;
|
|
@ -18,8 +18,8 @@ const columns = [
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'language',
|
name: 'languages',
|
||||||
label: 'Language',
|
label: 'Languages',
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,7 +11,7 @@ import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import TableRow from 'Components/Table/TableRow';
|
import TableRow from 'Components/Table/TableRow';
|
||||||
import Popover from 'Components/Tooltip/Popover';
|
import Popover from 'Components/Tooltip/Popover';
|
||||||
import Tooltip from 'Components/Tooltip/Tooltip';
|
import Tooltip from 'Components/Tooltip/Tooltip';
|
||||||
import EpisodeLanguage from 'Episode/EpisodeLanguage';
|
import EpisodeLanguages from 'Episode/EpisodeLanguages';
|
||||||
import EpisodeQuality from 'Episode/EpisodeQuality';
|
import EpisodeQuality from 'Episode/EpisodeQuality';
|
||||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||||
import formatPreferredWordScore from 'Utilities/Number/formatPreferredWordScore';
|
import formatPreferredWordScore from 'Utilities/Number/formatPreferredWordScore';
|
||||||
|
@ -65,7 +65,7 @@ class EpisodeHistoryRow extends Component {
|
||||||
const {
|
const {
|
||||||
eventType,
|
eventType,
|
||||||
sourceTitle,
|
sourceTitle,
|
||||||
language,
|
languages,
|
||||||
languageCutoffNotMet,
|
languageCutoffNotMet,
|
||||||
quality,
|
quality,
|
||||||
qualityCutoffNotMet,
|
qualityCutoffNotMet,
|
||||||
|
@ -90,8 +90,8 @@ class EpisodeHistoryRow extends Component {
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
<TableRowCell>
|
<TableRowCell>
|
||||||
<EpisodeLanguage
|
<EpisodeLanguages
|
||||||
language={language}
|
languages={languages}
|
||||||
isCutoffNotMet={languageCutoffNotMet}
|
isCutoffNotMet={languageCutoffNotMet}
|
||||||
/>
|
/>
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
@ -177,7 +177,7 @@ EpisodeHistoryRow.propTypes = {
|
||||||
id: PropTypes.number.isRequired,
|
id: PropTypes.number.isRequired,
|
||||||
eventType: PropTypes.string.isRequired,
|
eventType: PropTypes.string.isRequired,
|
||||||
sourceTitle: PropTypes.string.isRequired,
|
sourceTitle: PropTypes.string.isRequired,
|
||||||
language: PropTypes.object.isRequired,
|
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
languageCutoffNotMet: PropTypes.bool.isRequired,
|
languageCutoffNotMet: PropTypes.bool.isRequired,
|
||||||
quality: PropTypes.object.isRequired,
|
quality: PropTypes.object.isRequired,
|
||||||
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.language,
|
.languages,
|
||||||
.quality {
|
.quality {
|
||||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import TableRow from 'Components/Table/TableRow';
|
import TableRow from 'Components/Table/TableRow';
|
||||||
import Popover from 'Components/Tooltip/Popover';
|
import Popover from 'Components/Tooltip/Popover';
|
||||||
import EpisodeLanguage from 'Episode/EpisodeLanguage';
|
import EpisodeLanguages from 'Episode/EpisodeLanguages';
|
||||||
import EpisodeQuality from 'Episode/EpisodeQuality';
|
import EpisodeQuality from 'Episode/EpisodeQuality';
|
||||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||||
import formatBytes from 'Utilities/Number/formatBytes';
|
import formatBytes from 'Utilities/Number/formatBytes';
|
||||||
|
@ -50,7 +50,7 @@ class EpisodeFileRow extends Component {
|
||||||
const {
|
const {
|
||||||
path,
|
path,
|
||||||
size,
|
size,
|
||||||
language,
|
languages,
|
||||||
quality,
|
quality,
|
||||||
languageCutoffNotMet,
|
languageCutoffNotMet,
|
||||||
qualityCutoffNotMet,
|
qualityCutoffNotMet,
|
||||||
|
@ -87,14 +87,14 @@ class EpisodeFileRow extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name === 'language') {
|
if (name === 'languages') {
|
||||||
return (
|
return (
|
||||||
<TableRowCell
|
<TableRowCell
|
||||||
key={name}
|
key={name}
|
||||||
className={styles.language}
|
className={styles.languages}
|
||||||
>
|
>
|
||||||
<EpisodeLanguage
|
<EpisodeLanguages
|
||||||
language={language}
|
languages={languages}
|
||||||
isCutoffNotMet={languageCutoffNotMet}
|
isCutoffNotMet={languageCutoffNotMet}
|
||||||
/>
|
/>
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
@ -167,7 +167,7 @@ class EpisodeFileRow extends Component {
|
||||||
EpisodeFileRow.propTypes = {
|
EpisodeFileRow.propTypes = {
|
||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
size: PropTypes.number.isRequired,
|
size: PropTypes.number.isRequired,
|
||||||
language: PropTypes.object.isRequired,
|
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
languageCutoffNotMet: PropTypes.bool.isRequired,
|
languageCutoffNotMet: PropTypes.bool.isRequired,
|
||||||
quality: PropTypes.object.isRequired,
|
quality: PropTypes.object.isRequired,
|
||||||
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
||||||
|
|
|
@ -24,8 +24,8 @@ const columns = [
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'language',
|
name: 'languages',
|
||||||
label: 'Language',
|
label: 'Languages',
|
||||||
isSortable: false,
|
isSortable: false,
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
|
@ -84,7 +84,7 @@ class EpisodeSummary extends Component {
|
||||||
mediaInfo,
|
mediaInfo,
|
||||||
path,
|
path,
|
||||||
size,
|
size,
|
||||||
language,
|
languages,
|
||||||
quality,
|
quality,
|
||||||
languageCutoffNotMet,
|
languageCutoffNotMet,
|
||||||
qualityCutoffNotMet,
|
qualityCutoffNotMet,
|
||||||
|
@ -132,7 +132,7 @@ class EpisodeSummary extends Component {
|
||||||
<EpisodeFileRow
|
<EpisodeFileRow
|
||||||
path={path}
|
path={path}
|
||||||
size={size}
|
size={size}
|
||||||
language={language}
|
languages={languages}
|
||||||
languageCutoffNotMet={languageCutoffNotMet}
|
languageCutoffNotMet={languageCutoffNotMet}
|
||||||
quality={quality}
|
quality={quality}
|
||||||
qualityCutoffNotMet={qualityCutoffNotMet}
|
qualityCutoffNotMet={qualityCutoffNotMet}
|
||||||
|
@ -168,7 +168,7 @@ EpisodeSummary.propTypes = {
|
||||||
mediaInfo: PropTypes.object,
|
mediaInfo: PropTypes.object,
|
||||||
path: PropTypes.string,
|
path: PropTypes.string,
|
||||||
size: PropTypes.number,
|
size: PropTypes.number,
|
||||||
language: PropTypes.object,
|
languages: PropTypes.arrayOf(PropTypes.object),
|
||||||
languageCutoffNotMet: PropTypes.bool,
|
languageCutoffNotMet: PropTypes.bool,
|
||||||
quality: PropTypes.object,
|
quality: PropTypes.object,
|
||||||
qualityCutoffNotMet: PropTypes.bool,
|
qualityCutoffNotMet: PropTypes.bool,
|
||||||
|
|
|
@ -28,7 +28,7 @@ function createMapStateToProps() {
|
||||||
mediaInfo,
|
mediaInfo,
|
||||||
path,
|
path,
|
||||||
size,
|
size,
|
||||||
language,
|
languages,
|
||||||
languageCutoffNotMet,
|
languageCutoffNotMet,
|
||||||
quality,
|
quality,
|
||||||
qualityCutoffNotMet
|
qualityCutoffNotMet
|
||||||
|
@ -42,7 +42,7 @@ function createMapStateToProps() {
|
||||||
mediaInfo,
|
mediaInfo,
|
||||||
path,
|
path,
|
||||||
size,
|
size,
|
||||||
language,
|
languages,
|
||||||
languageCutoffNotMet,
|
languageCutoffNotMet,
|
||||||
quality,
|
quality,
|
||||||
qualityCutoffNotMet
|
qualityCutoffNotMet
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import EpisodeLanguage from 'Episode/EpisodeLanguage';
|
import EpisodeLanguages from 'Episode/EpisodeLanguages';
|
||||||
import createEpisodeFileSelector from 'Store/Selectors/createEpisodeFileSelector';
|
import createEpisodeFileSelector from 'Store/Selectors/createEpisodeFileSelector';
|
||||||
|
|
||||||
function createMapStateToProps() {
|
function createMapStateToProps() {
|
||||||
|
@ -8,10 +8,10 @@ function createMapStateToProps() {
|
||||||
createEpisodeFileSelector(),
|
createEpisodeFileSelector(),
|
||||||
(episodeFile) => {
|
(episodeFile) => {
|
||||||
return {
|
return {
|
||||||
language: episodeFile ? episodeFile.language : undefined
|
languages: episodeFile ? episodeFile.languages : undefined
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(createMapStateToProps)(EpisodeLanguage);
|
export default connect(createMapStateToProps)(EpisodeLanguages);
|
||||||
|
|
|
@ -3,7 +3,6 @@ export const BYTES = 'bytes';
|
||||||
export const DATE = 'date';
|
export const DATE = 'date';
|
||||||
export const DEFAULT = 'default';
|
export const DEFAULT = 'default';
|
||||||
export const INDEXER = 'indexer';
|
export const INDEXER = 'indexer';
|
||||||
export const LANGUAGE_PROFILE = 'languageProfile';
|
|
||||||
export const PROTOCOL = 'protocol';
|
export const PROTOCOL = 'protocol';
|
||||||
export const QUALITY = 'quality';
|
export const QUALITY = 'quality';
|
||||||
export const QUALITY_PROFILE = 'qualityProfile';
|
export const QUALITY_PROFILE = 'qualityProfile';
|
||||||
|
|
|
@ -9,8 +9,8 @@ export const OAUTH = 'oauth';
|
||||||
export const PASSWORD = 'password';
|
export const PASSWORD = 'password';
|
||||||
export const PATH = 'path';
|
export const PATH = 'path';
|
||||||
export const QUALITY_PROFILE_SELECT = 'qualityProfileSelect';
|
export const QUALITY_PROFILE_SELECT = 'qualityProfileSelect';
|
||||||
export const LANGUAGE_PROFILE_SELECT = 'languageProfileSelect';
|
|
||||||
export const INDEXER_SELECT = 'indexerSelect';
|
export const INDEXER_SELECT = 'indexerSelect';
|
||||||
|
export const LANGUAGE_SELECT = 'languageSelect';
|
||||||
export const DOWNLOAD_CLIENT_SELECT = 'downloadClientSelect';
|
export const DOWNLOAD_CLIENT_SELECT = 'downloadClientSelect';
|
||||||
export const ROOT_FOLDER_SELECT = 'rootFolderSelect';
|
export const ROOT_FOLDER_SELECT = 'rootFolderSelect';
|
||||||
export const SELECT = 'select';
|
export const SELECT = 'select';
|
||||||
|
@ -35,10 +35,10 @@ export const all = [
|
||||||
PASSWORD,
|
PASSWORD,
|
||||||
PATH,
|
PATH,
|
||||||
QUALITY_PROFILE_SELECT,
|
QUALITY_PROFILE_SELECT,
|
||||||
LANGUAGE_PROFILE_SELECT,
|
|
||||||
INDEXER_SELECT,
|
INDEXER_SELECT,
|
||||||
DOWNLOAD_CLIENT_SELECT,
|
DOWNLOAD_CLIENT_SELECT,
|
||||||
ROOT_FOLDER_SELECT,
|
ROOT_FOLDER_SELECT,
|
||||||
|
LANGUAGE_SELECT,
|
||||||
SELECT,
|
SELECT,
|
||||||
DYNAMIC_SELECT,
|
DYNAMIC_SELECT,
|
||||||
SERIES_TYPE_SELECT,
|
SERIES_TYPE_SELECT,
|
||||||
|
|
|
@ -66,8 +66,8 @@ const columns = [
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'language',
|
name: 'languages',
|
||||||
label: 'Language',
|
label: 'Languages',
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
|
|
|
@ -193,7 +193,7 @@ class InteractiveImportModalContentConnector extends Component {
|
||||||
episodes,
|
episodes,
|
||||||
releaseGroup,
|
releaseGroup,
|
||||||
quality,
|
quality,
|
||||||
language,
|
languages,
|
||||||
episodeFileId
|
episodeFileId
|
||||||
} = item;
|
} = item;
|
||||||
|
|
||||||
|
@ -217,8 +217,8 @@ class InteractiveImportModalContentConnector extends Component {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!language) {
|
if (!languages) {
|
||||||
this.setState({ interactiveImportErrorMessage: 'Language must be chosen for each selected file' });
|
this.setState({ interactiveImportErrorMessage: 'Language(s) must be chosen for each selected file' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,7 +230,7 @@ class InteractiveImportModalContentConnector extends Component {
|
||||||
id: episodeFileId,
|
id: episodeFileId,
|
||||||
releaseGroup,
|
releaseGroup,
|
||||||
quality,
|
quality,
|
||||||
language
|
languages
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -244,7 +244,7 @@ class InteractiveImportModalContentConnector extends Component {
|
||||||
episodeIds: episodes.map((e) => e.id),
|
episodeIds: episodes.map((e) => e.id),
|
||||||
releaseGroup,
|
releaseGroup,
|
||||||
quality,
|
quality,
|
||||||
language,
|
languages,
|
||||||
downloadId: this.props.downloadId,
|
downloadId: this.props.downloadId,
|
||||||
episodeFileId
|
episodeFileId
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.quality,
|
.quality,
|
||||||
.language {
|
.languages {
|
||||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||||
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import TableRowCellButton from 'Components/Table/Cells/TableRowCellButton';
|
||||||
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
||||||
import TableRow from 'Components/Table/TableRow';
|
import TableRow from 'Components/Table/TableRow';
|
||||||
import Popover from 'Components/Tooltip/Popover';
|
import Popover from 'Components/Tooltip/Popover';
|
||||||
import EpisodeLanguage from 'Episode/EpisodeLanguage';
|
import EpisodeLanguages from 'Episode/EpisodeLanguages';
|
||||||
import EpisodeQuality from 'Episode/EpisodeQuality';
|
import EpisodeQuality from 'Episode/EpisodeQuality';
|
||||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||||
import SelectEpisodeModal from 'InteractiveImport/Episode/SelectEpisodeModal';
|
import SelectEpisodeModal from 'InteractiveImport/Episode/SelectEpisodeModal';
|
||||||
|
@ -47,7 +47,7 @@ class InteractiveImportRow extends Component {
|
||||||
seasonNumber,
|
seasonNumber,
|
||||||
episodes,
|
episodes,
|
||||||
quality,
|
quality,
|
||||||
language,
|
languages,
|
||||||
episodeFileId,
|
episodeFileId,
|
||||||
columns
|
columns
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
@ -58,7 +58,7 @@ class InteractiveImportRow extends Component {
|
||||||
seasonNumber != null &&
|
seasonNumber != null &&
|
||||||
episodes.length &&
|
episodes.length &&
|
||||||
quality &&
|
quality &&
|
||||||
language
|
languages
|
||||||
) {
|
) {
|
||||||
this.props.onSelectedChange({
|
this.props.onSelectedChange({
|
||||||
id,
|
id,
|
||||||
|
@ -79,7 +79,7 @@ class InteractiveImportRow extends Component {
|
||||||
seasonNumber,
|
seasonNumber,
|
||||||
episodes,
|
episodes,
|
||||||
quality,
|
quality,
|
||||||
language,
|
languages,
|
||||||
isSelected,
|
isSelected,
|
||||||
onValidRowChange
|
onValidRowChange
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
@ -89,7 +89,7 @@ class InteractiveImportRow extends Component {
|
||||||
prevProps.seasonNumber === seasonNumber &&
|
prevProps.seasonNumber === seasonNumber &&
|
||||||
!hasDifferentItems(prevProps.episodes, episodes) &&
|
!hasDifferentItems(prevProps.episodes, episodes) &&
|
||||||
prevProps.quality === quality &&
|
prevProps.quality === quality &&
|
||||||
prevProps.language === language &&
|
prevProps.languages === languages &&
|
||||||
prevProps.isSelected === isSelected
|
prevProps.isSelected === isSelected
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
|
@ -100,7 +100,7 @@ class InteractiveImportRow extends Component {
|
||||||
seasonNumber != null &&
|
seasonNumber != null &&
|
||||||
episodes.length &&
|
episodes.length &&
|
||||||
quality &&
|
quality &&
|
||||||
language
|
languages
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isSelected && !isValid) {
|
if (isSelected && !isValid) {
|
||||||
|
@ -210,7 +210,7 @@ class InteractiveImportRow extends Component {
|
||||||
seasonNumber,
|
seasonNumber,
|
||||||
episodes,
|
episodes,
|
||||||
quality,
|
quality,
|
||||||
language,
|
languages,
|
||||||
releaseGroup,
|
releaseGroup,
|
||||||
size,
|
size,
|
||||||
rejections,
|
rejections,
|
||||||
|
@ -252,7 +252,7 @@ class InteractiveImportRow extends Component {
|
||||||
const showEpisodeNumbersPlaceholder = isSelected && Number.isInteger(seasonNumber) && !episodes.length;
|
const showEpisodeNumbersPlaceholder = isSelected && Number.isInteger(seasonNumber) && !episodes.length;
|
||||||
const showReleaseGroupPlaceholder = isSelected && !releaseGroup;
|
const showReleaseGroupPlaceholder = isSelected && !releaseGroup;
|
||||||
const showQualityPlaceholder = isSelected && !quality;
|
const showQualityPlaceholder = isSelected && !quality;
|
||||||
const showLanguagePlaceholder = isSelected && !language;
|
const showLanguagePlaceholder = isSelected && !languages;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
|
@ -352,10 +352,10 @@ class InteractiveImportRow extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
!showLanguagePlaceholder && !!language &&
|
!showLanguagePlaceholder && !!languages &&
|
||||||
<EpisodeLanguage
|
<EpisodeLanguages
|
||||||
className={styles.label}
|
className={styles.label}
|
||||||
language={language}
|
languages={languages}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
</TableRowCellButton>
|
</TableRowCellButton>
|
||||||
|
@ -441,7 +441,7 @@ class InteractiveImportRow extends Component {
|
||||||
<SelectLanguageModal
|
<SelectLanguageModal
|
||||||
isOpen={isSelectLanguageModalOpen}
|
isOpen={isSelectLanguageModalOpen}
|
||||||
ids={[id]}
|
ids={[id]}
|
||||||
languageId={language ? language.id : 0}
|
languageId={languages ? languages.id : 0}
|
||||||
modalTitle={modalTitle}
|
modalTitle={modalTitle}
|
||||||
onModalClose={this.onSelectLanguageModalClose}
|
onModalClose={this.onSelectLanguageModalClose}
|
||||||
/>
|
/>
|
||||||
|
@ -460,7 +460,7 @@ InteractiveImportRow.propTypes = {
|
||||||
episodes: PropTypes.arrayOf(PropTypes.object).isRequired,
|
episodes: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
releaseGroup: PropTypes.string,
|
releaseGroup: PropTypes.string,
|
||||||
quality: PropTypes.object,
|
quality: PropTypes.object,
|
||||||
language: PropTypes.object,
|
languages: PropTypes.arrayOf(PropTypes.object),
|
||||||
size: PropTypes.number.isRequired,
|
size: PropTypes.number.isRequired,
|
||||||
rejections: PropTypes.arrayOf(PropTypes.object).isRequired,
|
rejections: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
|
|
|
@ -4,7 +4,6 @@ import React, { Component } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import { reprocessInteractiveImportItems, updateInteractiveImportItems } from 'Store/Actions/interactiveImportActions';
|
import { reprocessInteractiveImportItems, updateInteractiveImportItems } from 'Store/Actions/interactiveImportActions';
|
||||||
import { fetchLanguageProfileSchema } from 'Store/Actions/settingsActions';
|
|
||||||
import createLanguagesSelector from 'Store/Selectors/createLanguagesSelector';
|
import createLanguagesSelector from 'Store/Selectors/createLanguagesSelector';
|
||||||
import SelectLanguageModalContent from './SelectLanguageModalContent';
|
import SelectLanguageModalContent from './SelectLanguageModalContent';
|
||||||
|
|
||||||
|
@ -18,22 +17,12 @@ function createMapStateToProps() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
dispatchFetchLanguageProfileSchema: fetchLanguageProfileSchema,
|
|
||||||
dispatchUpdateInteractiveImportItems: updateInteractiveImportItems,
|
dispatchUpdateInteractiveImportItems: updateInteractiveImportItems,
|
||||||
dispatchReprocessInteractiveImportItems: reprocessInteractiveImportItems
|
dispatchReprocessInteractiveImportItems: reprocessInteractiveImportItems
|
||||||
};
|
};
|
||||||
|
|
||||||
class SelectLanguageModalContentConnector extends Component {
|
class SelectLanguageModalContentConnector extends Component {
|
||||||
|
|
||||||
//
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
componentDidMount = () => {
|
|
||||||
if (!this.props.isPopulated) {
|
|
||||||
this.props.dispatchFetchLanguageProfileSchema();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Listeners
|
// Listeners
|
||||||
|
|
||||||
|
@ -44,13 +33,20 @@ class SelectLanguageModalContentConnector extends Component {
|
||||||
dispatchReprocessInteractiveImportItems
|
dispatchReprocessInteractiveImportItems
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const languageId = parseInt(value);
|
const languages = [];
|
||||||
|
|
||||||
|
value.forEach((languageId) => {
|
||||||
const language = _.find(this.props.items,
|
const language = _.find(this.props.items,
|
||||||
(item) => item.language.id === languageId).language;
|
(item) => item.id === parseInt(languageId));
|
||||||
|
|
||||||
|
if (language !== undefined) {
|
||||||
|
languages.push(language);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
dispatchUpdateInteractiveImportItems({
|
dispatchUpdateInteractiveImportItems({
|
||||||
ids,
|
ids,
|
||||||
language
|
languages
|
||||||
});
|
});
|
||||||
|
|
||||||
dispatchReprocessInteractiveImportItems({ ids });
|
dispatchReprocessInteractiveImportItems({ ids });
|
||||||
|
@ -77,7 +73,6 @@ SelectLanguageModalContentConnector.propTypes = {
|
||||||
isPopulated: PropTypes.bool.isRequired,
|
isPopulated: PropTypes.bool.isRequired,
|
||||||
error: PropTypes.object,
|
error: PropTypes.object,
|
||||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
dispatchFetchLanguageProfileSchema: PropTypes.func.isRequired,
|
|
||||||
dispatchUpdateInteractiveImportItems: PropTypes.func.isRequired,
|
dispatchUpdateInteractiveImportItems: PropTypes.func.isRequired,
|
||||||
dispatchReprocessInteractiveImportItems: PropTypes.func.isRequired,
|
dispatchReprocessInteractiveImportItems: PropTypes.func.isRequired,
|
||||||
onModalClose: PropTypes.func.isRequired
|
onModalClose: PropTypes.func.isRequired
|
||||||
|
|
|
@ -51,7 +51,7 @@ const columns = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'languageWeight',
|
name: 'languageWeight',
|
||||||
label: 'Language',
|
label: 'Languages',
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
|
|
|
@ -24,13 +24,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.quality,
|
.quality,
|
||||||
.language {
|
.languages {
|
||||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||||
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.language {
|
.languages {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import TableRow from 'Components/Table/TableRow';
|
import TableRow from 'Components/Table/TableRow';
|
||||||
import Popover from 'Components/Tooltip/Popover';
|
import Popover from 'Components/Tooltip/Popover';
|
||||||
import Tooltip from 'Components/Tooltip/Tooltip';
|
import Tooltip from 'Components/Tooltip/Tooltip';
|
||||||
import EpisodeLanguage from 'Episode/EpisodeLanguage';
|
import EpisodeLanguages from 'Episode/EpisodeLanguages';
|
||||||
import EpisodeQuality from 'Episode/EpisodeQuality';
|
import EpisodeQuality from 'Episode/EpisodeQuality';
|
||||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||||
import formatDateTime from 'Utilities/Date/formatDateTime';
|
import formatDateTime from 'Utilities/Date/formatDateTime';
|
||||||
|
@ -116,7 +116,7 @@ class InteractiveSearchRow extends Component {
|
||||||
seeders,
|
seeders,
|
||||||
leechers,
|
leechers,
|
||||||
quality,
|
quality,
|
||||||
language,
|
languages,
|
||||||
customFormatScore,
|
customFormatScore,
|
||||||
customFormats,
|
customFormats,
|
||||||
sceneMapping,
|
sceneMapping,
|
||||||
|
@ -188,8 +188,8 @@ class InteractiveSearchRow extends Component {
|
||||||
}
|
}
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
<TableRowCell className={styles.language}>
|
<TableRowCell className={styles.languages}>
|
||||||
<EpisodeLanguage language={language} />
|
<EpisodeLanguages languages={languages} />
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
<TableRowCell className={styles.quality}>
|
<TableRowCell className={styles.quality}>
|
||||||
|
@ -286,7 +286,7 @@ InteractiveSearchRow.propTypes = {
|
||||||
seeders: PropTypes.number,
|
seeders: PropTypes.number,
|
||||||
leechers: PropTypes.number,
|
leechers: PropTypes.number,
|
||||||
quality: PropTypes.object.isRequired,
|
quality: PropTypes.object.isRequired,
|
||||||
language: PropTypes.object.isRequired,
|
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
customFormats: PropTypes.arrayOf(PropTypes.object),
|
customFormats: PropTypes.arrayOf(PropTypes.object),
|
||||||
customFormatScore: PropTypes.number.isRequired,
|
customFormatScore: PropTypes.number.isRequired,
|
||||||
sceneMapping: PropTypes.object,
|
sceneMapping: PropTypes.object,
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.language,
|
.languages,
|
||||||
.audio,
|
.audio,
|
||||||
.video,
|
.video,
|
||||||
.status {
|
.status {
|
||||||
|
|
|
@ -180,11 +180,11 @@ class EpisodeRow extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name === 'language') {
|
if (name === 'languages') {
|
||||||
return (
|
return (
|
||||||
<TableRowCell
|
<TableRowCell
|
||||||
key={name}
|
key={name}
|
||||||
className={styles.language}
|
className={styles.languages}
|
||||||
>
|
>
|
||||||
<EpisodeFileLanguageConnector
|
<EpisodeFileLanguageConnector
|
||||||
episodeFileId={episodeFileId}
|
episodeFileId={episodeFileId}
|
||||||
|
|
|
@ -59,7 +59,6 @@ class EditSeriesModalContent extends Component {
|
||||||
title,
|
title,
|
||||||
item,
|
item,
|
||||||
isSaving,
|
isSaving,
|
||||||
showLanguageProfile,
|
|
||||||
originalPath,
|
originalPath,
|
||||||
onInputChange,
|
onInputChange,
|
||||||
onModalClose,
|
onModalClose,
|
||||||
|
@ -71,7 +70,6 @@ class EditSeriesModalContent extends Component {
|
||||||
monitored,
|
monitored,
|
||||||
seasonFolder,
|
seasonFolder,
|
||||||
qualityProfileId,
|
qualityProfileId,
|
||||||
languageProfileId,
|
|
||||||
seriesType,
|
seriesType,
|
||||||
path,
|
path,
|
||||||
tags
|
tags
|
||||||
|
@ -120,20 +118,6 @@ class EditSeriesModalContent extends Component {
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
{
|
|
||||||
showLanguageProfile &&
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>Language Profile</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.LANGUAGE_PROFILE_SELECT}
|
|
||||||
name="languageProfileId"
|
|
||||||
{...languageProfileId}
|
|
||||||
onChange={onInputChange}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
}
|
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>Series Type</FormLabel>
|
<FormLabel>Series Type</FormLabel>
|
||||||
|
|
||||||
|
@ -209,7 +193,6 @@ EditSeriesModalContent.propTypes = {
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
item: PropTypes.object.isRequired,
|
item: PropTypes.object.isRequired,
|
||||||
isSaving: PropTypes.bool.isRequired,
|
isSaving: PropTypes.bool.isRequired,
|
||||||
showLanguageProfile: PropTypes.bool.isRequired,
|
|
||||||
isPathChanging: PropTypes.bool.isRequired,
|
isPathChanging: PropTypes.bool.isRequired,
|
||||||
originalPath: PropTypes.string.isRequired,
|
originalPath: PropTypes.string.isRequired,
|
||||||
onInputChange: PropTypes.func.isRequired,
|
onInputChange: PropTypes.func.isRequired,
|
||||||
|
|
|
@ -27,10 +27,9 @@ function createIsPathChangingSelector() {
|
||||||
function createMapStateToProps() {
|
function createMapStateToProps() {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
(state) => state.series,
|
(state) => state.series,
|
||||||
(state) => state.settings.languageProfiles,
|
|
||||||
createSeriesSelector(),
|
createSeriesSelector(),
|
||||||
createIsPathChangingSelector(),
|
createIsPathChangingSelector(),
|
||||||
(seriesState, languageProfiles, series, isPathChanging) => {
|
(seriesState, series, isPathChanging) => {
|
||||||
const {
|
const {
|
||||||
isSaving,
|
isSaving,
|
||||||
saveError,
|
saveError,
|
||||||
|
@ -41,7 +40,6 @@ function createMapStateToProps() {
|
||||||
'monitored',
|
'monitored',
|
||||||
'seasonFolder',
|
'seasonFolder',
|
||||||
'qualityProfileId',
|
'qualityProfileId',
|
||||||
'languageProfileId',
|
|
||||||
'seriesType',
|
'seriesType',
|
||||||
'path',
|
'path',
|
||||||
'tags'
|
'tags'
|
||||||
|
@ -56,7 +54,6 @@ function createMapStateToProps() {
|
||||||
isPathChanging,
|
isPathChanging,
|
||||||
originalPath: series.path,
|
originalPath: series.path,
|
||||||
item: settings.settings,
|
item: settings.settings,
|
||||||
showLanguageProfile: languageProfiles.items.length > 1,
|
|
||||||
...settings
|
...settings
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,6 @@ class SeriesEditor extends Component {
|
||||||
deleteError={deleteError}
|
deleteError={deleteError}
|
||||||
isOrganizingSeries={isOrganizingSeries}
|
isOrganizingSeries={isOrganizingSeries}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
showLanguageProfile={columns.find((column) => column.name === 'languageProfileId').isVisible}
|
|
||||||
onSaveSelected={this.onSaveSelected}
|
onSaveSelected={this.onSaveSelected}
|
||||||
onOrganizeSeriesPress={this.onOrganizeSeriesPress}
|
onOrganizeSeriesPress={this.onOrganizeSeriesPress}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import LanguageProfileSelectInputConnector from 'Components/Form/LanguageProfileSelectInputConnector';
|
|
||||||
import QualityProfileSelectInputConnector from 'Components/Form/QualityProfileSelectInputConnector';
|
import QualityProfileSelectInputConnector from 'Components/Form/QualityProfileSelectInputConnector';
|
||||||
import RootFolderSelectInputConnector from 'Components/Form/RootFolderSelectInputConnector';
|
import RootFolderSelectInputConnector from 'Components/Form/RootFolderSelectInputConnector';
|
||||||
import SelectInput from 'Components/Form/SelectInput';
|
import SelectInput from 'Components/Form/SelectInput';
|
||||||
|
@ -27,7 +26,6 @@ class SeriesEditorFooter extends Component {
|
||||||
this.state = {
|
this.state = {
|
||||||
monitored: NO_CHANGE,
|
monitored: NO_CHANGE,
|
||||||
qualityProfileId: NO_CHANGE,
|
qualityProfileId: NO_CHANGE,
|
||||||
languageProfileId: NO_CHANGE,
|
|
||||||
seriesType: NO_CHANGE,
|
seriesType: NO_CHANGE,
|
||||||
seasonFolder: NO_CHANGE,
|
seasonFolder: NO_CHANGE,
|
||||||
rootFolderPath: NO_CHANGE,
|
rootFolderPath: NO_CHANGE,
|
||||||
|
@ -49,7 +47,6 @@ class SeriesEditorFooter extends Component {
|
||||||
this.setState({
|
this.setState({
|
||||||
monitored: NO_CHANGE,
|
monitored: NO_CHANGE,
|
||||||
qualityProfileId: NO_CHANGE,
|
qualityProfileId: NO_CHANGE,
|
||||||
languageProfileId: NO_CHANGE,
|
|
||||||
seriesType: NO_CHANGE,
|
seriesType: NO_CHANGE,
|
||||||
seasonFolder: NO_CHANGE,
|
seasonFolder: NO_CHANGE,
|
||||||
rootFolderPath: NO_CHANGE,
|
rootFolderPath: NO_CHANGE,
|
||||||
|
@ -152,7 +149,6 @@ class SeriesEditorFooter extends Component {
|
||||||
const {
|
const {
|
||||||
monitored,
|
monitored,
|
||||||
qualityProfileId,
|
qualityProfileId,
|
||||||
languageProfileId,
|
|
||||||
seriesType,
|
seriesType,
|
||||||
seasonFolder,
|
seasonFolder,
|
||||||
rootFolderPath,
|
rootFolderPath,
|
||||||
|
@ -225,28 +221,6 @@ class SeriesEditorFooter extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name === 'languageProfileId') {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={name}
|
|
||||||
className={styles.inputContainer}
|
|
||||||
>
|
|
||||||
<SeriesEditorFooterLabel
|
|
||||||
label="Language Profile"
|
|
||||||
isSaving={isSaving && languageProfileId !== NO_CHANGE}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<LanguageProfileSelectInputConnector
|
|
||||||
name="languageProfileId"
|
|
||||||
value={languageProfileId}
|
|
||||||
includeNoChange={true}
|
|
||||||
isDisabled={!selectedCount}
|
|
||||||
onChange={this.onInputChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name === 'seriesType') {
|
if (name === 'seriesType') {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -392,7 +366,6 @@ SeriesEditorFooter.propTypes = {
|
||||||
isDeleting: PropTypes.bool.isRequired,
|
isDeleting: PropTypes.bool.isRequired,
|
||||||
deleteError: PropTypes.object,
|
deleteError: PropTypes.object,
|
||||||
isOrganizingSeries: PropTypes.bool.isRequired,
|
isOrganizingSeries: PropTypes.bool.isRequired,
|
||||||
showLanguageProfile: PropTypes.bool.isRequired,
|
|
||||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
onSaveSelected: PropTypes.func.isRequired,
|
onSaveSelected: PropTypes.func.isRequired,
|
||||||
onOrganizeSeriesPress: PropTypes.func.isRequired
|
onOrganizeSeriesPress: PropTypes.func.isRequired
|
||||||
|
|
|
@ -33,7 +33,6 @@ class SeriesEditorRow extends Component {
|
||||||
titleSlug,
|
titleSlug,
|
||||||
seriesType,
|
seriesType,
|
||||||
qualityProfile,
|
qualityProfile,
|
||||||
languageProfile,
|
|
||||||
path,
|
path,
|
||||||
tags,
|
tags,
|
||||||
seasonFolder,
|
seasonFolder,
|
||||||
|
@ -95,14 +94,6 @@ class SeriesEditorRow extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name === 'languageProfileId') {
|
|
||||||
return (
|
|
||||||
<TableRowCell key={name}>
|
|
||||||
{languageProfile.name}
|
|
||||||
</TableRowCell>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name === 'seriesType') {
|
if (name === 'seriesType') {
|
||||||
return (
|
return (
|
||||||
<TableRowCell key={name}>
|
<TableRowCell key={name}>
|
||||||
|
@ -167,7 +158,6 @@ SeriesEditorRow.propTypes = {
|
||||||
titleSlug: PropTypes.string.isRequired,
|
titleSlug: PropTypes.string.isRequired,
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
monitored: PropTypes.bool.isRequired,
|
monitored: PropTypes.bool.isRequired,
|
||||||
languageProfile: PropTypes.object.isRequired,
|
|
||||||
qualityProfile: PropTypes.object.isRequired,
|
qualityProfile: PropTypes.object.isRequired,
|
||||||
seriesType: PropTypes.string.isRequired,
|
seriesType: PropTypes.string.isRequired,
|
||||||
seasonFolder: PropTypes.bool.isRequired,
|
seasonFolder: PropTypes.bool.isRequired,
|
||||||
|
|
|
@ -2,17 +2,14 @@ import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import createLanguageProfileSelector from 'Store/Selectors/createLanguageProfileSelector';
|
|
||||||
import createQualityProfileSelector from 'Store/Selectors/createQualityProfileSelector';
|
import createQualityProfileSelector from 'Store/Selectors/createQualityProfileSelector';
|
||||||
import SeriesEditorRow from './SeriesEditorRow';
|
import SeriesEditorRow from './SeriesEditorRow';
|
||||||
|
|
||||||
function createMapStateToProps() {
|
function createMapStateToProps() {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
createLanguageProfileSelector(),
|
|
||||||
createQualityProfileSelector(),
|
createQualityProfileSelector(),
|
||||||
(languageProfile, qualityProfile) => {
|
(qualityProfile) => {
|
||||||
return {
|
return {
|
||||||
languageProfile,
|
|
||||||
qualityProfile
|
qualityProfile
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,8 @@ const columns = [
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'language',
|
name: 'languages',
|
||||||
label: 'Language',
|
label: 'Languages',
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,7 +11,7 @@ import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import TableRow from 'Components/Table/TableRow';
|
import TableRow from 'Components/Table/TableRow';
|
||||||
import Popover from 'Components/Tooltip/Popover';
|
import Popover from 'Components/Tooltip/Popover';
|
||||||
import Tooltip from 'Components/Tooltip/Tooltip';
|
import Tooltip from 'Components/Tooltip/Tooltip';
|
||||||
import EpisodeLanguage from 'Episode/EpisodeLanguage';
|
import EpisodeLanguages from 'Episode/EpisodeLanguages';
|
||||||
import EpisodeNumber from 'Episode/EpisodeNumber';
|
import EpisodeNumber from 'Episode/EpisodeNumber';
|
||||||
import EpisodeQuality from 'Episode/EpisodeQuality';
|
import EpisodeQuality from 'Episode/EpisodeQuality';
|
||||||
import SeasonEpisodeNumber from 'Episode/SeasonEpisodeNumber';
|
import SeasonEpisodeNumber from 'Episode/SeasonEpisodeNumber';
|
||||||
|
@ -67,7 +67,7 @@ class SeriesHistoryRow extends Component {
|
||||||
const {
|
const {
|
||||||
eventType,
|
eventType,
|
||||||
sourceTitle,
|
sourceTitle,
|
||||||
language,
|
languages,
|
||||||
languageCutoffNotMet,
|
languageCutoffNotMet,
|
||||||
quality,
|
quality,
|
||||||
qualityCutoffNotMet,
|
qualityCutoffNotMet,
|
||||||
|
@ -110,8 +110,8 @@ class SeriesHistoryRow extends Component {
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
<TableRowCell>
|
<TableRowCell>
|
||||||
<EpisodeLanguage
|
<EpisodeLanguages
|
||||||
language={language}
|
languages={languages}
|
||||||
isCutoffNotMet={languageCutoffNotMet}
|
isCutoffNotMet={languageCutoffNotMet}
|
||||||
/>
|
/>
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
@ -197,7 +197,7 @@ SeriesHistoryRow.propTypes = {
|
||||||
id: PropTypes.number.isRequired,
|
id: PropTypes.number.isRequired,
|
||||||
eventType: PropTypes.string.isRequired,
|
eventType: PropTypes.string.isRequired,
|
||||||
sourceTitle: PropTypes.string.isRequired,
|
sourceTitle: PropTypes.string.isRequired,
|
||||||
language: PropTypes.object.isRequired,
|
languages: PropTypes.object.isRequired,
|
||||||
languageCutoffNotMet: PropTypes.bool.isRequired,
|
languageCutoffNotMet: PropTypes.bool.isRequired,
|
||||||
quality: PropTypes.object.isRequired,
|
quality: PropTypes.object.isRequired,
|
||||||
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
||||||
|
|
|
@ -55,15 +55,6 @@ function SeriesIndexSortMenu(props) {
|
||||||
Quality Profile
|
Quality Profile
|
||||||
</SortMenuItem>
|
</SortMenuItem>
|
||||||
|
|
||||||
<SortMenuItem
|
|
||||||
name="languageProfileId"
|
|
||||||
sortKey={sortKey}
|
|
||||||
sortDirection={sortDirection}
|
|
||||||
onPress={onSortSelect}
|
|
||||||
>
|
|
||||||
Language Profile
|
|
||||||
</SortMenuItem>
|
|
||||||
|
|
||||||
<SortMenuItem
|
<SortMenuItem
|
||||||
name="nextAiring"
|
name="nextAiring"
|
||||||
sortKey={sortKey}
|
sortKey={sortKey}
|
||||||
|
|
|
@ -188,7 +188,6 @@ class SeriesIndexOverviews extends Component {
|
||||||
isSmallScreen={isSmallScreen}
|
isSmallScreen={isSmallScreen}
|
||||||
style={style}
|
style={style}
|
||||||
seriesId={series.id}
|
seriesId={series.id}
|
||||||
languageProfileId={series.languageProfileId}
|
|
||||||
qualityProfileId={series.qualityProfileId}
|
qualityProfileId={series.qualityProfileId}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -243,7 +243,6 @@ class SeriesIndexPosters extends Component {
|
||||||
timeFormat={timeFormat}
|
timeFormat={timeFormat}
|
||||||
style={style}
|
style={style}
|
||||||
seriesId={series.id}
|
seriesId={series.id}
|
||||||
languageProfileId={series.languageProfileId}
|
|
||||||
qualityProfileId={series.qualityProfileId}
|
qualityProfileId={series.qualityProfileId}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { createSelector } from 'reselect';
|
||||||
import * as commandNames from 'Commands/commandNames';
|
import * as commandNames from 'Commands/commandNames';
|
||||||
import { executeCommand } from 'Store/Actions/commandActions';
|
import { executeCommand } from 'Store/Actions/commandActions';
|
||||||
import createExecutingCommandsSelector from 'Store/Selectors/createExecutingCommandsSelector';
|
import createExecutingCommandsSelector from 'Store/Selectors/createExecutingCommandsSelector';
|
||||||
import createSeriesLanguageProfileSelector from 'Store/Selectors/createSeriesLanguageProfileSelector';
|
|
||||||
import createSeriesQualityProfileSelector from 'Store/Selectors/createSeriesQualityProfileSelector';
|
import createSeriesQualityProfileSelector from 'Store/Selectors/createSeriesQualityProfileSelector';
|
||||||
import createSeriesSelector from 'Store/Selectors/createSeriesSelector';
|
import createSeriesSelector from 'Store/Selectors/createSeriesSelector';
|
||||||
|
|
||||||
|
@ -32,13 +31,11 @@ function createMapStateToProps() {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
createSeriesSelector(),
|
createSeriesSelector(),
|
||||||
createSeriesQualityProfileSelector(),
|
createSeriesQualityProfileSelector(),
|
||||||
createSeriesLanguageProfileSelector(),
|
|
||||||
selectShowSearchAction(),
|
selectShowSearchAction(),
|
||||||
createExecutingCommandsSelector(),
|
createExecutingCommandsSelector(),
|
||||||
(
|
(
|
||||||
series,
|
series,
|
||||||
qualityProfile,
|
qualityProfile,
|
||||||
languageProfile,
|
|
||||||
showSearchAction,
|
showSearchAction,
|
||||||
executingCommands
|
executingCommands
|
||||||
) => {
|
) => {
|
||||||
|
@ -71,7 +68,6 @@ function createMapStateToProps() {
|
||||||
return {
|
return {
|
||||||
...series,
|
...series,
|
||||||
qualityProfile,
|
qualityProfile,
|
||||||
languageProfile,
|
|
||||||
latestSeason,
|
latestSeason,
|
||||||
showSearchAction,
|
showSearchAction,
|
||||||
isRefreshingSeries,
|
isRefreshingSeries,
|
||||||
|
|
|
@ -30,8 +30,7 @@
|
||||||
flex: 2 0 90px;
|
flex: 2 0 90px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.qualityProfileId,
|
.qualityProfileId {
|
||||||
.languageProfileId {
|
|
||||||
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
||||||
|
|
||||||
flex: 1 0 125px;
|
flex: 1 0 125px;
|
||||||
|
|
|
@ -66,8 +66,7 @@
|
||||||
flex: 2 0 90px;
|
flex: 2 0 90px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.qualityProfileId,
|
.qualityProfileId {
|
||||||
.languageProfileId {
|
|
||||||
composes: cell;
|
composes: cell;
|
||||||
|
|
||||||
flex: 1 0 125px;
|
flex: 1 0 125px;
|
||||||
|
|
|
@ -86,7 +86,6 @@ class SeriesIndexRow extends Component {
|
||||||
seriesType,
|
seriesType,
|
||||||
network,
|
network,
|
||||||
qualityProfile,
|
qualityProfile,
|
||||||
languageProfile,
|
|
||||||
nextAiring,
|
nextAiring,
|
||||||
previousAiring,
|
previousAiring,
|
||||||
added,
|
added,
|
||||||
|
@ -224,17 +223,6 @@ class SeriesIndexRow extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name === 'languageProfileId') {
|
|
||||||
return (
|
|
||||||
<VirtualTableRowCell
|
|
||||||
key={name}
|
|
||||||
className={styles[name]}
|
|
||||||
>
|
|
||||||
{languageProfile.name}
|
|
||||||
</VirtualTableRowCell>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name === 'nextAiring') {
|
if (name === 'nextAiring') {
|
||||||
return (
|
return (
|
||||||
<RelativeDateCellConnector
|
<RelativeDateCellConnector
|
||||||
|
@ -525,7 +513,6 @@ SeriesIndexRow.propTypes = {
|
||||||
seriesType: PropTypes.string.isRequired,
|
seriesType: PropTypes.string.isRequired,
|
||||||
network: PropTypes.string,
|
network: PropTypes.string,
|
||||||
qualityProfile: PropTypes.object.isRequired,
|
qualityProfile: PropTypes.object.isRequired,
|
||||||
languageProfile: PropTypes.object.isRequired,
|
|
||||||
nextAiring: PropTypes.string,
|
nextAiring: PropTypes.string,
|
||||||
previousAiring: PropTypes.string,
|
previousAiring: PropTypes.string,
|
||||||
added: PropTypes.string,
|
added: PropTypes.string,
|
||||||
|
|
|
@ -62,7 +62,6 @@ class SeriesIndexTable extends Component {
|
||||||
component={SeriesIndexRow}
|
component={SeriesIndexRow}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
seriesId={series.id}
|
seriesId={series.id}
|
||||||
languageProfileId={series.languageProfileId}
|
|
||||||
qualityProfileId={series.qualityProfileId}
|
qualityProfileId={series.qualityProfileId}
|
||||||
showBanners={showBanners}
|
showBanners={showBanners}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
const growableColumns = [
|
const growableColumns = [
|
||||||
'network',
|
'network',
|
||||||
'qualityProfileId',
|
'qualityProfileId',
|
||||||
'languageProfileId',
|
|
||||||
'path',
|
'path',
|
||||||
'tags'
|
'tags'
|
||||||
];
|
];
|
||||||
|
|
|
@ -4,12 +4,6 @@
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hideLanguageProfile {
|
|
||||||
composes: group from '~Components/Form/FormGroup.css';
|
|
||||||
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.labelIcon {
|
.labelIcon {
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ function EditImportListModalContent(props) {
|
||||||
onSavePress,
|
onSavePress,
|
||||||
onTestPress,
|
onTestPress,
|
||||||
onDeleteImportListPress,
|
onDeleteImportListPress,
|
||||||
showLanguageProfile,
|
|
||||||
...otherProps
|
...otherProps
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
@ -46,7 +45,6 @@ function EditImportListModalContent(props) {
|
||||||
shouldMonitor,
|
shouldMonitor,
|
||||||
rootFolderPath,
|
rootFolderPath,
|
||||||
qualityProfileId,
|
qualityProfileId,
|
||||||
languageProfileId,
|
|
||||||
seriesType,
|
seriesType,
|
||||||
seasonFolder,
|
seasonFolder,
|
||||||
tags,
|
tags,
|
||||||
|
@ -148,18 +146,6 @@ function EditImportListModalContent(props) {
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup className={showLanguageProfile ? undefined : styles.hideLanguageProfile}>
|
|
||||||
<FormLabel>Language Profile</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.LANGUAGE_PROFILE_SELECT}
|
|
||||||
name="languageProfileId"
|
|
||||||
helpText={'Language Profile list items will be added with'}
|
|
||||||
{...languageProfileId}
|
|
||||||
onChange={onInputChange}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>
|
<FormLabel>
|
||||||
Series Type
|
Series Type
|
||||||
|
@ -279,7 +265,6 @@ EditImportListModalContent.propTypes = {
|
||||||
isTesting: PropTypes.bool.isRequired,
|
isTesting: PropTypes.bool.isRequired,
|
||||||
saveError: PropTypes.object,
|
saveError: PropTypes.object,
|
||||||
item: PropTypes.object.isRequired,
|
item: PropTypes.object.isRequired,
|
||||||
showLanguageProfile: PropTypes.bool.isRequired,
|
|
||||||
onInputChange: PropTypes.func.isRequired,
|
onInputChange: PropTypes.func.isRequired,
|
||||||
onFieldChange: PropTypes.func.isRequired,
|
onFieldChange: PropTypes.func.isRequired,
|
||||||
onModalClose: PropTypes.func.isRequired,
|
onModalClose: PropTypes.func.isRequired,
|
||||||
|
|
|
@ -9,12 +9,10 @@ import EditImportListModalContent from './EditImportListModalContent';
|
||||||
function createMapStateToProps() {
|
function createMapStateToProps() {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
(state) => state.settings.advancedSettings,
|
(state) => state.settings.advancedSettings,
|
||||||
(state) => state.settings.languageProfiles,
|
|
||||||
createProviderSettingsSelector('importLists'),
|
createProviderSettingsSelector('importLists'),
|
||||||
(advancedSettings, languageProfiles, importList) => {
|
(advancedSettings, importList) => {
|
||||||
return {
|
return {
|
||||||
advancedSettings,
|
advancedSettings,
|
||||||
showLanguageProfile: languageProfiles.items.length > 1,
|
|
||||||
...importList
|
...importList
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
import Modal from 'Components/Modal/Modal';
|
|
||||||
import { sizes } from 'Helpers/Props';
|
|
||||||
import EditLanguageProfileModalContentConnector from './EditLanguageProfileModalContentConnector';
|
|
||||||
|
|
||||||
function EditLanguageProfileModal({ isOpen, onModalClose, ...otherProps }) {
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
size={sizes.MEDIUM}
|
|
||||||
isOpen={isOpen}
|
|
||||||
onModalClose={onModalClose}
|
|
||||||
>
|
|
||||||
<EditLanguageProfileModalContentConnector
|
|
||||||
{...otherProps}
|
|
||||||
onModalClose={onModalClose}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
EditLanguageProfileModal.propTypes = {
|
|
||||||
isOpen: PropTypes.bool.isRequired,
|
|
||||||
onModalClose: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EditLanguageProfileModal;
|
|
|
@ -1,43 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { clearPendingChanges } from 'Store/Actions/baseActions';
|
|
||||||
import EditLanguageProfileModal from './EditLanguageProfileModal';
|
|
||||||
|
|
||||||
function mapStateToProps() {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
|
||||||
clearPendingChanges
|
|
||||||
};
|
|
||||||
|
|
||||||
class EditLanguageProfileModalConnector extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onModalClose = () => {
|
|
||||||
this.props.clearPendingChanges({ section: 'settings.languageProfiles' });
|
|
||||||
this.props.onModalClose();
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<EditLanguageProfileModal
|
|
||||||
{...this.props}
|
|
||||||
onModalClose={this.onModalClose}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EditLanguageProfileModalConnector.propTypes = {
|
|
||||||
onModalClose: PropTypes.func.isRequired,
|
|
||||||
clearPendingChanges: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(EditLanguageProfileModalConnector);
|
|
|
@ -1,3 +0,0 @@
|
||||||
.deleteButtonContainer {
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
|
@ -1,165 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
import Form from 'Components/Form/Form';
|
|
||||||
import FormGroup from 'Components/Form/FormGroup';
|
|
||||||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
|
||||||
import FormLabel from 'Components/Form/FormLabel';
|
|
||||||
import Button from 'Components/Link/Button';
|
|
||||||
import SpinnerErrorButton from 'Components/Link/SpinnerErrorButton';
|
|
||||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
|
||||||
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 { inputTypes, kinds } from 'Helpers/Props';
|
|
||||||
import LanguageProfileItems from './LanguageProfileItems';
|
|
||||||
import styles from './EditLanguageProfileModalContent.css';
|
|
||||||
|
|
||||||
function EditLanguageProfileModalContent(props) {
|
|
||||||
const {
|
|
||||||
isFetching,
|
|
||||||
error,
|
|
||||||
isSaving,
|
|
||||||
saveError,
|
|
||||||
languages,
|
|
||||||
item,
|
|
||||||
isInUse,
|
|
||||||
onInputChange,
|
|
||||||
onCutoffChange,
|
|
||||||
onSavePress,
|
|
||||||
onModalClose,
|
|
||||||
onDeleteLanguageProfilePress,
|
|
||||||
...otherProps
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const {
|
|
||||||
id,
|
|
||||||
name,
|
|
||||||
upgradeAllowed,
|
|
||||||
cutoff,
|
|
||||||
languages: itemLanguages
|
|
||||||
} = item;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ModalContent onModalClose={onModalClose}>
|
|
||||||
<ModalHeader>
|
|
||||||
{id ? 'Edit Language Profile' : 'Add Language Profile'}
|
|
||||||
</ModalHeader>
|
|
||||||
|
|
||||||
<ModalBody>
|
|
||||||
{
|
|
||||||
isFetching &&
|
|
||||||
<LoadingIndicator />
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
!isFetching && !!error &&
|
|
||||||
<div>Unable to add a new language profile, please try again.</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
!isFetching && !error &&
|
|
||||||
<Form {...otherProps}>
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>Name</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.TEXT}
|
|
||||||
name="name"
|
|
||||||
{...name}
|
|
||||||
onChange={onInputChange}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>
|
|
||||||
Upgrades Allowed
|
|
||||||
</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="upgradeAllowed"
|
|
||||||
{...upgradeAllowed}
|
|
||||||
helpText="If disabled languages will not be upgraded"
|
|
||||||
onChange={onInputChange}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
{
|
|
||||||
upgradeAllowed.value &&
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>Upgrade Until</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.SELECT}
|
|
||||||
name="cutoff"
|
|
||||||
{...cutoff}
|
|
||||||
value={cutoff ? cutoff.value.id : 0}
|
|
||||||
values={languages}
|
|
||||||
helpText="Once this language is reached Sonarr will no longer download episodes"
|
|
||||||
onChange={onCutoffChange}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
}
|
|
||||||
|
|
||||||
<LanguageProfileItems
|
|
||||||
languageProfileItems={itemLanguages.value}
|
|
||||||
errors={itemLanguages.errors}
|
|
||||||
warnings={itemLanguages.warnings}
|
|
||||||
{...otherProps}
|
|
||||||
/>
|
|
||||||
|
|
||||||
</Form>
|
|
||||||
}
|
|
||||||
</ModalBody>
|
|
||||||
<ModalFooter>
|
|
||||||
{
|
|
||||||
id &&
|
|
||||||
<div
|
|
||||||
className={styles.deleteButtonContainer}
|
|
||||||
title={isInUse && 'Can\'t delete a language profile that is attached to a series'}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
kind={kinds.DANGER}
|
|
||||||
isDisabled={isInUse}
|
|
||||||
onPress={onDeleteLanguageProfilePress}
|
|
||||||
>
|
|
||||||
Delete
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
<Button
|
|
||||||
onPress={onModalClose}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<SpinnerErrorButton
|
|
||||||
isSpinning={isSaving}
|
|
||||||
error={saveError}
|
|
||||||
onPress={onSavePress}
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</SpinnerErrorButton>
|
|
||||||
</ModalFooter>
|
|
||||||
</ModalContent>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
EditLanguageProfileModalContent.propTypes = {
|
|
||||||
isFetching: PropTypes.bool.isRequired,
|
|
||||||
error: PropTypes.object,
|
|
||||||
isSaving: PropTypes.bool.isRequired,
|
|
||||||
saveError: PropTypes.object,
|
|
||||||
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
||||||
item: PropTypes.object.isRequired,
|
|
||||||
isInUse: PropTypes.bool.isRequired,
|
|
||||||
onInputChange: PropTypes.func.isRequired,
|
|
||||||
onCutoffChange: PropTypes.func.isRequired,
|
|
||||||
onSavePress: PropTypes.func.isRequired,
|
|
||||||
onModalClose: PropTypes.func.isRequired,
|
|
||||||
onDeleteLanguageProfilePress: PropTypes.func
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EditLanguageProfileModalContent;
|
|
|
@ -1,189 +0,0 @@
|
||||||
import _ from 'lodash';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { createSelector } from 'reselect';
|
|
||||||
import { fetchLanguageProfileSchema, saveLanguageProfile, setLanguageProfileValue } from 'Store/Actions/settingsActions';
|
|
||||||
import createProfileInUseSelector from 'Store/Selectors/createProfileInUseSelector';
|
|
||||||
import createProviderSettingsSelector from 'Store/Selectors/createProviderSettingsSelector';
|
|
||||||
import EditLanguageProfileModalContent from './EditLanguageProfileModalContent';
|
|
||||||
|
|
||||||
function createLanguagesSelector() {
|
|
||||||
return createSelector(
|
|
||||||
createProviderSettingsSelector('languageProfiles'),
|
|
||||||
(languageProfile) => {
|
|
||||||
const languages = languageProfile.item.languages;
|
|
||||||
if (!languages || !languages.value) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return _.reduceRight(languages.value, (result, { allowed, language }) => {
|
|
||||||
if (allowed) {
|
|
||||||
result.push({
|
|
||||||
key: language.id,
|
|
||||||
value: language.name
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}, []);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createMapStateToProps() {
|
|
||||||
return createSelector(
|
|
||||||
createProviderSettingsSelector('languageProfiles'),
|
|
||||||
createLanguagesSelector(),
|
|
||||||
createProfileInUseSelector('languageProfileId'),
|
|
||||||
(languageProfile, languages, isInUse) => {
|
|
||||||
return {
|
|
||||||
languages,
|
|
||||||
...languageProfile,
|
|
||||||
isInUse
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
|
||||||
fetchLanguageProfileSchema,
|
|
||||||
setLanguageProfileValue,
|
|
||||||
saveLanguageProfile
|
|
||||||
};
|
|
||||||
|
|
||||||
class EditLanguageProfileModalContentConnector extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
constructor(props, context) {
|
|
||||||
super(props, context);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
dragIndex: null,
|
|
||||||
dropIndex: null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
if (!this.props.id && !this.props.isPopulated) {
|
|
||||||
this.props.fetchLanguageProfileSchema();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate(prevProps, prevState) {
|
|
||||||
if (prevProps.isSaving && !this.props.isSaving && !this.props.saveError) {
|
|
||||||
this.props.onModalClose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onInputChange = ({ name, value }) => {
|
|
||||||
this.props.setLanguageProfileValue({ name, value });
|
|
||||||
};
|
|
||||||
|
|
||||||
onCutoffChange = ({ name, value }) => {
|
|
||||||
const id = parseInt(value);
|
|
||||||
const item = _.find(this.props.item.languages.value, (i) => i.language.id === id);
|
|
||||||
|
|
||||||
this.props.setLanguageProfileValue({ name, value: item.language });
|
|
||||||
};
|
|
||||||
|
|
||||||
onSavePress = () => {
|
|
||||||
this.props.saveLanguageProfile({ id: this.props.id });
|
|
||||||
};
|
|
||||||
|
|
||||||
onLanguageProfileItemAllowedChange = (id, allowed) => {
|
|
||||||
const languageProfile = _.cloneDeep(this.props.item);
|
|
||||||
|
|
||||||
const item = _.find(languageProfile.languages.value, (i) => i.language.id === id);
|
|
||||||
item.allowed = allowed;
|
|
||||||
|
|
||||||
this.props.setLanguageProfileValue({
|
|
||||||
name: 'languages',
|
|
||||||
value: languageProfile.languages.value
|
|
||||||
});
|
|
||||||
|
|
||||||
const cutoff = languageProfile.cutoff.value;
|
|
||||||
|
|
||||||
// If the cutoff isn't allowed anymore or there isn't a cutoff set one
|
|
||||||
if (!cutoff || !_.find(languageProfile.languages.value, (i) => i.language.id === cutoff.id).allowed) {
|
|
||||||
const firstAllowed = _.find(languageProfile.languages.value, { allowed: true });
|
|
||||||
|
|
||||||
this.props.setLanguageProfileValue({ name: 'cutoff', value: firstAllowed ? firstAllowed.language : null });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onLanguageProfileItemDragMove = (dragIndex, dropIndex) => {
|
|
||||||
if (this.state.dragIndex !== dragIndex || this.state.dropIndex !== dropIndex) {
|
|
||||||
this.setState({
|
|
||||||
dragIndex,
|
|
||||||
dropIndex
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onLanguageProfileItemDragEnd = ({ id }, didDrop) => {
|
|
||||||
const {
|
|
||||||
dragIndex,
|
|
||||||
dropIndex
|
|
||||||
} = this.state;
|
|
||||||
|
|
||||||
if (didDrop && dropIndex !== null) {
|
|
||||||
const languageProfile = _.cloneDeep(this.props.item);
|
|
||||||
|
|
||||||
const languages = languageProfile.languages.value.splice(dragIndex, 1);
|
|
||||||
languageProfile.languages.value.splice(dropIndex, 0, languages[0]);
|
|
||||||
|
|
||||||
this.props.setLanguageProfileValue({
|
|
||||||
name: 'languages',
|
|
||||||
value: languageProfile.languages.value
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
dragIndex: null,
|
|
||||||
dropIndex: null
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
if (_.isEmpty(this.props.item.languages) && !this.props.isFetching) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<EditLanguageProfileModalContent
|
|
||||||
{...this.state}
|
|
||||||
{...this.props}
|
|
||||||
onSavePress={this.onSavePress}
|
|
||||||
onInputChange={this.onInputChange}
|
|
||||||
onCutoffChange={this.onCutoffChange}
|
|
||||||
onLanguageProfileItemAllowedChange={this.onLanguageProfileItemAllowedChange}
|
|
||||||
onLanguageProfileItemDragMove={this.onLanguageProfileItemDragMove}
|
|
||||||
onLanguageProfileItemDragEnd={this.onLanguageProfileItemDragEnd}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EditLanguageProfileModalContentConnector.propTypes = {
|
|
||||||
id: PropTypes.number,
|
|
||||||
isFetching: PropTypes.bool.isRequired,
|
|
||||||
isPopulated: PropTypes.bool.isRequired,
|
|
||||||
isSaving: PropTypes.bool.isRequired,
|
|
||||||
saveError: PropTypes.object,
|
|
||||||
item: PropTypes.object.isRequired,
|
|
||||||
setLanguageProfileValue: PropTypes.func.isRequired,
|
|
||||||
fetchLanguageProfileSchema: PropTypes.func.isRequired,
|
|
||||||
saveLanguageProfile: PropTypes.func.isRequired,
|
|
||||||
onModalClose: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(createMapStateToProps, mapDispatchToProps)(EditLanguageProfileModalContentConnector);
|
|
|
@ -1,31 +0,0 @@
|
||||||
.languageProfile {
|
|
||||||
composes: card from '~Components/Card.css';
|
|
||||||
|
|
||||||
width: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nameContainer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
|
||||||
@add-mixin truncate;
|
|
||||||
|
|
||||||
margin-bottom: 20px;
|
|
||||||
font-weight: 300;
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cloneButton {
|
|
||||||
composes: button from '~Components/Link/IconButton.css';
|
|
||||||
|
|
||||||
height: 36px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.languages {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
margin-top: 5px;
|
|
||||||
pointer-events: all;
|
|
||||||
}
|
|
|
@ -1,147 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import Card from 'Components/Card';
|
|
||||||
import Label from 'Components/Label';
|
|
||||||
import IconButton from 'Components/Link/IconButton';
|
|
||||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
|
||||||
import { icons, kinds } from 'Helpers/Props';
|
|
||||||
import EditLanguageProfileModalConnector from './EditLanguageProfileModalConnector';
|
|
||||||
import styles from './LanguageProfile.css';
|
|
||||||
|
|
||||||
class LanguageProfile extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
constructor(props, context) {
|
|
||||||
super(props, context);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
isEditLanguageProfileModalOpen: false,
|
|
||||||
isDeleteLanguageProfileModalOpen: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onEditLanguageProfilePress = () => {
|
|
||||||
this.setState({ isEditLanguageProfileModalOpen: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
onEditLanguageProfileModalClose = () => {
|
|
||||||
this.setState({ isEditLanguageProfileModalOpen: false });
|
|
||||||
};
|
|
||||||
|
|
||||||
onDeleteLanguageProfilePress = () => {
|
|
||||||
this.setState({
|
|
||||||
isEditLanguageProfileModalOpen: false,
|
|
||||||
isDeleteLanguageProfileModalOpen: true
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onDeleteLanguageProfileModalClose = () => {
|
|
||||||
this.setState({ isDeleteLanguageProfileModalOpen: false });
|
|
||||||
};
|
|
||||||
|
|
||||||
onConfirmDeleteLanguageProfile = () => {
|
|
||||||
this.props.onConfirmDeleteLanguageProfile(this.props.id);
|
|
||||||
};
|
|
||||||
|
|
||||||
onCloneLanguageProfilePress = () => {
|
|
||||||
const {
|
|
||||||
id,
|
|
||||||
onCloneLanguageProfilePress
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
onCloneLanguageProfilePress(id);
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
id,
|
|
||||||
name,
|
|
||||||
upgradeAllowed,
|
|
||||||
cutoff,
|
|
||||||
languages,
|
|
||||||
isDeleting
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Card
|
|
||||||
className={styles.languageProfile}
|
|
||||||
overlayContent={true}
|
|
||||||
onPress={this.onEditLanguageProfilePress}
|
|
||||||
>
|
|
||||||
<div className={styles.nameContainer}>
|
|
||||||
<div className={styles.name}>
|
|
||||||
{name}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<IconButton
|
|
||||||
className={styles.cloneButton}
|
|
||||||
title="Clone Profile"
|
|
||||||
name={icons.CLONE}
|
|
||||||
onPress={this.onCloneLanguageProfilePress}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.languages}>
|
|
||||||
{
|
|
||||||
languages.map((item) => {
|
|
||||||
if (!item.allowed) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isCutoff = upgradeAllowed && item.language.id === cutoff.id;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Label
|
|
||||||
key={item.language.id}
|
|
||||||
kind={isCutoff ? kinds.INFO : kinds.DEFAULT}
|
|
||||||
title={isCutoff ? 'Upgrade until this language is met or exceeded' : null}
|
|
||||||
>
|
|
||||||
{item.language.name}
|
|
||||||
</Label>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<EditLanguageProfileModalConnector
|
|
||||||
id={id}
|
|
||||||
isOpen={this.state.isEditLanguageProfileModalOpen}
|
|
||||||
onModalClose={this.onEditLanguageProfileModalClose}
|
|
||||||
onDeleteLanguageProfilePress={this.onDeleteLanguageProfilePress}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ConfirmModal
|
|
||||||
isOpen={this.state.isDeleteLanguageProfileModalOpen}
|
|
||||||
kind={kinds.DANGER}
|
|
||||||
title="Delete Language Profile"
|
|
||||||
message={`Are you sure you want to delete the language profile '${name}'?`}
|
|
||||||
confirmLabel="Delete"
|
|
||||||
isSpinning={isDeleting}
|
|
||||||
onConfirm={this.onConfirmDeleteLanguageProfile}
|
|
||||||
onCancel={this.onDeleteLanguageProfileModalClose}
|
|
||||||
/>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LanguageProfile.propTypes = {
|
|
||||||
id: PropTypes.number.isRequired,
|
|
||||||
name: PropTypes.string.isRequired,
|
|
||||||
upgradeAllowed: PropTypes.bool.isRequired,
|
|
||||||
cutoff: PropTypes.object.isRequired,
|
|
||||||
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
||||||
isDeleting: PropTypes.bool.isRequired,
|
|
||||||
onConfirmDeleteLanguageProfile: PropTypes.func.isRequired,
|
|
||||||
onCloneLanguageProfilePress: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default LanguageProfile;
|
|
|
@ -1,44 +0,0 @@
|
||||||
.languageProfileItem {
|
|
||||||
display: flex;
|
|
||||||
align-items: stretch;
|
|
||||||
width: 100%;
|
|
||||||
border: 1px solid #aaa;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: var(--inputBackgroundColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkContainer {
|
|
||||||
position: relative;
|
|
||||||
margin-right: 4px;
|
|
||||||
margin-bottom: 7px;
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.languageName {
|
|
||||||
display: flex;
|
|
||||||
flex-grow: 1;
|
|
||||||
margin-bottom: 0;
|
|
||||||
margin-left: 2px;
|
|
||||||
font-weight: normal;
|
|
||||||
line-height: 36px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dragHandle {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin-left: auto;
|
|
||||||
width: $dragHandleWidth;
|
|
||||||
text-align: center;
|
|
||||||
cursor: grab;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dragIcon {
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.isDragging {
|
|
||||||
opacity: 0.25;
|
|
||||||
}
|
|
|
@ -1,83 +0,0 @@
|
||||||
import classNames from 'classnames';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import CheckInput from 'Components/Form/CheckInput';
|
|
||||||
import Icon from 'Components/Icon';
|
|
||||||
import { icons } from 'Helpers/Props';
|
|
||||||
import styles from './LanguageProfileItem.css';
|
|
||||||
|
|
||||||
class LanguageProfileItem extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onAllowedChange = ({ value }) => {
|
|
||||||
const {
|
|
||||||
languageId,
|
|
||||||
onLanguageProfileItemAllowedChange
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
onLanguageProfileItemAllowedChange(languageId, value);
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
name,
|
|
||||||
allowed,
|
|
||||||
isDragging,
|
|
||||||
connectDragSource
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
styles.languageProfileItem,
|
|
||||||
isDragging && styles.isDragging
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<label
|
|
||||||
className={styles.languageName}
|
|
||||||
>
|
|
||||||
<CheckInput
|
|
||||||
containerClassName={styles.checkContainer}
|
|
||||||
name={name}
|
|
||||||
value={allowed}
|
|
||||||
onChange={this.onAllowedChange}
|
|
||||||
/>
|
|
||||||
{name}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
{
|
|
||||||
connectDragSource(
|
|
||||||
<div className={styles.dragHandle}>
|
|
||||||
<Icon
|
|
||||||
className={styles.dragIcon}
|
|
||||||
name={icons.REORDER}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LanguageProfileItem.propTypes = {
|
|
||||||
languageId: PropTypes.number.isRequired,
|
|
||||||
name: PropTypes.string.isRequired,
|
|
||||||
allowed: PropTypes.bool.isRequired,
|
|
||||||
sortIndex: PropTypes.number.isRequired,
|
|
||||||
isDragging: PropTypes.bool.isRequired,
|
|
||||||
connectDragSource: PropTypes.func,
|
|
||||||
onLanguageProfileItemAllowedChange: PropTypes.func
|
|
||||||
};
|
|
||||||
|
|
||||||
LanguageProfileItem.defaultProps = {
|
|
||||||
// The drag preview will not connect the drag handle.
|
|
||||||
connectDragSource: (node) => node
|
|
||||||
};
|
|
||||||
|
|
||||||
export default LanguageProfileItem;
|
|
|
@ -1,4 +0,0 @@
|
||||||
.dragPreview {
|
|
||||||
width: 380px;
|
|
||||||
opacity: 0.75;
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import { DragLayer } from 'react-dnd';
|
|
||||||
import DragPreviewLayer from 'Components/DragPreviewLayer';
|
|
||||||
import { QUALITY_PROFILE_ITEM } from 'Helpers/dragTypes';
|
|
||||||
import dimensions from 'Styles/Variables/dimensions.js';
|
|
||||||
import LanguageProfileItem from './LanguageProfileItem';
|
|
||||||
import styles from './LanguageProfileItemDragPreview.css';
|
|
||||||
|
|
||||||
const formGroupSmallWidth = parseInt(dimensions.formGroupSmallWidth);
|
|
||||||
const formLabelLargeWidth = parseInt(dimensions.formLabelLargeWidth);
|
|
||||||
const formLabelRightMarginWidth = parseInt(dimensions.formLabelRightMarginWidth);
|
|
||||||
const dragHandleWidth = parseInt(dimensions.dragHandleWidth);
|
|
||||||
|
|
||||||
function collectDragLayer(monitor) {
|
|
||||||
return {
|
|
||||||
item: monitor.getItem(),
|
|
||||||
itemType: monitor.getItemType(),
|
|
||||||
currentOffset: monitor.getSourceClientOffset()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class LanguageProfileItemDragPreview extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
item,
|
|
||||||
itemType,
|
|
||||||
currentOffset
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
if (!currentOffset || itemType !== QUALITY_PROFILE_ITEM) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The offset is shifted because the drag handle is on the right edge of the
|
|
||||||
// list item and the preview is wider than the drag handle.
|
|
||||||
|
|
||||||
const { x, y } = currentOffset;
|
|
||||||
const handleOffset = formGroupSmallWidth - formLabelLargeWidth - formLabelRightMarginWidth - dragHandleWidth;
|
|
||||||
const transform = `translate3d(${x - handleOffset}px, ${y}px, 0)`;
|
|
||||||
|
|
||||||
const style = {
|
|
||||||
position: 'absolute',
|
|
||||||
WebkitTransform: transform,
|
|
||||||
msTransform: transform,
|
|
||||||
transform
|
|
||||||
};
|
|
||||||
|
|
||||||
const {
|
|
||||||
languageId,
|
|
||||||
name,
|
|
||||||
allowed,
|
|
||||||
sortIndex
|
|
||||||
} = item;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DragPreviewLayer>
|
|
||||||
<div
|
|
||||||
className={styles.dragPreview}
|
|
||||||
style={style}
|
|
||||||
>
|
|
||||||
<LanguageProfileItem
|
|
||||||
languageId={languageId}
|
|
||||||
name={name}
|
|
||||||
allowed={allowed}
|
|
||||||
sortIndex={sortIndex}
|
|
||||||
isDragging={false}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</DragPreviewLayer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LanguageProfileItemDragPreview.propTypes = {
|
|
||||||
item: PropTypes.object,
|
|
||||||
itemType: PropTypes.string,
|
|
||||||
currentOffset: PropTypes.shape({
|
|
||||||
x: PropTypes.number.isRequired,
|
|
||||||
y: PropTypes.number.isRequired
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DragLayer(collectDragLayer)(LanguageProfileItemDragPreview);
|
|
|
@ -1,18 +0,0 @@
|
||||||
.languageProfileItemDragSource {
|
|
||||||
padding: 4px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.languageProfileItemPlaceholder {
|
|
||||||
width: 100%;
|
|
||||||
height: 36px;
|
|
||||||
border: 1px dotted #aaa;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.languageProfileItemPlaceholderBefore {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.languageProfileItemPlaceholderAfter {
|
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
|
@ -1,157 +0,0 @@
|
||||||
import classNames from 'classnames';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import { DragSource, DropTarget } from 'react-dnd';
|
|
||||||
import { findDOMNode } from 'react-dom';
|
|
||||||
import { QUALITY_PROFILE_ITEM } from 'Helpers/dragTypes';
|
|
||||||
import LanguageProfileItem from './LanguageProfileItem';
|
|
||||||
import styles from './LanguageProfileItemDragSource.css';
|
|
||||||
|
|
||||||
const languageProfileItemDragSource = {
|
|
||||||
beginDrag({ languageId, name, allowed, sortIndex }) {
|
|
||||||
return {
|
|
||||||
languageId,
|
|
||||||
name,
|
|
||||||
allowed,
|
|
||||||
sortIndex
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
endDrag(props, monitor, component) {
|
|
||||||
props.onLanguageProfileItemDragEnd(monitor.getItem(), monitor.didDrop());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const languageProfileItemDropTarget = {
|
|
||||||
hover(props, monitor, component) {
|
|
||||||
const dragIndex = monitor.getItem().sortIndex;
|
|
||||||
const hoverIndex = props.sortIndex;
|
|
||||||
|
|
||||||
const hoverBoundingRect = findDOMNode(component).getBoundingClientRect();
|
|
||||||
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
|
|
||||||
const clientOffset = monitor.getClientOffset();
|
|
||||||
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
|
|
||||||
|
|
||||||
// Moving up, only trigger if drag position is above 50%
|
|
||||||
if (dragIndex < hoverIndex && hoverClientY > hoverMiddleY) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Moving down, only trigger if drag position is below 50%
|
|
||||||
if (dragIndex > hoverIndex && hoverClientY < hoverMiddleY) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
props.onLanguageProfileItemDragMove(dragIndex, hoverIndex);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function collectDragSource(connect, monitor) {
|
|
||||||
return {
|
|
||||||
connectDragSource: connect.dragSource(),
|
|
||||||
isDragging: monitor.isDragging()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function collectDropTarget(connect, monitor) {
|
|
||||||
return {
|
|
||||||
connectDropTarget: connect.dropTarget(),
|
|
||||||
isOver: monitor.isOver()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class LanguageProfileItemDragSource extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
languageId,
|
|
||||||
name,
|
|
||||||
allowed,
|
|
||||||
sortIndex,
|
|
||||||
isDragging,
|
|
||||||
isDraggingUp,
|
|
||||||
isDraggingDown,
|
|
||||||
isOver,
|
|
||||||
connectDragSource,
|
|
||||||
connectDropTarget,
|
|
||||||
onLanguageProfileItemAllowedChange
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
const isBefore = !isDragging && isDraggingUp && isOver;
|
|
||||||
const isAfter = !isDragging && isDraggingDown && isOver;
|
|
||||||
|
|
||||||
// if (isDragging && !isOver) {
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
|
|
||||||
return connectDropTarget(
|
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
styles.languageProfileItemDragSource,
|
|
||||||
isBefore && styles.isDraggingUp,
|
|
||||||
isAfter && styles.isDraggingDown
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{
|
|
||||||
isBefore &&
|
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
styles.languageProfileItemPlaceholder,
|
|
||||||
styles.languageProfileItemPlaceholderBefore
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
|
|
||||||
<LanguageProfileItem
|
|
||||||
languageId={languageId}
|
|
||||||
name={name}
|
|
||||||
allowed={allowed}
|
|
||||||
sortIndex={sortIndex}
|
|
||||||
isDragging={isDragging}
|
|
||||||
isOver={isOver}
|
|
||||||
connectDragSource={connectDragSource}
|
|
||||||
onLanguageProfileItemAllowedChange={onLanguageProfileItemAllowedChange}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{
|
|
||||||
isAfter &&
|
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
styles.languageProfileItemPlaceholder,
|
|
||||||
styles.languageProfileItemPlaceholderAfter
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LanguageProfileItemDragSource.propTypes = {
|
|
||||||
languageId: PropTypes.number.isRequired,
|
|
||||||
name: PropTypes.string.isRequired,
|
|
||||||
allowed: PropTypes.bool.isRequired,
|
|
||||||
sortIndex: PropTypes.number.isRequired,
|
|
||||||
isDragging: PropTypes.bool,
|
|
||||||
isDraggingUp: PropTypes.bool,
|
|
||||||
isDraggingDown: PropTypes.bool,
|
|
||||||
isOver: PropTypes.bool,
|
|
||||||
connectDragSource: PropTypes.func,
|
|
||||||
connectDropTarget: PropTypes.func,
|
|
||||||
onLanguageProfileItemAllowedChange: PropTypes.func.isRequired,
|
|
||||||
onLanguageProfileItemDragMove: PropTypes.func.isRequired,
|
|
||||||
onLanguageProfileItemDragEnd: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DropTarget(
|
|
||||||
QUALITY_PROFILE_ITEM,
|
|
||||||
languageProfileItemDropTarget,
|
|
||||||
collectDropTarget
|
|
||||||
)(DragSource(
|
|
||||||
QUALITY_PROFILE_ITEM,
|
|
||||||
languageProfileItemDragSource,
|
|
||||||
collectDragSource
|
|
||||||
)(LanguageProfileItemDragSource));
|
|
|
@ -1,6 +0,0 @@
|
||||||
.languages {
|
|
||||||
margin-top: 10px;
|
|
||||||
/* TODO: This should consider the number of languages in the list */
|
|
||||||
min-height: 550px;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
|
@ -1,103 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import FormGroup from 'Components/Form/FormGroup';
|
|
||||||
import FormInputHelpText from 'Components/Form/FormInputHelpText';
|
|
||||||
import FormLabel from 'Components/Form/FormLabel';
|
|
||||||
import LanguageProfileItemDragPreview from './LanguageProfileItemDragPreview';
|
|
||||||
import LanguageProfileItemDragSource from './LanguageProfileItemDragSource';
|
|
||||||
import styles from './LanguageProfileItems.css';
|
|
||||||
|
|
||||||
class LanguageProfileItems extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
dragIndex,
|
|
||||||
dropIndex,
|
|
||||||
languageProfileItems,
|
|
||||||
errors,
|
|
||||||
warnings,
|
|
||||||
...otherProps
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
const isDragging = dropIndex !== null;
|
|
||||||
const isDraggingUp = isDragging && dropIndex > dragIndex;
|
|
||||||
const isDraggingDown = isDragging && dropIndex < dragIndex;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>Languages</FormLabel>
|
|
||||||
<div>
|
|
||||||
<FormInputHelpText
|
|
||||||
text="Languages higher in the list are more preferred. Only checked languages are wanted"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{
|
|
||||||
errors.map((error, index) => {
|
|
||||||
return (
|
|
||||||
<FormInputHelpText
|
|
||||||
key={index}
|
|
||||||
text={error.message}
|
|
||||||
isError={true}
|
|
||||||
isCheckInput={false}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
warnings.map((warning, index) => {
|
|
||||||
return (
|
|
||||||
<FormInputHelpText
|
|
||||||
key={index}
|
|
||||||
text={warning.message}
|
|
||||||
isWarning={true}
|
|
||||||
isCheckInput={false}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
<div className={styles.languages}>
|
|
||||||
{
|
|
||||||
languageProfileItems.map(({ allowed, language }, index) => {
|
|
||||||
return (
|
|
||||||
<LanguageProfileItemDragSource
|
|
||||||
key={language.id}
|
|
||||||
languageId={language.id}
|
|
||||||
name={language.name}
|
|
||||||
allowed={allowed}
|
|
||||||
sortIndex={index}
|
|
||||||
isDragging={isDragging}
|
|
||||||
isDraggingUp={isDraggingUp}
|
|
||||||
isDraggingDown={isDraggingDown}
|
|
||||||
{...otherProps}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}).reverse()
|
|
||||||
}
|
|
||||||
|
|
||||||
<LanguageProfileItemDragPreview />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</FormGroup>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LanguageProfileItems.propTypes = {
|
|
||||||
dragIndex: PropTypes.number,
|
|
||||||
dropIndex: PropTypes.number,
|
|
||||||
languageProfileItems: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
||||||
errors: PropTypes.arrayOf(PropTypes.object),
|
|
||||||
warnings: PropTypes.arrayOf(PropTypes.object)
|
|
||||||
};
|
|
||||||
|
|
||||||
LanguageProfileItems.defaultProps = {
|
|
||||||
errors: [],
|
|
||||||
warnings: []
|
|
||||||
};
|
|
||||||
|
|
||||||
export default LanguageProfileItems;
|
|
|
@ -1,31 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { createSelector } from 'reselect';
|
|
||||||
import createLanguageProfileSelector from 'Store/Selectors/createLanguageProfileSelector';
|
|
||||||
|
|
||||||
function createMapStateToProps() {
|
|
||||||
return createSelector(
|
|
||||||
createLanguageProfileSelector(),
|
|
||||||
(languageProfile) => {
|
|
||||||
return {
|
|
||||||
name: languageProfile.name
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function LanguageProfileNameConnector({ name, ...otherProps }) {
|
|
||||||
return (
|
|
||||||
<span>
|
|
||||||
{name}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
LanguageProfileNameConnector.propTypes = {
|
|
||||||
languageProfileId: PropTypes.number.isRequired,
|
|
||||||
name: PropTypes.string.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(createMapStateToProps)(LanguageProfileNameConnector);
|
|
|
@ -1,21 +0,0 @@
|
||||||
.languageProfiles {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.addLanguageProfile {
|
|
||||||
composes: languageProfile from '~./LanguageProfile.css';
|
|
||||||
|
|
||||||
background-color: var(--cardAlternateBackgroundColor);
|
|
||||||
color: var(--gray);
|
|
||||||
text-align: center;
|
|
||||||
font-size: 45px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 5px 20px 0;
|
|
||||||
border: 1px solid var(--borderColor);
|
|
||||||
border-radius: 4px;
|
|
||||||
background-color: var(--cardCenterBackgroundColor);
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import Card from 'Components/Card';
|
|
||||||
import FieldSet from 'Components/FieldSet';
|
|
||||||
import Icon from 'Components/Icon';
|
|
||||||
import PageSectionContent from 'Components/Page/PageSectionContent';
|
|
||||||
import { icons } from 'Helpers/Props';
|
|
||||||
import EditLanguageProfileModalConnector from './EditLanguageProfileModalConnector';
|
|
||||||
import LanguageProfile from './LanguageProfile';
|
|
||||||
import styles from './LanguageProfiles.css';
|
|
||||||
|
|
||||||
class LanguageProfiles extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
constructor(props, context) {
|
|
||||||
super(props, context);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
isLanguageProfileModalOpen: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onCloneLanguageProfilePress = (id) => {
|
|
||||||
this.props.onCloneLanguageProfilePress(id);
|
|
||||||
this.setState({ isLanguageProfileModalOpen: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
onEditLanguageProfilePress = () => {
|
|
||||||
this.setState({ isLanguageProfileModalOpen: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
onModalClose = () => {
|
|
||||||
this.setState({ isLanguageProfileModalOpen: false });
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
items,
|
|
||||||
isDeleting,
|
|
||||||
onConfirmDeleteLanguageProfile,
|
|
||||||
onCloneLanguageProfilePress,
|
|
||||||
...otherProps
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FieldSet legend="Language Profiles">
|
|
||||||
<PageSectionContent
|
|
||||||
errorMessage="Unable to load Language Profiles"
|
|
||||||
{...otherProps}
|
|
||||||
>
|
|
||||||
<div className={styles.languageProfiles}>
|
|
||||||
{
|
|
||||||
items.map((item) => {
|
|
||||||
return (
|
|
||||||
<LanguageProfile
|
|
||||||
key={item.id}
|
|
||||||
{...item}
|
|
||||||
isDeleting={isDeleting}
|
|
||||||
onConfirmDeleteLanguageProfile={onConfirmDeleteLanguageProfile}
|
|
||||||
onCloneLanguageProfilePress={this.onCloneLanguageProfilePress}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
<Card
|
|
||||||
className={styles.addLanguageProfile}
|
|
||||||
onPress={this.onEditLanguageProfilePress}
|
|
||||||
>
|
|
||||||
<div className={styles.center}>
|
|
||||||
<Icon
|
|
||||||
name={icons.ADD}
|
|
||||||
size={45}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<EditLanguageProfileModalConnector
|
|
||||||
isOpen={this.state.isLanguageProfileModalOpen}
|
|
||||||
onModalClose={this.onModalClose}
|
|
||||||
/>
|
|
||||||
</PageSectionContent>
|
|
||||||
</FieldSet>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LanguageProfiles.propTypes = {
|
|
||||||
advancedSettings: PropTypes.bool.isRequired,
|
|
||||||
isFetching: PropTypes.bool.isRequired,
|
|
||||||
error: PropTypes.object,
|
|
||||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
||||||
isDeleting: PropTypes.bool.isRequired,
|
|
||||||
onConfirmDeleteLanguageProfile: PropTypes.func.isRequired,
|
|
||||||
onCloneLanguageProfilePress: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default LanguageProfiles;
|
|
|
@ -1,69 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { createSelector } from 'reselect';
|
|
||||||
import { cloneLanguageProfile, deleteLanguageProfile, fetchLanguageProfiles } from 'Store/Actions/settingsActions';
|
|
||||||
import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector';
|
|
||||||
import sortByName from 'Utilities/Array/sortByName';
|
|
||||||
import LanguageProfiles from './LanguageProfiles';
|
|
||||||
|
|
||||||
function createMapStateToProps() {
|
|
||||||
return createSelector(
|
|
||||||
(state) => state.settings.advancedSettings,
|
|
||||||
createSortedSectionSelector('settings.languageProfiles', sortByName),
|
|
||||||
(advancedSettings, languageProfiles) => {
|
|
||||||
return {
|
|
||||||
advancedSettings,
|
|
||||||
...languageProfiles
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
|
||||||
dispatchFetchLanguageProfiles: fetchLanguageProfiles,
|
|
||||||
dispatchDeleteLanguageProfile: deleteLanguageProfile,
|
|
||||||
dispatchCloneLanguageProfile: cloneLanguageProfile
|
|
||||||
};
|
|
||||||
|
|
||||||
class LanguageProfilesConnector extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.props.dispatchFetchLanguageProfiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onConfirmDeleteLanguageProfile = (id) => {
|
|
||||||
this.props.dispatchDeleteLanguageProfile({ id });
|
|
||||||
};
|
|
||||||
|
|
||||||
onCloneLanguageProfilePress = (id) => {
|
|
||||||
this.props.dispatchCloneLanguageProfile({ id });
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<LanguageProfiles
|
|
||||||
onConfirmDeleteLanguageProfile={this.onConfirmDeleteLanguageProfile}
|
|
||||||
onCloneLanguageProfilePress={this.onCloneLanguageProfilePress}
|
|
||||||
{...this.props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LanguageProfilesConnector.propTypes = {
|
|
||||||
dispatchFetchLanguageProfiles: PropTypes.func.isRequired,
|
|
||||||
dispatchDeleteLanguageProfile: PropTypes.func.isRequired,
|
|
||||||
dispatchCloneLanguageProfile: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(createMapStateToProps, mapDispatchToProps)(LanguageProfilesConnector);
|
|
|
@ -5,7 +5,6 @@ import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
||||||
import DelayProfilesConnector from './Delay/DelayProfilesConnector';
|
import DelayProfilesConnector from './Delay/DelayProfilesConnector';
|
||||||
import LanguageProfilesConnector from './Language/LanguageProfilesConnector';
|
|
||||||
import QualityProfilesConnector from './Quality/QualityProfilesConnector';
|
import QualityProfilesConnector from './Quality/QualityProfilesConnector';
|
||||||
import ReleaseProfilesConnector from './Release/ReleaseProfilesConnector';
|
import ReleaseProfilesConnector from './Release/ReleaseProfilesConnector';
|
||||||
|
|
||||||
|
@ -25,7 +24,6 @@ class Profiles extends Component {
|
||||||
<PageContentBody>
|
<PageContentBody>
|
||||||
<DndProvider options={HTML5toTouch}>
|
<DndProvider options={HTML5toTouch}>
|
||||||
<QualityProfilesConnector />
|
<QualityProfilesConnector />
|
||||||
<LanguageProfilesConnector />
|
|
||||||
<DelayProfilesConnector />
|
<DelayProfilesConnector />
|
||||||
<ReleaseProfilesConnector />
|
<ReleaseProfilesConnector />
|
||||||
</DndProvider>
|
</DndProvider>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import React, { Component } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import { clearPendingChanges } from 'Store/Actions/baseActions';
|
import { clearPendingChanges } from 'Store/Actions/baseActions';
|
||||||
import { fetchLanguageProfileSchema, fetchUISettings, saveUISettings, setUISettingsValue } from 'Store/Actions/settingsActions';
|
import { fetchUISettings, saveUISettings, setUISettingsValue } from 'Store/Actions/settingsActions';
|
||||||
import createLanguagesSelector from 'Store/Selectors/createLanguagesSelector';
|
import createLanguagesSelector from 'Store/Selectors/createLanguagesSelector';
|
||||||
import createSettingsSectionSelector from 'Store/Selectors/createSettingsSectionSelector';
|
import createSettingsSectionSelector from 'Store/Selectors/createSettingsSectionSelector';
|
||||||
import UISettings from './UISettings';
|
import UISettings from './UISettings';
|
||||||
|
@ -20,11 +20,11 @@ function createFilteredLanguagesSelector() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const newItems = languages.items
|
const newItems = languages.items
|
||||||
.filter((lang) => !FILTER_LANGUAGES.includes(lang.language.name))
|
.filter((lang) => !FILTER_LANGUAGES.includes(lang.name))
|
||||||
.map((item) => {
|
.map((item) => {
|
||||||
return {
|
return {
|
||||||
key: item.language.id,
|
key: item.id,
|
||||||
value: item.language.name
|
value: item.name
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -58,8 +58,7 @@ const mapDispatchToProps = {
|
||||||
dispatchSetUISettingsValue: setUISettingsValue,
|
dispatchSetUISettingsValue: setUISettingsValue,
|
||||||
dispatchSaveUISettings: saveUISettings,
|
dispatchSaveUISettings: saveUISettings,
|
||||||
dispatchFetchUISettings: fetchUISettings,
|
dispatchFetchUISettings: fetchUISettings,
|
||||||
dispatchClearPendingChanges: clearPendingChanges,
|
dispatchClearPendingChanges: clearPendingChanges
|
||||||
dispatchFetchLanguageProfileSchema: fetchLanguageProfileSchema
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class UISettingsConnector extends Component {
|
class UISettingsConnector extends Component {
|
||||||
|
@ -69,16 +68,10 @@ class UISettingsConnector extends Component {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const {
|
const {
|
||||||
isLanguagesPopulated,
|
dispatchFetchUISettings
|
||||||
dispatchFetchUISettings,
|
|
||||||
dispatchFetchLanguageProfileSchema
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
dispatchFetchUISettings();
|
dispatchFetchUISettings();
|
||||||
|
|
||||||
if (!isLanguagesPopulated) {
|
|
||||||
dispatchFetchLanguageProfileSchema();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
@ -115,8 +108,7 @@ UISettingsConnector.propTypes = {
|
||||||
dispatchSetUISettingsValue: PropTypes.func.isRequired,
|
dispatchSetUISettingsValue: PropTypes.func.isRequired,
|
||||||
dispatchSaveUISettings: PropTypes.func.isRequired,
|
dispatchSaveUISettings: PropTypes.func.isRequired,
|
||||||
dispatchFetchUISettings: PropTypes.func.isRequired,
|
dispatchFetchUISettings: PropTypes.func.isRequired,
|
||||||
dispatchClearPendingChanges: PropTypes.func.isRequired,
|
dispatchClearPendingChanges: PropTypes.func.isRequired
|
||||||
dispatchFetchLanguageProfileSchema: PropTypes.func.isRequired
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(createMapStateToProps, mapDispatchToProps)(UISettingsConnector);
|
export default connect(createMapStateToProps, mapDispatchToProps)(UISettingsConnector);
|
||||||
|
|
|
@ -1,97 +0,0 @@
|
||||||
import { createAction } from 'redux-actions';
|
|
||||||
import createFetchHandler from 'Store/Actions/Creators/createFetchHandler';
|
|
||||||
import createFetchSchemaHandler from 'Store/Actions/Creators/createFetchSchemaHandler';
|
|
||||||
import createRemoveItemHandler from 'Store/Actions/Creators/createRemoveItemHandler';
|
|
||||||
import createSaveProviderHandler from 'Store/Actions/Creators/createSaveProviderHandler';
|
|
||||||
import createSetSettingValueReducer from 'Store/Actions/Creators/Reducers/createSetSettingValueReducer';
|
|
||||||
import { createThunk } from 'Store/thunks';
|
|
||||||
import getSectionState from 'Utilities/State/getSectionState';
|
|
||||||
import updateSectionState from 'Utilities/State/updateSectionState';
|
|
||||||
|
|
||||||
//
|
|
||||||
// Variables
|
|
||||||
|
|
||||||
const section = 'settings.languageProfiles';
|
|
||||||
|
|
||||||
//
|
|
||||||
// Actions Types
|
|
||||||
|
|
||||||
export const FETCH_LANGUAGE_PROFILES = 'settings/languageProfiles/fetchLanguageProfiles';
|
|
||||||
export const FETCH_LANGUAGE_PROFILE_SCHEMA = 'settings/languageProfiles/fetchLanguageProfileSchema';
|
|
||||||
export const SAVE_LANGUAGE_PROFILE = 'settings/languageProfiles/saveLanguageProfile';
|
|
||||||
export const DELETE_LANGUAGE_PROFILE = 'settings/languageProfiles/deleteLanguageProfile';
|
|
||||||
export const SET_LANGUAGE_PROFILE_VALUE = 'settings/languageProfiles/setLanguageProfileValue';
|
|
||||||
export const CLONE_LANGUAGE_PROFILE = 'settings/languageProfiles/cloneLanguageProfile';
|
|
||||||
|
|
||||||
//
|
|
||||||
// Action Creators
|
|
||||||
|
|
||||||
export const fetchLanguageProfiles = createThunk(FETCH_LANGUAGE_PROFILES);
|
|
||||||
export const fetchLanguageProfileSchema = createThunk(FETCH_LANGUAGE_PROFILE_SCHEMA);
|
|
||||||
export const saveLanguageProfile = createThunk(SAVE_LANGUAGE_PROFILE);
|
|
||||||
export const deleteLanguageProfile = createThunk(DELETE_LANGUAGE_PROFILE);
|
|
||||||
|
|
||||||
export const setLanguageProfileValue = createAction(SET_LANGUAGE_PROFILE_VALUE, (payload) => {
|
|
||||||
return {
|
|
||||||
section,
|
|
||||||
...payload
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
export const cloneLanguageProfile = createAction(CLONE_LANGUAGE_PROFILE);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Details
|
|
||||||
|
|
||||||
export default {
|
|
||||||
|
|
||||||
//
|
|
||||||
// State
|
|
||||||
|
|
||||||
defaultState: {
|
|
||||||
isFetching: false,
|
|
||||||
isPopulated: false,
|
|
||||||
error: null,
|
|
||||||
isDeleting: false,
|
|
||||||
deleteError: null,
|
|
||||||
isSchemaFetching: false,
|
|
||||||
isSchemaPopulated: false,
|
|
||||||
schemaError: null,
|
|
||||||
schema: {},
|
|
||||||
isSaving: false,
|
|
||||||
saveError: null,
|
|
||||||
items: [],
|
|
||||||
pendingChanges: {}
|
|
||||||
},
|
|
||||||
|
|
||||||
//
|
|
||||||
// Action Handlers
|
|
||||||
|
|
||||||
actionHandlers: {
|
|
||||||
[FETCH_LANGUAGE_PROFILES]: createFetchHandler(section, '/languageprofile'),
|
|
||||||
[FETCH_LANGUAGE_PROFILE_SCHEMA]: createFetchSchemaHandler(section, '/languageprofile/schema'),
|
|
||||||
[SAVE_LANGUAGE_PROFILE]: createSaveProviderHandler(section, '/languageprofile'),
|
|
||||||
[DELETE_LANGUAGE_PROFILE]: createRemoveItemHandler(section, '/languageprofile')
|
|
||||||
},
|
|
||||||
|
|
||||||
//
|
|
||||||
// Reducers
|
|
||||||
|
|
||||||
reducers: {
|
|
||||||
[SET_LANGUAGE_PROFILE_VALUE]: createSetSettingValueReducer(section),
|
|
||||||
|
|
||||||
[CLONE_LANGUAGE_PROFILE]: function(state, { payload }) {
|
|
||||||
const id = payload.id;
|
|
||||||
const newState = getSectionState(state, section);
|
|
||||||
const item = newState.items.find((i) => i.id === id);
|
|
||||||
const pendingChanges = { ...item, id: 0 };
|
|
||||||
delete pendingChanges.id;
|
|
||||||
|
|
||||||
pendingChanges.name = `${pendingChanges.name} - Copy`;
|
|
||||||
newState.pendingChanges = pendingChanges;
|
|
||||||
|
|
||||||
return updateSectionState(state, section, newState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
import createFetchHandler from 'Store/Actions/Creators/createFetchHandler';
|
||||||
|
import { createThunk } from 'Store/thunks';
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variables
|
||||||
|
|
||||||
|
const section = 'settings.languages';
|
||||||
|
|
||||||
|
//
|
||||||
|
// Actions Types
|
||||||
|
|
||||||
|
export const FETCH_LANGUAGES = 'settings/languages/fetchLanguages';
|
||||||
|
|
||||||
|
//
|
||||||
|
// Action Creators
|
||||||
|
|
||||||
|
export const fetchLanguages = createThunk(FETCH_LANGUAGES);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Details
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
//
|
||||||
|
// State
|
||||||
|
|
||||||
|
defaultState: {
|
||||||
|
isFetching: false,
|
||||||
|
isPopulated: false,
|
||||||
|
error: null,
|
||||||
|
items: []
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Action Handlers
|
||||||
|
|
||||||
|
actionHandlers: {
|
||||||
|
[FETCH_LANGUAGES]: createFetchHandler(section, '/language')
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reducers
|
||||||
|
|
||||||
|
reducers: {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
|
@ -34,7 +34,6 @@ export const defaultState = {
|
||||||
rootFolderPath: '',
|
rootFolderPath: '',
|
||||||
monitor: monitorOptions[0].key,
|
monitor: monitorOptions[0].key,
|
||||||
qualityProfileId: 0,
|
qualityProfileId: 0,
|
||||||
languageProfileId: 0,
|
|
||||||
seriesType: seriesTypes.STANDARD,
|
seriesType: seriesTypes.STANDARD,
|
||||||
seasonFolder: true,
|
seasonFolder: true,
|
||||||
searchForMissingEpisodes: false,
|
searchForMissingEpisodes: false,
|
||||||
|
|
|
@ -43,8 +43,8 @@ export const defaultState = {
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'language',
|
name: 'languages',
|
||||||
label: 'Language',
|
label: 'Languages',
|
||||||
isVisible: false
|
isVisible: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,8 +60,8 @@ export const defaultState = {
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'language',
|
name: 'languages',
|
||||||
label: 'Language',
|
label: 'Languages',
|
||||||
isVisible: false
|
isVisible: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -162,7 +162,7 @@ export const actionHandlers = handleThunks({
|
||||||
|
|
||||||
props.qualityCutoffNotMet = episodeFile.qualityCutoffNotMet;
|
props.qualityCutoffNotMet = episodeFile.qualityCutoffNotMet;
|
||||||
props.languageCutoffNotMet = episodeFile.languageCutoffNotMet;
|
props.languageCutoffNotMet = episodeFile.languageCutoffNotMet;
|
||||||
props.language = file.language;
|
props.languages = file.languages;
|
||||||
props.quality = file.quality;
|
props.quality = file.quality;
|
||||||
props.releaseGroup = file.releaseGroup;
|
props.releaseGroup = file.releaseGroup;
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,8 @@ export const defaultState = {
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'language',
|
name: 'languages',
|
||||||
label: 'Language',
|
label: 'Languages',
|
||||||
isVisible: false
|
isVisible: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -177,7 +177,7 @@ export const actionHandlers = handleThunks({
|
||||||
seasonNumber: item.seasonNumber,
|
seasonNumber: item.seasonNumber,
|
||||||
episodeIds: (item.episodes || []).map((e) => e.id),
|
episodeIds: (item.episodes || []).map((e) => e.id),
|
||||||
quality: item.quality,
|
quality: item.quality,
|
||||||
language: item.language,
|
languages: item.languages,
|
||||||
releaseGroup: item.releaseGroup,
|
releaseGroup: item.releaseGroup,
|
||||||
downloadId: item.downloadId
|
downloadId: item.downloadId
|
||||||
};
|
};
|
||||||
|
|
|
@ -87,8 +87,8 @@ export const defaultState = {
|
||||||
isVisible: false
|
isVisible: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'language',
|
name: 'languages',
|
||||||
label: 'Language',
|
label: 'Languages',
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: false
|
isVisible: false
|
||||||
},
|
},
|
||||||
|
|
|
@ -204,12 +204,6 @@ export const filterBuilderProps = [
|
||||||
type: filterBuilderTypes.EXACT,
|
type: filterBuilderTypes.EXACT,
|
||||||
valueType: filterBuilderValueTypes.QUALITY_PROFILE
|
valueType: filterBuilderValueTypes.QUALITY_PROFILE
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'languageProfileId',
|
|
||||||
label: 'Language Profile',
|
|
||||||
type: filterBuilderTypes.EXACT,
|
|
||||||
valueType: filterBuilderValueTypes.LANGUAGE_PROFILE
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'nextAiring',
|
name: 'nextAiring',
|
||||||
label: 'Next Airing',
|
label: 'Next Airing',
|
||||||
|
|
|
@ -53,12 +53,6 @@ export const defaultState = {
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'languageProfileId',
|
|
||||||
label: 'Language Profile',
|
|
||||||
isSortable: true,
|
|
||||||
isVisible: true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'seriesType',
|
name: 'seriesType',
|
||||||
label: 'Type',
|
label: 'Type',
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue