add ability to clone import lists

pull/7776/head
Stevie Robinson 3 weeks ago
parent b103005aa2
commit 6217036135

@ -4,6 +4,11 @@
width: 290px;
}
.nameContainer {
display: flex;
justify-content: space-between;
}
.name {
@add-mixin truncate;
@ -12,6 +17,12 @@
font-size: 24px;
}
.cloneButton {
composes: button from '~Components/Link/IconButton.css';
height: 36px;
}
.enabled {
display: flex;
flex-wrap: wrap;

@ -1,9 +1,11 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'cloneButton': string;
'enabled': string;
'list': string;
'name': string;
'nameContainer': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -2,9 +2,10 @@ import React, { useCallback, useState } from 'react';
import { useDispatch } from 'react-redux';
import Card from 'Components/Card';
import Label from 'Components/Label';
import IconButton from 'Components/Link/IconButton';
import ConfirmModal from 'Components/Modal/ConfirmModal';
import TagList from 'Components/TagList';
import { kinds } from 'Helpers/Props';
import { icons, kinds } from 'Helpers/Props';
import { deleteImportList } from 'Store/Actions/settingsActions';
import useTags from 'Tags/useTags';
import formatShortTimeSpan from 'Utilities/Date/formatShortTimeSpan';
@ -18,6 +19,7 @@ interface ImportListProps {
enableAutomaticAdd: boolean;
tags: number[];
minRefreshInterval: string;
onCloneImportListPress: (id: number) => void;
}
function ImportList({
@ -26,6 +28,7 @@ function ImportList({
enableAutomaticAdd,
tags,
minRefreshInterval,
onCloneImportListPress,
}: ImportListProps) {
const dispatch = useDispatch();
const tagList = useTags();
@ -57,13 +60,26 @@ function ImportList({
dispatch(deleteImportList({ id }));
}, [id, dispatch]);
const handleCloneImportListPress = useCallback(() => {
onCloneImportListPress(id);
}, [id, onCloneImportListPress]);
return (
<Card
className={styles.list}
overlayContent={true}
onPress={handleEditImportListPress}
>
<div className={styles.name}>{name}</div>
<div className={styles.nameContainer}>
<div className={styles.name}>{name}</div>
<IconButton
className={styles.cloneButton}
title={translate('CloneImportList')}
name={icons.CLONE}
onPress={handleCloneImportListPress}
/>
</div>
<div className={styles.enabled}>
{enableAutomaticAdd ? (

@ -7,7 +7,10 @@ import Icon from 'Components/Icon';
import PageSectionContent from 'Components/Page/PageSectionContent';
import { icons } from 'Helpers/Props';
import { fetchRootFolders } from 'Store/Actions/rootFolderActions';
import { fetchImportLists } from 'Store/Actions/settingsActions';
import {
cloneImportList,
fetchImportLists,
} from 'Store/Actions/settingsActions';
import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector';
import ImportListModel from 'typings/ImportList';
import sortByProp from 'Utilities/Array/sortByProp';
@ -49,6 +52,14 @@ function ImportLists() {
setIsEditImportListModalOpen(false);
}, []);
const handleCloneImportListPress = useCallback(
(id: number) => {
dispatch(cloneImportList({ id }));
setIsEditImportListModalOpen(true);
},
[dispatch]
);
useEffect(() => {
dispatch(fetchImportLists());
dispatch(fetchRootFolders());
@ -64,7 +75,13 @@ function ImportLists() {
>
<div className={styles.lists}>
{items.map((item) => {
return <ImportList key={item.id} {...item} />;
return (
<ImportList
key={item.id}
{...item}
onCloneImportListPress={handleCloneImportListPress}
/>
);
})}
<Card className={styles.addList} onPress={handleAddImportListPress}>

@ -10,7 +10,10 @@ import createTestProviderHandler, { createCancelTestProviderHandler } from 'Stor
import createSetProviderFieldValueReducer from 'Store/Actions/Creators/Reducers/createSetProviderFieldValueReducer';
import createSetSettingValueReducer from 'Store/Actions/Creators/Reducers/createSetSettingValueReducer';
import { createThunk } from 'Store/thunks';
import getSectionState from 'Utilities/State/getSectionState';
import selectProviderSchema from 'Utilities/State/selectProviderSchema';
import updateSectionState from 'Utilities/State/updateSectionState';
import translate from 'Utilities/String/translate';
//
// Variables
@ -33,6 +36,7 @@ export const CANCEL_TEST_IMPORT_LIST = 'settings/importLists/cancelTestImportLis
export const TEST_ALL_IMPORT_LISTS = 'settings/importLists/testAllImportLists';
export const BULK_EDIT_IMPORT_LISTS = 'settings/importLists/bulkEditImportLists';
export const BULK_DELETE_IMPORT_LISTS = 'settings/importLists/bulkDeleteImportLists';
export const CLONE_IMPORT_LIST = 'settings/importLists/cloneImportList';
//
// Action Creators
@ -64,6 +68,8 @@ export const setImportListFieldValue = createAction(SET_IMPORT_LIST_FIELD_VALUE,
};
});
export const cloneImportList = createAction(CLONE_IMPORT_LIST);
//
// Details
@ -127,6 +133,37 @@ export default {
return selectedSchema;
});
},
[CLONE_IMPORT_LIST]: (state, { payload }) => {
const id = payload.id;
const newState = getSectionState(state, section);
const item = newState.items.find((i) => i.id === id);
const selectedSchema = { ...item };
delete selectedSchema.id;
delete selectedSchema.name;
// Use selectedSchema so `createProviderSettingsSelector` works properly
selectedSchema.fields = selectedSchema.fields.map((field) => {
const newField = { ...field };
if (newField.privacy === 'apiKey' || newField.privacy === 'password') {
newField.value = '';
}
return newField;
});
newState.selectedSchema = selectedSchema;
const pendingChanges = { ...item, id: 0 };
delete pendingChanges.id;
pendingChanges.name = translate('DefaultNameCopiedImportList', { name: pendingChanges.name });
newState.pendingChanges = pendingChanges;
return updateSectionState(state, section, newState);
}
}

@ -228,6 +228,7 @@
"CloneAutoTag": "Clone Auto Tag",
"CloneCondition": "Clone Condition",
"CloneCustomFormat": "Clone Custom Format",
"CloneImportList": "Clone Import List",
"CloneIndexer": "Clone Indexer",
"CloneProfile": "Clone Profile",
"Close": "Close",
@ -322,6 +323,7 @@
"Default": "Default",
"DefaultCase": "Default Case",
"DefaultDelayProfileSeries": "This is the default profile. It applies to all series that don't have an explicit profile.",
"DefaultNameCopiedImportList": "{name} - Copy",
"DefaultNameCopiedProfile": "{name} - Copy",
"DefaultNameCopiedSpecification": "{name} - Copy",
"DefaultNotFoundMessage": "You must be lost, nothing to see here.",

Loading…
Cancel
Save