feat: refactor frontend tag interaction handlers
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import DesktopPreviewCard from './DesktopPreviewCard';
|
import DesktopPreviewCard from './DesktopPreviewCard';
|
||||||
import { resolveCorrespondents } from '../../documents/correspondents';
|
import { resolveCorrespondents } from '../../documents/correspondents';
|
||||||
import { getTagColorStyle } from '../../utils/colors';
|
|
||||||
import type { DocumentId } from '../../types/identifiers';
|
|
||||||
import type { Document } from '../../types/documents';
|
import type { Document } from '../../types/documents';
|
||||||
import { LayoutCard } from '../logic/LayoutSystem';
|
import { LayoutCard } from '../logic/LayoutSystem';
|
||||||
import { useCardPointer } from '../interactions/useCardPointer';
|
import { useCardPointer } from '../interactions/useCardPointer';
|
||||||
|
import DocumentTags from '../../documents/components/DocumentTags';
|
||||||
|
import { TagInteractionHandlers } from '../../documents/interactions/useTagInteractions';
|
||||||
|
|
||||||
const preventAll = (event?: React.SyntheticEvent | Event | null) => {
|
const preventAll = (event?: React.SyntheticEvent | Event | null) => {
|
||||||
if (!event) return;
|
if (!event) return;
|
||||||
@@ -27,12 +27,7 @@ interface DesktopDocumentCardProps {
|
|||||||
onDeselect: (ids: string[]) => void;
|
onDeselect: (ids: string[]) => void;
|
||||||
selection: string[];
|
selection: string[];
|
||||||
requestCanvasFocus?: () => void;
|
requestCanvasFocus?: () => void;
|
||||||
onTagDragEnter?: (event: React.DragEvent<HTMLDivElement>, docId: DocumentId) => void;
|
tagHandlers?: TagInteractionHandlers;
|
||||||
onTagDragOver?: (event: React.DragEvent<HTMLDivElement>, doc: Document) => void;
|
|
||||||
onTagDragLeave?: (event: React.DragEvent<HTMLDivElement>, docId: DocumentId) => void;
|
|
||||||
onTagDrop?: (event: React.DragEvent<HTMLDivElement>, doc: Document) => void;
|
|
||||||
onTagDragStart?: (event: React.DragEvent<HTMLElement>, doc: Document, tag: any) => void;
|
|
||||||
onTagDragEnd?: (event: React.DragEvent<HTMLElement>) => void;
|
|
||||||
layoutCard: LayoutCard;
|
layoutCard: LayoutCard;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,12 +45,7 @@ const DesktopDocumentCard: React.FC<DesktopDocumentCardProps> = ({
|
|||||||
onDeselect,
|
onDeselect,
|
||||||
selection,
|
selection,
|
||||||
requestCanvasFocus,
|
requestCanvasFocus,
|
||||||
onTagDragEnter,
|
tagHandlers,
|
||||||
onTagDragOver,
|
|
||||||
onTagDragLeave,
|
|
||||||
onTagDrop,
|
|
||||||
onTagDragStart,
|
|
||||||
onTagDragEnd,
|
|
||||||
layoutCard,
|
layoutCard,
|
||||||
}) => {
|
}) => {
|
||||||
const cardPointerHandlers = useCardPointer(
|
const cardPointerHandlers = useCardPointer(
|
||||||
@@ -89,10 +79,10 @@ const DesktopDocumentCard: React.FC<DesktopDocumentCardProps> = ({
|
|||||||
aria-hidden={ariaHidden}
|
aria-hidden={ariaHidden}
|
||||||
ref={(node) => layoutCard?.setRef(node)}
|
ref={(node) => layoutCard?.setRef(node)}
|
||||||
{...cardPointerHandlers}
|
{...cardPointerHandlers}
|
||||||
onDragEnter={(event) => onTagDragEnter?.(event, doc.id!)}
|
onDragEnter={(event) => tagHandlers?.onTagDragEnter(event, doc.id!)}
|
||||||
onDragOver={(event) => onTagDragOver?.(event, doc)}
|
onDragOver={(event) => tagHandlers?.onTagDragOver(event, doc)}
|
||||||
onDragLeave={(event) => onTagDragLeave?.(event, doc.id!)}
|
onDragLeave={(event) => tagHandlers?.onTagDragLeave(event, doc.id!)}
|
||||||
onDrop={(event) => onTagDrop?.(event, doc)}
|
onDrop={(event) => tagHandlers?.onTagDrop(event, doc)}
|
||||||
onKeyDown={(event) => {
|
onKeyDown={(event) => {
|
||||||
if (event.key === 'Enter' || event.key === ' ') {
|
if (event.key === 'Enter' || event.key === ' ') {
|
||||||
preventAll(event);
|
preventAll(event);
|
||||||
@@ -123,24 +113,12 @@ const DesktopDocumentCard: React.FC<DesktopDocumentCardProps> = ({
|
|||||||
)}
|
)}
|
||||||
{tags.length > 0 && (
|
{tags.length > 0 && (
|
||||||
<div className="desk-item__tags" aria-hidden="true">
|
<div className="desk-item__tags" aria-hidden="true">
|
||||||
{tags.map((tag) => {
|
<DocumentTags
|
||||||
const colorStyle = getTagColorStyle(tag.color);
|
doc={doc}
|
||||||
const tagClasses = ['badge', 'tag-chip', 'tag-chip--draggable'];
|
tags={tags}
|
||||||
return (
|
tagHandlers={tagHandlers}
|
||||||
<span
|
onTagClick={tagHandlers?.onTagClick}
|
||||||
key={tag.id}
|
/>
|
||||||
className={tagClasses.join(' ')}
|
|
||||||
style={colorStyle || undefined}
|
|
||||||
title={tag.label}
|
|
||||||
draggable
|
|
||||||
data-desk-tag-chip="true"
|
|
||||||
onDragStart={(event) => onTagDragStart?.(event, doc, tag)}
|
|
||||||
onDragEnd={(event) => onTagDragEnd?.(event)}
|
|
||||||
>
|
|
||||||
<span className="tag-chip__label">{tag.label}</span>
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { LayoutStore, LayoutCard } from '../logic/LayoutSystem';
|
|||||||
import DesktopDocumentCard from './DesktopDocumentCard';
|
import DesktopDocumentCard from './DesktopDocumentCard';
|
||||||
import usePreviewMetadata from '../hooks/usePreviewMetadata';
|
import usePreviewMetadata from '../hooks/usePreviewMetadata';
|
||||||
import {
|
import {
|
||||||
TagDragHandlers,
|
|
||||||
useTagInteractions,
|
useTagInteractions,
|
||||||
} from '../../documents/interactions/useTagInteractions';
|
} from '../../documents/interactions/useTagInteractions';
|
||||||
import './workspace-layout.css';
|
import './workspace-layout.css';
|
||||||
@@ -183,7 +182,7 @@ const DesktopWorkspaceContent: React.FC<DesktopWorkspaceProps> = ({
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Tag Interactions
|
// Tag Interactions
|
||||||
const tagDragHandlers: TagDragHandlers = useTagInteractions({
|
const tagHandlers = useTagInteractions({
|
||||||
onAssignTagToDocument: (docId: string, tagId: string) => {
|
onAssignTagToDocument: (docId: string, tagId: string) => {
|
||||||
tags.onAttach?.(docId, tagId);
|
tags.onAttach?.(docId, tagId);
|
||||||
},
|
},
|
||||||
@@ -191,6 +190,7 @@ const DesktopWorkspaceContent: React.FC<DesktopWorkspaceProps> = ({
|
|||||||
tags.onDetach?.(docId, tagId);
|
tags.onDetach?.(docId, tagId);
|
||||||
},
|
},
|
||||||
requestCanvasFocus: focusShell,
|
requestCanvasFocus: focusShell,
|
||||||
|
onTagClick: tags.onClick,
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -392,7 +392,7 @@ const DesktopWorkspaceContent: React.FC<DesktopWorkspaceProps> = ({
|
|||||||
openDocument(doc, isPreview ? 'preview' : 'sidepanel');
|
openDocument(doc, isPreview ? 'preview' : 'sidepanel');
|
||||||
}}
|
}}
|
||||||
layoutCard={layoutCard}
|
layoutCard={layoutCard}
|
||||||
{...tagDragHandlers}
|
tagHandlers={tagHandlers}
|
||||||
onSelect={(ids, extend = false) => {
|
onSelect={(ids, extend = false) => {
|
||||||
if (!extend) {
|
if (!extend) {
|
||||||
handleSelectionChange(ids);
|
handleSelectionChange(ids);
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import React from 'react';
|
|||||||
import type { DocumentViewLogic } from '../logic/useDocumentViewLogic';
|
import type { DocumentViewLogic } from '../logic/useDocumentViewLogic';
|
||||||
import { useDocumentItemLogic } from '../logic/useDocumentItemLogic';
|
import { useDocumentItemLogic } from '../logic/useDocumentItemLogic';
|
||||||
import EntryShell from './EntryShell';
|
import EntryShell from './EntryShell';
|
||||||
import type { TagDragHandlers } from '../interactions/useTagInteractions';
|
import type { TagInteractionHandlers } from '../interactions/useTagInteractions';
|
||||||
|
|
||||||
interface DocumentEntryProps {
|
interface DocumentEntryProps {
|
||||||
doc: any;
|
doc: any;
|
||||||
tagDragHandlers?: TagDragHandlers;
|
tagHandlers?: TagInteractionHandlers;
|
||||||
viewLogic: DocumentViewLogic;
|
viewLogic: DocumentViewLogic;
|
||||||
component: React.ElementType;
|
component: React.ElementType;
|
||||||
className?: string;
|
className?: string;
|
||||||
@@ -15,8 +15,8 @@ interface DocumentEntryProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const DocumentEntry: React.FC<DocumentEntryProps> = (props) => {
|
const DocumentEntry: React.FC<DocumentEntryProps> = (props) => {
|
||||||
const { doc, tagDragHandlers, component, className, role, children, viewLogic } = props;
|
const { doc, tagHandlers, component, className, role, children, viewLogic } = props;
|
||||||
const logic = useDocumentItemLogic({ doc, tagDragHandlers, viewLogic });
|
const logic = useDocumentItemLogic({ doc, tagHandlers, viewLogic });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EntryShell
|
<EntryShell
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ import React, { useMemo } from 'react';
|
|||||||
import { getTagColorStyle } from '../../utils/colors';
|
import { getTagColorStyle } from '../../utils/colors';
|
||||||
import type { Document, DocumentTag } from '../../types/documents';
|
import type { Document, DocumentTag } from '../../types/documents';
|
||||||
import type { Identifier } from '../../types/identifiers';
|
import type { Identifier } from '../../types/identifiers';
|
||||||
import type { TagDragHandlers } from '../interactions/useTagInteractions';
|
import type { TagInteractionHandlers } from '../interactions/useTagInteractions';
|
||||||
|
|
||||||
interface DocumentTagsProps {
|
interface DocumentTagsProps {
|
||||||
tags: DocumentTag[];
|
tags: DocumentTag[];
|
||||||
tagLookupById?: Map<Identifier, DocumentTag> | null;
|
tagLookupById?: Map<Identifier, DocumentTag> | null;
|
||||||
onTagClick?: (tagId: Identifier) => void;
|
onTagClick?: (tagId: Identifier) => void;
|
||||||
doc: Document;
|
doc: Document;
|
||||||
tagDragHandlers?: TagDragHandlers;
|
tagHandlers?: TagInteractionHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DocumentTags: React.FC<DocumentTagsProps> = ({
|
const DocumentTags: React.FC<DocumentTagsProps> = ({
|
||||||
@@ -17,7 +17,7 @@ const DocumentTags: React.FC<DocumentTagsProps> = ({
|
|||||||
tagLookupById,
|
tagLookupById,
|
||||||
onTagClick,
|
onTagClick,
|
||||||
doc,
|
doc,
|
||||||
tagDragHandlers,
|
tagHandlers,
|
||||||
}) => {
|
}) => {
|
||||||
const sortedTags = useMemo(() => {
|
const sortedTags = useMemo(() => {
|
||||||
return [...tags].sort((a, b) => {
|
return [...tags].sort((a, b) => {
|
||||||
@@ -38,12 +38,13 @@ const DocumentTags: React.FC<DocumentTagsProps> = ({
|
|||||||
const style = getTagColorStyle(colorSource);
|
const style = getTagColorStyle(colorSource);
|
||||||
const tagId = tag?.id ?? null;
|
const tagId = tag?.id ?? null;
|
||||||
const clickable = tagId != null && typeof onTagClick === 'function';
|
const clickable = tagId != null && typeof onTagClick === 'function';
|
||||||
|
const draggable = !!tagId;
|
||||||
const key = tagId ?? `${doc.id}-tag-${index}`;
|
const key = tagId ?? `${doc.id}-tag-${index}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
key={key}
|
key={key}
|
||||||
className="badge tag-chip"
|
className={`badge tag-chip${draggable ? ' tag-chip--draggable' : ''}`}
|
||||||
style={style || undefined}
|
style={style || undefined}
|
||||||
title={tag.label}
|
title={tag.label}
|
||||||
role={clickable ? 'button' : undefined}
|
role={clickable ? 'button' : undefined}
|
||||||
@@ -53,8 +54,8 @@ const DocumentTags: React.FC<DocumentTagsProps> = ({
|
|||||||
onTagClick?.(tagId);
|
onTagClick?.(tagId);
|
||||||
} : undefined}
|
} : undefined}
|
||||||
draggable={!!tagId}
|
draggable={!!tagId}
|
||||||
onDragStart={(event) => tagId && tagDragHandlers?.onTagDragStart(event, doc, tag)}
|
onDragStart={(event) => tagId && tagHandlers?.onTagDragStart(event, doc, tag)}
|
||||||
onDragEnd={tagDragHandlers?.onTagDragEnd}
|
onDragEnd={tagHandlers?.onTagDragEnd}
|
||||||
onKeyDown={clickable ? (event) => {
|
onKeyDown={clickable ? (event) => {
|
||||||
if (event.key === 'Enter' || event.key === ' ') {
|
if (event.key === 'Enter' || event.key === ' ') {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|||||||
@@ -12,17 +12,17 @@ import EntryCorrespondents from './EntryCorrespondents';
|
|||||||
import EntryTags from './EntryTags';
|
import EntryTags from './EntryTags';
|
||||||
import FolderEntry from './FolderEntry';
|
import FolderEntry from './FolderEntry';
|
||||||
import DocumentEntry from './DocumentEntry';
|
import DocumentEntry from './DocumentEntry';
|
||||||
import { TagDragHandlers } from '../interactions/useTagInteractions';
|
import { TagInteractionHandlers } from '../interactions/useTagInteractions';
|
||||||
|
|
||||||
interface DocumentsGridCardProps {
|
interface DocumentsGridCardProps {
|
||||||
entry: DocumentsListEntry;
|
entry: DocumentsListEntry;
|
||||||
viewLogic: DocumentViewLogic;
|
viewLogic: DocumentViewLogic;
|
||||||
iconSize?: number;
|
iconSize?: number;
|
||||||
tagDragHandlers?: TagDragHandlers;
|
tagHandlers?: TagInteractionHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DocumentsGridCard: React.FC<DocumentsGridCardProps> = (props) => {
|
const DocumentsGridCard: React.FC<DocumentsGridCardProps> = (props) => {
|
||||||
const { entry, iconSize, tagDragHandlers } = props;
|
const { entry, iconSize, tagHandlers } = props;
|
||||||
const { ensureAssetUrl, getDocumentAsset } = useDocumentsAssetContext();
|
const { ensureAssetUrl, getDocumentAsset } = useDocumentsAssetContext();
|
||||||
const { scrollRef, activeCorrespondentIdSet, tagLookupById } = useDocumentsViewStateContext();
|
const { scrollRef, activeCorrespondentIdSet, tagLookupById } = useDocumentsViewStateContext();
|
||||||
const {
|
const {
|
||||||
@@ -80,7 +80,7 @@ const DocumentsGridCard: React.FC<DocumentsGridCardProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<DocumentEntry
|
<DocumentEntry
|
||||||
doc={doc}
|
doc={doc}
|
||||||
tagDragHandlers={tagDragHandlers}
|
tagHandlers={tagHandlers}
|
||||||
viewLogic={props.viewLogic}
|
viewLogic={props.viewLogic}
|
||||||
component="div"
|
component="div"
|
||||||
className="document-card document"
|
className="document-card document"
|
||||||
@@ -127,7 +127,7 @@ const DocumentsGridCard: React.FC<DocumentsGridCardProps> = (props) => {
|
|||||||
tagLookupById={tagLookupById}
|
tagLookupById={tagLookupById}
|
||||||
onTagClick={onTagClick}
|
onTagClick={onTagClick}
|
||||||
doc={doc}
|
doc={doc}
|
||||||
tagDragHandlers={logic.handlers.tagDragHandlers}
|
tagHandlers={logic.handlers.tagHandlers}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,17 +14,17 @@ import EntryTags from './EntryTags';
|
|||||||
import FolderEntry from './FolderEntry';
|
import FolderEntry from './FolderEntry';
|
||||||
import DocumentEntry from './DocumentEntry';
|
import DocumentEntry from './DocumentEntry';
|
||||||
|
|
||||||
import { TagDragHandlers } from '../interactions/useTagInteractions';
|
import { TagInteractionHandlers } from '../interactions/useTagInteractions';
|
||||||
|
|
||||||
interface DocumentsListRowProps {
|
interface DocumentsListRowProps {
|
||||||
entry: DocumentsListEntry;
|
entry: DocumentsListEntry;
|
||||||
viewLogic: DocumentViewLogic;
|
viewLogic: DocumentViewLogic;
|
||||||
iconSize?: number;
|
iconSize?: number;
|
||||||
tagDragHandlers?: TagDragHandlers;
|
tagHandlers?: TagInteractionHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DocumentsListRow: React.FC<DocumentsListRowProps> = (props) => {
|
const DocumentsListRow: React.FC<DocumentsListRowProps> = (props) => {
|
||||||
const { entry, iconSize, tagDragHandlers } = props;
|
const { entry, iconSize, tagHandlers } = props;
|
||||||
const { ensureAssetUrl, getDocumentAsset } = useDocumentsAssetContext();
|
const { ensureAssetUrl, getDocumentAsset } = useDocumentsAssetContext();
|
||||||
const { scrollRef, activeCorrespondentIdSet, tagLookupById } = useDocumentsViewStateContext();
|
const { scrollRef, activeCorrespondentIdSet, tagLookupById } = useDocumentsViewStateContext();
|
||||||
const {
|
const {
|
||||||
@@ -91,7 +91,7 @@ const DocumentsListRow: React.FC<DocumentsListRowProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<DocumentEntry
|
<DocumentEntry
|
||||||
doc={doc}
|
doc={doc}
|
||||||
tagDragHandlers={tagDragHandlers}
|
tagHandlers={tagHandlers}
|
||||||
viewLogic={props.viewLogic}
|
viewLogic={props.viewLogic}
|
||||||
component="tr"
|
component="tr"
|
||||||
className="document"
|
className="document"
|
||||||
@@ -142,7 +142,7 @@ const DocumentsListRow: React.FC<DocumentsListRowProps> = (props) => {
|
|||||||
tagLookupById={tagLookupById}
|
tagLookupById={tagLookupById}
|
||||||
onTagClick={onTagClick}
|
onTagClick={onTagClick}
|
||||||
doc={doc}
|
doc={doc}
|
||||||
tagDragHandlers={logic.handlers.tagDragHandlers}
|
tagHandlers={logic.handlers.tagHandlers}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import DocumentTags from './DocumentTags';
|
import DocumentTags from './DocumentTags';
|
||||||
import type { Document, DocumentTag } from '../../types/documents';
|
import type { Document, DocumentTag } from '../../types/documents';
|
||||||
import type { TagDragHandlers } from '../interactions/useTagInteractions';
|
import type { TagInteractionHandlers } from '../interactions/useTagInteractions';
|
||||||
import type { Identifier } from '../../types/identifiers';
|
import type { Identifier } from '../../types/identifiers';
|
||||||
|
|
||||||
interface EntryTagsProps {
|
interface EntryTagsProps {
|
||||||
@@ -9,7 +9,7 @@ interface EntryTagsProps {
|
|||||||
tagLookupById?: Map<Identifier, DocumentTag> | null;
|
tagLookupById?: Map<Identifier, DocumentTag> | null;
|
||||||
onTagClick?: (tagId: Identifier) => void;
|
onTagClick?: (tagId: Identifier) => void;
|
||||||
doc: Document;
|
doc: Document;
|
||||||
tagDragHandlers?: TagDragHandlers;
|
tagHandlers?: TagInteractionHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EntryTags: React.FC<EntryTagsProps> = (props) => {
|
const EntryTags: React.FC<EntryTagsProps> = (props) => {
|
||||||
@@ -23,7 +23,7 @@ const EntryTags: React.FC<EntryTagsProps> = (props) => {
|
|||||||
tagLookupById={props.tagLookupById}
|
tagLookupById={props.tagLookupById}
|
||||||
onTagClick={props.onTagClick}
|
onTagClick={props.onTagClick}
|
||||||
doc={props.doc}
|
doc={props.doc}
|
||||||
tagDragHandlers={props.tagDragHandlers}
|
tagHandlers={props.tagHandlers}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ interface UseTagInteractionsArgs {
|
|||||||
onAssignTagToDocument?: (docId: Identifier, tagId: Identifier) => void;
|
onAssignTagToDocument?: (docId: Identifier, tagId: Identifier) => void;
|
||||||
onRemoveTagFromDocument?: (docId: Identifier, tagId: Identifier) => void;
|
onRemoveTagFromDocument?: (docId: Identifier, tagId: Identifier) => void;
|
||||||
requestCanvasFocus?: () => void;
|
requestCanvasFocus?: () => void;
|
||||||
|
onTagClick?: (tagId: Identifier) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DraggingTagState {
|
interface DraggingTagState {
|
||||||
@@ -55,20 +56,22 @@ interface DraggingTagState {
|
|||||||
previewClone?: HTMLElement;
|
previewClone?: HTMLElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TagDragHandlers {
|
export interface TagInteractionHandlers {
|
||||||
onTagDragEnter: (event: React.DragEvent<HTMLDivElement>, docId: Identifier) => void;
|
onTagDragEnter: (event: React.DragEvent<HTMLDivElement>, docId: Identifier) => void;
|
||||||
onTagDragOver: (event: React.DragEvent<HTMLDivElement>, doc: Document) => void;
|
onTagDragOver: (event: React.DragEvent<HTMLDivElement>, doc: Document) => void;
|
||||||
onTagDragLeave: (event: React.DragEvent<HTMLDivElement>, docId: Identifier) => void;
|
onTagDragLeave: (event: React.DragEvent<HTMLDivElement>, docId: Identifier) => void;
|
||||||
onTagDrop: (event: React.DragEvent<HTMLDivElement>, doc: Document) => void;
|
onTagDrop: (event: React.DragEvent<HTMLDivElement>, doc: Document) => void;
|
||||||
onTagDragStart: (event: React.DragEvent<HTMLElement>, doc: Document, tag: DocumentTag) => void;
|
onTagDragStart: (event: React.DragEvent<HTMLElement>, doc: Document, tag: DocumentTag) => void;
|
||||||
onTagDragEnd: (event: React.DragEvent<HTMLElement>) => void;
|
onTagDragEnd: (event: React.DragEvent<HTMLElement>) => void;
|
||||||
|
onTagClick?: (tagId: Identifier) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useTagInteractions = ({
|
export const useTagInteractions = ({
|
||||||
onAssignTagToDocument,
|
onAssignTagToDocument,
|
||||||
onRemoveTagFromDocument,
|
onRemoveTagFromDocument,
|
||||||
requestCanvasFocus,
|
requestCanvasFocus,
|
||||||
}: UseTagInteractionsArgs): TagDragHandlers => {
|
onTagClick,
|
||||||
|
}: UseTagInteractionsArgs): TagInteractionHandlers => {
|
||||||
const draggingTagRef = useRef<DraggingTagState | null>(null);
|
const draggingTagRef = useRef<DraggingTagState | null>(null);
|
||||||
|
|
||||||
const isTagTransfer = useCallback((event: React.DragEvent) => isTagTransferEvent(event), []);
|
const isTagTransfer = useCallback((event: React.DragEvent) => isTagTransferEvent(event), []);
|
||||||
@@ -241,5 +244,6 @@ export const useTagInteractions = ({
|
|||||||
onTagDrop,
|
onTagDrop,
|
||||||
onTagDragStart,
|
onTagDragStart,
|
||||||
onTagDragEnd,
|
onTagDragEnd,
|
||||||
|
onTagClick,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,16 +5,15 @@ import type { Document } from '../../types/documents';
|
|||||||
import { useDocumentsCommandContext } from '../context/DocumentsCommandContext';
|
import { useDocumentsCommandContext } from '../context/DocumentsCommandContext';
|
||||||
import { useDocumentsViewStateContext } from '../context/DocumentsViewStateContext';
|
import { useDocumentsViewStateContext } from '../context/DocumentsViewStateContext';
|
||||||
import type { DocumentViewLogic } from './useDocumentViewLogic';
|
import type { DocumentViewLogic } from './useDocumentViewLogic';
|
||||||
|
import { TagInteractionHandlers } from '../interactions/useTagInteractions';
|
||||||
import { TagDragHandlers } from '../interactions/useTagInteractions';
|
|
||||||
|
|
||||||
interface UseDocumentItemLogicArgs {
|
interface UseDocumentItemLogicArgs {
|
||||||
doc: Document;
|
doc: Document;
|
||||||
tagDragHandlers?: TagDragHandlers;
|
tagHandlers?: TagInteractionHandlers;
|
||||||
viewLogic: DocumentViewLogic; // Retained from original props
|
viewLogic: DocumentViewLogic; // Retained from original props
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useDocumentItemLogic = ({ doc, tagDragHandlers, viewLogic }: UseDocumentItemLogicArgs) => {
|
export const useDocumentItemLogic = ({ doc, tagHandlers, viewLogic }: UseDocumentItemLogicArgs) => {
|
||||||
const {
|
const {
|
||||||
draggingDocumentIdsSet
|
draggingDocumentIdsSet
|
||||||
} = useDocumentsViewStateContext();
|
} = useDocumentsViewStateContext();
|
||||||
@@ -70,10 +69,10 @@ export const useDocumentItemLogic = ({ doc, tagDragHandlers, viewLogic }: UseDoc
|
|||||||
},
|
},
|
||||||
onDragStart: (event: DragEvent<HTMLElement>) => onDocumentDragStart?.(event, doc),
|
onDragStart: (event: DragEvent<HTMLElement>) => onDocumentDragStart?.(event, doc),
|
||||||
onDragEnd: (event: DragEvent<HTMLElement>) => onDocumentDragEnd?.(event),
|
onDragEnd: (event: DragEvent<HTMLElement>) => onDocumentDragEnd?.(event),
|
||||||
onDragOver: (event: DragEvent<HTMLElement>) => tagDragHandlers?.onTagDragOver(event, doc),
|
onDragOver: (event: DragEvent<HTMLElement>) => tagHandlers?.onTagDragOver(event, doc),
|
||||||
onDragLeave: (event: DragEvent<HTMLElement>) => tagDragHandlers?.onTagDragLeave(event, doc.id),
|
onDragLeave: (event: DragEvent<HTMLElement>) => tagHandlers?.onTagDragLeave(event, doc.id),
|
||||||
onDrop: (event: DragEvent<HTMLElement>) => { tagDragHandlers?.onTagDrop(event, doc); },
|
onDrop: (event: DragEvent<HTMLElement>) => { tagHandlers?.onTagDrop(event, doc); },
|
||||||
tagDragHandlers,
|
tagHandlers,
|
||||||
onRenameChange: setDocumentDraft,
|
onRenameChange: setDocumentDraft,
|
||||||
onRenameSubmit: () => submitDocumentEditing(doc),
|
onRenameSubmit: () => submitDocumentEditing(doc),
|
||||||
onRenameCancel: (event?: React.SyntheticEvent) => cancelDocumentEditing(event),
|
onRenameCancel: (event?: React.SyntheticEvent) => cancelDocumentEditing(event),
|
||||||
|
|||||||
@@ -48,11 +48,11 @@ interface DocumentsPanelProps extends DocumentsPanelInnerProps {
|
|||||||
selectionValue: WorkspaceSelectionValue;
|
selectionValue: WorkspaceSelectionValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
import type { TagDragHandlers } from '../interactions/useTagInteractions';
|
import type { TagInteractionHandlers } from '../interactions/useTagInteractions';
|
||||||
|
|
||||||
export interface DocumentsViewProps {
|
export interface DocumentsViewProps {
|
||||||
entries: DocumentsListEntry[];
|
entries: DocumentsListEntry[];
|
||||||
tagDragHandlers?: TagDragHandlers;
|
tagHandlers?: TagInteractionHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = (props) => {
|
const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = (props) => {
|
||||||
@@ -88,7 +88,7 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = (props) => {
|
|||||||
assetContextValue,
|
assetContextValue,
|
||||||
viewStateContextValue,
|
viewStateContextValue,
|
||||||
commandContextValue,
|
commandContextValue,
|
||||||
tagDragHandlers,
|
tagHandlers,
|
||||||
scrollRef,
|
scrollRef,
|
||||||
hasDocumentEntries,
|
hasDocumentEntries,
|
||||||
} = useDocumentsContextValues(props);
|
} = useDocumentsContextValues(props);
|
||||||
@@ -246,7 +246,7 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = (props) => {
|
|||||||
const viewProps = {
|
const viewProps = {
|
||||||
entries,
|
entries,
|
||||||
viewId: currentFolderId,
|
viewId: currentFolderId,
|
||||||
tagDragHandlers,
|
tagHandlers,
|
||||||
};
|
};
|
||||||
|
|
||||||
const [iconSizes] = useState({
|
const [iconSizes] = useState({
|
||||||
|
|||||||
@@ -38,9 +38,10 @@ export const useDocumentsContextValues = (props: DocumentsPanelInnerProps) => {
|
|||||||
} = useDocumentsFilter();
|
} = useDocumentsFilter();
|
||||||
|
|
||||||
// Handlers
|
// Handlers
|
||||||
const tagDragHandlers = useTagInteractions({
|
const tagHandlers = useTagInteractions({
|
||||||
onAssignTagToDocument: props.onDocumentTagAttach,
|
onAssignTagToDocument: props.onDocumentTagAttach,
|
||||||
onRemoveTagFromDocument: props.onDocumentTagDetach,
|
onRemoveTagFromDocument: props.onDocumentTagDetach,
|
||||||
|
onTagClick: toggleTagFilter,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Derived State
|
// Derived State
|
||||||
@@ -147,7 +148,7 @@ export const useDocumentsContextValues = (props: DocumentsPanelInnerProps) => {
|
|||||||
handleFolderClick,
|
handleFolderClick,
|
||||||
handleDocumentDragStartLocal,
|
handleDocumentDragStartLocal,
|
||||||
handleDocumentDragEndLocal,
|
handleDocumentDragEndLocal,
|
||||||
tagDragHandlers,
|
tagHandlers,
|
||||||
toggleTagFilter,
|
toggleTagFilter,
|
||||||
toggleCorrespondentFilter,
|
toggleCorrespondentFilter,
|
||||||
});
|
});
|
||||||
@@ -158,7 +159,7 @@ export const useDocumentsContextValues = (props: DocumentsPanelInnerProps) => {
|
|||||||
handleFolderClick,
|
handleFolderClick,
|
||||||
handleDocumentDragStartLocal,
|
handleDocumentDragStartLocal,
|
||||||
handleDocumentDragEndLocal,
|
handleDocumentDragEndLocal,
|
||||||
tagDragHandlers,
|
tagHandlers,
|
||||||
toggleTagFilter,
|
toggleTagFilter,
|
||||||
toggleCorrespondentFilter,
|
toggleCorrespondentFilter,
|
||||||
};
|
};
|
||||||
@@ -198,7 +199,7 @@ export const useDocumentsContextValues = (props: DocumentsPanelInnerProps) => {
|
|||||||
assetContextValue,
|
assetContextValue,
|
||||||
viewStateContextValue,
|
viewStateContextValue,
|
||||||
commandContextValue,
|
commandContextValue,
|
||||||
tagDragHandlers,
|
tagHandlers,
|
||||||
scrollRef,
|
scrollRef,
|
||||||
hasDocumentEntries,
|
hasDocumentEntries,
|
||||||
isSearchLoading,
|
isSearchLoading,
|
||||||
|
|||||||
Reference in New Issue
Block a user