mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-21 15:33:11 +01:00
feat: drag item to root of collection
This commit is contained in:
parent
ee4734c957
commit
36d0550472
@ -51,7 +51,7 @@ const CollectionItem = ({ item, collection, searchText }) => {
|
||||
}
|
||||
},
|
||||
canDrop: (draggedItem) => {
|
||||
return draggedItem.id !== item.uid;
|
||||
return draggedItem.uid !== item.uid;
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isOver: monitor.isOver()
|
||||
|
@ -2,11 +2,11 @@ import React, { useState, forwardRef, useRef, useEffect } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import filter from 'lodash/filter';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import { DndProvider } from 'react-dnd';
|
||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||
import { useDrop } from 'react-dnd';
|
||||
import { IconChevronRight, IconDots } from '@tabler/icons';
|
||||
import Dropdown from 'components/Dropdown';
|
||||
import { collectionClicked } from 'providers/ReduxStore/slices/collections';
|
||||
import { moveItemToRootOfCollection } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import NewRequest from 'components/Sidebar/NewRequest';
|
||||
import NewFolder from 'components/Sidebar/NewFolder';
|
||||
@ -73,6 +73,21 @@ const Collection = ({ collection, searchText }) => {
|
||||
|
||||
const isLocal = isLocalCollection(collection);
|
||||
|
||||
const [{ isOver }, drop] = useDrop({
|
||||
accept: 'COLLECTION_ITEM',
|
||||
drop: (draggedItem) => {
|
||||
console.log('drop', draggedItem);
|
||||
dispatch(moveItemToRootOfCollection(collection.uid, draggedItem.uid));
|
||||
},
|
||||
canDrop: (draggedItem) => {
|
||||
// todo need to make sure that draggedItem belongs to the collection
|
||||
return true;
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isOver: monitor.isOver()
|
||||
})
|
||||
});
|
||||
|
||||
return (
|
||||
<StyledWrapper className="flex flex-col">
|
||||
{showNewRequestModal && <NewRequest collection={collection} onClose={() => setShowNewRequestModal(false)} />}
|
||||
@ -81,7 +96,7 @@ const Collection = ({ collection, searchText }) => {
|
||||
{showRemoveCollectionFromWSModal && <RemoveCollectionFromWorkspace collection={collection} onClose={() => setShowRemoveCollectionFromWSModal(false)} />}
|
||||
{showDeleteCollectionModal && <DeleteCollection collection={collection} onClose={() => setShowDeleteCollectionModal(false)} />}
|
||||
{showRemoveLocalCollectionModal && <RemoveLocalCollection collection={collection} onClose={() => setShowRemoveLocalCollectionModal(false)} />}
|
||||
<div className="flex py-1 collection-name items-center">
|
||||
<div className="flex py-1 collection-name items-center" ref={(node) => drop(node)}>
|
||||
<div className="flex flex-grow items-center" onClick={handleClick}>
|
||||
<IconChevronRight size={16} strokeWidth={2} className={iconClassName} style={{ width: 16, color: 'rgb(160 160 160)' }} />
|
||||
<div className="ml-1" id="sidebar-collection-name">{collection.name}</div>
|
||||
@ -164,21 +179,19 @@ const Collection = ({ collection, searchText }) => {
|
||||
|
||||
<div>
|
||||
{!collectionIsCollapsed ? (
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<div>
|
||||
{requestItems && requestItems.length
|
||||
? requestItems.map((i) => {
|
||||
return <CollectionItem key={i.uid} item={i} collection={collection} searchText={searchText} />;
|
||||
})
|
||||
: null}
|
||||
<div>
|
||||
{requestItems && requestItems.length
|
||||
? requestItems.map((i) => {
|
||||
return <CollectionItem key={i.uid} item={i} collection={collection} searchText={searchText} />;
|
||||
})
|
||||
: null}
|
||||
|
||||
{folderItems && folderItems.length
|
||||
? folderItems.map((i) => {
|
||||
return <CollectionItem key={i.uid} item={i} collection={collection} searchText={searchText} />;
|
||||
})
|
||||
: null}
|
||||
</div>
|
||||
</DndProvider>
|
||||
{folderItems && folderItems.length
|
||||
? folderItems.map((i) => {
|
||||
return <CollectionItem key={i.uid} item={i} collection={collection} searchText={searchText} />;
|
||||
})
|
||||
: null}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</StyledWrapper>
|
||||
|
@ -1,5 +1,7 @@
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { DndProvider } from 'react-dnd';
|
||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||
import find from 'lodash/find';
|
||||
import filter from 'lodash/filter';
|
||||
import Collection from './Collection';
|
||||
@ -26,7 +28,11 @@ const Collections = ({ searchText }) => {
|
||||
<div className="mt-4 flex flex-col">
|
||||
{collectionToDisplay && collectionToDisplay.length
|
||||
? collectionToDisplay.map((c) => {
|
||||
return <Collection searchText={searchText} collection={c} key={c.uid} />;
|
||||
return (
|
||||
<DndProvider backend={HTML5Backend} key={c.uid}>
|
||||
<Collection searchText={searchText} collection={c} />;
|
||||
</DndProvider>
|
||||
);
|
||||
})
|
||||
: null}
|
||||
</div>
|
||||
|
@ -8,6 +8,7 @@ import cloneDeep from 'lodash/cloneDeep';
|
||||
import {
|
||||
findItemInCollection,
|
||||
moveCollectionItem,
|
||||
moveCollectionItemToRootOfCollection,
|
||||
findCollectionByUid,
|
||||
recursivelyGetAllItemUids,
|
||||
transformCollectionToSaveToIdb,
|
||||
@ -35,6 +36,7 @@ import {
|
||||
cloneItem as _cloneItem,
|
||||
deleteItem as _deleteItem,
|
||||
moveItem as _moveItem,
|
||||
moveItemToRootOfCollection as _moveItemToRootOfCollection,
|
||||
saveRequest as _saveRequest,
|
||||
addEnvironment as _addEnvironment,
|
||||
renameEnvironment as _renameEnvironment,
|
||||
@ -615,6 +617,58 @@ export const moveItem = (collectionUid, draggedItemUid, targetItemUid) => (dispa
|
||||
});
|
||||
};
|
||||
|
||||
export const moveItemToRootOfCollection = (collectionUid, draggedItemUid) => (dispatch, getState) => {
|
||||
const state = getState();
|
||||
const collection = findCollectionByUid(state.collections.collections, collectionUid);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!collection) {
|
||||
return reject(new Error('Collection not found'));
|
||||
}
|
||||
|
||||
if (isLocalCollection(collection)) {
|
||||
const draggedItem = findItemInCollection(collection, draggedItemUid);
|
||||
|
||||
if (!draggedItem) {
|
||||
return reject(new Error('Dragged item not found'));
|
||||
}
|
||||
|
||||
const { ipcRenderer } = window;
|
||||
|
||||
ipcRenderer
|
||||
.invoke('renderer:move-item-to-root-of-collection', draggedItem.pathname)
|
||||
.then(() => resolve())
|
||||
.catch((error) => reject(error));
|
||||
return;
|
||||
}
|
||||
|
||||
const collectionCopy = cloneDeep(collection);
|
||||
const draggedItem = findItemInCollection(collectionCopy, draggedItemUid);
|
||||
|
||||
if (!draggedItem) {
|
||||
return reject(new Error('Dragged item not found'));
|
||||
}
|
||||
|
||||
moveCollectionItemToRootOfCollection(collectionCopy, draggedItem);
|
||||
|
||||
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
|
||||
|
||||
collectionSchema
|
||||
.validate(collectionToSave)
|
||||
.then(() => saveCollectionToIdb(window.__idb, collectionToSave))
|
||||
.then(() => {
|
||||
dispatch(
|
||||
_moveItemToRootOfCollection({
|
||||
collectionUid: collectionUid,
|
||||
draggedItemUid: draggedItemUid
|
||||
})
|
||||
);
|
||||
})
|
||||
.then(() => resolve())
|
||||
.catch((error) => reject(error));
|
||||
});
|
||||
};
|
||||
|
||||
export const newHttpRequest = (params) => (dispatch, getState) => {
|
||||
const { requestName, requestType, requestUrl, requestMethod, collectionUid, itemUid } = params;
|
||||
|
||||
|
@ -199,6 +199,21 @@ export const collectionsSlice = createSlice({
|
||||
addDepth(collection.items);
|
||||
}
|
||||
},
|
||||
moveItemToRootOfCollection: (state, action) => {
|
||||
const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
|
||||
const draggedItemUid = action.payload.draggedItemUid;
|
||||
|
||||
if (collection) {
|
||||
const draggedItem = findItemInCollection(collection, draggedItemUid);
|
||||
|
||||
if (!draggedItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
moveCollectionItemToRootOfCollection(collection, draggedItem);
|
||||
addDepth(collection.items);
|
||||
}
|
||||
},
|
||||
requestSent: (state, action) => {
|
||||
const { itemUid, collectionUid, cancelTokenUid } = action.payload;
|
||||
const collection = findCollectionByUid(state.collections, collectionUid);
|
||||
@ -804,6 +819,7 @@ export const {
|
||||
renameItem,
|
||||
cloneItem,
|
||||
moveItem,
|
||||
moveItemToRootOfCollection,
|
||||
requestSent,
|
||||
requestCancelled,
|
||||
responseReceived,
|
||||
|
@ -147,6 +147,18 @@ export const moveCollectionItem = (collection, draggedItem, targetItem) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const moveCollectionItemToRootOfCollection = (collection, draggedItem) => {
|
||||
let draggedItemParent = findParentItemInCollection(collection, draggedItem.uid);
|
||||
|
||||
if (draggedItemParent) {
|
||||
draggedItemParent.items = filter(draggedItemParent.items, (i) => i.uid !== draggedItem.uid);
|
||||
} else {
|
||||
collection.items = filter(collection.items, (i) => i.uid !== draggedItem.uid);
|
||||
}
|
||||
|
||||
collection.items.push(draggedItem);
|
||||
};
|
||||
|
||||
export const transformCollectionToSaveToIdb = (collection, options = {}) => {
|
||||
const copyHeaders = (headers) => {
|
||||
return map(headers, (header) => {
|
||||
|
Loading…
Reference in New Issue
Block a user