mirror of
https://github.com/Kong/insomnia.git
synced 2026-08-04 11:52:33 -04:00
fix: fix dnd for empty nodes (#9909)
* fix: fix dnd for empty nodes * remove console log Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -6,12 +6,16 @@ import { DropIndicator, useDragAndDrop } from 'react-aria-components';
|
||||
import { models } from '~/insomnia-data';
|
||||
import { useDebugReorderActionFetcher } from '~/routes/organization.$organizationId.project.$projectId.workspace.$workspaceId.debug.reorder';
|
||||
|
||||
import type { CollectionChildFlatItem, FlatItem } from './types';
|
||||
import type { CollectionChildFlatItem, EmptyNodeFlatItem, FlatItem } from './types';
|
||||
|
||||
const allowDragKinds: FlatItem['kind'][] = ['workspace', 'collectionChild'];
|
||||
const allowDropKinds: FlatItem['kind'][] = ['workspace', 'collectionChild', 'project'];
|
||||
const emptyNodeKinds: FlatItem['kind'][] = ['emptyFolder', 'emptyProject', 'emptyCollection'];
|
||||
const allowDropKinds: FlatItem['kind'][] = ['workspace', 'collectionChild', 'project', ...emptyNodeKinds];
|
||||
type AllowDragItem = Extract<FlatItem, { kind: 'workspace' | 'collectionChild' }>;
|
||||
type AllowDropTarget = Extract<FlatItem, { kind: 'workspace' | 'collectionChild' | 'project' }>;
|
||||
type AllowDropTarget = Extract<
|
||||
FlatItem,
|
||||
{ kind: 'workspace' | 'collectionChild' | 'project' | 'emptyFolder' | 'emptyProject' | 'emptyCollection' }
|
||||
>;
|
||||
|
||||
function isAllowDragItem(item: FlatItem): item is AllowDragItem {
|
||||
return allowDragKinds.includes(item.kind);
|
||||
@@ -21,6 +25,10 @@ function isAllowDropTarget(item: FlatItem): item is AllowDropTarget {
|
||||
return allowDropKinds.includes(item.kind);
|
||||
}
|
||||
|
||||
function isEmptyNode(item: FlatItem): item is EmptyNodeFlatItem {
|
||||
return emptyNodeKinds.includes(item.kind);
|
||||
}
|
||||
|
||||
function canDrop(
|
||||
dragItem: FlatItem,
|
||||
dropItem: FlatItem,
|
||||
@@ -47,13 +55,25 @@ function canDrop(
|
||||
|
||||
// workspace -> project: cannot involve cloud project, and cannot move into same project
|
||||
if (dragItem.kind === 'workspace') {
|
||||
if (realDropItem && realDropItem.kind === 'project') {
|
||||
return (
|
||||
dragItem.project._id !== realDropItem.doc._id &&
|
||||
!dragInCloud &&
|
||||
!models.project.isRemoteProject(realDropItem.doc)
|
||||
);
|
||||
if (realDropItem) {
|
||||
// move into project after
|
||||
if (realDropItem.kind === 'project') {
|
||||
return (
|
||||
dragItem.project._id !== realDropItem.doc._id &&
|
||||
!dragInCloud &&
|
||||
!models.project.isRemoteProject(realDropItem.doc)
|
||||
);
|
||||
}
|
||||
// move into between workspaces, only allow if they are from different projects and none of them are in cloud
|
||||
if (realDropItem.kind === 'workspace') {
|
||||
return (
|
||||
dragItem.project._id !== realDropItem.project._id &&
|
||||
!dragInCloud &&
|
||||
!models.project.isRemoteProject(realDropItem.project)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -73,8 +93,8 @@ function canDrop(
|
||||
return !dragInCloud && !dropInCloud;
|
||||
}
|
||||
|
||||
// move other things into workspace is not allowed
|
||||
if (realDropItem.kind === 'workspace') {
|
||||
// move other things into workspace is not allowed, or move after empty node is not allowed
|
||||
if (realDropItem.kind === 'workspace' || isEmptyNode(realDropItem)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -127,10 +147,11 @@ export const useSidebarDragAndDrop = ({
|
||||
return 'move';
|
||||
},
|
||||
onMove(event) {
|
||||
const { type, dropPosition, key } = event.target;
|
||||
const { type, dropPosition: _dropPosition, key } = event.target;
|
||||
if (type !== 'item') {
|
||||
return;
|
||||
}
|
||||
let dropPosition = _dropPosition;
|
||||
const isBefore = dropPosition === 'before';
|
||||
const droppedKey = key.toString();
|
||||
|
||||
@@ -154,7 +175,7 @@ export const useSidebarDragAndDrop = ({
|
||||
workspaceId: draggedItem.doc._id,
|
||||
params: {
|
||||
type: 'move-workspace',
|
||||
targetId: realTargetItem!.doc._id,
|
||||
targetId: realTargetItem?.kind === 'workspace' ? realTargetItem.project._id : realTargetItem!.doc._id,
|
||||
id: draggedItem.doc._id,
|
||||
},
|
||||
});
|
||||
@@ -182,25 +203,39 @@ export const useSidebarDragAndDrop = ({
|
||||
}
|
||||
|
||||
const id = draggedItem.doc._id;
|
||||
const targetId = targetItem.doc._id;
|
||||
let targetId = targetItem.doc._id;
|
||||
const targetIsEmptyNode = isEmptyNode(targetItem);
|
||||
const workspaceCollectionItems = flatItems.filter(
|
||||
(item): item is CollectionChildFlatItem =>
|
||||
item.kind === 'collectionChild' && item.workspace._id === draggedItem.workspace._id,
|
||||
);
|
||||
let metaSortKey = 0;
|
||||
const isMovingItemInsideFolder =
|
||||
models.requestGroup.isRequestGroup(targetItem.doc) && event.target.dropPosition === 'after';
|
||||
!targetIsEmptyNode && models.requestGroup.isRequestGroup(targetItem.doc) && dropPosition === 'after';
|
||||
|
||||
const isMovingOnEmptyNode =
|
||||
realTargetItem &&
|
||||
'type' in realTargetItem.doc &&
|
||||
models.requestGroup.isRequestGroup(realTargetItem.doc) &&
|
||||
targetIsEmptyNode;
|
||||
|
||||
if (isMovingItemInsideFolder) {
|
||||
// The reorder route interprets "after folder" as moving into that folder.
|
||||
const children = workspaceCollectionItems.filter(item => item.doc.parentId === targetId);
|
||||
metaSortKey = children.length > 0 ? children[0].doc.metaSortKey - 100 : -1 * Date.now();
|
||||
} else if (isMovingOnEmptyNode) {
|
||||
targetId = realTargetItem.doc._id;
|
||||
dropPosition = 'after';
|
||||
metaSortKey = -1 * Date.now();
|
||||
} else {
|
||||
// move before or after another request in same or different collection
|
||||
const siblingItems = workspaceCollectionItems.filter(item => item.doc.parentId === targetItem.doc.parentId);
|
||||
const siblingItems = workspaceCollectionItems.filter(
|
||||
item => 'parentId' in targetItem.doc && item.doc.parentId === targetItem.doc.parentId,
|
||||
);
|
||||
const targetIndex = siblingItems.findIndex(item => item.doc._id === targetId);
|
||||
|
||||
if ('metaSortKey' in targetItem.doc && targetItem.doc.metaSortKey != null) {
|
||||
if (event.target.dropPosition === 'after') {
|
||||
if (dropPosition === 'after') {
|
||||
const afterItem = siblingItems[targetIndex + 1];
|
||||
metaSortKey = afterItem
|
||||
? targetItem.doc.metaSortKey - (targetItem.doc.metaSortKey - afterItem.doc.metaSortKey) / 2
|
||||
@@ -225,7 +260,7 @@ export const useSidebarDragAndDrop = ({
|
||||
params: {
|
||||
targetId,
|
||||
id,
|
||||
dropPosition: event.target.dropPosition,
|
||||
dropPosition,
|
||||
metaSortKey,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user