refactor: Decompose document and folder views into modular components and hooks, replacing monolithic list/grid implementations.
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
import React from 'react';
|
||||
import { FolderIcon } from '../../ui/icons';
|
||||
import DocumentThumbnailImage from '../DocumentThumbnailImage';
|
||||
import { resolveCorrespondents } from '../correspondents';
|
||||
import type { DocumentsListEntry } from '../../types/documents';
|
||||
import type { DocumentsViewProps } from '../panel/DocumentsPanel';
|
||||
import type { DocumentViewLogic } from '../hooks/useDocumentViewLogic';
|
||||
import EditableEntryTitle from './EditableEntryTitle';
|
||||
import EntryCorrespondents from './EntryCorrespondents';
|
||||
import EntryTags from './EntryTags';
|
||||
import FolderEntry from './FolderEntry';
|
||||
import DocumentEntry from './DocumentEntry';
|
||||
|
||||
interface DocumentsGridCardProps extends DocumentsViewProps {
|
||||
entry: DocumentsListEntry;
|
||||
viewLogic: DocumentViewLogic;
|
||||
gridIconSize?: number;
|
||||
}
|
||||
|
||||
const DocumentsGridCard: React.FC<DocumentsGridCardProps> = (props) => {
|
||||
const { entry, gridIconSize } = props;
|
||||
|
||||
if (entry.type === 'folder') {
|
||||
const folder = entry.folder;
|
||||
if (!folder) return null;
|
||||
|
||||
return (
|
||||
<FolderEntry
|
||||
{...props}
|
||||
folder={folder}
|
||||
component="div"
|
||||
className="document-card folder-card"
|
||||
role="listitem"
|
||||
>
|
||||
{(logic) => (
|
||||
<>
|
||||
<div className="folder-card__icon">
|
||||
<FolderIcon className="folder-card__icon-svg" size={gridIconSize} />
|
||||
</div>
|
||||
<div className="folder-card__meta">
|
||||
<div className="folder-card__label-row">
|
||||
<EditableEntryTitle
|
||||
isEditing={logic.isFolderEditing}
|
||||
draftValue={logic.folderDraftValue}
|
||||
onChange={logic.handlers.onRenameChange}
|
||||
onSubmit={logic.handlers.onRenameSubmit}
|
||||
onCancel={logic.handlers.onRenameCancel}
|
||||
isSaving={logic.isFolderSaving}
|
||||
canSubmit={logic.canSubmitFolder}
|
||||
inputRef={logic.attachFolderInputRef}
|
||||
allowInlineEdit={logic.allowInlineFolderEdit}
|
||||
onBeginEditing={logic.handlers.onRenameBegin}
|
||||
className="folder-card__name"
|
||||
>
|
||||
{folder.name}
|
||||
</EditableEntryTitle>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</FolderEntry>
|
||||
);
|
||||
}
|
||||
|
||||
const doc = entry.document;
|
||||
if (!doc) return null;
|
||||
|
||||
const correspondents = resolveCorrespondents(doc);
|
||||
|
||||
return (
|
||||
<DocumentEntry
|
||||
{...props}
|
||||
doc={doc}
|
||||
component="div"
|
||||
className="document-card document"
|
||||
role="listitem"
|
||||
>
|
||||
{(logic) => (
|
||||
<>
|
||||
<DocumentThumbnailImage
|
||||
document={doc}
|
||||
ensureAssetUrl={props.ensureAssetUrl}
|
||||
getDocumentAsset={props.getDocumentAsset}
|
||||
alt={`Thumbnail for ${doc.title}`}
|
||||
maxSize={gridIconSize}
|
||||
scrollRootRef={props.scrollRef}
|
||||
/>
|
||||
<div className="document-card__meta">
|
||||
<div className="document-card__title" title={doc.title}>
|
||||
<EntryCorrespondents
|
||||
correspondents={correspondents}
|
||||
activeCorrespondentIdSet={props.activeCorrespondentIdSet}
|
||||
onCorrespondentClick={props.onCorrespondentClick}
|
||||
/>
|
||||
<div className="document-card__title-row">
|
||||
<EditableEntryTitle
|
||||
isEditing={logic.isEditingDoc}
|
||||
draftValue={logic.documentDraftValue}
|
||||
onChange={logic.handlers.onRenameChange}
|
||||
onSubmit={logic.handlers.onRenameSubmit}
|
||||
onCancel={logic.handlers.onRenameCancel}
|
||||
isSaving={logic.isDocumentSaving}
|
||||
canSubmit={logic.canSubmitDocument}
|
||||
inputRef={logic.attachDocumentInputRef}
|
||||
allowInlineEdit={logic.allowInlineDocumentEdit}
|
||||
onBeginEditing={logic.handlers.onRenameBegin}
|
||||
className="document-card__title-badge"
|
||||
>
|
||||
{doc.title}
|
||||
</EditableEntryTitle>
|
||||
</div>
|
||||
</div>
|
||||
<div className="document-card__tags">
|
||||
<EntryTags
|
||||
tags={doc.tags || []}
|
||||
tagLookupById={props.tagLookupById}
|
||||
onTagClick={props.onTagClick}
|
||||
docId={doc.id}
|
||||
maxTags={3}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</DocumentEntry>
|
||||
);
|
||||
};
|
||||
|
||||
export default DocumentsGridCard;
|
||||
Reference in New Issue
Block a user