diff --git a/frontend/src/Indexer/Index/IndexerIndex.tsx b/frontend/src/Indexer/Index/IndexerIndex.tsx
index 644c81493..3407aa05c 100644
--- a/frontend/src/Indexer/Index/IndexerIndex.tsx
+++ b/frontend/src/Indexer/Index/IndexerIndex.tsx
@@ -22,7 +22,7 @@ import AddIndexerModal from 'Indexer/Add/AddIndexerModal';
import EditIndexerModalConnector from 'Indexer/Edit/EditIndexerModalConnector';
import NoIndexer from 'Indexer/NoIndexer';
import { executeCommand } from 'Store/Actions/commandActions';
-import { testAllIndexers } from 'Store/Actions/indexerActions';
+import { cloneIndexer, testAllIndexers } from 'Store/Actions/indexerActions';
import {
setIndexerFilter,
setIndexerSort,
@@ -98,6 +98,15 @@ const IndexerIndex = withScrollPosition((props: IndexerIndexProps) => {
setIsEditIndexerModalOpen(false);
}, [setIsEditIndexerModalOpen]);
+ const onCloneIndexerPress = useCallback(
+ (id: number) => {
+ dispatch(cloneIndexer({ id }));
+
+ setIsEditIndexerModalOpen(true);
+ },
+ [dispatch, setIsEditIndexerModalOpen]
+ );
+
const onAppIndexerSyncPress = useCallback(() => {
dispatch(
executeCommand({
@@ -303,6 +312,7 @@ const IndexerIndex = withScrollPosition((props: IndexerIndexProps) => {
jumpToCharacter={jumpToCharacter}
isSelectMode={isSelectMode}
isSmallScreen={isSmallScreen}
+ onCloneIndexerPress={onCloneIndexerPress}
/>
diff --git a/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx b/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx
index 69afaeeba..721964298 100644
--- a/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx
+++ b/frontend/src/Indexer/Index/Table/IndexerIndexRow.tsx
@@ -27,10 +27,11 @@ interface IndexerIndexRowProps {
sortKey: string;
columns: Column[];
isSelectMode: boolean;
+ onCloneIndexerPress(id: number): void;
}
function IndexerIndexRow(props: IndexerIndexRowProps) {
- const { indexerId, columns, isSelectMode } = props;
+ const { indexerId, columns, isSelectMode, onCloneIndexerPress } = props;
const { indexer, appProfile, status, longDateFormat, timeFormat } =
useSelector(createIndexerIndexItemSelector(props.indexerId));
@@ -153,6 +154,7 @@ function IndexerIndexRow(props: IndexerIndexRowProps) {
);
diff --git a/frontend/src/Indexer/Index/Table/IndexerIndexTable.tsx b/frontend/src/Indexer/Index/Table/IndexerIndexTable.tsx
index 7889b547d..ee717317a 100644
--- a/frontend/src/Indexer/Index/Table/IndexerIndexTable.tsx
+++ b/frontend/src/Indexer/Index/Table/IndexerIndexTable.tsx
@@ -26,6 +26,7 @@ interface RowItemData {
sortKey: string;
columns: Column[];
isSelectMode: boolean;
+ onCloneIndexerPress(id: number): void;
}
interface IndexerIndexTableProps {
@@ -37,6 +38,7 @@ interface IndexerIndexTableProps {
scrollerRef: RefObject;
isSelectMode: boolean;
isSmallScreen: boolean;
+ onCloneIndexerPress(id: number): void;
}
const columnsSelector = createSelector(
@@ -49,7 +51,7 @@ const Row: React.FC> = ({
style,
data,
}) => {
- const { items, sortKey, columns, isSelectMode } = data;
+ const { items, sortKey, columns, isSelectMode, onCloneIndexerPress } = data;
if (index >= items.length) {
return null;
@@ -71,6 +73,7 @@ const Row: React.FC> = ({
sortKey={sortKey}
columns={columns}
isSelectMode={isSelectMode}
+ onCloneIndexerPress={onCloneIndexerPress}
/>
);
@@ -89,6 +92,7 @@ function IndexerIndexTable(props: IndexerIndexTableProps) {
isSelectMode,
isSmallScreen,
scrollerRef,
+ onCloneIndexerPress,
} = props;
const columns = useSelector(columnsSelector);
@@ -198,6 +202,7 @@ function IndexerIndexTable(props: IndexerIndexTableProps) {
sortKey,
columns,
isSelectMode,
+ onCloneIndexerPress,
}}
>
{Row}
diff --git a/frontend/src/Indexer/IndexerTitleLink.tsx b/frontend/src/Indexer/IndexerTitleLink.tsx
index 82f294d69..3c22b87f2 100644
--- a/frontend/src/Indexer/IndexerTitleLink.tsx
+++ b/frontend/src/Indexer/IndexerTitleLink.tsx
@@ -7,10 +7,11 @@ import styles from './IndexerTitleLink.css';
interface IndexerTitleLinkProps {
indexerName: string;
indexerId: number;
+ onCloneIndexerPress(id: number): void;
}
function IndexerTitleLink(props: IndexerTitleLinkProps) {
- const { indexerName, indexerId } = props;
+ const { indexerName, indexerId, onCloneIndexerPress } = props;
const [isIndexerInfoModalOpen, setIsIndexerInfoModalOpen] = useState(false);
@@ -32,6 +33,7 @@ function IndexerTitleLink(props: IndexerTitleLinkProps) {
indexerId={indexerId}
isOpen={isIndexerInfoModalOpen}
onModalClose={onIndexerInfoModalClose}
+ onCloneIndexerPress={onCloneIndexerPress}
/>
);
diff --git a/frontend/src/Indexer/Info/IndexerInfoModal.tsx b/frontend/src/Indexer/Info/IndexerInfoModal.tsx
index df2ead86d..0c19dca1e 100644
--- a/frontend/src/Indexer/Info/IndexerInfoModal.tsx
+++ b/frontend/src/Indexer/Info/IndexerInfoModal.tsx
@@ -7,16 +7,18 @@ interface IndexerInfoModalProps {
isOpen: boolean;
indexerId: number;
onModalClose(): void;
+ onCloneIndexerPress(id: number): void;
}
function IndexerInfoModal(props: IndexerInfoModalProps) {
- const { isOpen, onModalClose, indexerId } = props;
+ const { isOpen, indexerId, onModalClose, onCloneIndexerPress } = props;
return (
);
diff --git a/frontend/src/Indexer/Info/IndexerInfoModalContent.tsx b/frontend/src/Indexer/Info/IndexerInfoModalContent.tsx
index 8cb10993a..24f93c39b 100644
--- a/frontend/src/Indexer/Info/IndexerInfoModalContent.tsx
+++ b/frontend/src/Indexer/Info/IndexerInfoModalContent.tsx
@@ -41,12 +41,13 @@ function createIndexerInfoItemSelector(indexerId: number) {
interface IndexerInfoModalContentProps {
indexerId: number;
onModalClose(): void;
+ onCloneIndexerPress(id: number): void;
}
function IndexerInfoModalContent(props: IndexerInfoModalContentProps) {
- const { indexer } = useSelector(
- createIndexerInfoItemSelector(props.indexerId)
- );
+ const { indexerId, onCloneIndexerPress } = props;
+
+ const { indexer } = useSelector(createIndexerInfoItemSelector(indexerId));
const {
id,
@@ -92,6 +93,11 @@ function IndexerInfoModalContent(props: IndexerInfoModalContentProps) {
onModalClose();
}, [setIsDeleteIndexerModalOpen, onModalClose]);
+ const onCloneIndexerPressWrapper = useCallback(() => {
+ onCloneIndexerPress(id);
+ onModalClose();
+ }, [id, onCloneIndexerPress, onModalClose]);
+
return (
{`${name}`}
@@ -304,6 +310,9 @@ function IndexerInfoModalContent(props: IndexerInfoModalContentProps) {
>
{translate('Delete')}
+
diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json
index 4b26243ab..3412a360b 100644
--- a/src/NzbDrone.Core/Localization/Core/en.json
+++ b/src/NzbDrone.Core/Localization/Core/en.json
@@ -108,6 +108,7 @@
"ClearHistory": "Clear History",
"ClearHistoryMessageText": "Are you sure you want to clear all Prowlarr history?",
"ClientPriority": "Client Priority",
+ "Clone": "Clone",
"CloneProfile": "Clone Profile",
"Close": "Close",
"CloseCurrentModal": "Close Current Modal",