import React, { useCallback, useState } from 'react'; import { useSelector } from 'react-redux'; import { useSelect } from 'App/SelectContext'; import CheckInput from 'Components/Form/CheckInput'; import IconButton from 'Components/Link/IconButton'; import RelativeDateCell from 'Components/Table/Cells/RelativeDateCell'; import VirtualTableRowCell from 'Components/Table/Cells/VirtualTableRowCell'; import VirtualTableSelectCell from 'Components/Table/Cells/VirtualTableSelectCell'; import Column from 'Components/Table/Column'; import TagListConnector from 'Components/TagListConnector'; import { icons } from 'Helpers/Props'; import DeleteIndexerModal from 'Indexer/Delete/DeleteIndexerModal'; import EditIndexerModalConnector from 'Indexer/Edit/EditIndexerModalConnector'; import createIndexerIndexItemSelector from 'Indexer/Index/createIndexerIndexItemSelector'; import Indexer from 'Indexer/Indexer'; import IndexerTitleLink from 'Indexer/IndexerTitleLink'; import { SelectStateInputProps } from 'typings/props'; import translate from 'Utilities/String/translate'; import CapabilitiesLabel from './CapabilitiesLabel'; import IndexerStatusCell from './IndexerStatusCell'; import PrivacyLabel from './PrivacyLabel'; import ProtocolLabel from './ProtocolLabel'; import styles from './IndexerIndexRow.css'; interface IndexerIndexRowProps { indexerId: number; sortKey: string; columns: Column[]; isSelectMode: boolean; onCloneIndexerPress(id: number): void; } function IndexerIndexRow(props: IndexerIndexRowProps) { const { indexerId, columns, isSelectMode, onCloneIndexerPress } = props; const { indexer, appProfile, status, longDateFormat, timeFormat } = useSelector(createIndexerIndexItemSelector(indexerId)); const { id, name: indexerName, indexerUrls, enable, redirect, tags, protocol, privacy, priority, fields, added, capabilities, } = indexer as Indexer; const baseUrl = fields.find((field) => field.name === 'baseUrl')?.value ?? (Array.isArray(indexerUrls) ? indexerUrls[0] : undefined); const vipExpiration = fields.find((field) => field.name === 'vipExpiration')?.value ?? ''; const minimumSeeders = fields.find( (field) => field.name === 'torrentBaseSettings.appMinimumSeeders' )?.value ?? undefined; const seedRatio = fields.find((field) => field.name === 'torrentBaseSettings.seedRatio') ?.value ?? undefined; const seedTime = fields.find((field) => field.name === 'torrentBaseSettings.seedTime') ?.value ?? undefined; const packSeedTime = fields.find((field) => field.name === 'torrentBaseSettings.packSeedTime') ?.value ?? undefined; const preferMagnetUrl = fields.find((field) => field.name === 'torrentBaseSettings.preferMagnetUrl') ?.value ?? undefined; const rssUrl = `${window.location.origin}${ window.Prowlarr.urlBase }/${id}/api?apikey=${encodeURIComponent( window.Prowlarr.apiKey )}&extended=1&t=search`; const [isEditIndexerModalOpen, setIsEditIndexerModalOpen] = useState(false); const [isDeleteIndexerModalOpen, setIsDeleteIndexerModalOpen] = useState(false); const [selectState, selectDispatch] = useSelect(); 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); }, [setIsDeleteIndexerModalOpen]); const checkInputCallback = useCallback(() => { // Mock handler to satisfy `onChange` being required for `CheckInput`. }, []); const onSelectedChange = useCallback( ({ id, value, shiftKey }: SelectStateInputProps) => { selectDispatch({ type: 'toggleSelected', id, isSelected: value, shiftKey, }); }, [selectDispatch] ); return ( <> {isSelectMode ? ( ) : null} {columns.map((column) => { const { name, isVisible } = column; if (!isVisible) { return null; } if (name === 'status') { return ( ); } if (name === 'id') { return ( ); } if (name === 'sortName') { return ( ); } if (name === 'privacy') { return ( ); } if (name === 'priority') { return ( {priority} ); } if (name === 'protocol') { return ( ); } if (name === 'appProfileId') { return ( {appProfile?.name || ''} ); } if (name === 'capabilities') { return ( ); } if (name === 'added') { return ( // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore ts(2739) ); } if (name === 'vipExpiration') { return ( // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore ts(2739) ); } if (name === 'tags') { return ( ); } if (name === 'minimumSeeders') { return ( {minimumSeeders} ); } if (name === 'seedRatio') { return ( {seedRatio} ); } if (name === 'seedTime') { return ( {seedTime} ); } if (name === 'packSeedTime') { return ( {packSeedTime} ); } if (name === 'preferMagnetUrl') { return ( {preferMagnetUrl === undefined ? null : ( )} ); } if (name === 'actions') { return ( {baseUrl ? ( ) : null} ); } return null; })} ); } export default IndexerIndexRow;