Navbar drag drop using dnd kit (#18288)

This commit is contained in:
Abdul Rahman
2026-03-09 01:55:50 +05:30
committed by GitHub
parent 66d93c4d28
commit 5b28e59ca7
119 changed files with 3563 additions and 1297 deletions
@@ -1,66 +1,78 @@
import { isDefined } from 'twenty-shared/utils';
import type { NavigationMenuItem } from '~/generated-metadata/graphql';
import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
import { getPositionBetween } from '@/navigation-menu-item/utils/getPositionBetween';
import { isNavigationMenuItemFolder } from '@/navigation-menu-item/utils/isNavigationMenuItemFolder';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
const swapPositionsInDraft = (
draft: NavigationMenuItem[],
itemA: NavigationMenuItem,
itemB: NavigationMenuItem,
): NavigationMenuItem[] =>
draft.map((item) => {
if (item.id === itemA.id) {
return { ...item, position: itemB.position };
}
if (item.id === itemB.id) {
return { ...item, position: itemA.position };
}
return item;
});
import { useWorkspaceSectionItems } from './useWorkspaceSectionItems';
export const useNavigationMenuItemMoveRemove = () => {
const setNavigationMenuItemsDraft = useSetAtomState(
navigationMenuItemsDraftState,
);
const items = useWorkspaceSectionItems();
const visibleItemIds = new Set(items.map((item) => item.id));
const moveUp = (navigationMenuItemId: string) => {
setNavigationMenuItemsDraft((draft) => {
if (!draft) return draft;
if (!draft) {
return draft;
}
const currentItem = draft.find(
(item) => item.id === navigationMenuItemId,
);
if (!currentItem) return draft;
if (!currentItem) {
return draft;
}
const folderId = currentItem.folderId ?? null;
const siblings = draft
.filter((item) => (item.folderId ?? null) === folderId)
.filter(
(item) =>
(item.folderId ?? null) === folderId && visibleItemIds.has(item.id),
)
.sort((a, b) => a.position - b.position);
const currentIndex = siblings.findIndex(
(item) => item.id === navigationMenuItemId,
);
if (currentIndex <= 0) return draft;
if (currentIndex <= 0) {
return draft;
}
const itemAbove = siblings[currentIndex - 1];
return swapPositionsInDraft(draft, currentItem, itemAbove);
const prev = siblings[currentIndex - 1];
const prevPrev = siblings[currentIndex - 2];
const newPosition = getPositionBetween(prevPrev?.position, prev.position);
return draft.map((item) =>
item.id === navigationMenuItemId
? { ...item, position: newPosition }
: item,
);
});
};
const moveDown = (navigationMenuItemId: string) => {
setNavigationMenuItemsDraft((draft) => {
if (!draft) return draft;
if (!draft) {
return draft;
}
const currentItem = draft.find(
(item) => item.id === navigationMenuItemId,
);
if (!currentItem) return draft;
if (!currentItem) {
return draft;
}
const folderId = currentItem.folderId ?? null;
const siblings = draft
.filter((item) => (item.folderId ?? null) === folderId)
.filter(
(item) =>
(item.folderId ?? null) === folderId && visibleItemIds.has(item.id),
)
.sort((a, b) => a.position - b.position);
const currentIndex = siblings.findIndex(
@@ -70,19 +82,30 @@ export const useNavigationMenuItemMoveRemove = () => {
return draft;
}
const itemBelow = siblings[currentIndex + 1];
return swapPositionsInDraft(draft, currentItem, itemBelow);
const next = siblings[currentIndex + 1];
const nextNext = siblings[currentIndex + 2];
const newPosition = getPositionBetween(next.position, nextNext?.position);
return draft.map((item) =>
item.id === navigationMenuItemId
? { ...item, position: newPosition }
: item,
);
});
};
const remove = (navigationMenuItemId: string) => {
setNavigationMenuItemsDraft((draft) => {
if (!draft) return draft;
if (!draft) {
return draft;
}
const itemToRemove = draft.find(
(item) => item.id === navigationMenuItemId,
);
if (!itemToRemove) return draft;
if (!itemToRemove) {
return draft;
}
const isFolder = isNavigationMenuItemFolder(itemToRemove);
@@ -103,10 +126,14 @@ export const useNavigationMenuItemMoveRemove = () => {
targetFolderId: string | null,
) => {
setNavigationMenuItemsDraft((draft) => {
if (!draft) return draft;
if (!draft) {
return draft;
}
const itemToMove = draft.find((item) => item.id === navigationMenuItemId);
if (!itemToMove) return draft;
if (!itemToMove) {
return draft;
}
const isFolder = isNavigationMenuItemFolder(itemToMove);
if (isFolder && targetFolderId === navigationMenuItemId) {