From 65bae6a7ce0e642a766aaf262e35d1af6421d3ef Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 4 Jan 2025 11:53:10 -0800 Subject: [PATCH] Convert Notifications to TypeScript --- frontend/src/App/State/SettingsAppState.ts | 4 +- ...onSettings.js => NotificationSettings.tsx} | 8 +- .../Notifications/AddNotificationItem.js | 111 ------- .../Notifications/AddNotificationItem.tsx | 88 ++++++ .../Notifications/AddNotificationModal.js | 25 -- .../Notifications/AddNotificationModal.tsx | 26 ++ .../AddNotificationModalContent.js | 90 ------ .../AddNotificationModalContent.tsx | 79 +++++ .../AddNotificationModalContentConnector.js | 70 ----- .../AddNotificationPresetMenuItem.js | 49 ---- .../AddNotificationPresetMenuItem.tsx | 41 +++ .../Notifications/EditNotificationModal.js | 27 -- .../Notifications/EditNotificationModal.tsx | 44 +++ .../EditNotificationModalConnector.js | 65 ----- .../EditNotificationModalContent.js | 186 ------------ .../EditNotificationModalContent.tsx | 203 +++++++++++++ .../EditNotificationModalContentConnector.js | 93 ------ .../Notifications/Notification.js | 274 ------------------ .../Notifications/Notification.tsx | 179 ++++++++++++ ...entItems.js => NotificationEventItems.tsx} | 99 +++---- .../Notifications/Notifications.js | 118 -------- .../Notifications/Notifications.tsx | 94 ++++++ .../Notifications/NotificationsConnector.js | 63 ---- frontend/src/typings/Notification.ts | 27 ++ 24 files changed, 835 insertions(+), 1228 deletions(-) rename frontend/src/Settings/Notifications/{NotificationSettings.js => NotificationSettings.tsx} (73%) delete mode 100644 frontend/src/Settings/Notifications/Notifications/AddNotificationItem.js create mode 100644 frontend/src/Settings/Notifications/Notifications/AddNotificationItem.tsx delete mode 100644 frontend/src/Settings/Notifications/Notifications/AddNotificationModal.js create mode 100644 frontend/src/Settings/Notifications/Notifications/AddNotificationModal.tsx delete mode 100644 frontend/src/Settings/Notifications/Notifications/AddNotificationModalContent.js create mode 100644 frontend/src/Settings/Notifications/Notifications/AddNotificationModalContent.tsx delete mode 100644 frontend/src/Settings/Notifications/Notifications/AddNotificationModalContentConnector.js delete mode 100644 frontend/src/Settings/Notifications/Notifications/AddNotificationPresetMenuItem.js create mode 100644 frontend/src/Settings/Notifications/Notifications/AddNotificationPresetMenuItem.tsx delete mode 100644 frontend/src/Settings/Notifications/Notifications/EditNotificationModal.js create mode 100644 frontend/src/Settings/Notifications/Notifications/EditNotificationModal.tsx delete mode 100644 frontend/src/Settings/Notifications/Notifications/EditNotificationModalConnector.js delete mode 100644 frontend/src/Settings/Notifications/Notifications/EditNotificationModalContent.js create mode 100644 frontend/src/Settings/Notifications/Notifications/EditNotificationModalContent.tsx delete mode 100644 frontend/src/Settings/Notifications/Notifications/EditNotificationModalContentConnector.js delete mode 100644 frontend/src/Settings/Notifications/Notifications/Notification.js create mode 100644 frontend/src/Settings/Notifications/Notifications/Notification.tsx rename frontend/src/Settings/Notifications/Notifications/{NotificationEventItems.js => NotificationEventItems.tsx} (75%) delete mode 100644 frontend/src/Settings/Notifications/Notifications/Notifications.js create mode 100644 frontend/src/Settings/Notifications/Notifications/Notifications.tsx delete mode 100644 frontend/src/Settings/Notifications/Notifications/NotificationsConnector.js diff --git a/frontend/src/App/State/SettingsAppState.ts b/frontend/src/App/State/SettingsAppState.ts index 12045e4e0..e507fcf57 100644 --- a/frontend/src/App/State/SettingsAppState.ts +++ b/frontend/src/App/State/SettingsAppState.ts @@ -99,7 +99,9 @@ export interface IndexerAppState export interface NotificationAppState extends AppSectionState, - AppSectionDeleteState {} + AppSectionDeleteState, + AppSectionSaveState, + AppSectionSchemaState> {} export interface QualityDefinitionsAppState extends AppSectionState, diff --git a/frontend/src/Settings/Notifications/NotificationSettings.js b/frontend/src/Settings/Notifications/NotificationSettings.tsx similarity index 73% rename from frontend/src/Settings/Notifications/NotificationSettings.js rename to frontend/src/Settings/Notifications/NotificationSettings.tsx index 3195626d4..784b9d638 100644 --- a/frontend/src/Settings/Notifications/NotificationSettings.js +++ b/frontend/src/Settings/Notifications/NotificationSettings.tsx @@ -3,17 +3,15 @@ import PageContent from 'Components/Page/PageContent'; import PageContentBody from 'Components/Page/PageContentBody'; import SettingsToolbar from 'Settings/SettingsToolbar'; import translate from 'Utilities/String/translate'; -import NotificationsConnector from './Notifications/NotificationsConnector'; +import Notifications from './Notifications/Notifications'; function NotificationSettings() { return ( - + - + ); diff --git a/frontend/src/Settings/Notifications/Notifications/AddNotificationItem.js b/frontend/src/Settings/Notifications/Notifications/AddNotificationItem.js deleted file mode 100644 index 4cf8a6d57..000000000 --- a/frontend/src/Settings/Notifications/Notifications/AddNotificationItem.js +++ /dev/null @@ -1,111 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import Button from 'Components/Link/Button'; -import Link from 'Components/Link/Link'; -import Menu from 'Components/Menu/Menu'; -import MenuContent from 'Components/Menu/MenuContent'; -import { sizes } from 'Helpers/Props'; -import translate from 'Utilities/String/translate'; -import AddNotificationPresetMenuItem from './AddNotificationPresetMenuItem'; -import styles from './AddNotificationItem.css'; - -class AddNotificationItem extends Component { - - // - // Listeners - - onNotificationSelect = () => { - const { - implementation - } = this.props; - - this.props.onNotificationSelect({ implementation }); - }; - - // - // Render - - render() { - const { - implementation, - implementationName, - infoLink, - presets, - onNotificationSelect - } = this.props; - - const hasPresets = !!presets && !!presets.length; - - return ( -
- - -
-
- {implementationName} -
- -
- { - hasPresets && - - - - - - - - { - presets.map((preset) => { - return ( - - ); - }) - } - - - - } - - -
-
-
- ); - } -} - -AddNotificationItem.propTypes = { - implementation: PropTypes.string.isRequired, - implementationName: PropTypes.string.isRequired, - infoLink: PropTypes.string.isRequired, - presets: PropTypes.arrayOf(PropTypes.object), - onNotificationSelect: PropTypes.func.isRequired -}; - -export default AddNotificationItem; diff --git a/frontend/src/Settings/Notifications/Notifications/AddNotificationItem.tsx b/frontend/src/Settings/Notifications/Notifications/AddNotificationItem.tsx new file mode 100644 index 000000000..a9bf61fc4 --- /dev/null +++ b/frontend/src/Settings/Notifications/Notifications/AddNotificationItem.tsx @@ -0,0 +1,88 @@ +import React, { useCallback } from 'react'; +import { useDispatch } from 'react-redux'; +import Button from 'Components/Link/Button'; +import Link from 'Components/Link/Link'; +import Menu from 'Components/Menu/Menu'; +import MenuContent from 'Components/Menu/MenuContent'; +import { sizes } from 'Helpers/Props'; +import { selectNotificationSchema } from 'Store/Actions/settingsActions'; +import Notification from 'typings/Notification'; +import translate from 'Utilities/String/translate'; +import AddNotificationPresetMenuItem from './AddNotificationPresetMenuItem'; +import styles from './AddNotificationItem.css'; + +interface AddNotificationItemProps { + implementation: string; + implementationName: string; + infoLink: string; + presets?: Notification[]; + onNotificationSelect: () => void; +} + +function AddNotificationItem({ + implementation, + implementationName, + infoLink, + presets, + onNotificationSelect, +}: AddNotificationItemProps) { + const dispatch = useDispatch(); + const hasPresets = !!presets && !!presets.length; + + const handleNotificationSelect = useCallback(() => { + dispatch( + selectNotificationSchema({ + implementation, + implementationName, + }) + ); + + onNotificationSelect(); + }, [implementation, implementationName, dispatch, onNotificationSelect]); + + return ( +
+ + +
+
{implementationName}
+ +
+ {hasPresets ? ( + + + + + + + + {presets.map((preset) => { + return ( + + ); + })} + + + + ) : null} + + +
+
+
+ ); +} + +export default AddNotificationItem; diff --git a/frontend/src/Settings/Notifications/Notifications/AddNotificationModal.js b/frontend/src/Settings/Notifications/Notifications/AddNotificationModal.js deleted file mode 100644 index 45f5e14b6..000000000 --- a/frontend/src/Settings/Notifications/Notifications/AddNotificationModal.js +++ /dev/null @@ -1,25 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import Modal from 'Components/Modal/Modal'; -import AddNotificationModalContentConnector from './AddNotificationModalContentConnector'; - -function AddNotificationModal({ isOpen, onModalClose, ...otherProps }) { - return ( - - - - ); -} - -AddNotificationModal.propTypes = { - isOpen: PropTypes.bool.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default AddNotificationModal; diff --git a/frontend/src/Settings/Notifications/Notifications/AddNotificationModal.tsx b/frontend/src/Settings/Notifications/Notifications/AddNotificationModal.tsx new file mode 100644 index 000000000..d0bae54be --- /dev/null +++ b/frontend/src/Settings/Notifications/Notifications/AddNotificationModal.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import Modal from 'Components/Modal/Modal'; +import AddNotificationModalContent, { + AddNotificationModalContentProps, +} from './AddNotificationModalContent'; + +interface AddNotificationModalProps extends AddNotificationModalContentProps { + isOpen: boolean; +} + +function AddNotificationModal({ + isOpen, + onModalClose, + ...otherProps +}: AddNotificationModalProps) { + return ( + + + + ); +} + +export default AddNotificationModal; diff --git a/frontend/src/Settings/Notifications/Notifications/AddNotificationModalContent.js b/frontend/src/Settings/Notifications/Notifications/AddNotificationModalContent.js deleted file mode 100644 index f254ecabf..000000000 --- a/frontend/src/Settings/Notifications/Notifications/AddNotificationModalContent.js +++ /dev/null @@ -1,90 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import Alert from 'Components/Alert'; -import Button from 'Components/Link/Button'; -import LoadingIndicator from 'Components/Loading/LoadingIndicator'; -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 } from 'Helpers/Props'; -import translate from 'Utilities/String/translate'; -import AddNotificationItem from './AddNotificationItem'; -import styles from './AddNotificationModalContent.css'; - -class AddNotificationModalContent extends Component { - - // - // Render - - render() { - const { - isSchemaFetching, - isSchemaPopulated, - schemaError, - schema, - onNotificationSelect, - onModalClose - } = this.props; - - return ( - - - {translate('AddConnection')} - - - - { - isSchemaFetching && - - } - - { - !isSchemaFetching && !!schemaError && - - {translate('AddNotificationError')} - - } - - { - isSchemaPopulated && !schemaError && -
-
- { - schema.map((notification) => { - return ( - - ); - }) - } -
-
- } -
- - - -
- ); - } -} - -AddNotificationModalContent.propTypes = { - isSchemaFetching: PropTypes.bool.isRequired, - isSchemaPopulated: PropTypes.bool.isRequired, - schemaError: PropTypes.object, - schema: PropTypes.arrayOf(PropTypes.object).isRequired, - onNotificationSelect: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default AddNotificationModalContent; diff --git a/frontend/src/Settings/Notifications/Notifications/AddNotificationModalContent.tsx b/frontend/src/Settings/Notifications/Notifications/AddNotificationModalContent.tsx new file mode 100644 index 000000000..35761ee46 --- /dev/null +++ b/frontend/src/Settings/Notifications/Notifications/AddNotificationModalContent.tsx @@ -0,0 +1,79 @@ +import React, { useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import AppState from 'App/State/AppState'; +import Alert from 'Components/Alert'; +import FieldSet from 'Components/FieldSet'; +import Button from 'Components/Link/Button'; +import LoadingIndicator from 'Components/Loading/LoadingIndicator'; +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 } from 'Helpers/Props'; +import { fetchNotificationSchema } from 'Store/Actions/settingsActions'; +import translate from 'Utilities/String/translate'; +import AddNotificationItem from './AddNotificationItem'; +import styles from './AddNotificationModalContent.css'; + +export interface AddNotificationModalContentProps { + onNotificationSelect: () => void; + onModalClose: () => void; +} + +function AddNotificationModalContent({ + onNotificationSelect, + onModalClose, +}: AddNotificationModalContentProps) { + const dispatch = useDispatch(); + + const { isSchemaFetching, isSchemaPopulated, schemaError, schema } = + useSelector((state: AppState) => state.settings.notifications); + + useEffect(() => { + dispatch(fetchNotificationSchema()); + }, [dispatch]); + + return ( + + {translate('AddNotification')} + + + {isSchemaFetching ? : null} + + {!isSchemaFetching && !!schemaError ? ( + {translate('AddNotificationError')} + ) : null} + + {isSchemaPopulated && !schemaError ? ( +
+ +
{translate('SupportedNotifications')}
+
{translate('SupportedNotificationsMoreInfo')}
+
+ +
+
+ {schema.map((notification) => { + return ( + + ); + })} +
+
+
+ ) : null} +
+ + + + +
+ ); +} + +export default AddNotificationModalContent; diff --git a/frontend/src/Settings/Notifications/Notifications/AddNotificationModalContentConnector.js b/frontend/src/Settings/Notifications/Notifications/AddNotificationModalContentConnector.js deleted file mode 100644 index 749038688..000000000 --- a/frontend/src/Settings/Notifications/Notifications/AddNotificationModalContentConnector.js +++ /dev/null @@ -1,70 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { fetchNotificationSchema, selectNotificationSchema } from 'Store/Actions/settingsActions'; -import AddNotificationModalContent from './AddNotificationModalContent'; - -function createMapStateToProps() { - return createSelector( - (state) => state.settings.notifications, - (notifications) => { - const { - isSchemaFetching, - isSchemaPopulated, - schemaError, - schema - } = notifications; - - return { - isSchemaFetching, - isSchemaPopulated, - schemaError, - schema - }; - } - ); -} - -const mapDispatchToProps = { - fetchNotificationSchema, - selectNotificationSchema -}; - -class AddNotificationModalContentConnector extends Component { - - // - // Lifecycle - - componentDidMount() { - this.props.fetchNotificationSchema(); - } - - // - // Listeners - - onNotificationSelect = ({ implementation, name }) => { - this.props.selectNotificationSchema({ implementation, presetName: name }); - this.props.onModalClose({ notificationSelected: true }); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -AddNotificationModalContentConnector.propTypes = { - fetchNotificationSchema: PropTypes.func.isRequired, - selectNotificationSchema: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(AddNotificationModalContentConnector); diff --git a/frontend/src/Settings/Notifications/Notifications/AddNotificationPresetMenuItem.js b/frontend/src/Settings/Notifications/Notifications/AddNotificationPresetMenuItem.js deleted file mode 100644 index dd325906f..000000000 --- a/frontend/src/Settings/Notifications/Notifications/AddNotificationPresetMenuItem.js +++ /dev/null @@ -1,49 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import MenuItem from 'Components/Menu/MenuItem'; - -class AddNotificationPresetMenuItem extends Component { - - // - // Listeners - - onPress = () => { - const { - name, - implementation - } = this.props; - - this.props.onPress({ - name, - implementation - }); - }; - - // - // Render - - render() { - const { - name, - implementation, - ...otherProps - } = this.props; - - return ( - - {name} - - ); - } -} - -AddNotificationPresetMenuItem.propTypes = { - name: PropTypes.string.isRequired, - implementation: PropTypes.string.isRequired, - onPress: PropTypes.func.isRequired -}; - -export default AddNotificationPresetMenuItem; diff --git a/frontend/src/Settings/Notifications/Notifications/AddNotificationPresetMenuItem.tsx b/frontend/src/Settings/Notifications/Notifications/AddNotificationPresetMenuItem.tsx new file mode 100644 index 000000000..27e39582c --- /dev/null +++ b/frontend/src/Settings/Notifications/Notifications/AddNotificationPresetMenuItem.tsx @@ -0,0 +1,41 @@ +import React, { useCallback } from 'react'; +import { useDispatch } from 'react-redux'; +import MenuItem from 'Components/Menu/MenuItem'; +import { selectNotificationSchema } from 'Store/Actions/settingsActions'; + +interface AddNotificationPresetMenuItemProps { + name: string; + implementation: string; + implementationName: string; + onPress: () => void; +} + +function AddNotificationPresetMenuItem({ + name, + implementation, + implementationName, + onPress, + ...otherProps +}: AddNotificationPresetMenuItemProps) { + const dispatch = useDispatch(); + + const handlePress = useCallback(() => { + dispatch( + selectNotificationSchema({ + implementation, + implementationName, + presetName: name, + }) + ); + + onPress(); + }, [name, implementation, implementationName, dispatch, onPress]); + + return ( + + {name} + + ); +} + +export default AddNotificationPresetMenuItem; diff --git a/frontend/src/Settings/Notifications/Notifications/EditNotificationModal.js b/frontend/src/Settings/Notifications/Notifications/EditNotificationModal.js deleted file mode 100644 index bc7f4ab18..000000000 --- a/frontend/src/Settings/Notifications/Notifications/EditNotificationModal.js +++ /dev/null @@ -1,27 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import Modal from 'Components/Modal/Modal'; -import { sizes } from 'Helpers/Props'; -import EditNotificationModalContentConnector from './EditNotificationModalContentConnector'; - -function EditNotificationModal({ isOpen, onModalClose, ...otherProps }) { - return ( - - - - ); -} - -EditNotificationModal.propTypes = { - isOpen: PropTypes.bool.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default EditNotificationModal; diff --git a/frontend/src/Settings/Notifications/Notifications/EditNotificationModal.tsx b/frontend/src/Settings/Notifications/Notifications/EditNotificationModal.tsx new file mode 100644 index 000000000..cee73925f --- /dev/null +++ b/frontend/src/Settings/Notifications/Notifications/EditNotificationModal.tsx @@ -0,0 +1,44 @@ +import React, { useCallback } from 'react'; +import { useDispatch } from 'react-redux'; +import Modal from 'Components/Modal/Modal'; +import { sizes } from 'Helpers/Props'; +import { clearPendingChanges } from 'Store/Actions/baseActions'; +import { + cancelSaveNotification, + cancelTestNotification, +} from 'Store/Actions/settingsActions'; +import EditNotificationModalContent, { + EditNotificationModalContentProps, +} from './EditNotificationModalContent'; + +const section = 'settings.notifications'; + +interface EditNotificationModalProps extends EditNotificationModalContentProps { + isOpen: boolean; +} + +function EditNotificationModal({ + isOpen, + onModalClose, + ...otherProps +}: EditNotificationModalProps) { + const dispatch = useDispatch(); + + const handleModalClose = useCallback(() => { + dispatch(clearPendingChanges({ section })); + dispatch(cancelTestNotification({ section })); + dispatch(cancelSaveNotification({ section })); + onModalClose(); + }, [dispatch, onModalClose]); + + return ( + + + + ); +} + +export default EditNotificationModal; diff --git a/frontend/src/Settings/Notifications/Notifications/EditNotificationModalConnector.js b/frontend/src/Settings/Notifications/Notifications/EditNotificationModalConnector.js deleted file mode 100644 index 91070a979..000000000 --- a/frontend/src/Settings/Notifications/Notifications/EditNotificationModalConnector.js +++ /dev/null @@ -1,65 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { clearPendingChanges } from 'Store/Actions/baseActions'; -import { cancelSaveNotification, cancelTestNotification } from 'Store/Actions/settingsActions'; -import EditNotificationModal from './EditNotificationModal'; - -function createMapDispatchToProps(dispatch, props) { - const section = 'settings.notifications'; - - return { - dispatchClearPendingChanges() { - dispatch(clearPendingChanges({ section })); - }, - - dispatchCancelTestNotification() { - dispatch(cancelTestNotification({ section })); - }, - - dispatchCancelSaveNotification() { - dispatch(cancelSaveNotification({ section })); - } - }; -} - -class EditNotificationModalConnector extends Component { - - // - // Listeners - - onModalClose = () => { - this.props.dispatchClearPendingChanges(); - this.props.dispatchCancelTestNotification(); - this.props.dispatchCancelSaveNotification(); - this.props.onModalClose(); - }; - - // - // Render - - render() { - const { - dispatchClearPendingChanges, - dispatchCancelTestNotification, - dispatchCancelSaveNotification, - ...otherProps - } = this.props; - - return ( - - ); - } -} - -EditNotificationModalConnector.propTypes = { - onModalClose: PropTypes.func.isRequired, - dispatchClearPendingChanges: PropTypes.func.isRequired, - dispatchCancelTestNotification: PropTypes.func.isRequired, - dispatchCancelSaveNotification: PropTypes.func.isRequired -}; - -export default connect(null, createMapDispatchToProps)(EditNotificationModalConnector); diff --git a/frontend/src/Settings/Notifications/Notifications/EditNotificationModalContent.js b/frontend/src/Settings/Notifications/Notifications/EditNotificationModalContent.js deleted file mode 100644 index 791030833..000000000 --- a/frontend/src/Settings/Notifications/Notifications/EditNotificationModalContent.js +++ /dev/null @@ -1,186 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import Alert from 'Components/Alert'; -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 ProviderFieldFormGroup from 'Components/Form/ProviderFieldFormGroup'; -import Button from 'Components/Link/Button'; -import SpinnerErrorButton from 'Components/Link/SpinnerErrorButton'; -import LoadingIndicator from 'Components/Loading/LoadingIndicator'; -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, kinds } from 'Helpers/Props'; -import AdvancedSettingsButton from 'Settings/AdvancedSettingsButton'; -import translate from 'Utilities/String/translate'; -import NotificationEventItems from './NotificationEventItems'; -import styles from './EditNotificationModalContent.css'; - -function EditNotificationModalContent(props) { - const { - advancedSettings, - isFetching, - error, - isSaving, - isTesting, - saveError, - item, - onInputChange, - onFieldChange, - onModalClose, - onSavePress, - onTestPress, - onDeleteNotificationPress, - ...otherProps - } = props; - - const { - id, - implementationName, - name, - tags, - fields, - message - } = item; - - return ( - - - {id ? translate('EditConnectionImplementation', { implementationName }) : translate('AddConnectionImplementation', { implementationName })} - - - - { - isFetching && - - } - - { - !isFetching && !!error && - - {translate('AddNotificationError')} - - } - - { - !isFetching && !error && -
- { - !!message && - - {message.value.message} - - } - - - {translate('Name')} - - - - - - - - {translate('Tags')} - - - - - { - fields.map((field) => { - return ( - - ); - }) - } - - - } -
- - { - id && - - } - - - - - {translate('Test')} - - - - - - {translate('Save')} - - -
- ); -} - -EditNotificationModalContent.propTypes = { - advancedSettings: PropTypes.bool.isRequired, - isFetching: PropTypes.bool.isRequired, - error: PropTypes.object, - isSaving: PropTypes.bool.isRequired, - isTesting: PropTypes.bool.isRequired, - saveError: PropTypes.object, - item: PropTypes.object.isRequired, - onInputChange: PropTypes.func.isRequired, - onFieldChange: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired, - onSavePress: PropTypes.func.isRequired, - onTestPress: PropTypes.func.isRequired, - onDeleteNotificationPress: PropTypes.func -}; - -export default EditNotificationModalContent; diff --git a/frontend/src/Settings/Notifications/Notifications/EditNotificationModalContent.tsx b/frontend/src/Settings/Notifications/Notifications/EditNotificationModalContent.tsx new file mode 100644 index 000000000..201d766df --- /dev/null +++ b/frontend/src/Settings/Notifications/Notifications/EditNotificationModalContent.tsx @@ -0,0 +1,203 @@ +import React, { useCallback, useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { NotificationAppState } from 'App/State/SettingsAppState'; +import Alert from 'Components/Alert'; +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 ProviderFieldFormGroup from 'Components/Form/ProviderFieldFormGroup'; +import Button from 'Components/Link/Button'; +import SpinnerErrorButton from 'Components/Link/SpinnerErrorButton'; +import LoadingIndicator from 'Components/Loading/LoadingIndicator'; +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 usePrevious from 'Helpers/Hooks/usePrevious'; +import useShowAdvancedSettings from 'Helpers/Hooks/useShowAdvancedSettings'; +import { inputTypes, kinds } from 'Helpers/Props'; +import AdvancedSettingsButton from 'Settings/AdvancedSettingsButton'; +import { + saveNotification, + setNotificationFieldValue, + setNotificationValue, + testNotification, +} from 'Store/Actions/settingsActions'; +import { createProviderSettingsSelectorHook } from 'Store/Selectors/createProviderSettingsSelector'; +import { InputChanged } from 'typings/inputs'; +import Notification from 'typings/Notification'; +import translate from 'Utilities/String/translate'; +import NotificationEventItems from './NotificationEventItems'; +import styles from './EditNotificationModalContent.css'; + +export interface EditNotificationModalContentProps { + id?: number; + onModalClose: () => void; + onDeleteNotificationPress?: () => void; +} + +function EditNotificationModalContent({ + id, + onModalClose, + onDeleteNotificationPress, +}: EditNotificationModalContentProps) { + const dispatch = useDispatch(); + const showAdvancedSettings = useShowAdvancedSettings(); + + const { + isFetching, + error, + isSaving, + isTesting = false, + saveError, + item, + validationErrors, + validationWarnings, + } = useSelector( + createProviderSettingsSelectorHook( + 'notifications', + id + ) + ); + + const wasSaving = usePrevious(isSaving); + + const { implementationName, name, fields, tags, message } = item; + + const handleInputChange = useCallback( + (change: InputChanged) => { + // @ts-expect-error - actions are not typed + dispatch(setNotificationValue(change)); + }, + [dispatch] + ); + + const handleFieldChange = useCallback( + (change: InputChanged) => { + // @ts-expect-error - actions are not typed + dispatch(setNotificationFieldValue(change)); + }, + [dispatch] + ); + + const handleTestPress = useCallback(() => { + dispatch(testNotification({ id })); + }, [id, dispatch]); + + const handleSavePress = useCallback(() => { + dispatch(saveNotification({ id })); + }, [id, dispatch]); + + useEffect(() => { + if (wasSaving && !isSaving && !saveError) { + onModalClose(); + } + }, [isSaving, wasSaving, saveError, onModalClose]); + + return ( + + + {id + ? translate('EditConnectionImplementation', { implementationName }) + : translate('AddConnectionImplementation', { implementationName })} + + + + {isFetching ? : null} + + {!isFetching && !!error ? ( + {translate('AddNotificationError')} + ) : null} + + {!isFetching && !error ? ( +
+ {message ? ( + + {message.value.message} + + ) : null} + + + {translate('Name')} + + + + + + + + {translate('Tags')} + + + + + {fields.map((field) => { + return ( + + ); + })} + + ) : null} +
+ + + {id ? ( + + ) : null} + + + + + {translate('Test')} + + + + + + {translate('Save')} + + +
+ ); +} + +export default EditNotificationModalContent; diff --git a/frontend/src/Settings/Notifications/Notifications/EditNotificationModalContentConnector.js b/frontend/src/Settings/Notifications/Notifications/EditNotificationModalContentConnector.js deleted file mode 100644 index 45199487b..000000000 --- a/frontend/src/Settings/Notifications/Notifications/EditNotificationModalContentConnector.js +++ /dev/null @@ -1,93 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { - saveNotification, - setNotificationFieldValues, - setNotificationValue, - testNotification -} from 'Store/Actions/settingsActions'; -import createProviderSettingsSelector from 'Store/Selectors/createProviderSettingsSelector'; -import EditNotificationModalContent from './EditNotificationModalContent'; - -function createMapStateToProps() { - return createSelector( - (state) => state.settings.advancedSettings, - createProviderSettingsSelector('notifications'), - (advancedSettings, notification) => { - return { - advancedSettings, - ...notification - }; - } - ); -} - -const mapDispatchToProps = { - setNotificationValue, - setNotificationFieldValues, - saveNotification, - testNotification -}; - -class EditNotificationModalContentConnector extends Component { - - // - // Lifecycle - - componentDidUpdate(prevProps, prevState) { - if (prevProps.isSaving && !this.props.isSaving && !this.props.saveError) { - this.props.onModalClose(); - } - } - - // - // Listeners - - onInputChange = ({ name, value }) => { - this.props.setNotificationValue({ name, value }); - }; - - onFieldChange = ({ name, value, additionalProperties = {} }) => { - this.props.setNotificationFieldValues({ properties: { ...additionalProperties, [name]: value } }); - }; - - onSavePress = () => { - this.props.saveNotification({ id: this.props.id }); - }; - - onTestPress = () => { - this.props.testNotification({ id: this.props.id }); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -EditNotificationModalContentConnector.propTypes = { - id: PropTypes.number, - isFetching: PropTypes.bool.isRequired, - isSaving: PropTypes.bool.isRequired, - saveError: PropTypes.object, - item: PropTypes.object.isRequired, - setNotificationValue: PropTypes.func.isRequired, - setNotificationFieldValues: PropTypes.func.isRequired, - saveNotification: PropTypes.func.isRequired, - testNotification: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(EditNotificationModalContentConnector); diff --git a/frontend/src/Settings/Notifications/Notifications/Notification.js b/frontend/src/Settings/Notifications/Notifications/Notification.js deleted file mode 100644 index b2d0b29b5..000000000 --- a/frontend/src/Settings/Notifications/Notifications/Notification.js +++ /dev/null @@ -1,274 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import Card from 'Components/Card'; -import Label from 'Components/Label'; -import ConfirmModal from 'Components/Modal/ConfirmModal'; -import TagList from 'Components/TagList'; -import { kinds } from 'Helpers/Props'; -import translate from 'Utilities/String/translate'; -import EditNotificationModalConnector from './EditNotificationModalConnector'; -import styles from './Notification.css'; - -class Notification extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this.state = { - isEditNotificationModalOpen: false, - isDeleteNotificationModalOpen: false - }; - } - - // - // Listeners - - onEditNotificationPress = () => { - this.setState({ isEditNotificationModalOpen: true }); - }; - - onEditNotificationModalClose = () => { - this.setState({ isEditNotificationModalOpen: false }); - }; - - onDeleteNotificationPress = () => { - this.setState({ - isEditNotificationModalOpen: false, - isDeleteNotificationModalOpen: true - }); - }; - - onDeleteNotificationModalClose = () => { - this.setState({ isDeleteNotificationModalOpen: false }); - }; - - onConfirmDeleteNotification = () => { - this.props.onConfirmDeleteNotification(this.props.id); - }; - - // - // Render - - render() { - const { - id, - name, - onGrab, - onDownload, - onUpgrade, - onImportComplete, - onRename, - onSeriesAdd, - onSeriesDelete, - onEpisodeFileDelete, - onEpisodeFileDeleteForUpgrade, - onHealthIssue, - onHealthRestored, - onApplicationUpdate, - onManualInteractionRequired, - supportsOnGrab, - supportsOnDownload, - supportsOnUpgrade, - supportsOnImportComplete, - supportsOnRename, - supportsOnSeriesAdd, - supportsOnSeriesDelete, - supportsOnEpisodeFileDelete, - supportsOnEpisodeFileDeleteForUpgrade, - supportsOnHealthIssue, - supportsOnHealthRestored, - supportsOnApplicationUpdate, - supportsOnManualInteractionRequired, - tags, - tagList - } = this.props; - - return ( - -
- {name} -
- - { - supportsOnGrab && onGrab ? - : - null - } - - { - supportsOnDownload && onDownload ? - : - null - } - - { - supportsOnUpgrade && onDownload && onUpgrade ? - : - null - } - - { - supportsOnImportComplete && onImportComplete ? - : - null - } - - { - supportsOnRename && onRename ? - : - null - } - - { - supportsOnHealthIssue && onHealthIssue ? - : - null - } - - { - supportsOnHealthRestored && onHealthRestored ? - : - null - } - - { - supportsOnApplicationUpdate && onApplicationUpdate ? - : - null - } - - { - supportsOnSeriesAdd && onSeriesAdd ? - : - null - } - - { - supportsOnSeriesDelete && onSeriesDelete ? - : - null - } - - { - supportsOnEpisodeFileDelete && onEpisodeFileDelete ? - : - null - } - - { - supportsOnEpisodeFileDeleteForUpgrade && onEpisodeFileDelete && onEpisodeFileDeleteForUpgrade ? - : - null - } - - { - supportsOnManualInteractionRequired && onManualInteractionRequired ? - : - null - } - - { - !onGrab && !onDownload && !onRename && !onImportComplete && !onHealthIssue && !onHealthRestored && !onApplicationUpdate && !onSeriesAdd && !onSeriesDelete && !onEpisodeFileDelete && !onManualInteractionRequired ? - : - null - } - - - - - - -
- ); - } -} - -Notification.propTypes = { - id: PropTypes.number.isRequired, - name: PropTypes.string.isRequired, - onGrab: PropTypes.bool.isRequired, - onDownload: PropTypes.bool.isRequired, - onUpgrade: PropTypes.bool.isRequired, - onImportComplete: PropTypes.bool.isRequired, - onRename: PropTypes.bool.isRequired, - onSeriesAdd: PropTypes.bool.isRequired, - onSeriesDelete: PropTypes.bool.isRequired, - onEpisodeFileDelete: PropTypes.bool.isRequired, - onEpisodeFileDeleteForUpgrade: PropTypes.bool.isRequired, - onHealthIssue: PropTypes.bool.isRequired, - onHealthRestored: PropTypes.bool.isRequired, - onApplicationUpdate: PropTypes.bool.isRequired, - onManualInteractionRequired: PropTypes.bool.isRequired, - supportsOnGrab: PropTypes.bool.isRequired, - supportsOnDownload: PropTypes.bool.isRequired, - supportsOnImportComplete: PropTypes.bool.isRequired, - supportsOnSeriesAdd: PropTypes.bool.isRequired, - supportsOnSeriesDelete: PropTypes.bool.isRequired, - supportsOnEpisodeFileDelete: PropTypes.bool.isRequired, - supportsOnEpisodeFileDeleteForUpgrade: PropTypes.bool.isRequired, - supportsOnUpgrade: PropTypes.bool.isRequired, - supportsOnRename: PropTypes.bool.isRequired, - supportsOnHealthIssue: PropTypes.bool.isRequired, - supportsOnHealthRestored: PropTypes.bool.isRequired, - supportsOnApplicationUpdate: PropTypes.bool.isRequired, - supportsOnManualInteractionRequired: PropTypes.bool.isRequired, - tags: PropTypes.arrayOf(PropTypes.number).isRequired, - tagList: PropTypes.arrayOf(PropTypes.object).isRequired, - onConfirmDeleteNotification: PropTypes.func.isRequired -}; - -export default Notification; diff --git a/frontend/src/Settings/Notifications/Notifications/Notification.tsx b/frontend/src/Settings/Notifications/Notifications/Notification.tsx new file mode 100644 index 000000000..53981d89f --- /dev/null +++ b/frontend/src/Settings/Notifications/Notifications/Notification.tsx @@ -0,0 +1,179 @@ +import React, { useCallback, useState } from 'react'; +import { useDispatch } from 'react-redux'; +import Card from 'Components/Card'; +import Label from 'Components/Label'; +import ConfirmModal from 'Components/Modal/ConfirmModal'; +import TagList from 'Components/TagList'; +import { kinds } from 'Helpers/Props'; +import { deleteNotification } from 'Store/Actions/settingsActions'; +import useTags from 'Tags/useTags'; +import NotificationModel from 'typings/Notification'; +import translate from 'Utilities/String/translate'; +import EditNotificationModal from './EditNotificationModal'; +import styles from './Notification.css'; + +function Notification({ + id, + name, + onGrab, + onDownload, + onUpgrade, + onImportComplete, + onRename, + onSeriesAdd, + onSeriesDelete, + onEpisodeFileDelete, + onEpisodeFileDeleteForUpgrade, + onHealthIssue, + onHealthRestored, + onApplicationUpdate, + onManualInteractionRequired, + supportsOnGrab, + supportsOnDownload, + supportsOnUpgrade, + supportsOnImportComplete, + supportsOnRename, + supportsOnSeriesAdd, + supportsOnSeriesDelete, + supportsOnEpisodeFileDelete, + supportsOnEpisodeFileDeleteForUpgrade, + supportsOnHealthIssue, + supportsOnHealthRestored, + supportsOnApplicationUpdate, + supportsOnManualInteractionRequired, + tags, +}: NotificationModel) { + const dispatch = useDispatch(); + const tagList = useTags(); + + const [isEditNotificationModalOpen, setIsEditNotificationModalOpen] = + useState(false); + const [isDeleteNotificationModalOpen, setIsDeleteNotificationModalOpen] = + useState(false); + + const handleEditNotificationPress = useCallback(() => { + setIsEditNotificationModalOpen(true); + }, []); + + const handleEditNotificationModalClose = useCallback(() => { + setIsEditNotificationModalOpen(false); + }, []); + + const handleDeleteNotificationPress = useCallback(() => { + setIsEditNotificationModalOpen(false); + setIsDeleteNotificationModalOpen(true); + }, []); + + const handleDeleteNotificationModalClose = useCallback(() => { + setIsDeleteNotificationModalOpen(false); + }, []); + + const handleConfirmDeleteNotification = useCallback(() => { + dispatch(deleteNotification({ id })); + }, [id, dispatch]); + + return ( + +
{name}
+ + {supportsOnGrab && onGrab ? ( + + ) : null} + + {supportsOnDownload && onDownload ? ( + + ) : null} + + {supportsOnUpgrade && onDownload && onUpgrade ? ( + + ) : null} + + {supportsOnImportComplete && onImportComplete ? ( + + ) : null} + + {supportsOnRename && onRename ? ( + + ) : null} + + {supportsOnHealthIssue && onHealthIssue ? ( + + ) : null} + + {supportsOnHealthRestored && onHealthRestored ? ( + + ) : null} + + {supportsOnApplicationUpdate && onApplicationUpdate ? ( + + ) : null} + + {supportsOnSeriesAdd && onSeriesAdd ? ( + + ) : null} + + {supportsOnSeriesDelete && onSeriesDelete ? ( + + ) : null} + + {supportsOnEpisodeFileDelete && onEpisodeFileDelete ? ( + + ) : null} + + {supportsOnEpisodeFileDeleteForUpgrade && + onEpisodeFileDelete && + onEpisodeFileDeleteForUpgrade ? ( + + ) : null} + + {supportsOnManualInteractionRequired && onManualInteractionRequired ? ( + + ) : null} + + {!onGrab && + !onDownload && + !onRename && + !onImportComplete && + !onHealthIssue && + !onHealthRestored && + !onApplicationUpdate && + !onSeriesAdd && + !onSeriesDelete && + !onEpisodeFileDelete && + !onManualInteractionRequired ? ( + + ) : null} + + + + + + +
+ ); +} + +export default Notification; diff --git a/frontend/src/Settings/Notifications/Notifications/NotificationEventItems.js b/frontend/src/Settings/Notifications/Notifications/NotificationEventItems.tsx similarity index 75% rename from frontend/src/Settings/Notifications/Notifications/NotificationEventItems.js rename to frontend/src/Settings/Notifications/Notifications/NotificationEventItems.tsx index cb09783b6..afa9c7dd8 100644 --- a/frontend/src/Settings/Notifications/Notifications/NotificationEventItems.js +++ b/frontend/src/Settings/Notifications/Notifications/NotificationEventItems.tsx @@ -1,19 +1,24 @@ -import PropTypes from 'prop-types'; import React from 'react'; import FormGroup from 'Components/Form/FormGroup'; import FormInputGroup from 'Components/Form/FormInputGroup'; import FormInputHelpText from 'Components/Form/FormInputHelpText'; import FormLabel from 'Components/Form/FormLabel'; import { inputTypes } from 'Helpers/Props'; +import { CheckInputChanged } from 'typings/inputs'; +import Notification from 'typings/Notification'; +import { PendingSection } from 'typings/pending'; import translate from 'Utilities/String/translate'; import styles from './NotificationEventItems.css'; -function NotificationEventItems(props) { - const { - item, - onInputChange - } = props; +interface NotificationEventItemsProps { + item: PendingSection; + onInputChange: (change: CheckInputChanged) => void; +} +function NotificationEventItems({ + item, + onInputChange, +}: NotificationEventItemsProps) { const { onGrab, onDownload, @@ -41,7 +46,7 @@ function NotificationEventItems(props) { supportsOnManualInteractionRequired, supportsOnHealthIssue, supportsOnHealthRestored, - includeHealthWarnings + includeHealthWarnings, } = item; return ( @@ -75,19 +80,18 @@ function NotificationEventItems(props) { /> - { - onDownload.value && -
- -
- } + {onDownload.value && ( +
+ +
+ )}
- { - onEpisodeFileDelete.value && -
- -
- } + {onEpisodeFileDelete.value && ( +
+ +
+ )}
- { - (onHealthIssue.value || onHealthRestored.value) && -
- -
- } + {(onHealthIssue.value || onHealthRestored.value) && ( +
+ +
+ )}
{ - this.setState({ isAddNotificationModalOpen: true }); - }; - - onAddNotificationModalClose = ({ notificationSelected = false } = {}) => { - this.setState({ - isAddNotificationModalOpen: false, - isEditNotificationModalOpen: notificationSelected - }); - }; - - onEditNotificationModalClose = () => { - this.setState({ isEditNotificationModalOpen: false }); - }; - - // - // Render - - render() { - const { - items, - tagList, - onConfirmDeleteNotification, - ...otherProps - } = this.props; - - const { - isAddNotificationModalOpen, - isEditNotificationModalOpen - } = this.state; - - return ( -
- -
- { - items.map((item) => { - return ( - - ); - }) - } - - -
- -
-
-
- - - - -
-
- ); - } -} - -Notifications.propTypes = { - isFetching: PropTypes.bool.isRequired, - error: PropTypes.object, - items: PropTypes.arrayOf(PropTypes.object).isRequired, - tagList: PropTypes.arrayOf(PropTypes.object).isRequired, - onConfirmDeleteNotification: PropTypes.func.isRequired -}; - -export default Notifications; diff --git a/frontend/src/Settings/Notifications/Notifications/Notifications.tsx b/frontend/src/Settings/Notifications/Notifications/Notifications.tsx new file mode 100644 index 000000000..b77ab8034 --- /dev/null +++ b/frontend/src/Settings/Notifications/Notifications/Notifications.tsx @@ -0,0 +1,94 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { NotificationAppState } from 'App/State/SettingsAppState'; +import Card from 'Components/Card'; +import FieldSet from 'Components/FieldSet'; +import Icon from 'Components/Icon'; +import PageSectionContent from 'Components/Page/PageSectionContent'; +import { icons } from 'Helpers/Props'; +import { fetchNotifications } from 'Store/Actions/settingsActions'; +import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector'; +import NotificationModel from 'typings/Notification'; +import sortByProp from 'Utilities/Array/sortByProp'; +import translate from 'Utilities/String/translate'; +import AddNotificationModal from './AddNotificationModal'; +import EditNotificationModal from './EditNotificationModal'; +import Notification from './Notification'; +import styles from './Notifications.css'; + +function Notifications() { + const dispatch = useDispatch(); + + const { error, isFetching, isPopulated, items } = useSelector( + createSortedSectionSelector( + 'settings.notifications', + sortByProp('name') + ) + ); + + const [isAddNotificationModalOpen, setIsAddNotificationModalOpen] = + useState(false); + + const [isEditNotificationModalOpen, setIsEditNotificationModalOpen] = + useState(false); + + const handleAddNotificationPress = useCallback(() => { + setIsAddNotificationModalOpen(true); + }, []); + + const handleNotificationSelect = useCallback(() => { + setIsAddNotificationModalOpen(false); + setIsEditNotificationModalOpen(true); + }, []); + + const handleAddNotificationModalClose = useCallback(() => { + setIsAddNotificationModalOpen(false); + }, []); + + const handleEditNotificationModalClose = useCallback(() => { + setIsEditNotificationModalOpen(false); + }, []); + + useEffect(() => { + dispatch(fetchNotifications()); + }, [dispatch]); + + return ( +
+ +
+ {items.map((item) => ( + + ))} + + +
+ +
+
+
+ + + + +
+
+ ); +} + +export default Notifications; diff --git a/frontend/src/Settings/Notifications/Notifications/NotificationsConnector.js b/frontend/src/Settings/Notifications/Notifications/NotificationsConnector.js deleted file mode 100644 index 6351c6f8a..000000000 --- a/frontend/src/Settings/Notifications/Notifications/NotificationsConnector.js +++ /dev/null @@ -1,63 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { deleteNotification, fetchNotifications } from 'Store/Actions/settingsActions'; -import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector'; -import createTagsSelector from 'Store/Selectors/createTagsSelector'; -import sortByProp from 'Utilities/Array/sortByProp'; -import Notifications from './Notifications'; - -function createMapStateToProps() { - return createSelector( - createSortedSectionSelector('settings.notifications', sortByProp('name')), - createTagsSelector(), - (notifications, tagList) => { - return { - ...notifications, - tagList - }; - } - ); -} - -const mapDispatchToProps = { - fetchNotifications, - deleteNotification -}; - -class NotificationsConnector extends Component { - - // - // Lifecycle - - componentDidMount() { - this.props.fetchNotifications(); - } - - // - // Listeners - - onConfirmDeleteNotification = (id) => { - this.props.deleteNotification({ id }); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -NotificationsConnector.propTypes = { - fetchNotifications: PropTypes.func.isRequired, - deleteNotification: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(NotificationsConnector); diff --git a/frontend/src/typings/Notification.ts b/frontend/src/typings/Notification.ts index 12057015b..e7dec26c4 100644 --- a/frontend/src/typings/Notification.ts +++ b/frontend/src/typings/Notification.ts @@ -2,6 +2,33 @@ import Provider from './Provider'; interface Notification extends Provider { enable: boolean; + onGrab: boolean; + onDownload: boolean; + onUpgrade: boolean; + onImportComplete: boolean; + onRename: boolean; + onSeriesAdd: boolean; + onSeriesDelete: boolean; + onEpisodeFileDelete: boolean; + onEpisodeFileDeleteForUpgrade: boolean; + onHealthIssue: boolean; + includeHealthWarnings: boolean; + onHealthRestored: boolean; + onApplicationUpdate: boolean; + onManualInteractionRequired: boolean; + supportsOnGrab: boolean; + supportsOnDownload: boolean; + supportsOnUpgrade: boolean; + supportsOnImportComplete: boolean; + supportsOnRename: boolean; + supportsOnSeriesAdd: boolean; + supportsOnSeriesDelete: boolean; + supportsOnEpisodeFileDelete: boolean; + supportsOnEpisodeFileDeleteForUpgrade: boolean; + supportsOnHealthIssue: boolean; + supportsOnHealthRestored: boolean; + supportsOnApplicationUpdate: boolean; + supportsOnManualInteractionRequired: boolean; tags: number[]; }