Quality Profile
@@ -174,8 +202,10 @@ ImportMovieFooter.propTypes = {
isLookingUpMovie: PropTypes.bool.isRequired,
defaultMonitor: PropTypes.string.isRequired,
defaultQualityProfileId: PropTypes.number,
+ defaultMinimumAvailability: PropTypes.string,
isMonitorMixed: PropTypes.bool.isRequired,
isQualityProfileIdMixed: PropTypes.bool.isRequired,
+ isMinimumAvailabilityMixed: PropTypes.bool.isRequired,
onInputChange: PropTypes.func.isRequired,
onImportPress: PropTypes.func.isRequired,
onCancelLookupPress: PropTypes.func.isRequired
diff --git a/frontend/src/AddMovie/ImportMovie/Import/ImportMovieFooterConnector.js b/frontend/src/AddMovie/ImportMovie/Import/ImportMovieFooterConnector.js
index 28f991b0d..3c0c58325 100644
--- a/frontend/src/AddMovie/ImportMovie/Import/ImportMovieFooterConnector.js
+++ b/frontend/src/AddMovie/ImportMovie/Import/ImportMovieFooterConnector.js
@@ -18,7 +18,8 @@ function createMapStateToProps() {
(addMovie, importMovie, selectedIds) => {
const {
monitor: defaultMonitor,
- qualityProfileId: defaultQualityProfileId
+ qualityProfileId: defaultQualityProfileId,
+ minimumAvailability: defaultMinimumAvailability
} = addMovie.defaults;
const {
@@ -29,6 +30,7 @@ function createMapStateToProps() {
const isMonitorMixed = isMixed(items, selectedIds, defaultMonitor, 'monitor');
const isQualityProfileIdMixed = isMixed(items, selectedIds, defaultQualityProfileId, 'qualityProfileId');
+ const isMinimumAvailabilityMixed = isMixed(items, selectedIds, defaultMinimumAvailability, 'minimumAvailability');
return {
selectedCount: selectedIds.length,
@@ -36,8 +38,10 @@ function createMapStateToProps() {
isImporting,
defaultMonitor,
defaultQualityProfileId,
+ defaultMinimumAvailability,
isMonitorMixed,
- isQualityProfileIdMixed
+ isQualityProfileIdMixed,
+ isMinimumAvailabilityMixed
};
}
);
diff --git a/frontend/src/AddMovie/ImportMovie/Import/ImportMovieHeader.css b/frontend/src/AddMovie/ImportMovie/Import/ImportMovieHeader.css
index 2682c188d..dec42e592 100644
--- a/frontend/src/AddMovie/ImportMovie/Import/ImportMovieHeader.css
+++ b/frontend/src/AddMovie/ImportMovie/Import/ImportMovieHeader.css
@@ -11,6 +11,7 @@
min-width: 185px;
}
+.minimumAvailability,
.qualityProfile {
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
diff --git a/frontend/src/AddMovie/ImportMovie/Import/ImportMovieHeader.js b/frontend/src/AddMovie/ImportMovie/Import/ImportMovieHeader.js
index 7b59b409f..eaf61ccf3 100644
--- a/frontend/src/AddMovie/ImportMovie/Import/ImportMovieHeader.js
+++ b/frontend/src/AddMovie/ImportMovie/Import/ImportMovieHeader.js
@@ -34,6 +34,13 @@ function ImportMovieHeader(props) {
Monitor
+
+ Min Availability
+
+
+
+
+
+
{
@@ -165,6 +167,7 @@ ImportMovieTable.propTypes = {
unmappedFolders: PropTypes.arrayOf(PropTypes.object),
defaultMonitor: PropTypes.string.isRequired,
defaultQualityProfileId: PropTypes.number,
+ defaultMinimumAvailability: PropTypes.string,
allSelected: PropTypes.bool.isRequired,
allUnselected: PropTypes.bool.isRequired,
selectedState: PropTypes.object.isRequired,
diff --git a/frontend/src/AddMovie/ImportMovie/Import/ImportMovieTableConnector.js b/frontend/src/AddMovie/ImportMovie/Import/ImportMovieTableConnector.js
index 42499c703..2717336c9 100644
--- a/frontend/src/AddMovie/ImportMovie/Import/ImportMovieTableConnector.js
+++ b/frontend/src/AddMovie/ImportMovie/Import/ImportMovieTableConnector.js
@@ -14,6 +14,7 @@ function createMapStateToProps() {
return {
defaultMonitor: addMovie.defaults.monitor,
defaultQualityProfileId: addMovie.defaults.qualityProfileId,
+ defaultMinimumAvailability: addMovie.defaults.minimumAvailability,
items: importMovie.items,
isSmallScreen: dimensions.isSmallScreen,
allMovies
diff --git a/frontend/src/Components/Form/AvailabilitySelectInput.js b/frontend/src/Components/Form/AvailabilitySelectInput.js
new file mode 100644
index 000000000..af9bdb2d6
--- /dev/null
+++ b/frontend/src/Components/Form/AvailabilitySelectInput.js
@@ -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 (
+
+ );
+}
+
+AvailabilitySelectInput.propTypes = {
+ includeNoChange: PropTypes.bool.isRequired,
+ includeMixed: PropTypes.bool.isRequired
+};
+
+AvailabilitySelectInput.defaultProps = {
+ includeNoChange: false,
+ includeMixed: false
+};
+
+export default AvailabilitySelectInput;
diff --git a/frontend/src/Components/Form/FormInputGroup.js b/frontend/src/Components/Form/FormInputGroup.js
index 5cbbc1f37..06a4de336 100644
--- a/frontend/src/Components/Form/FormInputGroup.js
+++ b/frontend/src/Components/Form/FormInputGroup.js
@@ -3,6 +3,7 @@ import React from 'react';
import { inputTypes } from 'Helpers/Props';
import Link from 'Components/Link/Link';
import AutoCompleteInput from './AutoCompleteInput';
+import AvailabilitySelectInput from './AvailabilitySelectInput';
import CaptchaInputConnector from './CaptchaInputConnector';
import CheckInput from './CheckInput';
import DeviceInputConnector from './DeviceInputConnector';
@@ -26,6 +27,9 @@ function getComponent(type) {
case inputTypes.AUTO_COMPLETE:
return AutoCompleteInput;
+ case inputTypes.AVAILABILITY_SELECT:
+ return AvailabilitySelectInput;
+
case inputTypes.CAPTCHA:
return CaptchaInputConnector;
diff --git a/frontend/src/Helpers/Props/inputTypes.js b/frontend/src/Helpers/Props/inputTypes.js
index 92a7d2d39..5f42c4c3c 100644
--- a/frontend/src/Helpers/Props/inputTypes.js
+++ b/frontend/src/Helpers/Props/inputTypes.js
@@ -1,4 +1,5 @@
export const AUTO_COMPLETE = 'autoComplete';
+export const AVAILABILITY_SELECT = 'availabilitySelect';
export const CAPTCHA = 'captcha';
export const CHECK = 'check';
export const DEVICE = 'device';
@@ -16,6 +17,7 @@ export const TEXT_TAG = 'textTag';
export const all = [
AUTO_COMPLETE,
+ AVAILABILITY_SELECT,
CAPTCHA,
CHECK,
DEVICE,
diff --git a/frontend/src/Movie/Edit/EditMovieModalContent.js b/frontend/src/Movie/Edit/EditMovieModalContent.js
index 40cdf816e..7a27800e3 100644
--- a/frontend/src/Movie/Edit/EditMovieModalContent.js
+++ b/frontend/src/Movie/Edit/EditMovieModalContent.js
@@ -69,6 +69,7 @@ class EditMovieModalContent extends Component {
const {
monitored,
qualityProfileId,
+ minimumAvailability,
// Id,
path,
tags
@@ -96,6 +97,17 @@ class EditMovieModalContent extends Component {
/>
+
+ Minimum Availability
+
+
+
+
Quality Profile
diff --git a/frontend/src/Movie/Edit/EditMovieModalContentConnector.js b/frontend/src/Movie/Edit/EditMovieModalContentConnector.js
index a5bd045a1..11971a69e 100644
--- a/frontend/src/Movie/Edit/EditMovieModalContentConnector.js
+++ b/frontend/src/Movie/Edit/EditMovieModalContentConnector.js
@@ -39,6 +39,7 @@ function createMapStateToProps() {
const movieSettings = _.pick(movie, [
'monitored',
'qualityProfileId',
+ 'minimumAvailability',
'path',
'tags'
]);
diff --git a/frontend/src/Movie/Editor/MovieEditorFooter.js b/frontend/src/Movie/Editor/MovieEditorFooter.js
index 501b72a81..3ce3ae4ca 100644
--- a/frontend/src/Movie/Editor/MovieEditorFooter.js
+++ b/frontend/src/Movie/Editor/MovieEditorFooter.js
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { kinds } from 'Helpers/Props';
import SelectInput from 'Components/Form/SelectInput';
+import AvailabilitySelectInput from 'Components/Form/AvailabilitySelectInput';
import QualityProfileSelectInputConnector from 'Components/Form/QualityProfileSelectInputConnector';
import RootFolderSelectInputConnector from 'Components/Form/RootFolderSelectInputConnector';
import SpinnerButton from 'Components/Link/SpinnerButton';
@@ -25,6 +26,7 @@ class MovieEditorFooter extends Component {
this.state = {
monitored: NO_CHANGE,
qualityProfileId: NO_CHANGE,
+ minimumAvailability: NO_CHANGE,
rootFolderPath: NO_CHANGE,
savingTags: false,
isDeleteMovieModalOpen: false,
@@ -44,6 +46,7 @@ class MovieEditorFooter extends Component {
this.setState({
monitored: NO_CHANGE,
qualityProfileId: NO_CHANGE,
+ minimumAvailability: NO_CHANGE,
rootFolderPath: NO_CHANGE,
savingTags: false
});
@@ -140,6 +143,7 @@ class MovieEditorFooter extends Component {
const {
monitored,
qualityProfileId,
+ minimumAvailability,
rootFolderPath,
savingTags,
isTagsModalOpen,
@@ -186,6 +190,21 @@ class MovieEditorFooter extends Component {
/>
+
+
- );
+ if (name === 'select') {
+ if (isMovieEditorActive) {
+ return (
+
+ );
+ }
+
+ return null;
}
if (name === 'actions') {
diff --git a/frontend/src/Movie/Index/Table/MovieIndexRow.css b/frontend/src/Movie/Index/Table/MovieIndexRow.css
index 2585cd57b..03179a787 100644
--- a/frontend/src/Movie/Index/Table/MovieIndexRow.css
+++ b/frontend/src/Movie/Index/Table/MovieIndexRow.css
@@ -1,23 +1,36 @@
-.status {
+.cell {
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
+ display: flex;
+ align-items: center;
+}
+
+.status {
+ composes: cell;
+
flex: 0 0 60px;
}
.sortTitle {
- composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
+ composes: cell;
flex: 4 0 110px;
}
+.minimumAvailability {
+ composes: cell;
+
+ flex: 0 0 140px;
+}
+
.studio {
- composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
+ composes: cell;
flex: 2 0 90px;
}
.qualityProfileId {
- composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
+ composes: cell;
flex: 1 0 125px;
}
@@ -26,44 +39,44 @@
.inCinemas,
.physicalRelease,
.genres {
- composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
+ composes: cell;
flex: 0 0 180px;
}
.movieStatus,
.certification {
- composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
+ composes: cell;
flex: 0 0 100px;
}
.path {
- composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
+ composes: cell;
flex: 1 0 150px;
}
.sizeOnDisk {
- composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
+ composes: cell;
flex: 0 0 120px;
}
.ratings {
- composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
+ composes: cell;
flex: 0 0 80px;
}
.tags {
- composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
+ composes: cell;
flex: 1 0 60px;
}
.actions {
- composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
+ composes: cell;
flex: 0 1 90px;
}
diff --git a/frontend/src/Movie/Index/Table/MovieIndexRow.js b/frontend/src/Movie/Index/Table/MovieIndexRow.js
index 939016435..c7c47bdc7 100644
--- a/frontend/src/Movie/Index/Table/MovieIndexRow.js
+++ b/frontend/src/Movie/Index/Table/MovieIndexRow.js
@@ -1,6 +1,7 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
// import getProgressBarKind from 'Utilities/Series/getProgressBarKind';
+import titleCase from 'Utilities/String/titleCase';
import { icons } from 'Helpers/Props';
import HeartRating from 'Components/HeartRating';
import IconButton from 'Components/Link/IconButton';
@@ -73,6 +74,7 @@ class MovieIndexRow extends Component {
added,
inCinemas,
physicalRelease,
+ minimumAvailability,
path,
genres,
ratings,
@@ -201,6 +203,17 @@ class MovieIndexRow extends Component {
);
}
+ if (name === 'minimumAvailability') {
+ return (
+
+ {titleCase(minimumAvailability)}
+
+ );
+ }
+
if (name === 'path') {
return (
MovieIds { get; set; }
public bool? Monitored { get; set; }
public int? QualityProfileId { get; set; }
+ public MovieStatusType? MinimumAvailability { get; set; }
public string RootFolderPath { get; set; }
public List Tags { get; set; }
public ApplyTags ApplyTags { get; set; }