mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
@@ -12,7 +12,7 @@ import { icons } from 'Helpers/Props';
|
|||||||
import DeleteIndexerModal from 'Indexer/Delete/DeleteIndexerModal';
|
import DeleteIndexerModal from 'Indexer/Delete/DeleteIndexerModal';
|
||||||
import EditIndexerModalConnector from 'Indexer/Edit/EditIndexerModalConnector';
|
import EditIndexerModalConnector from 'Indexer/Edit/EditIndexerModalConnector';
|
||||||
import createIndexerIndexItemSelector from 'Indexer/Index/createIndexerIndexItemSelector';
|
import createIndexerIndexItemSelector from 'Indexer/Index/createIndexerIndexItemSelector';
|
||||||
import IndexerInfoModal from 'Indexer/Info/IndexerInfoModal';
|
import IndexerTitleLink from 'Indexer/IndexerTitleLink';
|
||||||
import titleCase from 'Utilities/String/titleCase';
|
import titleCase from 'Utilities/String/titleCase';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import CapabilitiesLabel from './CapabilitiesLabel';
|
import CapabilitiesLabel from './CapabilitiesLabel';
|
||||||
@@ -53,7 +53,6 @@ function IndexerIndexRow(props: IndexerIndexRowProps) {
|
|||||||
fields.find((field) => field.name === 'baseUrl')?.value ??
|
fields.find((field) => field.name === 'baseUrl')?.value ??
|
||||||
(Array.isArray(indexerUrls) ? indexerUrls[0] : undefined);
|
(Array.isArray(indexerUrls) ? indexerUrls[0] : undefined);
|
||||||
|
|
||||||
const [isIndexerInfoModalOpen, setIsIndexerInfoModalOpen] = useState(false);
|
|
||||||
const [isEditIndexerModalOpen, setIsEditIndexerModalOpen] = useState(false);
|
const [isEditIndexerModalOpen, setIsEditIndexerModalOpen] = useState(false);
|
||||||
const [isDeleteIndexerModalOpen, setIsDeleteIndexerModalOpen] =
|
const [isDeleteIndexerModalOpen, setIsDeleteIndexerModalOpen] =
|
||||||
useState(false);
|
useState(false);
|
||||||
@@ -67,14 +66,6 @@ function IndexerIndexRow(props: IndexerIndexRowProps) {
|
|||||||
setIsEditIndexerModalOpen(false);
|
setIsEditIndexerModalOpen(false);
|
||||||
}, [setIsEditIndexerModalOpen]);
|
}, [setIsEditIndexerModalOpen]);
|
||||||
|
|
||||||
const onIndexerInfoPress = useCallback(() => {
|
|
||||||
setIsIndexerInfoModalOpen(true);
|
|
||||||
}, [setIsIndexerInfoModalOpen]);
|
|
||||||
|
|
||||||
const onIndexerInfoModalClose = useCallback(() => {
|
|
||||||
setIsIndexerInfoModalOpen(false);
|
|
||||||
}, [setIsIndexerInfoModalOpen]);
|
|
||||||
|
|
||||||
const onDeleteIndexerPress = useCallback(() => {
|
const onDeleteIndexerPress = useCallback(() => {
|
||||||
setIsEditIndexerModalOpen(false);
|
setIsEditIndexerModalOpen(false);
|
||||||
setIsDeleteIndexerModalOpen(true);
|
setIsDeleteIndexerModalOpen(true);
|
||||||
@@ -134,7 +125,10 @@ function IndexerIndexRow(props: IndexerIndexRowProps) {
|
|||||||
if (name === 'sortName') {
|
if (name === 'sortName') {
|
||||||
return (
|
return (
|
||||||
<VirtualTableRowCell key={name} className={styles[name]}>
|
<VirtualTableRowCell key={name} className={styles[name]}>
|
||||||
{indexerName}
|
<IndexerTitleLink
|
||||||
|
indexerId={indexerId}
|
||||||
|
indexerName={indexerName}
|
||||||
|
/>
|
||||||
</VirtualTableRowCell>
|
</VirtualTableRowCell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -204,12 +198,6 @@ function IndexerIndexRow(props: IndexerIndexRowProps) {
|
|||||||
key={column.name}
|
key={column.name}
|
||||||
className={styles[column.name]}
|
className={styles[column.name]}
|
||||||
>
|
>
|
||||||
<IconButton
|
|
||||||
name={icons.INFO}
|
|
||||||
title={translate('IndexerInfo')}
|
|
||||||
onPress={onIndexerInfoPress}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{baseUrl ? (
|
{baseUrl ? (
|
||||||
<IconButton
|
<IconButton
|
||||||
className={styles.externalLink}
|
className={styles.externalLink}
|
||||||
@@ -238,12 +226,6 @@ function IndexerIndexRow(props: IndexerIndexRowProps) {
|
|||||||
onDeleteIndexerPress={onDeleteIndexerPress}
|
onDeleteIndexerPress={onDeleteIndexerPress}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<IndexerInfoModal
|
|
||||||
indexerId={indexerId}
|
|
||||||
isOpen={isIndexerInfoModalOpen}
|
|
||||||
onModalClose={onIndexerInfoModalClose}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<DeleteIndexerModal
|
<DeleteIndexerModal
|
||||||
isOpen={isDeleteIndexerModalOpen}
|
isOpen={isDeleteIndexerModalOpen}
|
||||||
indexerId={indexerId}
|
indexerId={indexerId}
|
||||||
|
@@ -13,6 +13,12 @@ export interface IndexerCategory extends ModelBase {
|
|||||||
export interface IndexerCapabilities extends ModelBase {
|
export interface IndexerCapabilities extends ModelBase {
|
||||||
limitsMax: number;
|
limitsMax: number;
|
||||||
limitsDefault: number;
|
limitsDefault: number;
|
||||||
|
supportsRawSearch: boolean;
|
||||||
|
searchParams: string[];
|
||||||
|
tvSearchParams: string[];
|
||||||
|
movieSearchParams: string[];
|
||||||
|
musicSearchParams: string[];
|
||||||
|
bookSearchParams: string[];
|
||||||
categories: IndexerCategory[];
|
categories: IndexerCategory[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,6 +32,9 @@ export interface IndexerField extends ModelBase {
|
|||||||
|
|
||||||
interface Indexer extends ModelBase {
|
interface Indexer extends ModelBase {
|
||||||
name: string;
|
name: string;
|
||||||
|
description: string;
|
||||||
|
encoding: string;
|
||||||
|
language: string;
|
||||||
added: Date;
|
added: Date;
|
||||||
enable: boolean;
|
enable: boolean;
|
||||||
redirect: boolean;
|
redirect: boolean;
|
||||||
|
8
frontend/src/Indexer/IndexerTitleLink.css
Normal file
8
frontend/src/Indexer/IndexerTitleLink.css
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
.link {
|
||||||
|
composes: link from '~Components/Link/Link.css';
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--linkHoverColor);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
7
frontend/src/Indexer/IndexerTitleLink.css.d.ts
vendored
Normal file
7
frontend/src/Indexer/IndexerTitleLink.css.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
// This file is automatically generated.
|
||||||
|
// Please do not change this file!
|
||||||
|
interface CssExports {
|
||||||
|
'link': string;
|
||||||
|
}
|
||||||
|
export const cssExports: CssExports;
|
||||||
|
export default cssExports;
|
44
frontend/src/Indexer/IndexerTitleLink.tsx
Normal file
44
frontend/src/Indexer/IndexerTitleLink.tsx
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React, { useCallback, useState } from 'react';
|
||||||
|
import Link from 'Components/Link/Link';
|
||||||
|
import IndexerInfoModal from './Info/IndexerInfoModal';
|
||||||
|
import styles from './IndexerTitleLink.css';
|
||||||
|
|
||||||
|
interface IndexerTitleLinkProps {
|
||||||
|
indexerName: string;
|
||||||
|
indexerId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function IndexerTitleLink(props: IndexerTitleLinkProps) {
|
||||||
|
const { indexerName, indexerId } = props;
|
||||||
|
|
||||||
|
const [isIndexerInfoModalOpen, setIsIndexerInfoModalOpen] = useState(false);
|
||||||
|
|
||||||
|
const onIndexerInfoPress = useCallback(() => {
|
||||||
|
setIsIndexerInfoModalOpen(true);
|
||||||
|
}, [setIsIndexerInfoModalOpen]);
|
||||||
|
|
||||||
|
const onIndexerInfoModalClose = useCallback(() => {
|
||||||
|
setIsIndexerInfoModalOpen(false);
|
||||||
|
}, [setIsIndexerInfoModalOpen]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Link className={styles.link} onPress={onIndexerInfoPress}>
|
||||||
|
{indexerName}
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<IndexerInfoModal
|
||||||
|
indexerId={indexerId}
|
||||||
|
isOpen={isIndexerInfoModalOpen}
|
||||||
|
onModalClose={onIndexerInfoModalClose}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexerTitleLink.propTypes = {
|
||||||
|
indexerName: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default IndexerTitleLink;
|
@@ -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 (
|
|
||||||
<Modal
|
|
||||||
size={sizes.MEDIUM}
|
|
||||||
isOpen={isOpen}
|
|
||||||
onModalClose={onModalClose}
|
|
||||||
>
|
|
||||||
<IndexerInfoModalContentConnector
|
|
||||||
{...otherProps}
|
|
||||||
onModalClose={onModalClose}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexerInfoModal.propTypes = {
|
|
||||||
isOpen: PropTypes.bool.isRequired,
|
|
||||||
onModalClose: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default IndexerInfoModal;
|
|
25
frontend/src/Indexer/Info/IndexerInfoModal.tsx
Normal file
25
frontend/src/Indexer/Info/IndexerInfoModal.tsx
Normal file
@@ -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 (
|
||||||
|
<Modal size={sizes.MEDIUM} isOpen={isOpen} onModalClose={onModalClose}>
|
||||||
|
<IndexerInfoModalContent
|
||||||
|
indexerId={indexerId}
|
||||||
|
onModalClose={onModalClose}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IndexerInfoModal;
|
@@ -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 (
|
|
||||||
<ModalContent onModalClose={onModalClose}>
|
|
||||||
<ModalHeader>
|
|
||||||
{`${name}`}
|
|
||||||
</ModalHeader>
|
|
||||||
|
|
||||||
<ModalBody>
|
|
||||||
<FieldSet legend={translate('IndexerDetails')}>
|
|
||||||
<div className={styles.groups}>
|
|
||||||
<DescriptionList>
|
|
||||||
<DescriptionListItem
|
|
||||||
descriptionClassName={styles.description}
|
|
||||||
title={translate('Id')}
|
|
||||||
data={id}
|
|
||||||
/>
|
|
||||||
<DescriptionListItem
|
|
||||||
descriptionClassName={styles.description}
|
|
||||||
title={translate('Description')}
|
|
||||||
data={description ? description : '-'}
|
|
||||||
/>
|
|
||||||
<DescriptionListItem
|
|
||||||
descriptionClassName={styles.description}
|
|
||||||
title={translate('Encoding')}
|
|
||||||
data={encoding ? encoding : '-'}
|
|
||||||
/>
|
|
||||||
<DescriptionListItem
|
|
||||||
descriptionClassName={styles.description}
|
|
||||||
title={translate('Language')}
|
|
||||||
data={language ?? '-'}
|
|
||||||
/>
|
|
||||||
<DescriptionListItemTitle>{translate('IndexerSite')}</DescriptionListItemTitle>
|
|
||||||
<DescriptionListItemDescription>
|
|
||||||
<Link to={baseUrl}>{baseUrl}</Link>
|
|
||||||
</DescriptionListItemDescription>
|
|
||||||
<DescriptionListItemTitle>{`${protocol === 'usenet' ? 'Newznab' : 'Torznab'} Url`}</DescriptionListItemTitle>
|
|
||||||
<DescriptionListItemDescription>
|
|
||||||
{`${window.location.origin}${window.Prowlarr.urlBase}/${id}/api`}
|
|
||||||
</DescriptionListItemDescription>
|
|
||||||
</DescriptionList>
|
|
||||||
</div>
|
|
||||||
</FieldSet>
|
|
||||||
<FieldSet legend={translate('SearchCapabilities')}>
|
|
||||||
<div className={styles.groups}>
|
|
||||||
<DescriptionList>
|
|
||||||
<DescriptionListItem
|
|
||||||
descriptionClassName={styles.description}
|
|
||||||
title={translate('RawSearchSupported')}
|
|
||||||
data={capabilities.supportsRawSearch ? translate('Yes') : translate('No')}
|
|
||||||
/>
|
|
||||||
<DescriptionListItem
|
|
||||||
descriptionClassName={styles.description}
|
|
||||||
title={translate('SearchTypes')}
|
|
||||||
data={capabilities.searchParams.length === 0 ? translate('NotSupported') : capabilities.searchParams[0]}
|
|
||||||
/>
|
|
||||||
<DescriptionListItem
|
|
||||||
descriptionClassName={styles.description}
|
|
||||||
title={translate('TVSearchTypes')}
|
|
||||||
data={capabilities.tvSearchParams.length === 0 ? translate('NotSupported') : capabilities.tvSearchParams.join(', ')}
|
|
||||||
/>
|
|
||||||
<DescriptionListItem
|
|
||||||
descriptionClassName={styles.description}
|
|
||||||
title={translate('MovieSearchTypes')}
|
|
||||||
data={capabilities.movieSearchParams.length === 0 ? translate('NotSupported') : capabilities.movieSearchParams.join(', ')}
|
|
||||||
/>
|
|
||||||
<DescriptionListItem
|
|
||||||
descriptionClassName={styles.description}
|
|
||||||
title={translate('BookSearchTypes')}
|
|
||||||
data={capabilities.bookSearchParams.length === 0 ? translate('NotSupported') : capabilities.bookSearchParams.join(', ')}
|
|
||||||
/>
|
|
||||||
<DescriptionListItem
|
|
||||||
descriptionClassName={styles.description}
|
|
||||||
title={translate('MusicSearchTypes')}
|
|
||||||
data={capabilities.musicSearchParams.length === 0 ? translate('NotSupported') : capabilities.musicSearchParams.join(', ')}
|
|
||||||
/>
|
|
||||||
</DescriptionList>
|
|
||||||
</div>
|
|
||||||
</FieldSet>
|
|
||||||
</ModalBody>
|
|
||||||
</ModalContent >
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
200
frontend/src/Indexer/Info/IndexerInfoModalContent.tsx
Normal file
200
frontend/src/Indexer/Info/IndexerInfoModalContent.tsx
Normal file
@@ -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 (
|
||||||
|
<ModalContent onModalClose={onModalClose}>
|
||||||
|
<ModalHeader>{`${name}`}</ModalHeader>
|
||||||
|
|
||||||
|
<ModalBody>
|
||||||
|
<FieldSet legend={translate('IndexerDetails')}>
|
||||||
|
<div>
|
||||||
|
<DescriptionList>
|
||||||
|
<DescriptionListItem
|
||||||
|
descriptionClassName={styles.description}
|
||||||
|
title={translate('Id')}
|
||||||
|
data={id}
|
||||||
|
/>
|
||||||
|
<DescriptionListItem
|
||||||
|
descriptionClassName={styles.description}
|
||||||
|
title={translate('Description')}
|
||||||
|
data={description ? description : '-'}
|
||||||
|
/>
|
||||||
|
<DescriptionListItem
|
||||||
|
descriptionClassName={styles.description}
|
||||||
|
title={translate('Encoding')}
|
||||||
|
data={encoding ? encoding : '-'}
|
||||||
|
/>
|
||||||
|
<DescriptionListItem
|
||||||
|
descriptionClassName={styles.description}
|
||||||
|
title={translate('Language')}
|
||||||
|
data={language ?? '-'}
|
||||||
|
/>
|
||||||
|
<DescriptionListItemTitle>
|
||||||
|
{translate('IndexerSite')}
|
||||||
|
</DescriptionListItemTitle>
|
||||||
|
<DescriptionListItemDescription>
|
||||||
|
<Link to={baseUrl}>{baseUrl.replace('api.', '')}</Link>
|
||||||
|
</DescriptionListItemDescription>
|
||||||
|
<DescriptionListItemTitle>{`${
|
||||||
|
protocol === 'usenet' ? 'Newznab' : 'Torznab'
|
||||||
|
} Url`}</DescriptionListItemTitle>
|
||||||
|
<DescriptionListItemDescription>
|
||||||
|
{`${window.location.origin}${window.Prowlarr.urlBase}/${id}/api`}
|
||||||
|
</DescriptionListItemDescription>
|
||||||
|
</DescriptionList>
|
||||||
|
</div>
|
||||||
|
</FieldSet>
|
||||||
|
<FieldSet legend={translate('SearchCapabilities')}>
|
||||||
|
<div>
|
||||||
|
<DescriptionList>
|
||||||
|
<DescriptionListItem
|
||||||
|
descriptionClassName={styles.description}
|
||||||
|
title={translate('RawSearchSupported')}
|
||||||
|
data={
|
||||||
|
capabilities.supportsRawSearch
|
||||||
|
? translate('Yes')
|
||||||
|
: translate('No')
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<DescriptionListItem
|
||||||
|
descriptionClassName={styles.description}
|
||||||
|
title={translate('SearchTypes')}
|
||||||
|
data={
|
||||||
|
capabilities.searchParams.length === 0 ? (
|
||||||
|
translate('NotSupported')
|
||||||
|
) : (
|
||||||
|
<Label kind={kinds.PRIMARY}>
|
||||||
|
{capabilities.searchParams[0]}
|
||||||
|
</Label>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<DescriptionListItem
|
||||||
|
descriptionClassName={styles.description}
|
||||||
|
title={translate('TVSearchTypes')}
|
||||||
|
data={
|
||||||
|
capabilities.tvSearchParams.length === 0
|
||||||
|
? translate('NotSupported')
|
||||||
|
: capabilities.tvSearchParams.map((p) => {
|
||||||
|
return (
|
||||||
|
<Label key={p} kind={kinds.PRIMARY}>
|
||||||
|
{p}
|
||||||
|
</Label>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<DescriptionListItem
|
||||||
|
descriptionClassName={styles.description}
|
||||||
|
title={translate('MovieSearchTypes')}
|
||||||
|
data={
|
||||||
|
capabilities.movieSearchParams.length === 0
|
||||||
|
? translate('NotSupported')
|
||||||
|
: capabilities.movieSearchParams.map((p) => {
|
||||||
|
return (
|
||||||
|
<Label key={p} kind={kinds.PRIMARY}>
|
||||||
|
{p}
|
||||||
|
</Label>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<DescriptionListItem
|
||||||
|
descriptionClassName={styles.description}
|
||||||
|
title={translate('BookSearchTypes')}
|
||||||
|
data={
|
||||||
|
capabilities.bookSearchParams.length === 0
|
||||||
|
? translate('NotSupported')
|
||||||
|
: capabilities.bookSearchParams.map((p) => {
|
||||||
|
return (
|
||||||
|
<Label key={p} kind={kinds.PRIMARY}>
|
||||||
|
{p}
|
||||||
|
</Label>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<DescriptionListItem
|
||||||
|
descriptionClassName={styles.description}
|
||||||
|
title={translate('MusicSearchTypes')}
|
||||||
|
data={
|
||||||
|
capabilities.musicSearchParams.length === 0
|
||||||
|
? translate('NotSupported')
|
||||||
|
: capabilities.musicSearchParams.map((p) => {
|
||||||
|
return (
|
||||||
|
<Label key={p} kind={kinds.PRIMARY}>
|
||||||
|
{p}
|
||||||
|
</Label>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</DescriptionList>
|
||||||
|
</div>
|
||||||
|
</FieldSet>
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter>
|
||||||
|
<Button onPress={onModalClose}>{translate('Close')}</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</ModalContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IndexerInfoModalContent;
|
@@ -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 (
|
|
||||||
<IndexerInfoModalContent
|
|
||||||
{...this.props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexerInfoModalContentConnector.propTypes = {
|
|
||||||
indexerId: PropTypes.number,
|
|
||||||
onModalClose: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(createMapStateToProps)(IndexerInfoModalContentConnector);
|
|
Reference in New Issue
Block a user