mirror of
https://github.com/Radarr/Radarr.git
synced 2024-10-05 15:47:20 +02:00
New: Added MinAvailability Option to UI
This commit is contained in:
parent
5eb7fe958f
commit
1514613f61
@ -55,6 +55,7 @@ class AddNewMovieModalContent extends Component {
|
|||||||
rootFolderPath,
|
rootFolderPath,
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId,
|
qualityProfileId,
|
||||||
|
minimumAvailability,
|
||||||
folder,
|
folder,
|
||||||
tags,
|
tags,
|
||||||
isSmallScreen,
|
isSmallScreen,
|
||||||
@ -126,6 +127,17 @@ class AddNewMovieModalContent extends Component {
|
|||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>Minimum Availability</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.AVAILABILITY_SELECT}
|
||||||
|
name="minimumAvailability"
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...minimumAvailability}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>Quality Profile</FormLabel>
|
<FormLabel>Quality Profile</FormLabel>
|
||||||
|
|
||||||
@ -191,6 +203,7 @@ AddNewMovieModalContent.propTypes = {
|
|||||||
rootFolderPath: PropTypes.object,
|
rootFolderPath: PropTypes.object,
|
||||||
monitor: PropTypes.object.isRequired,
|
monitor: PropTypes.object.isRequired,
|
||||||
qualityProfileId: PropTypes.object,
|
qualityProfileId: PropTypes.object,
|
||||||
|
minimumAvailability: PropTypes.object.isRequired,
|
||||||
folder: PropTypes.string.isRequired,
|
folder: PropTypes.string.isRequired,
|
||||||
tags: PropTypes.object.isRequired,
|
tags: PropTypes.object.isRequired,
|
||||||
isSmallScreen: PropTypes.bool.isRequired,
|
isSmallScreen: PropTypes.bool.isRequired,
|
||||||
|
@ -59,6 +59,7 @@ class AddNewMovieModalContentConnector extends Component {
|
|||||||
rootFolderPath,
|
rootFolderPath,
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId,
|
qualityProfileId,
|
||||||
|
minimumAvailability,
|
||||||
tags
|
tags
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
@ -67,6 +68,7 @@ class AddNewMovieModalContentConnector extends Component {
|
|||||||
rootFolderPath: rootFolderPath.value,
|
rootFolderPath: rootFolderPath.value,
|
||||||
monitor: monitor.value,
|
monitor: monitor.value,
|
||||||
qualityProfileId: qualityProfileId.value,
|
qualityProfileId: qualityProfileId.value,
|
||||||
|
minimumAvailability: minimumAvailability.value,
|
||||||
tags: tags.value,
|
tags: tags.value,
|
||||||
searchForMovie
|
searchForMovie
|
||||||
});
|
});
|
||||||
@ -91,6 +93,7 @@ AddNewMovieModalContentConnector.propTypes = {
|
|||||||
rootFolderPath: PropTypes.object,
|
rootFolderPath: PropTypes.object,
|
||||||
monitor: PropTypes.object.isRequired,
|
monitor: PropTypes.object.isRequired,
|
||||||
qualityProfileId: PropTypes.object,
|
qualityProfileId: PropTypes.object,
|
||||||
|
minimumAvailability: PropTypes.object.isRequired,
|
||||||
tags: PropTypes.object.isRequired,
|
tags: PropTypes.object.isRequired,
|
||||||
onModalClose: PropTypes.func.isRequired,
|
onModalClose: PropTypes.func.isRequired,
|
||||||
setAddMovieDefault: PropTypes.func.isRequired,
|
setAddMovieDefault: PropTypes.func.isRequired,
|
||||||
|
@ -22,12 +22,14 @@ class ImportMovieFooter extends Component {
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
defaultMonitor,
|
defaultMonitor,
|
||||||
defaultQualityProfileId
|
defaultQualityProfileId,
|
||||||
|
defaultMinimumAvailability
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
monitor: defaultMonitor,
|
monitor: defaultMonitor,
|
||||||
qualityProfileId: defaultQualityProfileId
|
qualityProfileId: defaultQualityProfileId,
|
||||||
|
minimumAvailability: defaultMinimumAvailability
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,13 +37,16 @@ class ImportMovieFooter extends Component {
|
|||||||
const {
|
const {
|
||||||
defaultMonitor,
|
defaultMonitor,
|
||||||
defaultQualityProfileId,
|
defaultQualityProfileId,
|
||||||
|
defaultMinimumAvailability,
|
||||||
isMonitorMixed,
|
isMonitorMixed,
|
||||||
isQualityProfileIdMixed
|
isQualityProfileIdMixed,
|
||||||
|
isMinimumAvailabilityMixed
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId
|
qualityProfileId,
|
||||||
|
minimumAvailability
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
const newState = {};
|
const newState = {};
|
||||||
@ -58,6 +63,12 @@ class ImportMovieFooter extends Component {
|
|||||||
newState.qualityProfileId = defaultQualityProfileId;
|
newState.qualityProfileId = defaultQualityProfileId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isMinimumAvailabilityMixed && minimumAvailability !== MIXED) {
|
||||||
|
newState.minimumAvailability = MIXED;
|
||||||
|
} else if (!isMinimumAvailabilityMixed && minimumAvailability !== defaultMinimumAvailability) {
|
||||||
|
newState.minimumAvailability = defaultMinimumAvailability;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_.isEmpty(newState)) {
|
if (!_.isEmpty(newState)) {
|
||||||
this.setState(newState);
|
this.setState(newState);
|
||||||
}
|
}
|
||||||
@ -81,13 +92,15 @@ class ImportMovieFooter extends Component {
|
|||||||
isLookingUpMovie,
|
isLookingUpMovie,
|
||||||
isMonitorMixed,
|
isMonitorMixed,
|
||||||
isQualityProfileIdMixed,
|
isQualityProfileIdMixed,
|
||||||
|
isMinimumAvailabilityMixed,
|
||||||
onImportPress,
|
onImportPress,
|
||||||
onCancelLookupPress
|
onCancelLookupPress
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId
|
qualityProfileId,
|
||||||
|
minimumAvailability
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -107,6 +120,21 @@ class ImportMovieFooter extends Component {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.inputContainer}>
|
||||||
|
<div className={styles.label}>
|
||||||
|
Minimum Availability
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.AVAILABILITY_SELECT}
|
||||||
|
name="minimumAvailability"
|
||||||
|
value={minimumAvailability}
|
||||||
|
isDisabled={!selectedCount}
|
||||||
|
includeMixed={isMinimumAvailabilityMixed}
|
||||||
|
onChange={this.onInputChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className={styles.inputContainer}>
|
<div className={styles.inputContainer}>
|
||||||
<div className={styles.label}>
|
<div className={styles.label}>
|
||||||
Quality Profile
|
Quality Profile
|
||||||
@ -174,8 +202,10 @@ ImportMovieFooter.propTypes = {
|
|||||||
isLookingUpMovie: PropTypes.bool.isRequired,
|
isLookingUpMovie: PropTypes.bool.isRequired,
|
||||||
defaultMonitor: PropTypes.string.isRequired,
|
defaultMonitor: PropTypes.string.isRequired,
|
||||||
defaultQualityProfileId: PropTypes.number,
|
defaultQualityProfileId: PropTypes.number,
|
||||||
|
defaultMinimumAvailability: PropTypes.string,
|
||||||
isMonitorMixed: PropTypes.bool.isRequired,
|
isMonitorMixed: PropTypes.bool.isRequired,
|
||||||
isQualityProfileIdMixed: PropTypes.bool.isRequired,
|
isQualityProfileIdMixed: PropTypes.bool.isRequired,
|
||||||
|
isMinimumAvailabilityMixed: PropTypes.bool.isRequired,
|
||||||
onInputChange: PropTypes.func.isRequired,
|
onInputChange: PropTypes.func.isRequired,
|
||||||
onImportPress: PropTypes.func.isRequired,
|
onImportPress: PropTypes.func.isRequired,
|
||||||
onCancelLookupPress: PropTypes.func.isRequired
|
onCancelLookupPress: PropTypes.func.isRequired
|
||||||
|
@ -18,7 +18,8 @@ function createMapStateToProps() {
|
|||||||
(addMovie, importMovie, selectedIds) => {
|
(addMovie, importMovie, selectedIds) => {
|
||||||
const {
|
const {
|
||||||
monitor: defaultMonitor,
|
monitor: defaultMonitor,
|
||||||
qualityProfileId: defaultQualityProfileId
|
qualityProfileId: defaultQualityProfileId,
|
||||||
|
minimumAvailability: defaultMinimumAvailability
|
||||||
} = addMovie.defaults;
|
} = addMovie.defaults;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -29,6 +30,7 @@ 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 isMinimumAvailabilityMixed = isMixed(items, selectedIds, defaultMinimumAvailability, 'minimumAvailability');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
selectedCount: selectedIds.length,
|
selectedCount: selectedIds.length,
|
||||||
@ -36,8 +38,10 @@ function createMapStateToProps() {
|
|||||||
isImporting,
|
isImporting,
|
||||||
defaultMonitor,
|
defaultMonitor,
|
||||||
defaultQualityProfileId,
|
defaultQualityProfileId,
|
||||||
|
defaultMinimumAvailability,
|
||||||
isMonitorMixed,
|
isMonitorMixed,
|
||||||
isQualityProfileIdMixed
|
isQualityProfileIdMixed,
|
||||||
|
isMinimumAvailabilityMixed
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
min-width: 185px;
|
min-width: 185px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.minimumAvailability,
|
||||||
.qualityProfile {
|
.qualityProfile {
|
||||||
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
||||||
|
|
||||||
|
@ -34,6 +34,13 @@ function ImportMovieHeader(props) {
|
|||||||
Monitor
|
Monitor
|
||||||
</VirtualTableHeaderCell>
|
</VirtualTableHeaderCell>
|
||||||
|
|
||||||
|
<VirtualTableHeaderCell
|
||||||
|
className={styles.minimumAvailability}
|
||||||
|
name="minimumAvailability"
|
||||||
|
>
|
||||||
|
Min Availability
|
||||||
|
</VirtualTableHeaderCell>
|
||||||
|
|
||||||
<VirtualTableHeaderCell
|
<VirtualTableHeaderCell
|
||||||
className={styles.qualityProfile}
|
className={styles.qualityProfile}
|
||||||
name="qualityProfileId"
|
name="qualityProfileId"
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
min-width: 185px;
|
min-width: 185px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.minimumAvailability,
|
||||||
.qualityProfile {
|
.qualityProfile {
|
||||||
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ function ImportMovieRow(props) {
|
|||||||
id,
|
id,
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId,
|
qualityProfileId,
|
||||||
|
minimumAvailability,
|
||||||
selectedMovie,
|
selectedMovie,
|
||||||
isExistingMovie,
|
isExistingMovie,
|
||||||
isSelected,
|
isSelected,
|
||||||
@ -44,6 +45,15 @@ function ImportMovieRow(props) {
|
|||||||
/>
|
/>
|
||||||
</VirtualTableRowCell>
|
</VirtualTableRowCell>
|
||||||
|
|
||||||
|
<VirtualTableRowCell className={styles.minimumAvailability}>
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.AVAILABILITY_SELECT}
|
||||||
|
name="minimumAvailability"
|
||||||
|
value={minimumAvailability}
|
||||||
|
onChange={onInputChange}
|
||||||
|
/>
|
||||||
|
</VirtualTableRowCell>
|
||||||
|
|
||||||
<VirtualTableRowCell className={styles.qualityProfile}>
|
<VirtualTableRowCell className={styles.qualityProfile}>
|
||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.QUALITY_PROFILE_SELECT}
|
type={inputTypes.QUALITY_PROFILE_SELECT}
|
||||||
@ -68,6 +78,7 @@ ImportMovieRow.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,
|
||||||
|
minimumAvailability: PropTypes.string.isRequired,
|
||||||
selectedMovie: PropTypes.object,
|
selectedMovie: PropTypes.object,
|
||||||
isExistingMovie: PropTypes.bool.isRequired,
|
isExistingMovie: PropTypes.bool.isRequired,
|
||||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
|
@ -15,13 +15,15 @@ class ImportMovieTable extends Component {
|
|||||||
unmappedFolders,
|
unmappedFolders,
|
||||||
defaultMonitor,
|
defaultMonitor,
|
||||||
defaultQualityProfileId,
|
defaultQualityProfileId,
|
||||||
|
defaultMinimumAvailability,
|
||||||
onMovieLookup,
|
onMovieLookup,
|
||||||
onSetImportMovieValue
|
onSetImportMovieValue
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const values = {
|
const values = {
|
||||||
monitor: defaultMonitor,
|
monitor: defaultMonitor,
|
||||||
qualityProfileId: defaultQualityProfileId
|
qualityProfileId: defaultQualityProfileId,
|
||||||
|
minimumAvailability: defaultMinimumAvailability
|
||||||
};
|
};
|
||||||
|
|
||||||
unmappedFolders.forEach((unmappedFolder) => {
|
unmappedFolders.forEach((unmappedFolder) => {
|
||||||
@ -165,6 +167,7 @@ ImportMovieTable.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,
|
||||||
|
defaultMinimumAvailability: PropTypes.string,
|
||||||
allSelected: PropTypes.bool.isRequired,
|
allSelected: PropTypes.bool.isRequired,
|
||||||
allUnselected: PropTypes.bool.isRequired,
|
allUnselected: PropTypes.bool.isRequired,
|
||||||
selectedState: PropTypes.object.isRequired,
|
selectedState: PropTypes.object.isRequired,
|
||||||
|
@ -14,6 +14,7 @@ function createMapStateToProps() {
|
|||||||
return {
|
return {
|
||||||
defaultMonitor: addMovie.defaults.monitor,
|
defaultMonitor: addMovie.defaults.monitor,
|
||||||
defaultQualityProfileId: addMovie.defaults.qualityProfileId,
|
defaultQualityProfileId: addMovie.defaults.qualityProfileId,
|
||||||
|
defaultMinimumAvailability: addMovie.defaults.minimumAvailability,
|
||||||
items: importMovie.items,
|
items: importMovie.items,
|
||||||
isSmallScreen: dimensions.isSmallScreen,
|
isSmallScreen: dimensions.isSmallScreen,
|
||||||
allMovies
|
allMovies
|
||||||
|
54
frontend/src/Components/Form/AvailabilitySelectInput.js
Normal file
54
frontend/src/Components/Form/AvailabilitySelectInput.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import SelectInput from './SelectInput';
|
||||||
|
|
||||||
|
const availabilityOptions = [
|
||||||
|
{ key: 'announced', value: 'Announced' },
|
||||||
|
{ key: 'inCinemas', value: 'In Cinemas' },
|
||||||
|
{ key: 'released', value: 'Released' },
|
||||||
|
{ key: 'preDB', value: 'PreDB' }
|
||||||
|
];
|
||||||
|
|
||||||
|
function AvailabilitySelectInput(props) {
|
||||||
|
const values = [...availabilityOptions];
|
||||||
|
|
||||||
|
const {
|
||||||
|
includeNoChange,
|
||||||
|
includeMixed
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
if (includeNoChange) {
|
||||||
|
values.unshift({
|
||||||
|
key: 'noChange',
|
||||||
|
value: 'No Change',
|
||||||
|
disabled: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (includeMixed) {
|
||||||
|
values.unshift({
|
||||||
|
key: 'mixed',
|
||||||
|
value: '(Mixed)',
|
||||||
|
disabled: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SelectInput
|
||||||
|
{...props}
|
||||||
|
values={values}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
AvailabilitySelectInput.propTypes = {
|
||||||
|
includeNoChange: PropTypes.bool.isRequired,
|
||||||
|
includeMixed: PropTypes.bool.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
AvailabilitySelectInput.defaultProps = {
|
||||||
|
includeNoChange: false,
|
||||||
|
includeMixed: false
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AvailabilitySelectInput;
|
@ -3,6 +3,7 @@ import React from 'react';
|
|||||||
import { inputTypes } from 'Helpers/Props';
|
import { inputTypes } from 'Helpers/Props';
|
||||||
import Link from 'Components/Link/Link';
|
import Link from 'Components/Link/Link';
|
||||||
import AutoCompleteInput from './AutoCompleteInput';
|
import AutoCompleteInput from './AutoCompleteInput';
|
||||||
|
import AvailabilitySelectInput from './AvailabilitySelectInput';
|
||||||
import CaptchaInputConnector from './CaptchaInputConnector';
|
import CaptchaInputConnector from './CaptchaInputConnector';
|
||||||
import CheckInput from './CheckInput';
|
import CheckInput from './CheckInput';
|
||||||
import DeviceInputConnector from './DeviceInputConnector';
|
import DeviceInputConnector from './DeviceInputConnector';
|
||||||
@ -26,6 +27,9 @@ function getComponent(type) {
|
|||||||
case inputTypes.AUTO_COMPLETE:
|
case inputTypes.AUTO_COMPLETE:
|
||||||
return AutoCompleteInput;
|
return AutoCompleteInput;
|
||||||
|
|
||||||
|
case inputTypes.AVAILABILITY_SELECT:
|
||||||
|
return AvailabilitySelectInput;
|
||||||
|
|
||||||
case inputTypes.CAPTCHA:
|
case inputTypes.CAPTCHA:
|
||||||
return CaptchaInputConnector;
|
return CaptchaInputConnector;
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
export const AUTO_COMPLETE = 'autoComplete';
|
export const AUTO_COMPLETE = 'autoComplete';
|
||||||
|
export const AVAILABILITY_SELECT = 'availabilitySelect';
|
||||||
export const CAPTCHA = 'captcha';
|
export const CAPTCHA = 'captcha';
|
||||||
export const CHECK = 'check';
|
export const CHECK = 'check';
|
||||||
export const DEVICE = 'device';
|
export const DEVICE = 'device';
|
||||||
@ -16,6 +17,7 @@ export const TEXT_TAG = 'textTag';
|
|||||||
|
|
||||||
export const all = [
|
export const all = [
|
||||||
AUTO_COMPLETE,
|
AUTO_COMPLETE,
|
||||||
|
AVAILABILITY_SELECT,
|
||||||
CAPTCHA,
|
CAPTCHA,
|
||||||
CHECK,
|
CHECK,
|
||||||
DEVICE,
|
DEVICE,
|
||||||
|
@ -69,6 +69,7 @@ class EditMovieModalContent extends Component {
|
|||||||
const {
|
const {
|
||||||
monitored,
|
monitored,
|
||||||
qualityProfileId,
|
qualityProfileId,
|
||||||
|
minimumAvailability,
|
||||||
// Id,
|
// Id,
|
||||||
path,
|
path,
|
||||||
tags
|
tags
|
||||||
@ -96,6 +97,17 @@ class EditMovieModalContent extends Component {
|
|||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>Minimum Availability</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.AVAILABILITY_SELECT}
|
||||||
|
name="minimumAvailability"
|
||||||
|
{...minimumAvailability}
|
||||||
|
onChange={onInputChange}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>Quality Profile</FormLabel>
|
<FormLabel>Quality Profile</FormLabel>
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ function createMapStateToProps() {
|
|||||||
const movieSettings = _.pick(movie, [
|
const movieSettings = _.pick(movie, [
|
||||||
'monitored',
|
'monitored',
|
||||||
'qualityProfileId',
|
'qualityProfileId',
|
||||||
|
'minimumAvailability',
|
||||||
'path',
|
'path',
|
||||||
'tags'
|
'tags'
|
||||||
]);
|
]);
|
||||||
|
@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { kinds } from 'Helpers/Props';
|
import { kinds } from 'Helpers/Props';
|
||||||
import SelectInput from 'Components/Form/SelectInput';
|
import SelectInput from 'Components/Form/SelectInput';
|
||||||
|
import AvailabilitySelectInput from 'Components/Form/AvailabilitySelectInput';
|
||||||
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 SpinnerButton from 'Components/Link/SpinnerButton';
|
import SpinnerButton from 'Components/Link/SpinnerButton';
|
||||||
@ -25,6 +26,7 @@ class MovieEditorFooter extends Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
monitored: NO_CHANGE,
|
monitored: NO_CHANGE,
|
||||||
qualityProfileId: NO_CHANGE,
|
qualityProfileId: NO_CHANGE,
|
||||||
|
minimumAvailability: NO_CHANGE,
|
||||||
rootFolderPath: NO_CHANGE,
|
rootFolderPath: NO_CHANGE,
|
||||||
savingTags: false,
|
savingTags: false,
|
||||||
isDeleteMovieModalOpen: false,
|
isDeleteMovieModalOpen: false,
|
||||||
@ -44,6 +46,7 @@ class MovieEditorFooter extends Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
monitored: NO_CHANGE,
|
monitored: NO_CHANGE,
|
||||||
qualityProfileId: NO_CHANGE,
|
qualityProfileId: NO_CHANGE,
|
||||||
|
minimumAvailability: NO_CHANGE,
|
||||||
rootFolderPath: NO_CHANGE,
|
rootFolderPath: NO_CHANGE,
|
||||||
savingTags: false
|
savingTags: false
|
||||||
});
|
});
|
||||||
@ -140,6 +143,7 @@ class MovieEditorFooter extends Component {
|
|||||||
const {
|
const {
|
||||||
monitored,
|
monitored,
|
||||||
qualityProfileId,
|
qualityProfileId,
|
||||||
|
minimumAvailability,
|
||||||
rootFolderPath,
|
rootFolderPath,
|
||||||
savingTags,
|
savingTags,
|
||||||
isTagsModalOpen,
|
isTagsModalOpen,
|
||||||
@ -186,6 +190,21 @@ class MovieEditorFooter extends Component {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.inputContainer}>
|
||||||
|
<MovieEditorFooterLabel
|
||||||
|
label="Minimum Availability"
|
||||||
|
isSaving={isSaving && minimumAvailability !== NO_CHANGE}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<AvailabilitySelectInput
|
||||||
|
name="minimumAvailability"
|
||||||
|
value={minimumAvailability}
|
||||||
|
includeNoChange={true}
|
||||||
|
isDisabled={!selectedCount}
|
||||||
|
onChange={this.onInputChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className={styles.inputContainer}>
|
<div className={styles.inputContainer}>
|
||||||
<MovieEditorFooterLabel
|
<MovieEditorFooterLabel
|
||||||
label="Root Folder"
|
label="Root Folder"
|
||||||
|
@ -10,6 +10,12 @@
|
|||||||
flex: 4 0 110px;
|
flex: 4 0 110px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.minimumAvailability {
|
||||||
|
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
||||||
|
|
||||||
|
flex: 0 0 140px;
|
||||||
|
}
|
||||||
|
|
||||||
.studio {
|
.studio {
|
||||||
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
||||||
|
|
||||||
|
@ -62,15 +62,19 @@ class MovieIndexHeader extends Component {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMovieEditorActive && name === 'select') {
|
if (name === 'select') {
|
||||||
return (
|
if (isMovieEditorActive) {
|
||||||
<VirtualTableSelectAllHeaderCell
|
return (
|
||||||
key={name}
|
<VirtualTableSelectAllHeaderCell
|
||||||
allSelected={allSelected}
|
key={name}
|
||||||
allUnselected={allUnselected}
|
allSelected={allSelected}
|
||||||
onSelectAllChange={onSelectAllChange}
|
allUnselected={allUnselected}
|
||||||
/>
|
onSelectAllChange={onSelectAllChange}
|
||||||
);
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name === 'actions') {
|
if (name === 'actions') {
|
||||||
|
@ -1,23 +1,36 @@
|
|||||||
.status {
|
.cell {
|
||||||
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status {
|
||||||
|
composes: cell;
|
||||||
|
|
||||||
flex: 0 0 60px;
|
flex: 0 0 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sortTitle {
|
.sortTitle {
|
||||||
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
composes: cell;
|
||||||
|
|
||||||
flex: 4 0 110px;
|
flex: 4 0 110px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.minimumAvailability {
|
||||||
|
composes: cell;
|
||||||
|
|
||||||
|
flex: 0 0 140px;
|
||||||
|
}
|
||||||
|
|
||||||
.studio {
|
.studio {
|
||||||
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
composes: cell;
|
||||||
|
|
||||||
flex: 2 0 90px;
|
flex: 2 0 90px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.qualityProfileId {
|
.qualityProfileId {
|
||||||
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
composes: cell;
|
||||||
|
|
||||||
flex: 1 0 125px;
|
flex: 1 0 125px;
|
||||||
}
|
}
|
||||||
@ -26,44 +39,44 @@
|
|||||||
.inCinemas,
|
.inCinemas,
|
||||||
.physicalRelease,
|
.physicalRelease,
|
||||||
.genres {
|
.genres {
|
||||||
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
composes: cell;
|
||||||
|
|
||||||
flex: 0 0 180px;
|
flex: 0 0 180px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.movieStatus,
|
.movieStatus,
|
||||||
.certification {
|
.certification {
|
||||||
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
composes: cell;
|
||||||
|
|
||||||
flex: 0 0 100px;
|
flex: 0 0 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.path {
|
.path {
|
||||||
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
composes: cell;
|
||||||
|
|
||||||
flex: 1 0 150px;
|
flex: 1 0 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sizeOnDisk {
|
.sizeOnDisk {
|
||||||
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
composes: cell;
|
||||||
|
|
||||||
flex: 0 0 120px;
|
flex: 0 0 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ratings {
|
.ratings {
|
||||||
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
composes: cell;
|
||||||
|
|
||||||
flex: 0 0 80px;
|
flex: 0 0 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tags {
|
.tags {
|
||||||
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
composes: cell;
|
||||||
|
|
||||||
flex: 1 0 60px;
|
flex: 1 0 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions {
|
.actions {
|
||||||
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
|
composes: cell;
|
||||||
|
|
||||||
flex: 0 1 90px;
|
flex: 0 1 90px;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
// import getProgressBarKind from 'Utilities/Series/getProgressBarKind';
|
// import getProgressBarKind from 'Utilities/Series/getProgressBarKind';
|
||||||
|
import titleCase from 'Utilities/String/titleCase';
|
||||||
import { icons } from 'Helpers/Props';
|
import { icons } from 'Helpers/Props';
|
||||||
import HeartRating from 'Components/HeartRating';
|
import HeartRating from 'Components/HeartRating';
|
||||||
import IconButton from 'Components/Link/IconButton';
|
import IconButton from 'Components/Link/IconButton';
|
||||||
@ -73,6 +74,7 @@ class MovieIndexRow extends Component {
|
|||||||
added,
|
added,
|
||||||
inCinemas,
|
inCinemas,
|
||||||
physicalRelease,
|
physicalRelease,
|
||||||
|
minimumAvailability,
|
||||||
path,
|
path,
|
||||||
genres,
|
genres,
|
||||||
ratings,
|
ratings,
|
||||||
@ -201,6 +203,17 @@ class MovieIndexRow extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name === 'minimumAvailability') {
|
||||||
|
return (
|
||||||
|
<VirtualTableRowCell
|
||||||
|
key={name}
|
||||||
|
className={styles[name]}
|
||||||
|
>
|
||||||
|
{titleCase(minimumAvailability)}
|
||||||
|
</VirtualTableRowCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (name === 'path') {
|
if (name === 'path') {
|
||||||
return (
|
return (
|
||||||
<VirtualTableRowCell
|
<VirtualTableRowCell
|
||||||
@ -343,6 +356,7 @@ MovieIndexRow.propTypes = {
|
|||||||
added: PropTypes.string,
|
added: PropTypes.string,
|
||||||
inCinemas: PropTypes.string,
|
inCinemas: PropTypes.string,
|
||||||
physicalRelease: PropTypes.string,
|
physicalRelease: PropTypes.string,
|
||||||
|
minimumAvailability: PropTypes.string.isRequired,
|
||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
genres: PropTypes.arrayOf(PropTypes.string).isRequired,
|
genres: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||||
ratings: PropTypes.object.isRequired,
|
ratings: PropTypes.object.isRequired,
|
||||||
|
@ -45,6 +45,7 @@ export const defaultState = {
|
|||||||
rootFolderPath: '',
|
rootFolderPath: '',
|
||||||
monitor: 'true',
|
monitor: 'true',
|
||||||
qualityProfileId: 0,
|
qualityProfileId: 0,
|
||||||
|
minimumAvailability: 'announced',
|
||||||
tags: []
|
tags: []
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -108,6 +108,12 @@ export const defaultState = {
|
|||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: false
|
isVisible: false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'minimumAvailability',
|
||||||
|
label: 'Min Availability',
|
||||||
|
isSortable: true,
|
||||||
|
isVisible: false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'path',
|
name: 'path',
|
||||||
label: 'Path',
|
label: 'Path',
|
||||||
|
@ -4,6 +4,7 @@ function getNewMovie(movie, payload) {
|
|||||||
rootFolderPath,
|
rootFolderPath,
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId,
|
qualityProfileId,
|
||||||
|
minimumAvailability,
|
||||||
tags,
|
tags,
|
||||||
searchForMovie = false
|
searchForMovie = false
|
||||||
} = payload;
|
} = payload;
|
||||||
@ -15,6 +16,7 @@ function getNewMovie(movie, payload) {
|
|||||||
movie.addOptions = addOptions;
|
movie.addOptions = addOptions;
|
||||||
movie.monitored = monitor === 'true';
|
movie.monitored = monitor === 'true';
|
||||||
movie.qualityProfileId = qualityProfileId;
|
movie.qualityProfileId = qualityProfileId;
|
||||||
|
movie.minimumAvailability = minimumAvailability;
|
||||||
movie.rootFolderPath = rootFolderPath;
|
movie.rootFolderPath = rootFolderPath;
|
||||||
movie.tags = tags;
|
movie.tags = tags;
|
||||||
|
|
||||||
|
@ -41,6 +41,11 @@ private object SaveAll()
|
|||||||
movie.ProfileId = resource.QualityProfileId.Value;
|
movie.ProfileId = resource.QualityProfileId.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (resource.MinimumAvailability.HasValue)
|
||||||
|
{
|
||||||
|
movie.MinimumAvailability = resource.MinimumAvailability.Value;
|
||||||
|
}
|
||||||
|
|
||||||
if (resource.RootFolderPath.IsNotNullOrWhiteSpace())
|
if (resource.RootFolderPath.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
movie.RootFolderPath = resource.RootFolderPath;
|
movie.RootFolderPath = resource.RootFolderPath;
|
||||||
|
@ -9,6 +9,7 @@ public class MovieEditorResource
|
|||||||
public List<int> MovieIds { get; set; }
|
public List<int> MovieIds { get; set; }
|
||||||
public bool? Monitored { get; set; }
|
public bool? Monitored { get; set; }
|
||||||
public int? QualityProfileId { get; set; }
|
public int? QualityProfileId { get; set; }
|
||||||
|
public MovieStatusType? MinimumAvailability { get; set; }
|
||||||
public string RootFolderPath { get; set; }
|
public string RootFolderPath { get; set; }
|
||||||
public List<int> Tags { get; set; }
|
public List<int> Tags { get; set; }
|
||||||
public ApplyTags ApplyTags { get; set; }
|
public ApplyTags ApplyTags { get; set; }
|
||||||
|
Loading…
Reference in New Issue
Block a user