refactor: Introduce a layered architecture for card interactions, separating drag logic, and selection handling.
This commit is contained in:
@@ -15,6 +15,7 @@ import '../styles/workspace/workspace-layout.css';
|
||||
import '../styles/workspace/workspace-items.css';
|
||||
import '../styles/workspace/workspace-cards.css';
|
||||
import { useWorkspaceSelectionContext } from '../app/WorkspaceSelectionContext';
|
||||
import { createDocumentEntryKey } from '../app/entryKey';
|
||||
import type { Identifier } from '../types/identifiers';
|
||||
import type { DocumentsListEntry, Document } from '../types/documents';
|
||||
|
||||
@@ -56,10 +57,16 @@ export interface DesktopWorkspaceProps {
|
||||
}
|
||||
|
||||
// Wrapper to handle hooks per card
|
||||
const DesktopDocumentContainer: React.FC<React.ComponentProps<typeof DesktopDocumentCard>> = React.memo((props) => {
|
||||
const { layoutCard, selected } = props;
|
||||
const DesktopDocumentContainer: React.FC<React.ComponentProps<typeof DesktopDocumentCard> & {
|
||||
onSelect: (ids: string[], extend?: boolean) => void;
|
||||
onDeselect: (ids: string[]) => void;
|
||||
onDocumentActivate?: (id: string) => void;
|
||||
selection: string[];
|
||||
}> = React.memo((props) => {
|
||||
const { layoutCard, selected, onSelect, onDeselect, onDocumentActivate, selection } = props;
|
||||
|
||||
// We assume layoutCard is always present in this context
|
||||
const cardPointerHandlers = useCardPointer(layoutCard!, !!selected);
|
||||
const cardPointerHandlers = useCardPointer(layoutCard!, !!selected, selection, onSelect, onDeselect, onDocumentActivate);
|
||||
|
||||
return (
|
||||
<DesktopDocumentCard
|
||||
@@ -94,22 +101,18 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
|
||||
|
||||
// Selection Context
|
||||
const {
|
||||
selectedDocumentIds: contextSelectedIds,
|
||||
setSelectedDocumentIds,
|
||||
selectedDocumentIds,
|
||||
setSelectedEntries,
|
||||
clearSelection,
|
||||
} = useWorkspaceSelectionContext();
|
||||
|
||||
const [localSelectedIds, setLocalSelectedIds] = useState<Identifier[]>([]);
|
||||
const selectedDocumentIds = contextSelectedIds || localSelectedIds;
|
||||
|
||||
const handleSelectionChange = useCallback((ids: Identifier[]) => {
|
||||
if (setSelectedDocumentIds) {
|
||||
setSelectedDocumentIds(ids);
|
||||
} else {
|
||||
setLocalSelectedIds(ids);
|
||||
if (setSelectedEntries) {
|
||||
const keys = ids.map(id => createDocumentEntryKey(id));
|
||||
setSelectedEntries(keys);
|
||||
}
|
||||
onSelectionChange?.(ids);
|
||||
}, [setSelectedDocumentIds, onSelectionChange]);
|
||||
}, [setSelectedEntries, onSelectionChange]);
|
||||
|
||||
const onClearSelection = useCallback(() => {
|
||||
clearSelection ? clearSelection() : handleSelectionChange([]);
|
||||
@@ -207,7 +210,7 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
|
||||
ensureAssetUrl={ensureAssetUrl}
|
||||
getDocumentAsset={getDocumentAsset}
|
||||
handleNavigatorSnapshot={() => { }}
|
||||
onDocumentActivate={onDocumentActivate}
|
||||
onDocumentActivate={(id) => { onDocumentActivate?.({ id } as DeskDocument) }}
|
||||
layoutCard={layoutCard}
|
||||
onTagDragEnter={tagInteractions.handleTagDragEnterDoc}
|
||||
onTagDragOver={tagInteractions.handleTagDragOverDoc}
|
||||
@@ -220,6 +223,21 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
|
||||
tagTargetActive={tagDropTargetId === docId}
|
||||
tagTargetPending={pendingTagDocId === docId}
|
||||
pendingRemovalTag={pendingRemovalTag}
|
||||
onSelect={(ids, extend = false) => {
|
||||
if (!extend) {
|
||||
handleSelectionChange(ids);
|
||||
} else {
|
||||
const newSelection = new Set(selectedDocumentIds);
|
||||
ids.forEach(id => newSelection.add(id));
|
||||
handleSelectionChange(Array.from(newSelection));
|
||||
}
|
||||
}}
|
||||
onDeselect={(ids) => {
|
||||
const newSelection = new Set(selectedDocumentIds);
|
||||
ids.forEach(id => newSelection.delete(id));
|
||||
handleSelectionChange(Array.from(newSelection));
|
||||
}}
|
||||
selection={selectedDocumentIds}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user