forked from extern/bruno
feat: rename collection item
This commit is contained in:
parent
42920b0596
commit
afb545e14b
@ -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;
|
@ -8,6 +8,7 @@ import { addTab, focusTab } from 'providers/ReduxStore/slices/tabs';
|
|||||||
import { isItemARequest, isItemAFolder, itemIsOpenedInTabs } from 'utils/tabs';
|
import { isItemARequest, isItemAFolder, itemIsOpenedInTabs } from 'utils/tabs';
|
||||||
import Dropdown from 'components/Dropdown';
|
import Dropdown from 'components/Dropdown';
|
||||||
import RequestMethod from './RequestMethod';
|
import RequestMethod from './RequestMethod';
|
||||||
|
import RenameCollectionItem from './RenameCollectionItem';
|
||||||
import DeleteCollectionItem from './DeleteCollectionItem';
|
import DeleteCollectionItem from './DeleteCollectionItem';
|
||||||
|
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
@ -17,6 +18,7 @@ const CollectionItem = ({item, collection}) => {
|
|||||||
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
|
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const [renameItemModalOpen, setRenameItemModalOpen] = useState(false);
|
||||||
const [deleteItemModalOpen, setDeleteItemModalOpen] = useState(false);
|
const [deleteItemModalOpen, setDeleteItemModalOpen] = useState(false);
|
||||||
|
|
||||||
const dropdownTippyRef = useRef();
|
const dropdownTippyRef = useRef();
|
||||||
@ -65,6 +67,7 @@ const CollectionItem = ({item, collection}) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledWrapper className="flex flex-col">
|
<StyledWrapper className="flex flex-col">
|
||||||
|
{renameItemModalOpen && <RenameCollectionItem item={item} collection={collection} onClose={() => setRenameItemModalOpen(false)}/>}
|
||||||
{deleteItemModalOpen && <DeleteCollectionItem item={item} collection={collection} onClose={() => setDeleteItemModalOpen(false)}/>}
|
{deleteItemModalOpen && <DeleteCollectionItem item={item} collection={collection} onClose={() => setDeleteItemModalOpen(false)}/>}
|
||||||
<div
|
<div
|
||||||
className={itemRowClassName}
|
className={itemRowClassName}
|
||||||
@ -120,6 +123,7 @@ const CollectionItem = ({item, collection}) => {
|
|||||||
)}
|
)}
|
||||||
<div className="dropdown-item" onClick={(e) => {
|
<div className="dropdown-item" onClick={(e) => {
|
||||||
dropdownTippyRef.current.hide();
|
dropdownTippyRef.current.hide();
|
||||||
|
setRenameItemModalOpen(true);
|
||||||
}}>
|
}}>
|
||||||
Rename
|
Rename
|
||||||
</div>
|
</div>
|
||||||
|
@ -58,7 +58,6 @@ export const collectionsSlice = createSlice({
|
|||||||
const item = findItemInCollection(collection, action.payload.itemUid);
|
const item = findItemInCollection(collection, action.payload.itemUid);
|
||||||
|
|
||||||
if(item && item.draft) {
|
if(item && item.draft) {
|
||||||
item.name = item.draft.name;
|
|
||||||
item.request = item.draft.request;
|
item.request = item.draft.request;
|
||||||
item.draft = null;
|
item.draft = null;
|
||||||
}
|
}
|
||||||
@ -92,6 +91,17 @@ export const collectionsSlice = createSlice({
|
|||||||
deleteItemInCollection(action.payload.itemUid, collection);
|
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) => {
|
collectionClicked: (state, action) => {
|
||||||
const collection = findCollectionByUid(state.collections, action.payload);
|
const collection = findCollectionByUid(state.collections, action.payload);
|
||||||
|
|
||||||
@ -125,6 +135,7 @@ export const {
|
|||||||
_newFolder,
|
_newFolder,
|
||||||
_newRequest,
|
_newRequest,
|
||||||
_deleteItem,
|
_deleteItem,
|
||||||
|
_renameItem,
|
||||||
collectionClicked,
|
collectionClicked,
|
||||||
requestUrlChanged,
|
requestUrlChanged,
|
||||||
} = collectionsSlice.actions;
|
} = 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;
|
export default collectionsSlice.reducer;
|
||||||
|
@ -53,7 +53,7 @@ export const cloneItem = (item) => {
|
|||||||
return cloneDeep(item);
|
return cloneDeep(item);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const transformCollectionToSaveToIdb = (collection) => {
|
export const transformCollectionToSaveToIdb = (collection, options = {}) => {
|
||||||
const copyItems = (sourceItems, destItems) => {
|
const copyItems = (sourceItems, destItems) => {
|
||||||
each(sourceItems, (si) => {
|
each(sourceItems, (si) => {
|
||||||
const di = {
|
const di = {
|
||||||
@ -61,10 +61,10 @@ export const transformCollectionToSaveToIdb = (collection) => {
|
|||||||
type: si.type
|
type: si.type
|
||||||
};
|
};
|
||||||
|
|
||||||
// if items is draft, then take data from draft to save
|
di.name = si.name;
|
||||||
if(si.draft) {
|
|
||||||
di.name = si.draft.name;
|
|
||||||
|
|
||||||
|
// if items is draft, then take data from draft to save
|
||||||
|
if(!options.ignoreDraft && si.draft) {
|
||||||
if(si.draft.request) {
|
if(si.draft.request) {
|
||||||
di.request = {
|
di.request = {
|
||||||
url: si.draft.request.url,
|
url: si.draft.request.url,
|
||||||
@ -74,8 +74,6 @@ export const transformCollectionToSaveToIdb = (collection) => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
di.name = si.name;
|
|
||||||
|
|
||||||
if(si.request) {
|
if(si.request) {
|
||||||
di.request = {
|
di.request = {
|
||||||
url: si.request.url,
|
url: si.request.url,
|
||||||
|
Loading…
Reference in New Issue
Block a user