diff --git a/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx b/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx index 288bce991..dd1a89ce2 100644 --- a/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx +++ b/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx @@ -12,7 +12,7 @@ import { icons } from 'Helpers/Props'; import DeleteIndexerModal from 'Indexer/Delete/DeleteIndexerModal'; import EditIndexerModalConnector from 'Indexer/Edit/EditIndexerModalConnector'; import createIndexerIndexItemSelector from 'Indexer/Index/createIndexerIndexItemSelector'; -import IndexerInfoModal from 'Indexer/Info/IndexerInfoModal'; +import IndexerTitleLink from 'Indexer/IndexerTitleLink'; import titleCase from 'Utilities/String/titleCase'; import translate from 'Utilities/String/translate'; import CapabilitiesLabel from './CapabilitiesLabel'; @@ -53,7 +53,6 @@ function IndexerIndexRow(props: IndexerIndexRowProps) { fields.find((field) => field.name === 'baseUrl')?.value ?? (Array.isArray(indexerUrls) ? indexerUrls[0] : undefined); - const [isIndexerInfoModalOpen, setIsIndexerInfoModalOpen] = useState(false); const [isEditIndexerModalOpen, setIsEditIndexerModalOpen] = useState(false); const [isDeleteIndexerModalOpen, setIsDeleteIndexerModalOpen] = useState(false); @@ -67,14 +66,6 @@ function IndexerIndexRow(props: IndexerIndexRowProps) { setIsEditIndexerModalOpen(false); }, [setIsEditIndexerModalOpen]); - const onIndexerInfoPress = useCallback(() => { - setIsIndexerInfoModalOpen(true); - }, [setIsIndexerInfoModalOpen]); - - const onIndexerInfoModalClose = useCallback(() => { - setIsIndexerInfoModalOpen(false); - }, [setIsIndexerInfoModalOpen]); - const onDeleteIndexerPress = useCallback(() => { setIsEditIndexerModalOpen(false); setIsDeleteIndexerModalOpen(true); @@ -134,7 +125,10 @@ function IndexerIndexRow(props: IndexerIndexRowProps) { if (name === 'sortName') { return ( - {indexerName} + ); } @@ -204,12 +198,6 @@ function IndexerIndexRow(props: IndexerIndexRowProps) { key={column.name} className={styles[column.name]} > - - {baseUrl ? ( - - { + setIsIndexerInfoModalOpen(true); + }, [setIsIndexerInfoModalOpen]); + + const onIndexerInfoModalClose = useCallback(() => { + setIsIndexerInfoModalOpen(false); + }, [setIsIndexerInfoModalOpen]); + + return ( + + + {indexerName} + + + + + ); +} + +IndexerTitleLink.propTypes = { + indexerName: PropTypes.string.isRequired, +}; + +export default IndexerTitleLink; diff --git a/frontend/src/Indexer/Info/IndexerInfoModal.js b/frontend/src/Indexer/Info/IndexerInfoModal.js deleted file mode 100644 index b83e669cd..000000000 --- a/frontend/src/Indexer/Info/IndexerInfoModal.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 IndexerInfoModalContentConnector from './IndexerInfoModalContentConnector'; - -function IndexerInfoModal({ isOpen, onModalClose, ...otherProps }) { - return ( - - - - ); -} - -IndexerInfoModal.propTypes = { - isOpen: PropTypes.bool.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default IndexerInfoModal; diff --git a/frontend/src/Indexer/Info/IndexerInfoModal.tsx b/frontend/src/Indexer/Info/IndexerInfoModal.tsx new file mode 100644 index 000000000..df2ead86d --- /dev/null +++ b/frontend/src/Indexer/Info/IndexerInfoModal.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import Modal from 'Components/Modal/Modal'; +import { sizes } from 'Helpers/Props'; +import IndexerInfoModalContent from './IndexerInfoModalContent'; + +interface IndexerInfoModalProps { + isOpen: boolean; + indexerId: number; + onModalClose(): void; +} + +function IndexerInfoModal(props: IndexerInfoModalProps) { + const { isOpen, onModalClose, indexerId } = props; + + return ( + + + + ); +} + +export default IndexerInfoModal; diff --git a/frontend/src/Indexer/Info/IndexerInfoModalContent.js b/frontend/src/Indexer/Info/IndexerInfoModalContent.js deleted file mode 100644 index 81d6cdca1..000000000 --- a/frontend/src/Indexer/Info/IndexerInfoModalContent.js +++ /dev/null @@ -1,126 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import DescriptionList from 'Components/DescriptionList/DescriptionList'; -import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'; -import DescriptionListItemDescription from 'Components/DescriptionList/DescriptionListItemDescription'; -import DescriptionListItemTitle from 'Components/DescriptionList/DescriptionListItemTitle'; -import FieldSet from 'Components/FieldSet'; -import Link from 'Components/Link/Link'; -import ModalBody from 'Components/Modal/ModalBody'; -import ModalContent from 'Components/Modal/ModalContent'; -import ModalHeader from 'Components/Modal/ModalHeader'; -import translate from 'Utilities/String/translate'; -import styles from './IndexerInfoModalContent.css'; - -function IndexerInfoModalContent(props) { - const { - id, - name, - description, - encoding, - language, - indexerUrls, - fields, - protocol, - capabilities, - onModalClose - } = props; - - const baseUrl = fields.find((field) => field.name === 'baseUrl')?.value ?? indexerUrls[0]; - - return ( - - - {`${name}`} - - - - - - - - - - - {translate('IndexerSite')} - - {baseUrl} - - {`${protocol === 'usenet' ? 'Newznab' : 'Torznab'} Url`} - - {`${window.location.origin}${window.Prowlarr.urlBase}/${id}/api`} - - - - - - - - - - - - - - - - - - - ); -} - -IndexerInfoModalContent.propTypes = { - id: PropTypes.number.isRequired, - name: PropTypes.string.isRequired, - description: PropTypes.string.isRequired, - encoding: PropTypes.string.isRequired, - language: PropTypes.string.isRequired, - indexerUrls: PropTypes.arrayOf(PropTypes.string).isRequired, - fields: PropTypes.arrayOf(PropTypes.object).isRequired, - protocol: PropTypes.string.isRequired, - capabilities: PropTypes.object.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default IndexerInfoModalContent; diff --git a/frontend/src/Indexer/Info/IndexerInfoModalContent.tsx b/frontend/src/Indexer/Info/IndexerInfoModalContent.tsx new file mode 100644 index 000000000..620234bad --- /dev/null +++ b/frontend/src/Indexer/Info/IndexerInfoModalContent.tsx @@ -0,0 +1,200 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; +import { createSelector } from 'reselect'; +import DescriptionList from 'Components/DescriptionList/DescriptionList'; +import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'; +import DescriptionListItemDescription from 'Components/DescriptionList/DescriptionListItemDescription'; +import DescriptionListItemTitle from 'Components/DescriptionList/DescriptionListItemTitle'; +import FieldSet from 'Components/FieldSet'; +import Label from 'Components/Label'; +import Button from 'Components/Link/Button'; +import Link from 'Components/Link/Link'; +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 Indexer from 'Indexer/Indexer'; +import createIndexerSelector from 'Store/Selectors/createIndexerSelector'; +import translate from 'Utilities/String/translate'; +import styles from './IndexerInfoModalContent.css'; + +function createIndexerInfoItemSelector(indexerId: number) { + return createSelector( + createIndexerSelector(indexerId), + (indexer: Indexer) => { + return { + indexer, + }; + } + ); +} + +interface IndexerInfoModalContentProps { + indexerId: number; + onModalClose(): void; +} + +function IndexerInfoModalContent(props: IndexerInfoModalContentProps) { + const { indexer } = useSelector( + createIndexerInfoItemSelector(props.indexerId) + ); + + const { + id, + name, + description, + encoding, + language, + indexerUrls, + fields, + protocol, + capabilities, + } = indexer; + + const { onModalClose } = props; + + const baseUrl = + fields.find((field) => field.name === 'baseUrl')?.value ?? + (Array.isArray(indexerUrls) ? indexerUrls[0] : undefined); + + return ( + + {`${name}`} + + + + + + + + + + + {translate('IndexerSite')} + + + {baseUrl.replace('api.', '')} + + {`${ + protocol === 'usenet' ? 'Newznab' : 'Torznab' + } Url`} + + {`${window.location.origin}${window.Prowlarr.urlBase}/${id}/api`} + + + + + + + + + + {capabilities.searchParams[0]} + + ) + } + /> + { + return ( + + {p} + + ); + }) + } + /> + { + return ( + + {p} + + ); + }) + } + /> + { + return ( + + {p} + + ); + }) + } + /> + { + return ( + + {p} + + ); + }) + } + /> + + + + + + {translate('Close')} + + + ); +} + +export default IndexerInfoModalContent; diff --git a/frontend/src/Indexer/Info/IndexerInfoModalContentConnector.js b/frontend/src/Indexer/Info/IndexerInfoModalContentConnector.js deleted file mode 100644 index 2bfde3a25..000000000 --- a/frontend/src/Indexer/Info/IndexerInfoModalContentConnector.js +++ /dev/null @@ -1,40 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import createIndexerSelector from 'Store/Selectors/createIndexerSelector'; -import IndexerInfoModalContent from './IndexerInfoModalContent'; - -function createMapStateToProps() { - return createSelector( - (state) => state.settings.advancedSettings, - createIndexerSelector(), - (advancedSettings, indexer) => { - return { - advancedSettings, - ...indexer - }; - } - ); -} - -class IndexerInfoModalContentConnector extends Component { - - // - // Render - - render() { - return ( - - ); - } -} - -IndexerInfoModalContentConnector.propTypes = { - indexerId: PropTypes.number, - onModalClose: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps)(IndexerInfoModalContentConnector);