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

View File

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

View File

@@ -1,15 +1,17 @@
import { Data, useDraggable } from '@dnd-kit/core'; import { Data, useDraggable } from '@dnd-kit/core';
import { PropsWithChildren } from 'react';
type DraggableProps<T> = { type DraggableProps<T> = {
id: string; id: string;
data?: Data<T>; 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({ const { attributes, listeners, setNodeRef } = useDraggable({
id: props.id, id: props.id,
data: props.data, data: props.data,
disabled: props.disabled,
}); });
return ( return (