refactor(documents): encapsulate panel logic and state into dedicated React contexts

This commit is contained in:
2025-12-08 12:31:30 +01:00
parent 44cf4603fe
commit 73468bbb02
13 changed files with 524 additions and 338 deletions
@@ -4,7 +4,9 @@ import { formatDate } from '../../utils/date';
import DocumentThumbnailImage from '../DocumentThumbnailImage';
import { resolveCorrespondents } from '../correspondents';
import type { DocumentsListEntry } from '../../types/documents';
import type { DocumentsViewProps } from '../panel/DocumentsPanel';
import { useDocumentsAssetContext } from '../context/DocumentsAssetContext';
import { useDocumentsViewStateContext } from '../context/DocumentsViewStateContext';
import { useDocumentsCommandContext } from '../context/DocumentsCommandContext';
import type { DocumentViewLogic } from '../logic/useDocumentViewLogic';
import EditableEntryTitle from './EditableEntryTitle';
import EntryCorrespondents from './EntryCorrespondents';
@@ -12,7 +14,7 @@ import EntryTags from './EntryTags';
import FolderEntry from './FolderEntry';
import DocumentEntry from './DocumentEntry';
interface DocumentsListRowProps extends DocumentsViewProps {
interface DocumentsListRowProps {
entry: DocumentsListEntry;
viewLogic: DocumentViewLogic;
iconSize?: number;
@@ -20,6 +22,12 @@ interface DocumentsListRowProps extends DocumentsViewProps {
const DocumentsListRow: React.FC<DocumentsListRowProps> = (props) => {
const { entry, iconSize } = props;
const { ensureAssetUrl, getDocumentAsset } = useDocumentsAssetContext();
const { scrollRef, activeCorrespondentIdSet, tagLookupById } = useDocumentsViewStateContext();
const {
correspondents: { onClick: onCorrespondentClick },
tags: { onClick: onTagClick, onDetach: onDocumentTagDetach }
} = useDocumentsCommandContext();
if (entry.type === 'folder') {
const folder = entry.folder;
@@ -27,8 +35,8 @@ const DocumentsListRow: React.FC<DocumentsListRowProps> = (props) => {
return (
<FolderEntry
{...props}
folder={folder}
viewLogic={props.viewLogic}
component="tr"
className="folder"
>
@@ -79,8 +87,8 @@ const DocumentsListRow: React.FC<DocumentsListRowProps> = (props) => {
return (
<DocumentEntry
{...props}
doc={doc}
viewLogic={props.viewLogic}
component="tr"
className="document"
>
@@ -89,10 +97,10 @@ const DocumentsListRow: React.FC<DocumentsListRowProps> = (props) => {
<td className="thumb-cell">
<DocumentThumbnailImage
document={doc}
ensureAssetUrl={props.ensureAssetUrl}
getAsset={props.getDocumentAsset}
ensureAssetUrl={ensureAssetUrl}
getAsset={getDocumentAsset}
alt={`Thumbnail for ${doc.title}`}
scrollRootRef={props.scrollRef}
scrollRootRef={scrollRef}
maxSize={props.iconSize}
/>
</td>
@@ -102,8 +110,8 @@ const DocumentsListRow: React.FC<DocumentsListRowProps> = (props) => {
<span className="doc-name__title">
<EntryCorrespondents
correspondents={correspondents}
activeCorrespondentIdSet={props.activeCorrespondentIdSet}
onCorrespondentClick={props.onCorrespondentClick}
activeCorrespondentIdSet={activeCorrespondentIdSet}
onCorrespondentClick={onCorrespondentClick}
/>
<span className="doc-name__primary">
<EditableEntryTitle
@@ -127,10 +135,10 @@ const DocumentsListRow: React.FC<DocumentsListRowProps> = (props) => {
<div className="doc-name__tags">
<EntryTags
tags={doc.tags || []}
tagLookupById={props.tagLookupById}
onTagClick={props.onTagClick}
tagLookupById={tagLookupById}
onTagClick={onTagClick}
docId={doc.id}
onDocumentTagDetach={props.onDocumentTagDetach}
onDocumentTagDetach={onDocumentTagDetach}
onTagDragStart={logic.handlers.onTagDragStart}
onTagDragEnd={logic.handlers.onTagDragEnd}
/>
@@ -145,4 +153,5 @@ const DocumentsListRow: React.FC<DocumentsListRowProps> = (props) => {
);
};
export default DocumentsListRow;