This commit is contained in:
2025-11-24 20:49:22 +01:00
parent 46fa63af8a
commit 8aab635b13
@@ -1,9 +1,9 @@
import { useCallback, useEffect, useRef } from 'react';
import { useCallback, useEffect, useMemo, useRef } from 'react';
import type { DragEvent } from 'react';
import { isPlainObject } from '../../utils/typeGuards';
type Identifier = string | number;
type FolderIdentifier = Identifier | 'root';
type FolderIdentifier = string | 'root';
type FolderInput = FolderIdentifier | number;
interface DocumentLike {
id?: Identifier | null;
@@ -24,7 +24,7 @@ type HandleEntrySelectionFn = (
interface UseDocumentDragHandlersOptions {
selectedEntries: string[];
selectedDocumentIds: Identifier[];
selectedFolderIds: FolderIdentifier[];
selectedFolderIds: FolderInput[];
applySelection: ApplySelectionFn;
handleEntrySelection: HandleEntrySelectionFn;
documentLookup: Map<Identifier, DocumentLike>;
@@ -49,6 +49,10 @@ const useDocumentDragHandlers = ({
documentsViewMode,
}: UseDocumentDragHandlersOptions) => {
const dragPreviewRef = useRef<HTMLDivElement | null>(null);
const normalizedFolderIds = useMemo(
() => selectedFolderIds.map((id) => (id === 'root' ? 'root' : String(id))) as FolderIdentifier[],
[selectedFolderIds],
);
const destroyDragPreview = useCallback(() => {
const node = dragPreviewRef.current;
@@ -61,7 +65,7 @@ const useDocumentDragHandlers = ({
useEffect(() => destroyDragPreview, [destroyDragPreview]);
const createDragPreview = useCallback(
({ documents = [], folders = [] }: { documents?: DocumentLike[]; folders?: Array<FolderIdentifier | Identifier> } = {}) => {
({ documents = [], folders = [] }: { documents?: DocumentLike[]; folders?: FolderIdentifier[] } = {}) => {
destroyDragPreview();
const docEntries = (documents || []).filter(Boolean);
@@ -145,17 +149,7 @@ const useDocumentDragHandlers = ({
}
} else {
const payload = item.payload;
const folderId = (() => {
if (isPlainObject(payload) && 'id' in payload) {
return (payload as { id?: FolderIdentifier }).id ?? null;
}
const maybeTrim = (payload as { trim?: () => string })?.trim;
if (typeof maybeTrim === 'function') {
const nextValue = maybeTrim.call(payload);
return nextValue || null;
}
return null;
})();
const folderId = payload as FolderIdentifier;
const rowEl = folderId
? (document.getElementById(`folder-row-${folderId}`)
|| document.getElementById(`folder-card-${folderId}`))
@@ -300,28 +294,29 @@ const useDocumentDragHandlers = ({
);
const handleFolderDragStart = useCallback(
(event: DragEvent<HTMLElement>, folderId: FolderIdentifier) => {
if (folderId === 'root') {
(event: DragEvent<HTMLElement>, folderId: FolderInput) => {
const normalizedFolderId: FolderIdentifier = folderId === 'root' ? 'root' : String(folderId);
if (normalizedFolderId === 'root') {
return;
}
event.stopPropagation();
const folderKey = resolveFolderRowKey(folderId);
const folderKey = resolveFolderRowKey(normalizedFolderId);
const isAlreadySelected = folderKey ? selectedEntries.includes(folderKey) : false;
let effectiveFolderSelection: FolderIdentifier[] = selectedFolderIds;
let effectiveFolderSelection: FolderIdentifier[] = normalizedFolderIds;
let effectiveDocumentSelection: Identifier[] = selectedDocumentIds;
if (!isAlreadySelected && folderKey) {
effectiveFolderSelection = [folderId];
effectiveFolderSelection = [normalizedFolderId];
effectiveDocumentSelection = [];
handleEntrySelection(folderKey, { preventDefault: () => {} });
}
const uniqueFolders = effectiveFolderSelection.length
? Array.from(new Set(effectiveFolderSelection.filter(Boolean)))
: [folderId];
: [normalizedFolderId];
setDraggedFolderId(folderId);
setDraggedFolderId(normalizedFolderId);
if (effectiveDocumentSelection.length) {
setDraggedDocumentIds(effectiveDocumentSelection);
}
@@ -360,7 +355,7 @@ const useDocumentDragHandlers = ({
}
},
[
selectedFolderIds,
normalizedFolderIds,
selectedEntries,
selectedDocumentIds,
handleEntrySelection,