refactor(documents): encapsulate panel logic and state into dedicated React contexts
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
import React from 'react';
|
||||
import type { DocumentsViewProps } from '../panel/DocumentsPanel';
|
||||
import type { DocumentViewLogic } from '../logic/useDocumentViewLogic';
|
||||
import { useDocumentItemLogic } from '../logic/useDocumentItemLogic';
|
||||
import EntryShell from './EntryShell';
|
||||
|
||||
interface DocumentEntryProps extends DocumentsViewProps {
|
||||
interface DocumentEntryProps {
|
||||
doc: any;
|
||||
viewLogic: DocumentViewLogic;
|
||||
component: React.ElementType;
|
||||
@@ -15,7 +14,7 @@ interface DocumentEntryProps extends DocumentsViewProps {
|
||||
|
||||
const DocumentEntry: React.FC<DocumentEntryProps> = (props) => {
|
||||
const { doc, component, className, role, children, viewLogic } = props;
|
||||
const logic = useDocumentItemLogic({ doc, viewLogic, ...props });
|
||||
const logic = useDocumentItemLogic({ doc, viewLogic });
|
||||
|
||||
return (
|
||||
<EntryShell
|
||||
|
||||
@@ -3,7 +3,9 @@ import { FolderIcon } from '../../components/icons';
|
||||
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';
|
||||
@@ -11,7 +13,7 @@ import EntryTags from './EntryTags';
|
||||
import FolderEntry from './FolderEntry';
|
||||
import DocumentEntry from './DocumentEntry';
|
||||
|
||||
interface DocumentsGridCardProps extends DocumentsViewProps {
|
||||
interface DocumentsGridCardProps {
|
||||
entry: DocumentsListEntry;
|
||||
viewLogic: DocumentViewLogic;
|
||||
iconSize?: number;
|
||||
@@ -19,6 +21,12 @@ interface DocumentsGridCardProps extends DocumentsViewProps {
|
||||
|
||||
const DocumentsGridCard: React.FC<DocumentsGridCardProps> = (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;
|
||||
@@ -26,8 +34,8 @@ const DocumentsGridCard: React.FC<DocumentsGridCardProps> = (props) => {
|
||||
|
||||
return (
|
||||
<FolderEntry
|
||||
{...props}
|
||||
folder={folder}
|
||||
viewLogic={props.viewLogic}
|
||||
component="div"
|
||||
className="document-card folder-card"
|
||||
role="listitem"
|
||||
@@ -69,8 +77,8 @@ const DocumentsGridCard: React.FC<DocumentsGridCardProps> = (props) => {
|
||||
|
||||
return (
|
||||
<DocumentEntry
|
||||
{...props}
|
||||
doc={doc}
|
||||
viewLogic={props.viewLogic}
|
||||
component="div"
|
||||
className="document-card document"
|
||||
role="listitem"
|
||||
@@ -79,18 +87,18 @@ const DocumentsGridCard: React.FC<DocumentsGridCardProps> = (props) => {
|
||||
<>
|
||||
<DocumentThumbnailImage
|
||||
document={doc}
|
||||
ensureAssetUrl={props.ensureAssetUrl}
|
||||
getAsset={props.getDocumentAsset}
|
||||
ensureAssetUrl={ensureAssetUrl}
|
||||
getAsset={getDocumentAsset}
|
||||
alt={`Thumbnail for ${doc.title}`}
|
||||
maxSize={iconSize}
|
||||
scrollRootRef={props.scrollRef}
|
||||
scrollRootRef={scrollRef}
|
||||
/>
|
||||
<div className="document-card__meta">
|
||||
<div className="document-card__title" title={doc.title}>
|
||||
<EntryCorrespondents
|
||||
correspondents={correspondents}
|
||||
activeCorrespondentIdSet={props.activeCorrespondentIdSet}
|
||||
onCorrespondentClick={props.onCorrespondentClick}
|
||||
activeCorrespondentIdSet={activeCorrespondentIdSet}
|
||||
onCorrespondentClick={onCorrespondentClick}
|
||||
/>
|
||||
<div className="document-card__title-row">
|
||||
<EditableEntryTitle
|
||||
@@ -113,10 +121,10 @@ const DocumentsGridCard: React.FC<DocumentsGridCardProps> = (props) => {
|
||||
<div className="document-card__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}
|
||||
/>
|
||||
@@ -128,4 +136,5 @@ const DocumentsGridCard: React.FC<DocumentsGridCardProps> = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
export default DocumentsGridCard;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import React from 'react';
|
||||
import type { DocumentsViewProps } from '../panel/DocumentsPanel';
|
||||
import type { DocumentViewLogic } from '../logic/useDocumentViewLogic';
|
||||
import { useFolderItemLogic } from '../features/folders/useFolderItemLogic';
|
||||
import EntryShell from './EntryShell';
|
||||
|
||||
interface FolderEntryProps extends DocumentsViewProps {
|
||||
interface FolderEntryProps {
|
||||
folder: any;
|
||||
viewLogic: DocumentViewLogic;
|
||||
component: React.ElementType;
|
||||
@@ -15,7 +14,7 @@ interface FolderEntryProps extends DocumentsViewProps {
|
||||
|
||||
const FolderEntry: React.FC<FolderEntryProps> = (props) => {
|
||||
const { folder, component, className, role, children, viewLogic } = props;
|
||||
const logic = useFolderItemLogic({ folder, viewLogic, ...props });
|
||||
const logic = useFolderItemLogic({ folder, viewLogic });
|
||||
|
||||
return (
|
||||
<EntryShell
|
||||
|
||||
Reference in New Issue
Block a user