refactor: Decompose document and folder views into modular components and hooks, replacing monolithic list/grid implementations.

This commit is contained in:
2025-11-26 01:50:53 +01:00
parent 342714528a
commit 0a4a3ae35c
20 changed files with 1074 additions and 917 deletions
@@ -0,0 +1,89 @@
import React, { type DragEvent } from 'react';
import { parseTagTransferPayload } from '../tagTransfer';
import type { Document } from '../../types/documents';
import type { DocumentsViewProps } from '../panel/DocumentsPanel';
import type { DocumentViewLogic } from './useDocumentViewLogic';
interface UseDocumentItemLogicProps extends DocumentsViewProps {
doc: Document;
viewLogic: DocumentViewLogic;
}
export const useDocumentItemLogic = (props: UseDocumentItemLogicProps) => {
const {
doc,
viewLogic,
draggingDocumentIdsSet,
onDocumentClick,
onDocumentActivate,
onDocumentDragStart,
onDocumentDragEnd,
onDocumentTagDragOver,
onDocumentTagDragLeave,
onDocumentTagDrop,
onDocumentRename,
} = props;
const {
selectedDocumentIdsSet,
totalSelectionCount,
documentRename: {
editingId: editingDocumentId,
draftValue: documentDraft,
setDraftValue: setDocumentDraft,
beginEditing: beginDocumentEditing,
cancelEditing: cancelDocumentEditing,
submitEditing: submitDocumentEditing,
savingId: savingDocumentId,
attachInputRef: attachDocumentInputRef,
},
} = viewLogic;
const isSelected = selectedDocumentIdsSet?.has(doc.id);
const isDraggingDoc = draggingDocumentIdsSet?.has(doc.id);
const isEditingDoc = editingDocumentId === doc.id;
const documentDraftValue = isEditingDoc ? documentDraft : doc.title;
const trimmedDocumentDraft = isEditingDoc ? documentDraft.trim() : '';
const isDocumentSaving = savingDocumentId === doc.id;
const canSubmitDocument =
isEditingDoc && trimmedDocumentDraft.length > 0 && trimmedDocumentDraft !== doc.title;
const allowInlineDocumentEdit = onDocumentRename && isSelected && totalSelectionCount === 1;
const handlers = {
onClick: (event: React.MouseEvent) => onDocumentClick?.(doc, event),
onDoubleClick: (event: React.MouseEvent) => onDocumentActivate?.(doc, event),
onDragStart: (event: DragEvent<HTMLElement>) => onDocumentDragStart?.(event, doc),
onDragEnd: (event: DragEvent<HTMLElement>) => onDocumentDragEnd?.(event),
onDragOver: (event: DragEvent<HTMLElement>) => onDocumentTagDragOver?.(event),
onDragLeave: onDocumentTagDragLeave,
onDrop: (event: DragEvent<HTMLElement>) => {
event.preventDefault();
event.stopPropagation();
const payload = parseTagTransferPayload(event);
if (payload && onDocumentTagDrop) {
onDocumentTagDrop(doc.id, payload);
}
},
onRenameChange: setDocumentDraft,
onRenameSubmit: () => submitDocumentEditing(doc),
onRenameCancel: (event?: React.SyntheticEvent) => cancelDocumentEditing(event),
onRenameBegin: (event: React.SyntheticEvent) => {
if (!allowInlineDocumentEdit) return;
event.preventDefault();
event.stopPropagation();
beginDocumentEditing(doc);
},
};
return {
isSelected,
isDraggingDoc,
isEditingDoc,
documentDraftValue,
isDocumentSaving,
canSubmitDocument,
allowInlineDocumentEdit,
attachDocumentInputRef,
handlers,
};
};