From 7b4bd50f187850cf0d0ae93d968f28084f997c48 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Thu, 9 Jan 2025 19:19:15 -0800 Subject: [PATCH] Convert MoveSeriesModal to TypeScript --- frontend/src/Series/Edit/EditSeriesModal.tsx | 10 +- .../Series/Edit/EditSeriesModalConnector.js | 40 ------ .../Series/Edit/EditSeriesModalContent.tsx | 11 +- .../Edit/EditSeriesModalContentConnector.js | 118 ------------------ .../src/Series/MoveSeries/MoveSeriesModal.js | 86 ------------- .../src/Series/MoveSeries/MoveSeriesModal.tsx | 76 +++++++++++ 6 files changed, 90 insertions(+), 251 deletions(-) delete mode 100644 frontend/src/Series/Edit/EditSeriesModalConnector.js delete mode 100644 frontend/src/Series/Edit/EditSeriesModalContentConnector.js delete mode 100644 frontend/src/Series/MoveSeries/MoveSeriesModal.js create mode 100644 frontend/src/Series/MoveSeries/MoveSeriesModal.tsx diff --git a/frontend/src/Series/Edit/EditSeriesModal.tsx b/frontend/src/Series/Edit/EditSeriesModal.tsx index 5aabeb556..9ebf52e54 100644 --- a/frontend/src/Series/Edit/EditSeriesModal.tsx +++ b/frontend/src/Series/Edit/EditSeriesModal.tsx @@ -2,8 +2,9 @@ import React, { useCallback } from 'react'; import { useDispatch } from 'react-redux'; import Modal from 'Components/Modal/Modal'; import { clearPendingChanges } from 'Store/Actions/baseActions'; -import { EditSeriesModalContentProps } from './EditSeriesModalContent'; -import EditSeriesModalContentConnector from './EditSeriesModalContentConnector'; +import EditSeriesModalContent, { + EditSeriesModalContentProps, +} from './EditSeriesModalContent'; interface EditSeriesModalProps extends EditSeriesModalContentProps { isOpen: boolean; @@ -23,10 +24,7 @@ function EditSeriesModal({ return ( - + ); } diff --git a/frontend/src/Series/Edit/EditSeriesModalConnector.js b/frontend/src/Series/Edit/EditSeriesModalConnector.js deleted file mode 100644 index ed1e5c6a6..000000000 --- a/frontend/src/Series/Edit/EditSeriesModalConnector.js +++ /dev/null @@ -1,40 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { clearPendingChanges } from 'Store/Actions/baseActions'; -import EditSeriesModal from './EditSeriesModal'; - -const mapDispatchToProps = { - clearPendingChanges -}; - -class EditSeriesModalConnector extends Component { - - // - // Listeners - - onModalClose = () => { - this.props.clearPendingChanges({ section: 'series' }); - this.props.onModalClose(); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -EditSeriesModalConnector.propTypes = { - ...EditSeriesModal.propTypes, - onModalClose: PropTypes.func.isRequired, - clearPendingChanges: PropTypes.func.isRequired -}; - -export default connect(undefined, mapDispatchToProps)(EditSeriesModalConnector); diff --git a/frontend/src/Series/Edit/EditSeriesModalContent.tsx b/frontend/src/Series/Edit/EditSeriesModalContent.tsx index 86318c65a..9bd8fd54f 100644 --- a/frontend/src/Series/Edit/EditSeriesModalContent.tsx +++ b/frontend/src/Series/Edit/EditSeriesModalContent.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import SeriesMonitorNewItemsOptionsPopoverContent from 'AddSeries/SeriesMonitorNewItemsOptionsPopoverContent'; import AppState from 'App/State/AppState'; @@ -15,6 +15,7 @@ import ModalContent from 'Components/Modal/ModalContent'; import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; import Popover from 'Components/Tooltip/Popover'; +import usePrevious from 'Helpers/Hooks/usePrevious'; import { icons, inputTypes, @@ -59,6 +60,8 @@ function EditSeriesModalContent({ (state: AppState) => state.series ); + const wasSaving = usePrevious(isSaving); + const [isRootFolderModalOpen, setIsRootFolderModalOpen] = useState(false); const [rootFolderPath, setRootFolderPath] = useState(initialRootFolderPath); @@ -151,6 +154,12 @@ function EditSeriesModalContent({ ); }, [seriesId, dispatch]); + useEffect(() => { + if (!isSaving && wasSaving && !saveError) { + onModalClose(); + } + }, [isSaving, wasSaving, saveError, onModalClose]); + return ( {translate('EditSeriesModalHeader', { title })} diff --git a/frontend/src/Series/Edit/EditSeriesModalContentConnector.js b/frontend/src/Series/Edit/EditSeriesModalContentConnector.js deleted file mode 100644 index b4a53685a..000000000 --- a/frontend/src/Series/Edit/EditSeriesModalContentConnector.js +++ /dev/null @@ -1,118 +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 { saveSeries, setSeriesValue } from 'Store/Actions/seriesActions'; -import createSeriesSelector from 'Store/Selectors/createSeriesSelector'; -import selectSettings from 'Store/Selectors/selectSettings'; -import EditSeriesModalContent from './EditSeriesModalContent'; - -function createIsPathChangingSelector() { - return createSelector( - (state) => state.series.pendingChanges, - createSeriesSelector(), - (pendingChanges, series) => { - const path = pendingChanges.path; - - if (path == null) { - return false; - } - - return series.path !== path; - } - ); -} - -function createMapStateToProps() { - return createSelector( - (state) => state.series, - createSeriesSelector(), - createIsPathChangingSelector(), - (seriesState, series, isPathChanging) => { - const { - isSaving, - saveError, - pendingChanges - } = seriesState; - - const seriesSettings = _.pick(series, [ - 'monitored', - 'monitorNewItems', - 'seasonFolder', - 'qualityProfileId', - 'seriesType', - 'path', - 'tags' - ]); - - const settings = selectSettings(seriesSettings, pendingChanges, saveError); - - return { - title: series.title, - isSaving, - saveError, - isPathChanging, - originalPath: series.path, - item: settings.settings, - ...settings - }; - } - ); -} - -const mapDispatchToProps = { - dispatchSetSeriesValue: setSeriesValue, - dispatchSaveSeries: saveSeries -}; - -class EditSeriesModalContentConnector extends Component { - - // - // Lifecycle - - componentDidUpdate(prevProps, prevState) { - if (prevProps.isSaving && !this.props.isSaving && !this.props.saveError) { - this.props.onModalClose(); - } - } - - // - // Listeners - - onInputChange = ({ name, value }) => { - this.props.dispatchSetSeriesValue({ name, value }); - }; - - onSavePress = (moveFiles) => { - this.props.dispatchSaveSeries({ - id: this.props.seriesId, - moveFiles - }); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -EditSeriesModalContentConnector.propTypes = { - seriesId: PropTypes.number, - isSaving: PropTypes.bool.isRequired, - saveError: PropTypes.object, - dispatchSetSeriesValue: PropTypes.func.isRequired, - dispatchSaveSeries: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(EditSeriesModalContentConnector); diff --git a/frontend/src/Series/MoveSeries/MoveSeriesModal.js b/frontend/src/Series/MoveSeries/MoveSeriesModal.js deleted file mode 100644 index a2b872806..000000000 --- a/frontend/src/Series/MoveSeries/MoveSeriesModal.js +++ /dev/null @@ -1,86 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import Button from 'Components/Link/Button'; -import Modal from 'Components/Modal/Modal'; -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 { kinds, sizes } from 'Helpers/Props'; -import translate from 'Utilities/String/translate'; -import styles from './MoveSeriesModal.css'; - -function MoveSeriesModal(props) { - const { - originalPath, - destinationPath, - destinationRootFolder, - isOpen, - onModalClose, - onSavePress, - onMoveSeriesPress - } = props; - - if ( - isOpen && - !originalPath && - !destinationPath && - !destinationRootFolder - ) { - console.error('originalPath and destinationPath OR destinationRootFolder must be provided'); - } - - return ( - - - - {translate('MoveFiles')} - - - - { - destinationRootFolder ? - translate('MoveSeriesFoldersToRootFolder', { destinationRootFolder }) : - translate('MoveSeriesFoldersToNewPath', { originalPath, destinationPath }) - } - - - - - - - - - - ); -} - -MoveSeriesModal.propTypes = { - originalPath: PropTypes.string, - destinationPath: PropTypes.string, - destinationRootFolder: PropTypes.string, - isOpen: PropTypes.bool.isRequired, - onModalClose: PropTypes.func.isRequired, - onSavePress: PropTypes.func.isRequired, - onMoveSeriesPress: PropTypes.func.isRequired -}; - -export default MoveSeriesModal; diff --git a/frontend/src/Series/MoveSeries/MoveSeriesModal.tsx b/frontend/src/Series/MoveSeries/MoveSeriesModal.tsx new file mode 100644 index 000000000..0988e312b --- /dev/null +++ b/frontend/src/Series/MoveSeries/MoveSeriesModal.tsx @@ -0,0 +1,76 @@ +import React from 'react'; +import Button from 'Components/Link/Button'; +import Modal from 'Components/Modal/Modal'; +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 { kinds, sizes } from 'Helpers/Props'; +import translate from 'Utilities/String/translate'; +import styles from './MoveSeriesModal.css'; + +interface MoveSeriesModalProps { + originalPath?: string; + destinationPath?: string; + destinationRootFolder?: string; + isOpen: boolean; + onModalClose: () => void; + onSavePress: () => void; + onMoveSeriesPress: () => void; +} + +function MoveSeriesModal({ + originalPath, + destinationPath, + destinationRootFolder, + isOpen, + onModalClose, + onSavePress, + onMoveSeriesPress, +}: MoveSeriesModalProps) { + if (isOpen && !originalPath && !destinationPath && !destinationRootFolder) { + console.error( + 'originalPath and destinationPath OR destinationRootFolder must be provided' + ); + } + + return ( + + + {translate('MoveFiles')} + + + {destinationRootFolder + ? translate('MoveSeriesFoldersToRootFolder', { + destinationRootFolder, + }) + : null} + + {originalPath && destinationPath + ? translate('MoveSeriesFoldersToNewPath', { + originalPath, + destinationPath, + }) + : null} + + + + + + + + + + ); +} + +export default MoveSeriesModal;