import { uniqBy } from 'lodash'; import React, { useCallback, useState } from 'react'; import { useSelector } from 'react-redux'; import { Tab, TabList, TabPanel, Tabs } from 'react-tabs'; 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 TableRowCell from 'Components/Table/Cells/TableRowCell'; import Table from 'Components/Table/Table'; import TableBody from 'Components/Table/TableBody'; import TableRow from 'Components/Table/TableRow'; import TagListConnector from 'Components/TagListConnector'; import { kinds } from 'Helpers/Props'; import DeleteIndexerModal from 'Indexer/Delete/DeleteIndexerModal'; import EditIndexerModalConnector from 'Indexer/Edit/EditIndexerModalConnector'; import Indexer from 'Indexer/Indexer'; import { createIndexerSelectorForHook } from 'Store/Selectors/createIndexerSelector'; import translate from 'Utilities/String/translate'; import IndexerHistory from './History/IndexerHistory'; import styles from './IndexerInfoModalContent.css'; function createIndexerInfoItemSelector(indexerId: number) { return createSelector( createIndexerSelectorForHook(indexerId), (indexer?: Indexer) => { return { indexer, }; } ); } const tabs = ['details', 'categories', 'history', 'stats']; interface IndexerInfoModalContentProps { indexerId: number; onModalClose(): void; onCloneIndexerPress(id: number): void; } function IndexerInfoModalContent(props: IndexerInfoModalContentProps) { const { indexerId, onCloneIndexerPress } = props; const { indexer } = useSelector(createIndexerInfoItemSelector(indexerId)); const { id, name, description, encoding, language, indexerUrls, fields, tags, protocol, capabilities, } = indexer as Indexer; const { onModalClose } = props; const baseUrl = fields.find((field) => field.name === 'baseUrl')?.value ?? (Array.isArray(indexerUrls) ? indexerUrls[0] : undefined); const vipExpiration = fields.find((field) => field.name === 'vipExpiration')?.value ?? undefined; const [selectedTab, setSelectedTab] = useState(tabs[0]); const [isEditIndexerModalOpen, setIsEditIndexerModalOpen] = useState(false); const [isDeleteIndexerModalOpen, setIsDeleteIndexerModalOpen] = useState(false); const onTabSelect = useCallback( (index: number) => { const selectedTab = tabs[index]; setSelectedTab(selectedTab); }, [setSelectedTab] ); const onEditIndexerPress = useCallback(() => { setIsEditIndexerModalOpen(true); }, [setIsEditIndexerModalOpen]); const onEditIndexerModalClose = useCallback(() => { setIsEditIndexerModalOpen(false); }, [setIsEditIndexerModalOpen]); const onDeleteIndexerPress = useCallback(() => { setIsEditIndexerModalOpen(false); setIsDeleteIndexerModalOpen(true); }, [setIsDeleteIndexerModalOpen]); const onDeleteIndexerModalClose = useCallback(() => { setIsDeleteIndexerModalOpen(false); onModalClose(); }, [setIsDeleteIndexerModalOpen, onModalClose]); const onCloneIndexerPressWrapper = useCallback(() => { onCloneIndexerPress(id); onModalClose(); }, [id, onCloneIndexerPress, onModalClose]); return ( {`${name}`} {translate('Details')} {translate('Categories')} {translate('History')}
{vipExpiration ? ( ) : null} {translate('IndexerSite')} {baseUrl ? ( {baseUrl.replace(/(:\/\/)api\./, '$1')} ) : ( '-' )} {protocol === 'usenet' ? translate('NewznabUrl') : translate('TorznabUrl')} {`${window.location.origin}${window.Prowlarr.urlBase}/${id}/api`} {tags.length > 0 ? ( <> {translate('Tags')} ) : null}
{capabilities.searchParams[0]} ) } /> { return ( ); }) } /> { return ( ); }) } /> { return ( ); }) } /> { return ( ); }) } />
{capabilities?.categories?.length > 0 ? (
{uniqBy(capabilities.categories, 'id') .sort((a, b) => a.id - b.id) .map((category) => { return ( {category.id} {category.name} {category?.subCategories?.length > 0 ? uniqBy(category.subCategories, 'id') .sort((a, b) => a.id - b.id) .map((subCategory) => { return ( {subCategory.id} {subCategory.name} ); }) : null} ); })}
) : null}
); } export default IndexerInfoModalContent;