refactor: Consolidate document view props into a shared interface and refine tag drop payload handling.

This commit is contained in:
2025-11-25 12:11:42 +01:00
parent 9c116cfe8c
commit 5191d50d42
4 changed files with 105 additions and 163 deletions
+32 -63
View File
@@ -10,7 +10,7 @@ import type {
DocumentTag,
} from '../DocumentsList';
import DesktopWorkspace from '../../desktop/DesktopWorkspace';
import { isTagTransferEvent, parseTagTransferPayload } from '../tagTransfer';
import { isTagTransferEvent } from '../tagTransfer';
import PreviewZoomOverlay from '../../detail/PreviewZoomOverlay';
import { isPointerModifierEvent, isPrimaryPointerEvent } from '../useEntryPointer';
import {
@@ -48,7 +48,7 @@ const defaultGetDocumentAsset = (_doc?: unknown, _type?: string) => null;
export type DocumentLinkLike = { url?: string | null; mimeType?: string | null };
export interface DocumentsListProps {
export interface DocumentsViewProps {
entries: DocumentsListEntry[];
draggingDocumentIdsSet?: Set<Identifier> | null;
draggedFolderId?: Identifier | 'root' | null;
@@ -56,25 +56,33 @@ export interface DocumentsListProps {
getDocumentAsset?: (...args: any[]) => unknown;
onFolderClick?: FolderEventHandler;
onFolderSelect?: (folderId: Identifier | 'root') => void;
onFolderDragOver?: (event: DragEvent<HTMLTableRowElement>, folderId: Identifier | 'root') => void;
onFolderDragLeave?: (event: DragEvent<HTMLTableRowElement>) => void;
onFolderDrop?: (event: DragEvent<HTMLTableRowElement>, folderId: Identifier | 'root') => void;
onFolderDragStart?: (event: DragEvent<HTMLTableRowElement>, folderId: Identifier | 'root') => void;
onFolderDragEnd?: (event: DragEvent<HTMLTableRowElement>) => void;
onFolderDragOver?: (event: DragEvent<HTMLElement>, folderId: Identifier | 'root') => void;
onFolderDragLeave?: (event: DragEvent<HTMLElement>) => void;
onFolderDrop?: (event: DragEvent<HTMLElement>, folderId: Identifier | 'root') => void;
onFolderDragStart?: (event: DragEvent<HTMLElement>, folderId: Identifier | 'root') => void;
onFolderDragEnd?: (event: DragEvent<HTMLElement>) => void;
onFolderRename?: (folderId: Identifier | 'root', nextName: string) => Promise<boolean> | boolean;
onDocumentClick?: DocumentEventHandler;
onDocumentActivate?: DocumentEventHandler;
onDocumentDragStart?: (event: DragEvent<HTMLTableRowElement>, document: DocumentLike) => void;
onDocumentDragEnd?: (event: DragEvent<HTMLTableRowElement>) => void;
onDocumentTagDragOver?: (event: DragEvent<HTMLTableRowElement>) => void;
onDocumentTagDragLeave?: (event: DragEvent<HTMLTableRowElement>) => void;
onDocumentTagDrop?: (event: DragEvent<HTMLTableRowElement>, documentId: Identifier) => void;
onDocumentDragStart?: (event: DragEvent<HTMLElement>, document: DocumentLike) => void;
onDocumentDragEnd?: (event: DragEvent<HTMLElement>) => void;
onDocumentTagDragOver?: (event: DragEvent<HTMLElement>) => void;
onDocumentTagDragLeave?: (event: DragEvent<HTMLElement>) => void;
onDocumentTagDrop?: (documentId: Identifier, tag: any) => void;
onDocumentRename?: (documentId: Identifier, nextTitle: string) => Promise<boolean> | boolean;
tagLookupById?: Map<Identifier, DocumentTag> | null;
onTagClick?: (tagId: Identifier) => void;
onCorrespondentClick?: (correspondentId: Identifier) => void;
activeCorrespondentIdSet?: Set<Identifier> | null;
scrollRef?: RefObject<HTMLElement | null>;
// Desk specific (optional for now or handled via intersection)
tenantId?: Identifier | null;
viewId?: string | null;
documentLinks?: Map<Identifier, any> | null;
ensureDownloadUrl?: (docId: Identifier, options?: { force?: boolean }) => Promise<any>;
onDocumentStackSelect?: (docIds: Identifier[], event?: any) => void;
onPromoteSelection?: (docId: Identifier | null) => void;
activeTagFilters?: Array<Identifier | null>;
}
const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
@@ -777,53 +785,7 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
[entries],
);
const handleListDocumentTagDrop = useCallback(
(event: React.DragEvent<HTMLElement>, docId: Identifier) => {
event.preventDefault();
event.stopPropagation();
const payload = parseTagTransferPayload(event);
if (payload && onDocumentTagDrop) {
onDocumentTagDrop(docId, payload);
}
},
[onDocumentTagDrop],
);
const deskWorkspaceProps = useMemo(
() => ({
entries: rows,
onDocumentActivate,
onDocumentClick: onEntryPointer,
onDocumentStackSelect: handleDeskDocumentStackSelect,
onPromoteSelection: promoteSelectionOrder,
onDocumentTagDrop,
ensureAssetUrl,
getDocumentAsset,
activeTagFilters,
tenantId: currentTenantId,
viewId: deskViewId,
documentLinks: documentLinkMap,
ensureDownloadUrl,
}),
[
rows,
onDocumentActivate,
onEntryPointer,
handleDeskDocumentStackSelect,
promoteSelectionOrder,
onDocumentTagDrop,
ensureAssetUrl,
getDocumentAsset,
activeTagFilters,
currentTenantId,
deskViewId,
documentLinkMap,
ensureDownloadUrl,
],
);
const listProps: DocumentsListProps = {
const viewProps: DocumentsViewProps = {
entries,
draggingDocumentIdsSet: draggingSet,
draggedFolderId,
@@ -840,7 +802,7 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
onDocumentDragEnd: handleDocumentDragEndLocal,
onDocumentTagDragOver: handleDocumentTagDragOver,
onDocumentTagDragLeave: handleDocumentTagDragLeave,
onDocumentTagDrop: handleListDocumentTagDrop,
onDocumentTagDrop,
onDocumentRename,
onFolderRename,
ensureAssetUrl,
@@ -850,6 +812,13 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
onCorrespondentClick: toggleCorrespondentFilter,
activeCorrespondentIdSet: activeCorrespondentIdSet,
scrollRef,
// Desk specific
onDocumentStackSelect: handleDeskDocumentStackSelect,
onPromoteSelection: promoteSelectionOrder,
tenantId: currentTenantId,
viewId: deskViewId,
documentLinks: documentLinkMap,
ensureDownloadUrl,
};
const renderBody = () => {
@@ -874,12 +843,12 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
switch (viewMode) {
case 'desk':
return <DesktopWorkspace {...deskWorkspaceProps} />;
return <DesktopWorkspace {...viewProps} />;
case 'grid':
return <DocumentsGrid {...listProps} gridIconSize={gridIconSize} />;
return <DocumentsGrid {...viewProps} gridIconSize={gridIconSize} />;
case 'list':
default:
return <DocumentsList {...listProps} />;
return <DocumentsList {...viewProps} />;
}
};