From 0e1474579a1365ff714d5654e075735f6b36402f Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Thu, 9 Jan 2025 19:34:14 -0800 Subject: [PATCH] Convert Monitoring Options to TypeScript --- .../MonitoringOptionModalConnector.js | 39 ----- .../MonitoringOptionsModal.js | 25 --- .../MonitoringOptionsModal.tsx | 27 ++++ .../MonitoringOptionsModalContent.js | 151 ------------------ .../MonitoringOptionsModalContent.tsx | 107 +++++++++++++ .../MonitoringOptionsModalContentConnector.js | 77 --------- 6 files changed, 134 insertions(+), 292 deletions(-) delete mode 100644 frontend/src/Series/MonitoringOptions/MonitoringOptionModalConnector.js delete mode 100644 frontend/src/Series/MonitoringOptions/MonitoringOptionsModal.js create mode 100644 frontend/src/Series/MonitoringOptions/MonitoringOptionsModal.tsx delete mode 100644 frontend/src/Series/MonitoringOptions/MonitoringOptionsModalContent.js create mode 100644 frontend/src/Series/MonitoringOptions/MonitoringOptionsModalContent.tsx delete mode 100644 frontend/src/Series/MonitoringOptions/MonitoringOptionsModalContentConnector.js diff --git a/frontend/src/Series/MonitoringOptions/MonitoringOptionModalConnector.js b/frontend/src/Series/MonitoringOptions/MonitoringOptionModalConnector.js deleted file mode 100644 index 44b412613..000000000 --- a/frontend/src/Series/MonitoringOptions/MonitoringOptionModalConnector.js +++ /dev/null @@ -1,39 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { clearPendingChanges } from 'Store/Actions/baseActions'; -import MonitoringOptionsModal from './MonitoringOptionsModal'; - -const mapDispatchToProps = { - clearPendingChanges -}; - -class MonitoringOptionsModalConnector extends Component { - - // - // Listeners - - onModalClose = () => { - this.props.clearPendingChanges({ section: 'series' }); - this.props.onModalClose(); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -MonitoringOptionsModalConnector.propTypes = { - onModalClose: PropTypes.func.isRequired, - clearPendingChanges: PropTypes.func.isRequired -}; - -export default connect(undefined, mapDispatchToProps)(MonitoringOptionsModalConnector); diff --git a/frontend/src/Series/MonitoringOptions/MonitoringOptionsModal.js b/frontend/src/Series/MonitoringOptions/MonitoringOptionsModal.js deleted file mode 100644 index 4071e7f9a..000000000 --- a/frontend/src/Series/MonitoringOptions/MonitoringOptionsModal.js +++ /dev/null @@ -1,25 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import Modal from 'Components/Modal/Modal'; -import MonitoringOptionsModalContentConnector from './MonitoringOptionsModalContentConnector'; - -function MonitoringOptionsModal({ isOpen, onModalClose, ...otherProps }) { - return ( - - - - ); -} - -MonitoringOptionsModal.propTypes = { - isOpen: PropTypes.bool.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default MonitoringOptionsModal; diff --git a/frontend/src/Series/MonitoringOptions/MonitoringOptionsModal.tsx b/frontend/src/Series/MonitoringOptions/MonitoringOptionsModal.tsx new file mode 100644 index 000000000..48323de50 --- /dev/null +++ b/frontend/src/Series/MonitoringOptions/MonitoringOptionsModal.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import Modal from 'Components/Modal/Modal'; +import MonitoringOptionsModalContent, { + MonitoringOptionsModalContentProps, +} from './MonitoringOptionsModalContent'; + +interface MonitoringOptionsModalProps + extends MonitoringOptionsModalContentProps { + isOpen: boolean; +} + +function MonitoringOptionsModal({ + isOpen, + onModalClose, + ...otherProps +}: MonitoringOptionsModalProps) { + return ( + + + + ); +} + +export default MonitoringOptionsModal; diff --git a/frontend/src/Series/MonitoringOptions/MonitoringOptionsModalContent.js b/frontend/src/Series/MonitoringOptions/MonitoringOptionsModalContent.js deleted file mode 100644 index 61024f1c4..000000000 --- a/frontend/src/Series/MonitoringOptions/MonitoringOptionsModalContent.js +++ /dev/null @@ -1,151 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import SeriesMonitoringOptionsPopoverContent from 'AddSeries/SeriesMonitoringOptionsPopoverContent'; -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 Icon from 'Components/Icon'; -import Button from 'Components/Link/Button'; -import SpinnerButton from 'Components/Link/SpinnerButton'; -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 Popover from 'Components/Tooltip/Popover'; -import { icons, inputTypes, tooltipPositions } from 'Helpers/Props'; -import translate from 'Utilities/String/translate'; -import styles from './MonitoringOptionsModalContent.css'; - -const NO_CHANGE = 'noChange'; - -class MonitoringOptionsModalContent extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this.state = { - monitor: NO_CHANGE - }; - } - - componentDidUpdate(prevProps) { - const { - isSaving, - saveError - } = this.props; - - if (prevProps.isSaving && !isSaving && !saveError) { - this.setState({ - monitor: NO_CHANGE - }); - } - } - - onInputChange = ({ name, value }) => { - this.setState({ [name]: value }); - }; - - // - // Listeners - - onSavePress = () => { - const { - onSavePress - } = this.props; - const { - monitor - } = this.state; - - if (monitor !== NO_CHANGE) { - onSavePress({ monitor }); - } - }; - - // - // Render - - render() { - const { - isSaving, - onInputChange, - onModalClose, - ...otherProps - } = this.props; - - const { - monitor - } = this.state; - - return ( - - - {translate('MonitorSeries')} - - - -
- - - {translate('Monitoring')} - - - } - title={translate('MonitoringOptions')} - body={} - position={tooltipPositions.RIGHT} - /> - - - - -
-
- - - - - - {translate('Save')} - - -
- ); - } -} - -MonitoringOptionsModalContent.propTypes = { - seriesId: PropTypes.number.isRequired, - saveError: PropTypes.object, - isSaving: PropTypes.bool.isRequired, - onInputChange: PropTypes.func.isRequired, - onSavePress: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -MonitoringOptionsModalContent.defaultProps = { - isSaving: false -}; - -export default MonitoringOptionsModalContent; diff --git a/frontend/src/Series/MonitoringOptions/MonitoringOptionsModalContent.tsx b/frontend/src/Series/MonitoringOptions/MonitoringOptionsModalContent.tsx new file mode 100644 index 000000000..15780bc20 --- /dev/null +++ b/frontend/src/Series/MonitoringOptions/MonitoringOptionsModalContent.tsx @@ -0,0 +1,107 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import SeriesMonitoringOptionsPopoverContent from 'AddSeries/SeriesMonitoringOptionsPopoverContent'; +import AppState from 'App/State/AppState'; +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 Icon from 'Components/Icon'; +import Button from 'Components/Link/Button'; +import SpinnerButton from 'Components/Link/SpinnerButton'; +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 Popover from 'Components/Tooltip/Popover'; +import usePrevious from 'Helpers/Hooks/usePrevious'; +import { icons, tooltipPositions } from 'Helpers/Props'; +import { updateSeriesMonitor } from 'Store/Actions/seriesActions'; +import { InputChanged } from 'typings/inputs'; +import translate from 'Utilities/String/translate'; +import styles from './MonitoringOptionsModalContent.css'; + +const NO_CHANGE = 'noChange'; + +export interface MonitoringOptionsModalContentProps { + seriesId: number; + onModalClose: () => void; +} + +function MonitoringOptionsModalContent({ + seriesId, + onModalClose, +}: MonitoringOptionsModalContentProps) { + const dispatch = useDispatch(); + const { isSaving, saveError } = useSelector( + (state: AppState) => state.series + ); + + const [monitor, setMonitor] = useState(NO_CHANGE); + const wasSaving = usePrevious(isSaving); + + const handleMonitorChange = useCallback(({ value }: InputChanged) => { + setMonitor(value); + }, []); + + const handleSavePress = useCallback(() => { + if (monitor === NO_CHANGE) { + return; + } + + dispatch( + updateSeriesMonitor({ + seriesIds: [seriesId], + monitor, + shouldFetchEpisodesAfterUpdate: true, + }) + ); + }, [monitor, seriesId, dispatch]); + + useEffect(() => { + if (!isSaving && wasSaving && !saveError) { + onModalClose(); + } + }, [isSaving, wasSaving, saveError, onModalClose]); + + return ( + + {translate('MonitorSeries')} + + +
+ + + {translate('Monitoring')} + + } + title={translate('MonitoringOptions')} + body={} + position={tooltipPositions.RIGHT} + /> + + + + +
+
+ + + + + + {translate('Save')} + + +
+ ); +} + +export default MonitoringOptionsModalContent; diff --git a/frontend/src/Series/MonitoringOptions/MonitoringOptionsModalContentConnector.js b/frontend/src/Series/MonitoringOptions/MonitoringOptionsModalContentConnector.js deleted file mode 100644 index 1d4772a14..000000000 --- a/frontend/src/Series/MonitoringOptions/MonitoringOptionsModalContentConnector.js +++ /dev/null @@ -1,77 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { updateSeriesMonitor } from 'Store/Actions/seriesActions'; -import MonitoringOptionsModalContent from './MonitoringOptionsModalContent'; - -function createMapStateToProps() { - return createSelector( - (state) => state.series, - (seriesState) => { - const { - isSaving, - saveError - } = seriesState; - - return { - isSaving, - saveError - }; - } - ); -} - -const mapDispatchToProps = { - dispatchUpdateMonitoringOptions: updateSeriesMonitor -}; - -class MonitoringOptionsModalContentConnector extends Component { - - // - // Lifecycle - - componentDidUpdate(prevProps, prevState) { - if (prevProps.isSaving && !this.props.isSaving && !this.props.saveError) { - this.props.onModalClose(true); - } - } - - // - // Listeners - - onInputChange = ({ name, value }) => { - this.setState({ name, value }); - }; - - onSavePress = ({ monitor }) => { - this.props.dispatchUpdateMonitoringOptions({ - seriesIds: [this.props.seriesId], - monitor, - shouldFetchEpisodesAfterUpdate: true - }); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -MonitoringOptionsModalContentConnector.propTypes = { - seriesId: PropTypes.number.isRequired, - isSaving: PropTypes.bool.isRequired, - saveError: PropTypes.object, - dispatchUpdateMonitoringOptions: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(MonitoringOptionsModalContentConnector);