feat: Implement new drag-and-drop system for documents and tags, including workspace-level handling and improved visual feedback.

This commit is contained in:
2025-12-08 23:30:18 +01:00
parent a850f70e24
commit 757913cf00
15 changed files with 293 additions and 355 deletions
@@ -1,6 +1,5 @@
import React, { useMemo } from 'react';
import { getTagColorStyle } from '../../utils/colors';
import { writeTagTransferData } from '../features/tagging/tagTransfer';
import type { DocumentTag } from '../../types/documents';
import type { Identifier } from '../../types/identifiers';
@@ -9,8 +8,7 @@ interface DocumentTagsProps {
tagLookupById?: Map<Identifier, DocumentTag> | null;
onTagClick?: (tagId: Identifier) => void;
docId: Identifier;
onDocumentTagDetach?: (docId: Identifier, tagId: Identifier) => void;
onTagDragStart?: (event: React.DragEvent<HTMLElement>, tagId: Identifier) => void;
onTagDragStart?: (event: React.DragEvent<HTMLElement>, tag: DocumentTag) => void;
onTagDragEnd?: (event: React.DragEvent<HTMLElement>) => void;
}
@@ -19,7 +17,6 @@ const DocumentTags: React.FC<DocumentTagsProps> = ({
tagLookupById,
onTagClick,
docId,
onDocumentTagDetach,
onTagDragStart,
onTagDragEnd,
}) => {
@@ -58,24 +55,13 @@ const DocumentTags: React.FC<DocumentTagsProps> = ({
} : undefined}
draggable
onDragStart={(event) => {
event.stopPropagation();
try {
if (event.dataTransfer) {
event.dataTransfer.effectAllowed = 'copyMove';
}
} catch (error) {
console.warn('[documents] Failed to configure drag effect', error);
}
writeTagTransferData(event.dataTransfer, tag, docId);
if (tagId) {
onTagDragStart?.(event, tagId);
// Let the hook handle the data transfer and UI
if (tagId && onTagDragStart) {
onTagDragStart(event, tag);
}
}}
onDragEnd={(event) => {
event.stopPropagation();
if (event.dataTransfer.dropEffect === 'move' && tagId && onDocumentTagDetach) {
onDocumentTagDetach(docId, tagId);
}
// Let the hook handle the cleanup and logic
onTagDragEnd?.(event);
}}
onKeyDown={clickable ? (event) => {
@@ -9,7 +9,7 @@ interface EntryTagsProps {
onTagClick?: (tagId: Identifier) => void;
docId: Identifier;
onDocumentTagDetach?: (docId: Identifier, tagId: Identifier) => void;
onTagDragStart?: (event: React.DragEvent<HTMLElement>, tagId: Identifier) => void;
onTagDragStart?: (event: React.DragEvent<HTMLElement>, tag: DocumentTag) => void;
onTagDragEnd?: (event: React.DragEvent<HTMLElement>) => void;
}