🐛(frontend) disable DND grid item when dialog open

We could drag and drop the items even if the
modal was opened, which could cause some unexpected
behaviors. This commit disables the DND
functionality when a dialog box is open.
This commit is contained in:
Anthony LC
2026-02-19 14:27:39 +01:00
parent 53985f77f3
commit 217af2e2a8
3 changed files with 36 additions and 16 deletions

View File

@@ -3,7 +3,7 @@ import { getEventCoordinates } from '@dnd-kit/utilities';
import { useModal } from '@gouvfr-lasuite/cunningham-react';
import { TreeViewMoveModeEnum } from '@gouvfr-lasuite/ui-kit';
import { useQueryClient } from '@tanstack/react-query';
import { useMemo, useRef } from 'react';
import { useEffect, useMemo, useRef, useState } from 'react';
import { Trans, useTranslation } from 'react-i18next';
import { AlertModal, Card, Text } from '@/components';
@@ -15,6 +15,7 @@ import {
useDeleteDocInvitation,
} from '@/docs/doc-share';
import { useMoveDoc } from '@/docs/doc-tree';
import { useResponsiveStore } from '@/stores/useResponsiveStore';
import { DocDragEndData, useDragAndDrop } from '../hooks/useDragAndDrop';
@@ -151,9 +152,24 @@ export const DraggableDocGridContentList = ({
const cannotMoveDoc =
!canDrag || (canDrop !== undefined && !canDrop) || isError;
if (docs.length === 0) {
return null;
}
const [isDraggableDisabled, setIsDraggableDisabled] = useState(false);
useEffect(() => {
const checkModal = () => {
const modalOpen = document.querySelector('[role="dialog"]');
setIsDraggableDisabled(!!modalOpen);
};
checkModal();
const observer = new MutationObserver(checkModal);
observer.observe(document.body, {
childList: true,
subtree: true,
});
return () => observer.disconnect();
}, []);
return (
<>
@@ -170,6 +186,7 @@ export const DraggableDocGridContentList = ({
dragMode={!!selectedDoc}
canDrag={!!canDrag}
updateCanDrop={updateCanDrop}
disabled={isDraggableDisabled}
/>
))}
<DragOverlay dropAnimation={null}>
@@ -216,6 +233,7 @@ export const DraggableDocGridContentList = ({
};
interface DraggableDocGridItemProps {
disabled: boolean;
doc: Doc;
dragMode: boolean;
canDrag: boolean;
@@ -223,6 +241,7 @@ interface DraggableDocGridItemProps {
}
export const DraggableDocGridItem = ({
disabled,
doc,
dragMode,
canDrag,
@@ -238,7 +257,7 @@ export const DraggableDocGridItem = ({
id={doc.id}
data={doc}
>
<Draggable id={doc.id} data={doc}>
<Draggable id={doc.id} data={doc} disabled={disabled}>
<DocsGridItem dragMode={dragMode} doc={doc} />
</Draggable>
</Droppable>
@@ -246,10 +265,16 @@ export const DraggableDocGridItem = ({
};
export const DocGridContentList = ({ docs }: DocGridContentListProps) => {
const { isDesktop } = useResponsiveStore();
if (docs.length === 0) {
return null;
}
if (isDesktop) {
return <DraggableDocGridContentList docs={docs} />;
}
return docs.map((doc) => (
<DocsGridItem dragMode={false} doc={doc} key={doc.id} />
));

View File

@@ -16,10 +16,7 @@ import { useInfiniteDocsTrashbin } from '../api';
import { useImport } from '../hooks/useImport';
import { useResponsiveDocGrid } from '../hooks/useResponsiveDocGrid';
import {
DocGridContentList,
DraggableDocGridContentList,
} from './DocGridContentList';
import { DocGridContentList } from './DocGridContentList';
import { DocsGridLoader } from './DocsGridLoader';
const Tooltip = styled(TooltipBase)`
@@ -166,11 +163,7 @@ export const DocsGrid = ({
</Box>
</Box>
<Box role="rowgroup">
{isDesktop ? (
<DraggableDocGridContentList docs={docs} />
) : (
<DocGridContentList docs={docs} />
)}
<DocGridContentList docs={docs} />
</Box>
</Box>
{hasNextPage && !loading && (

View File

@@ -1,15 +1,17 @@
import { Data, useDraggable } from '@dnd-kit/core';
import { PropsWithChildren } from 'react';
type DraggableProps<T> = {
id: string;
data?: Data<T>;
children: React.ReactNode;
disabled?: boolean;
};
export const Draggable = <T,>(props: DraggableProps<T>) => {
export const Draggable = <T,>(props: PropsWithChildren<DraggableProps<T>>) => {
const { attributes, listeners, setNodeRef } = useDraggable({
id: props.id,
data: props.data,
disabled: props.disabled,
});
return (