mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-09 06:55:03 +00:00
feat: add copy and paste functionality for requests (#5907)
This commit is contained in:
@@ -7,8 +7,9 @@ import { useDrag, useDrop } from 'react-dnd';
|
||||
import { IconChevronRight, IconDots } from '@tabler/icons';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import { addTab, focusTab, makeTabPermanent } from 'providers/ReduxStore/slices/tabs';
|
||||
import { handleCollectionItemDrop, sendRequest, showInFolder } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import { handleCollectionItemDrop, sendRequest, showInFolder, pasteItem } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import { toggleCollectionItem } from 'providers/ReduxStore/slices/collections';
|
||||
import { copyRequest } from 'providers/ReduxStore/slices/app';
|
||||
import Dropdown from 'components/Dropdown';
|
||||
import NewRequest from 'components/Sidebar/NewRequest';
|
||||
import NewFolder from 'components/Sidebar/NewFolder';
|
||||
@@ -40,6 +41,7 @@ const CollectionItem = ({ item, collectionUid, collectionPathname, searchText })
|
||||
const isTabForItemPresent = useSelector(_isTabForItemPresentSelector, isEqual);
|
||||
|
||||
const isSidebarDragging = useSelector((state) => state.app.isDragging);
|
||||
const { hasCopiedItems } = useSelector((state) => state.app.clipboard);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
// We use a single ref for drag and drop.
|
||||
@@ -306,6 +308,23 @@ const CollectionItem = ({ item, collectionUid, collectionPathname, searchText })
|
||||
}
|
||||
};
|
||||
|
||||
const handleCopyRequest = () => {
|
||||
dropdownTippyRef.current.hide();
|
||||
dispatch(copyRequest(item));
|
||||
toast.success('Request copied to clipboard');
|
||||
};
|
||||
|
||||
const handlePasteRequest = () => {
|
||||
dropdownTippyRef.current.hide();
|
||||
dispatch(pasteItem(collectionUid, item.uid))
|
||||
.then(() => {
|
||||
toast.success('Request pasted successfully');
|
||||
})
|
||||
.catch((err) => {
|
||||
toast.error(err ? err.message : 'An error occurred while pasting the request');
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledWrapper className={className}>
|
||||
{renameItemModalOpen && (
|
||||
@@ -431,6 +450,22 @@ const CollectionItem = ({ item, collectionUid, collectionPathname, searchText })
|
||||
>
|
||||
Clone
|
||||
</div>
|
||||
{!isFolder && (
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={handleCopyRequest}
|
||||
>
|
||||
Copy
|
||||
</div>
|
||||
)}
|
||||
{isFolder && hasCopiedItems && (
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={handlePasteRequest}
|
||||
>
|
||||
Paste
|
||||
</div>
|
||||
)}
|
||||
{!isFolder && (
|
||||
<div
|
||||
className="dropdown-item"
|
||||
|
||||
@@ -7,10 +7,11 @@ import { useDrop, useDrag } from 'react-dnd';
|
||||
import { IconChevronRight, IconDots, IconLoader2 } from '@tabler/icons';
|
||||
import Dropdown from 'components/Dropdown';
|
||||
import { toggleCollection, collapseFullCollection } from 'providers/ReduxStore/slices/collections';
|
||||
import { mountCollection, moveCollectionAndPersist, handleCollectionItemDrop } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import { mountCollection, moveCollectionAndPersist, handleCollectionItemDrop, pasteItem } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { hideHomePage } from 'providers/ReduxStore/slices/app';
|
||||
import { addTab, makeTabPermanent } from 'providers/ReduxStore/slices/tabs';
|
||||
import toast from 'react-hot-toast';
|
||||
import NewRequest from 'components/Sidebar/NewRequest';
|
||||
import NewFolder from 'components/Sidebar/NewFolder';
|
||||
import CollectionItem from './CollectionItem';
|
||||
@@ -41,7 +42,7 @@ const Collection = ({ collection, searchText }) => {
|
||||
const collectionRef = useRef(null);
|
||||
|
||||
const isCollectionFocused = useSelector(isTabForItemActive({ itemUid: collection.uid }));
|
||||
|
||||
const { hasCopiedItems } = useSelector((state) => state.app.clipboard);
|
||||
const menuDropdownTippyRef = useRef();
|
||||
const onMenuDropdownCreate = (ref) => (menuDropdownTippyRef.current = ref);
|
||||
const MenuIcon = forwardRef((_props, ref) => {
|
||||
@@ -146,6 +147,17 @@ const Collection = ({ collection, searchText }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const handlePasteRequest = () => {
|
||||
menuDropdownTippyRef.current.hide();
|
||||
dispatch(pasteItem(collection.uid, null))
|
||||
.then(() => {
|
||||
toast.success('Request pasted successfully');
|
||||
})
|
||||
.catch((err) => {
|
||||
toast.error(err ? err.message : 'An error occurred while pasting the request');
|
||||
});
|
||||
};
|
||||
|
||||
const isCollectionItem = (itemType) => {
|
||||
return itemType === 'collection-item';
|
||||
};
|
||||
@@ -286,6 +298,14 @@ const Collection = ({ collection, searchText }) => {
|
||||
>
|
||||
Clone
|
||||
</div>
|
||||
{hasCopiedItems && (
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={handlePasteRequest}
|
||||
>
|
||||
Paste
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(_e) => {
|
||||
|
||||
@@ -90,7 +90,7 @@ const NewFolder = ({ collectionUid, item, onClose }) => {
|
||||
Folder Name
|
||||
</label>
|
||||
<input
|
||||
id="collection-name"
|
||||
id="folder-name"
|
||||
type="text"
|
||||
name="folderName"
|
||||
ref={inputRef}
|
||||
|
||||
Reference in New Issue
Block a user