|
|
|
import React, { useCallback, useState } from 'react';
|
|
|
|
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 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 } from 'Helpers/Props';
|
|
|
|
import MoveMovieModal from 'Movie/MoveMovie/MoveMovieModal';
|
|
|
|
import translate from 'Utilities/String/translate';
|
|
|
|
import styles from './EditMoviesModalContent.css';
|
|
|
|
|
|
|
|
interface SavePayload {
|
|
|
|
monitored?: boolean;
|
|
|
|
qualityProfileId?: number;
|
|
|
|
minimumAvailability?: string;
|
|
|
|
rootFolderPath?: string;
|
|
|
|
moveFiles?: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface EditMoviesModalContentProps {
|
|
|
|
movieIds: number[];
|
|
|
|
onSavePress(payload: object): void;
|
|
|
|
onModalClose(): void;
|
|
|
|
}
|
|
|
|
|
|
|
|
const NO_CHANGE = 'noChange';
|
|
|
|
|
|
|
|
const monitoredOptions = [
|
|
|
|
{
|
|
|
|
key: NO_CHANGE,
|
|
|
|
get value() {
|
|
|
|
return translate('NoChange');
|
|
|
|
},
|
|
|
|
disabled: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'monitored',
|
|
|
|
get value() {
|
|
|
|
return translate('Monitored');
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'unmonitored',
|
|
|
|
get value() {
|
|
|
|
return translate('Unmonitored');
|
|
|
|
},
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
function EditMoviesModalContent(props: EditMoviesModalContentProps) {
|
|
|
|
const { movieIds, onSavePress, onModalClose } = props;
|
|
|
|
|
|
|
|
const [monitored, setMonitored] = useState(NO_CHANGE);
|
|
|
|
const [qualityProfileId, setQualityProfileId] = useState<string | number>(
|
|
|
|
NO_CHANGE
|
|
|
|
);
|
|
|
|
const [minimumAvailability, setMinimumAvailability] = useState(NO_CHANGE);
|
|
|
|
const [rootFolderPath, setRootFolderPath] = useState(NO_CHANGE);
|
|
|
|
const [isConfirmMoveModalOpen, setIsConfirmMoveModalOpen] = useState(false);
|
|
|
|
|
|
|
|
const save = useCallback(
|
|
|
|
(moveFiles: boolean) => {
|
|
|
|
let hasChanges = false;
|
|
|
|
const payload: SavePayload = {};
|
|
|
|
|
|
|
|
if (monitored !== NO_CHANGE) {
|
|
|
|
hasChanges = true;
|
|
|
|
payload.monitored = monitored === 'monitored';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qualityProfileId !== NO_CHANGE) {
|
|
|
|
hasChanges = true;
|
|
|
|
payload.qualityProfileId = qualityProfileId as number;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (minimumAvailability !== NO_CHANGE) {
|
|
|
|
hasChanges = true;
|
|
|
|
payload.minimumAvailability = minimumAvailability as string;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rootFolderPath !== NO_CHANGE) {
|
|
|
|
hasChanges = true;
|
|
|
|
payload.rootFolderPath = rootFolderPath;
|
|
|
|
payload.moveFiles = moveFiles;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hasChanges) {
|
|
|
|
onSavePress(payload);
|
|
|
|
}
|
|
|
|
|
|
|
|
onModalClose();
|
|
|
|
},
|
|
|
|
[
|
|
|
|
monitored,
|
|
|
|
qualityProfileId,
|
|
|
|
minimumAvailability,
|
|
|
|
rootFolderPath,
|
|
|
|
onSavePress,
|
|
|
|
onModalClose,
|
|
|
|
]
|
|
|
|
);
|
|
|
|
|
|
|
|
const onInputChange = useCallback(
|
|
|
|
({ name, value }: { name: string; value: string }) => {
|
|
|
|
switch (name) {
|
|
|
|
case 'monitored':
|
|
|
|
setMonitored(value);
|
|
|
|
break;
|
|
|
|
case 'qualityProfileId':
|
|
|
|
setQualityProfileId(value);
|
|
|
|
break;
|
|
|
|
case 'minimumAvailability':
|
|
|
|
setMinimumAvailability(value);
|
|
|
|
break;
|
|
|
|
case 'rootFolderPath':
|
|
|
|
setRootFolderPath(value);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
console.warn('EditMoviesModalContent Unknown Input');
|
|
|
|
}
|
|
|
|
},
|
|
|
|
[setMonitored]
|
|
|
|
);
|
|
|
|
|
|
|
|
const onSavePressWrapper = useCallback(() => {
|
|
|
|
if (rootFolderPath === NO_CHANGE) {
|
|
|
|
save(false);
|
|
|
|
} else {
|
|
|
|
setIsConfirmMoveModalOpen(true);
|
|
|
|
}
|
|
|
|
}, [rootFolderPath, save]);
|
|
|
|
|
|
|
|
const onCancelPress = useCallback(() => {
|
|
|
|
setIsConfirmMoveModalOpen(false);
|
|
|
|
}, [setIsConfirmMoveModalOpen]);
|
|
|
|
|
|
|
|
const onDoNotMoveMoviePress = useCallback(() => {
|
|
|
|
setIsConfirmMoveModalOpen(false);
|
|
|
|
save(false);
|
|
|
|
}, [setIsConfirmMoveModalOpen, save]);
|
|
|
|
|
|
|
|
const onMoveMoviePress = useCallback(() => {
|
|
|
|
setIsConfirmMoveModalOpen(false);
|
|
|
|
save(true);
|
|
|
|
}, [setIsConfirmMoveModalOpen, save]);
|
|
|
|
|
|
|
|
const selectedCount = movieIds.length;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<ModalContent onModalClose={onModalClose}>
|
|
|
|
<ModalHeader>{translate('EditSelectedMovies')}</ModalHeader>
|
|
|
|
|
|
|
|
<ModalBody>
|
|
|
|
<FormGroup>
|
|
|
|
<FormLabel>{translate('Monitored')}</FormLabel>
|
|
|
|
|
|
|
|
<FormInputGroup
|
|
|
|
type={inputTypes.SELECT}
|
|
|
|
name="monitored"
|
|
|
|
value={monitored}
|
|
|
|
values={monitoredOptions}
|
|
|
|
onChange={onInputChange}
|
|
|
|
/>
|
|
|
|
</FormGroup>
|
|
|
|
|
|
|
|
<FormGroup>
|
|
|
|
<FormLabel>{translate('QualityProfile')}</FormLabel>
|
|
|
|
|
|
|
|
<FormInputGroup
|
|
|
|
type={inputTypes.QUALITY_PROFILE_SELECT}
|
|
|
|
name="qualityProfileId"
|
|
|
|
value={qualityProfileId}
|
|
|
|
includeNoChange={true}
|
|
|
|
includeNoChangeDisabled={false}
|
|
|
|
onChange={onInputChange}
|
|
|
|
/>
|
|
|
|
</FormGroup>
|
|
|
|
|
|
|
|
<FormGroup>
|
|
|
|
<FormLabel>{translate('MinimumAvailability')}</FormLabel>
|
|
|
|
|
|
|
|
<FormInputGroup
|
|
|
|
type={inputTypes.AVAILABILITY_SELECT}
|
|
|
|
name="minimumAvailability"
|
|
|
|
value={minimumAvailability}
|
|
|
|
includeNoChange={true}
|
|
|
|
includeNoChangeDisabled={false}
|
|
|
|
onChange={onInputChange}
|
|
|
|
/>
|
|
|
|
</FormGroup>
|
|
|
|
|
|
|
|
<FormGroup>
|
|
|
|
<FormLabel>{translate('RootFolder')}</FormLabel>
|
|
|
|
|
|
|
|
<FormInputGroup
|
|
|
|
type={inputTypes.ROOT_FOLDER_SELECT}
|
|
|
|
name="rootFolderPath"
|
|
|
|
value={rootFolderPath}
|
|
|
|
includeNoChange={true}
|
|
|
|
includeNoChangeDisabled={false}
|
|
|
|
selectedValueOptions={{ includeFreeSpace: false }}
|
|
|
|
helpText={
|
|
|
|
'Moving movies to the same root folder can be used to rename movie folders to match updated title or naming format'
|
|
|
|
}
|
|
|
|
onChange={onInputChange}
|
|
|
|
/>
|
|
|
|
</FormGroup>
|
|
|
|
</ModalBody>
|
|
|
|
|
|
|
|
<ModalFooter className={styles.modalFooter}>
|
|
|
|
<div className={styles.selected}>
|
|
|
|
{translate('MoviesSelectedInterp', [selectedCount])}
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div>
|
|
|
|
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
|
|
|
|
|
|
|
<Button onPress={onSavePressWrapper}>
|
|
|
|
{translate('ApplyChanges')}
|
|
|
|
</Button>
|
|
|
|
</div>
|
|
|
|
</ModalFooter>
|
|
|
|
|
|
|
|
<MoveMovieModal
|
|
|
|
isOpen={isConfirmMoveModalOpen}
|
|
|
|
destinationRootFolder={rootFolderPath}
|
|
|
|
onModalClose={onCancelPress}
|
|
|
|
onSavePress={onDoNotMoveMoviePress}
|
|
|
|
onMoveMoviePress={onMoveMoviePress}
|
|
|
|
/>
|
|
|
|
</ModalContent>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export default EditMoviesModalContent;
|