feat: Implement new drag-and-drop system for documents and tags, including workspace-level handling and improved visual feedback.
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import { useMemo, useCallback, useRef } from 'react';
|
||||
import type { DocumentsPanelInnerProps } from './DocumentsPanel';
|
||||
import { isTagTransferEvent } from '../features/tagging/tagTransfer';
|
||||
import { isPointerModifierEvent, isPrimaryPointerEvent } from '../features/selection/useEntryPointer';
|
||||
import { useDocumentsFilter } from '../context/DocumentsFilterContext';
|
||||
import { useWorkspaceSelectionContext } from '../../app/WorkspaceSelectionContext';
|
||||
import type { Identifier } from '../../types/identifiers';
|
||||
import { useTagInteractions } from '../interactions/useTagInteractions';
|
||||
|
||||
const EntryType = {
|
||||
folder: 'folder',
|
||||
@@ -37,6 +37,12 @@ export const useDocumentsContextValues = (props: DocumentsPanelInnerProps) => {
|
||||
toggleCorrespondent: toggleCorrespondentFilter,
|
||||
} = useDocumentsFilter();
|
||||
|
||||
// Handlers
|
||||
const tagDragHandlers = useTagInteractions({
|
||||
onAssignTagToDocument: props.onDocumentTagAttach,
|
||||
onRemoveTagFromDocument: props.onDocumentTagDetach,
|
||||
});
|
||||
|
||||
// Derived State
|
||||
const draggingDocumentIdsSet = useMemo(
|
||||
() => new Set(draggingDocumentIds || []),
|
||||
@@ -69,52 +75,6 @@ export const useDocumentsContextValues = (props: DocumentsPanelInnerProps) => {
|
||||
// Refs
|
||||
const scrollRef = useRef<HTMLElement | null>(null);
|
||||
const suppressDocumentClickRef = useRef(false);
|
||||
const draggingTagRef = useRef<{ docId: Identifier; tagId: Identifier } | null>(null);
|
||||
|
||||
// Handlers
|
||||
const isTagDragEvent = useCallback((event: any) => isTagTransferEvent(event), []);
|
||||
|
||||
const handleDocumentTagDragStart = useCallback(
|
||||
(_event: any, docId: Identifier, tagId: Identifier) => {
|
||||
draggingTagRef.current = { docId, tagId };
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const handleDocumentTagDragEnd = useCallback(
|
||||
(_event: any) => {
|
||||
draggingTagRef.current = null;
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const handleDocumentTagDragOver = useCallback(
|
||||
(event: any, docId: Identifier) => {
|
||||
if (!isTagDragEvent(event)) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
|
||||
const isSource = draggingTagRef.current?.docId === docId;
|
||||
event.dataTransfer.dropEffect = isSource ? 'copy' : 'move';
|
||||
|
||||
event.currentTarget.classList.add('tag-drop-target');
|
||||
},
|
||||
[isTagDragEvent],
|
||||
);
|
||||
|
||||
const handleDocumentTagDragLeave = useCallback(
|
||||
(event: any) => {
|
||||
if (!isTagDragEvent(event)) {
|
||||
return;
|
||||
}
|
||||
if (event.relatedTarget && event.currentTarget.contains(event.relatedTarget)) {
|
||||
return;
|
||||
}
|
||||
event.currentTarget.classList.remove('tag-drop-target');
|
||||
},
|
||||
[isTagDragEvent],
|
||||
);
|
||||
|
||||
const handleFolderClick = useCallback(
|
||||
(folder: any, event: any) => {
|
||||
@@ -187,10 +147,7 @@ export const useDocumentsContextValues = (props: DocumentsPanelInnerProps) => {
|
||||
handleFolderClick,
|
||||
handleDocumentDragStartLocal,
|
||||
handleDocumentDragEndLocal,
|
||||
handleDocumentTagDragStart,
|
||||
handleDocumentTagDragEnd,
|
||||
handleDocumentTagDragOver,
|
||||
handleDocumentTagDragLeave,
|
||||
tagDragHandlers,
|
||||
toggleTagFilter,
|
||||
toggleCorrespondentFilter,
|
||||
});
|
||||
@@ -201,10 +158,7 @@ export const useDocumentsContextValues = (props: DocumentsPanelInnerProps) => {
|
||||
handleFolderClick,
|
||||
handleDocumentDragStartLocal,
|
||||
handleDocumentDragEndLocal,
|
||||
handleDocumentTagDragStart,
|
||||
handleDocumentTagDragEnd,
|
||||
handleDocumentTagDragOver,
|
||||
handleDocumentTagDragLeave,
|
||||
tagDragHandlers,
|
||||
toggleTagFilter,
|
||||
toggleCorrespondentFilter,
|
||||
};
|
||||
@@ -231,10 +185,11 @@ export const useDocumentsContextValues = (props: DocumentsPanelInnerProps) => {
|
||||
},
|
||||
tags: {
|
||||
onDrag: {
|
||||
start: (e: any, d: any, t: any) => latestHandlersRef.current.handleDocumentTagDragStart(e, d, t),
|
||||
end: (e: any) => latestHandlersRef.current.handleDocumentTagDragEnd(e),
|
||||
over: (e: any, d: any) => latestHandlersRef.current.handleDocumentTagDragOver(e, d),
|
||||
leave: (e: any) => latestHandlersRef.current.handleDocumentTagDragLeave(e),
|
||||
start: (e: any, d: any, t: any) => latestHandlersRef.current.tagDragHandlers.onTagDragStart(e, d, t),
|
||||
end: (e: any) => latestHandlersRef.current.tagDragHandlers.onTagDragEnd(e),
|
||||
over: (e: any, d: any) => latestHandlersRef.current.tagDragHandlers.onTagDragOver(e, d),
|
||||
leave: (e: any, d: any) => latestHandlersRef.current.tagDragHandlers.onTagDragLeave(e, d.id),
|
||||
drop: (e: any, d: any) => latestHandlersRef.current.tagDragHandlers.onTagDrop(e, d),
|
||||
},
|
||||
onAttach: (d: any, t: any) => latestPropsRef.current.onDocumentTagAttach?.(d, t),
|
||||
onDetach: (d: any, t: any) => latestPropsRef.current.onDocumentTagDetach?.(d, t),
|
||||
|
||||
Reference in New Issue
Block a user