This commit is contained in:
2025-11-24 20:19:44 +01:00
parent 66848e8526
commit 4c8ff39305
10 changed files with 130 additions and 109 deletions
+78 -48
View File
@@ -28,6 +28,7 @@ import usePreviewMetadata from './hooks/usePreviewMetadata';
import '../styles/workspace/workspace-layout.css';
import '../styles/workspace/workspace-items.css';
import '../styles/workspace/workspace-cards.css';
import { useWorkspaceSelectionContext } from '../app/WorkspaceSelectionContext';
type Identifier = string | number;
@@ -118,17 +119,13 @@ type WorkspaceSnapshotState = {
};
interface DesktopWorkspaceProps {
documents?: DeskDocument[];
onInspectDocument?: (...args: unknown[]) => void;
onEntryPointer?: (...args: unknown[]) => void;
onDocumentStackSelect?: (docIds: Identifier[]) => void;
onPromoteSelection?: (...args: unknown[]) => void;
onAssignTagToDocument?: (...args: unknown[]) => void;
entries?: DeskDocument[];
onDocumentActivate?: (...args: unknown[]) => void;
onDocumentClick?: (...args: unknown[]) => void;
onDocumentTagDrop?: (...args: unknown[]) => void;
ensureAssetUrl?: EnsureAssetUrl;
getDocumentAsset?: GetAsset;
activeTagIds?: Array<Identifier | null>;
selectedDocumentIds?: Identifier[];
onClearSelection?: () => void;
activeTagFilters?: Array<Identifier | null>;
tenantId?: Identifier | null;
viewId?: string | null;
}
@@ -167,12 +164,12 @@ interface DesktopWorkspaceViewProps {
overlayOriginRect: DOMRect | null;
overlayOriginTransform: OverlayOriginTransform | null;
overlayDocument: DeskDocument | null;
onEntryPointer?: DesktopWorkspaceProps['onEntryPointer'];
onDocumentStackSelect?: DesktopWorkspaceProps['onDocumentStackSelect'];
onPromoteSelection?: DesktopWorkspaceProps['onPromoteSelection'];
selectedDocumentIds: Identifier[];
onClearSelection?: DesktopWorkspaceProps['onClearSelection'];
onDocumentClick?: DesktopWorkspaceProps['onDocumentClick'];
onDocumentStackSelect?: (docIds: Identifier[], event?: PointerEvent | MouseEvent | null) => void;
onPromoteSelection?: (docId: Identifier | null) => void;
documentLookup: Map<string, DeskDocument>;
selectedDocumentIds: Identifier[];
onClearSelection: () => void;
resolveBaseMetrics: (doc: DeskDocument | null, cardWidth: number, cardHeight: number) => {
baseWidth: number;
baseHeight: number;
@@ -184,7 +181,7 @@ interface DesktopWorkspaceViewProps {
openOverlayForDoc: (docId: Identifier | null, originInfo?: OverlayOriginHint | null) => void;
recalcVisibleDocIds: () => void;
dragSettings: DragSettings;
onInspectDocument?: DesktopWorkspaceProps['onInspectDocument'];
onDocumentActivate?: DesktopWorkspaceProps['onDocumentActivate'];
markLayoutDirty: () => void;
}
@@ -193,23 +190,60 @@ const DEBUG_FOCUS = false;
const defaultGetDocumentAsset: GetAsset = () => null;
const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
documents = [],
onInspectDocument = null,
onEntryPointer = null,
onDocumentStackSelect = null,
onPromoteSelection = null,
onAssignTagToDocument = null,
entries = [],
onDocumentActivate = null,
onDocumentClick = null,
onDocumentTagDrop = null,
ensureAssetUrl = null,
getDocumentAsset = defaultGetDocumentAsset,
activeTagIds = [],
selectedDocumentIds = [],
onClearSelection = null,
activeTagFilters = [],
tenantId = null,
viewId = 'default',
documentLinks,
ensureDownloadUrl,
}) => {
const items = useMemo<DeskDocument[]>(() => documents, [documents]);
const {
selectedDocumentIds,
clearSelection,
handleEntrySelection,
promoteSelectionOrder,
} = useWorkspaceSelectionContext();
const items = useMemo<DeskDocument[]>(
() => (Array.isArray(entries) ? entries.filter((doc): doc is DeskDocument => Boolean(doc)) : []),
[entries],
);
const getDocRowKey = useCallback((id: Identifier | null) => (id != null ? `document:${id}` : null), []);
const handleStackSelect = useCallback(
(docIds: Identifier[], event?: PointerEvent | MouseEvent | null) => {
if (!Array.isArray(docIds) || docIds.length === 0) {
return;
}
const syntheticEvent = event || ({
metaKey: true,
ctrlKey: true,
preventDefault: () => {},
} as unknown as PointerEvent);
docIds.forEach((id) => {
const key = getDocRowKey(id);
if (key) {
handleEntrySelection(key, syntheticEvent);
}
});
},
[getDocRowKey, handleEntrySelection],
);
const handlePromoteSelection = useCallback(
(docId: Identifier | null) => {
const key = getDocRowKey(docId);
if (key && promoteSelectionOrder) {
promoteSelectionOrder(key);
}
},
[getDocRowKey, promoteSelectionOrder],
);
const allowLayoutPersistence = Boolean(tenantId && viewId && viewId.startsWith('folder:'));
const documentLinkMap = documentLinks instanceof Map ? documentLinks : null;
@@ -380,17 +414,17 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
[applySnapshotDimensions],
);
const activeTagSet = useMemo<Set<string>>(() => {
if (!Array.isArray(activeTagIds) || activeTagIds.length === 0) {
if (!Array.isArray(activeTagFilters) || activeTagFilters.length === 0) {
return new Set();
}
const set = new Set<string>();
activeTagIds.forEach((id) => {
activeTagFilters.forEach((id) => {
if (id != null) {
set.add(String(id));
}
});
return set;
}, [activeTagIds]);
}, [activeTagFilters]);
useLayoutEffect(() => {
const container = containerRef.current;
@@ -480,7 +514,7 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
const tagInteractions = useDeskTagInteractions({
engine,
onAssignTagToDocument,
onAssignTagToDocument: onDocumentTagDrop,
requestCanvasFocus,
});
@@ -782,11 +816,11 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
overlayOriginRect,
overlayOriginTransform,
overlayDocument,
onEntryPointer,
onDocumentStackSelect,
onPromoteSelection,
onDocumentClick,
onDocumentStackSelect: handleStackSelect,
onPromoteSelection: handlePromoteSelection,
selectedDocumentIds,
onClearSelection,
onClearSelection: clearSelection,
documentLookup,
resolveBaseMetrics,
bringToFront,
@@ -795,7 +829,7 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
openOverlayForDoc,
recalcVisibleDocIds,
dragSettings,
onInspectDocument,
onDocumentActivate,
markLayoutDirty,
}),
[
@@ -827,10 +861,7 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
items,
layoutRef,
layoutSnapshot,
onClearSelection,
onDocumentStackSelect,
onEntryPointer,
onPromoteSelection,
onDocumentClick,
openOverlayForDoc,
overlayDisplay,
overlayOriginRect,
@@ -843,7 +874,7 @@ const DesktopWorkspace: React.FC<DesktopWorkspaceProps> = ({
resolveBaseMetrics,
setDraggingId,
selectedDocumentIds,
onInspectDocument,
onDocumentActivate,
markLayoutDirty,
tagDropTargetId,
visibleDocIds,
@@ -885,7 +916,7 @@ function DesktopWorkspaceView({
overlayOriginRect,
overlayOriginTransform,
overlayDocument,
onEntryPointer,
onDocumentClick,
onDocumentStackSelect,
onPromoteSelection,
selectedDocumentIds,
@@ -898,7 +929,7 @@ function DesktopWorkspaceView({
openOverlayForDoc,
recalcVisibleDocIds,
dragSettings,
onInspectDocument,
onDocumentActivate,
markLayoutDirty,
dragTransformsRef,
}: DesktopWorkspaceViewProps) {
@@ -918,8 +949,7 @@ function DesktopWorkspaceView({
recalcVisibleDocIds,
settings: dragSettings,
containerRef,
onInspectDocument,
onDocumentStackSelect,
onDocumentActivate,
selectedDocumentIds,
markLayoutDirty,
}) as {
@@ -939,10 +969,10 @@ function DesktopWorkspaceView({
handlePointerMove,
handlePointerUp,
handlePointerCancel,
onEntryPointer,
onDocumentClick,
onDocumentStackSelect,
onPromoteSelection,
onInspectDocument,
onDocumentActivate,
selectedDocumentIds,
openOverlayForDoc,
}) as {
@@ -967,7 +997,7 @@ function DesktopWorkspaceView({
<>
<div className="desk-shell" onPointerDown={(event) => {
if (event.target === event.currentTarget) {
onClearSelection?.();
onClearSelection();
}
focusShell();
}}
@@ -982,7 +1012,7 @@ function DesktopWorkspaceView({
onDrop={handleCanvasDrop}
onPointerDown={(event) => {
if (event.target === event.currentTarget) {
onClearSelection?.();
onClearSelection();
}
focusShell();
}}
@@ -1073,7 +1103,7 @@ function DesktopWorkspaceView({
getDocumentAsset={getDocumentAsset}
handleNavigatorSnapshot={handleNavigatorSnapshot}
cardPointerHandlers={cardPointerHandlers}
onInspectDocument={onInspectDocument}
onDocumentActivate={onDocumentActivate}
onTagDragEnter={handleTagDragEnterDoc}
onTagDragOver={handleTagDragOverDoc}
onTagDragLeave={handleTagDragLeaveDoc}