feat: rename collection item

This commit is contained in:
Anoop M D 2022-03-19 03:18:15 +05:30
parent 42920b0596
commit afb545e14b
4 changed files with 111 additions and 7 deletions

View File

@ -0,0 +1,65 @@
import React, { useRef, useEffect } from 'react';
import { useFormik } from 'formik';
import * as Yup from 'yup';
import Modal from 'components/Modal';
import { useDispatch } from 'react-redux';
import { isItemAFolder } from 'utils/tabs';
import { renameItem } from 'providers/ReduxStore/slices/collections';
const RenameCollectionItem = ({collection, item, onClose}) => {
const dispatch = useDispatch();
const isFolder = isItemAFolder(item);
const inputRef = useRef();
const formik = useFormik({
enableReinitialize: true,
initialValues: {
name: item.name
},
validationSchema: Yup.object({
name: Yup.string()
.min(1, 'must be atleast 1 characters')
.max(50, 'must be 50 characters or less')
.required('name is required')
}),
onSubmit: (values) => {
dispatch(renameItem(values.name, item.uid, collection.uid));
onClose();
}
});
useEffect(() => {
if(inputRef && inputRef.current) {
inputRef.current.focus();
}
}, [inputRef]);
const onSubmit = () => formik.handleSubmit();
return (
<Modal
size="sm"
title={`Rename ${isFolder ? 'Folder' : 'Request'}`}
confirmText='Rename'
handleConfirm={onSubmit}
handleCancel={onClose}
>
<form className="grafnode-form" onSubmit={formik.handleSubmit}>
<div>
<label htmlFor="name" className="block font-semibold">{isFolder ? 'Folder' : 'Request'} Name</label>
<input
id="collection-item-name" type="text" name="name"
ref={inputRef}
className="block textbox mt-2 w-full"
onChange={formik.handleChange}
value={formik.values.name || ''}
/>
{formik.touched.name && formik.errors.name ? (
<div className="text-red-500">{formik.errors.name}</div>
) : null}
</div>
</form>
</Modal>
);
};
export default RenameCollectionItem;

View File

@ -8,6 +8,7 @@ import { addTab, focusTab } from 'providers/ReduxStore/slices/tabs';
import { isItemARequest, isItemAFolder, itemIsOpenedInTabs } from 'utils/tabs';
import Dropdown from 'components/Dropdown';
import RequestMethod from './RequestMethod';
import RenameCollectionItem from './RenameCollectionItem';
import DeleteCollectionItem from './DeleteCollectionItem';
import StyledWrapper from './StyledWrapper';
@ -17,6 +18,7 @@ const CollectionItem = ({item, collection}) => {
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
const dispatch = useDispatch();
const [renameItemModalOpen, setRenameItemModalOpen] = useState(false);
const [deleteItemModalOpen, setDeleteItemModalOpen] = useState(false);
const dropdownTippyRef = useRef();
@ -65,6 +67,7 @@ const CollectionItem = ({item, collection}) => {
return (
<StyledWrapper className="flex flex-col">
{renameItemModalOpen && <RenameCollectionItem item={item} collection={collection} onClose={() => setRenameItemModalOpen(false)}/>}
{deleteItemModalOpen && <DeleteCollectionItem item={item} collection={collection} onClose={() => setDeleteItemModalOpen(false)}/>}
<div
className={itemRowClassName}
@ -120,6 +123,7 @@ const CollectionItem = ({item, collection}) => {
)}
<div className="dropdown-item" onClick={(e) => {
dropdownTippyRef.current.hide();
setRenameItemModalOpen(true);
}}>
Rename
</div>

View File

@ -58,7 +58,6 @@ export const collectionsSlice = createSlice({
const item = findItemInCollection(collection, action.payload.itemUid);
if(item && item.draft) {
item.name = item.draft.name;
item.request = item.draft.request;
item.draft = null;
}
@ -92,6 +91,17 @@ export const collectionsSlice = createSlice({
deleteItemInCollection(action.payload.itemUid, collection);
}
},
_renameItem: (state, action) => {
const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
if(collection) {
const item = findItemInCollection(collection, action.payload.itemUid);
if(item) {
item.name = action.payload.newName;
}
}
},
collectionClicked: (state, action) => {
const collection = findCollectionByUid(state.collections, action.payload);
@ -125,6 +135,7 @@ export const {
_newFolder,
_newRequest,
_deleteItem,
_renameItem,
collectionClicked,
requestUrlChanged,
} = collectionsSlice.actions;
@ -268,4 +279,30 @@ export const deleteItem = (itemUid, collectionUid) => (dispatch, getState) => {
}
};
export const renameItem = (newName, itemUid, collectionUid) => (dispatch, getState) => {
const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid);
if(collection) {
const collectionCopy = cloneDeep(collection);
const item = findItemInCollection(collectionCopy, itemUid);
if(item) {
item.name = newName;
}
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy, {
ignoreDraft: true
});
saveCollectionToIdb(window.__idb, collectionToSave)
.then(() => {
dispatch(_renameItem({
newName: newName,
itemUid: itemUid,
collectionUid: collectionUid
}));
})
.catch((err) => console.log(err));
}
};
export default collectionsSlice.reducer;

View File

@ -53,7 +53,7 @@ export const cloneItem = (item) => {
return cloneDeep(item);
};
export const transformCollectionToSaveToIdb = (collection) => {
export const transformCollectionToSaveToIdb = (collection, options = {}) => {
const copyItems = (sourceItems, destItems) => {
each(sourceItems, (si) => {
const di = {
@ -61,10 +61,10 @@ export const transformCollectionToSaveToIdb = (collection) => {
type: si.type
};
// if items is draft, then take data from draft to save
if(si.draft) {
di.name = si.draft.name;
di.name = si.name;
// if items is draft, then take data from draft to save
if(!options.ignoreDraft && si.draft) {
if(si.draft.request) {
di.request = {
url: si.draft.request.url,
@ -74,8 +74,6 @@ export const transformCollectionToSaveToIdb = (collection) => {
};
}
} else {
di.name = si.name;
if(si.request) {
di.request = {
url: si.request.url,