feat: refactor document opening/preview logic to support preview/sidepanel actions.
This commit is contained in:
@@ -4,8 +4,8 @@ import { useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
DocumentsFilterProvider,
|
||||
} from '../documents/context/DocumentsFilterContext';
|
||||
import { PreviewProvider } from '../preview/PreviewContext';
|
||||
import { DocumentOpenProvider } from '../context/DocumentOpenContext';
|
||||
import { PreviewProvider, usePreviewContext } from '../preview/PreviewContext';
|
||||
import { DocumentOpenProvider } from '../contexts/DocumentOpenContext';
|
||||
import { useWorkspaceSurface } from './useWorkspaceSurface';
|
||||
import { DocumentsHeaderBreadcrumb } from '../documents/panel/DocumentsPanelHeader';
|
||||
import { SidebarProvider, useSidebarContext } from '../sidebar/SidebarContext';
|
||||
@@ -24,8 +24,11 @@ const DocumentsRouteContent: React.FC = () => {
|
||||
const {
|
||||
sidebarSuppressed,
|
||||
expandSidebar,
|
||||
openDetailPanel,
|
||||
} = usePanelManager();
|
||||
|
||||
const { openPreview } = usePreviewContext();
|
||||
|
||||
const sidebarHidden = sidebarCollapsed || sidebarSuppressed;
|
||||
|
||||
const handleHeaderBreadcrumbClick = useCallback((crumb: DocumentsHeaderBreadcrumb) => {
|
||||
@@ -40,6 +43,12 @@ const DocumentsRouteContent: React.FC = () => {
|
||||
navigate(`/documents/${documentId}`);
|
||||
}, [navigate]);
|
||||
|
||||
const handleOpenSidepanel = useCallback((docId: string) => {
|
||||
if (openDetailPanel) {
|
||||
openDetailPanel({ documentIds: [docId] });
|
||||
}
|
||||
}, [openDetailPanel]);
|
||||
|
||||
const documentsTablePropsWithNav = useMemo(() => (
|
||||
surfaceConfig.documentsTableProps
|
||||
? { ...surfaceConfig.documentsTableProps, onBreadcrumbNavigate: handleHeaderBreadcrumbClick }
|
||||
@@ -84,7 +93,11 @@ const DocumentsRouteContent: React.FC = () => {
|
||||
<PreviewProvider
|
||||
onNavigate={handleDocumentNavigate}
|
||||
>
|
||||
<DocumentOpenProvider onOpenViewer={handleDocumentNavigate}>
|
||||
<DocumentOpenProvider
|
||||
onOpenViewer={handleDocumentNavigate}
|
||||
onOpenPreview={openPreview}
|
||||
onOpenSidepanel={handleOpenSidepanel}
|
||||
>
|
||||
{content}
|
||||
</DocumentOpenProvider>
|
||||
</PreviewProvider>
|
||||
|
||||
+18
-14
@@ -1,6 +1,4 @@
|
||||
import React, { createContext, useContext, useCallback } from 'react';
|
||||
import { usePreviewContext } from '../preview/PreviewContext';
|
||||
import { useAppShell } from '../appShellContext';
|
||||
import type { Document } from '../types/documents';
|
||||
import type { Identifier } from '../types/identifiers';
|
||||
|
||||
@@ -20,25 +18,31 @@ export const useDocumentOpen = () => {
|
||||
return context;
|
||||
};
|
||||
|
||||
export const DocumentOpenProvider: React.FC<{ children: React.ReactNode; onOpenViewer?: (docId: Identifier) => void }> = ({ children, onOpenViewer }) => {
|
||||
const { openPreview } = usePreviewContext();
|
||||
const appShell = useAppShell();
|
||||
|
||||
// We cast appShell.openDetailPanel because AppShellContext is loosely typed
|
||||
const openDetailPanel = appShell.openDetailPanel as ((args: { documentIds: Identifier[] }) => void) | undefined;
|
||||
interface DocumentOpenProviderProps {
|
||||
children: React.ReactNode;
|
||||
onOpenViewer?: (docId: Identifier) => void;
|
||||
onOpenPreview?: (doc: Document) => void;
|
||||
onOpenSidepanel?: (docId: Identifier) => void;
|
||||
}
|
||||
|
||||
export const DocumentOpenProvider: React.FC<DocumentOpenProviderProps> = ({
|
||||
children,
|
||||
onOpenViewer,
|
||||
onOpenPreview,
|
||||
onOpenSidepanel,
|
||||
}) => {
|
||||
const openDocument = useCallback((doc: Document, target: DocumentOpenTarget = 'preview') => {
|
||||
if (!doc) return;
|
||||
|
||||
switch (target) {
|
||||
case 'preview':
|
||||
openPreview(doc);
|
||||
if (onOpenPreview) {
|
||||
onOpenPreview(doc);
|
||||
}
|
||||
break;
|
||||
case 'sidepanel':
|
||||
if (openDetailPanel) {
|
||||
openDetailPanel({ documentIds: [doc.id] });
|
||||
} else {
|
||||
console.warn('openDetailPanel is not available in AppShellContext');
|
||||
if (onOpenSidepanel) {
|
||||
onOpenSidepanel(doc.id);
|
||||
}
|
||||
break;
|
||||
case 'viewer':
|
||||
@@ -47,7 +51,7 @@ export const DocumentOpenProvider: React.FC<{ children: React.ReactNode; onOpenV
|
||||
}
|
||||
break;
|
||||
}
|
||||
}, [openPreview, openDetailPanel, onOpenViewer]);
|
||||
}, [onOpenPreview, onOpenSidepanel, onOpenViewer]);
|
||||
|
||||
return (
|
||||
<DocumentOpenContext.Provider value={{ openDocument }}>
|
||||
@@ -19,7 +19,7 @@ import { PointerTrackingProvider, usePointerTracking } from './PointerTrackingCo
|
||||
import type { Identifier } from '../types/identifiers';
|
||||
import type { DocumentsListEntry, Document } from '../types/documents';
|
||||
import { useAppState } from '../app/appState';
|
||||
import { useDocumentOpen } from '../context/DocumentOpenContext';
|
||||
import { useDocumentOpen } from '../contexts/DocumentOpenContext';
|
||||
|
||||
type TagLike = { id?: Identifier | null; label?: string; color?: string | null } | null;
|
||||
type OverlaySource = { url: string; alt?: string | null; mimeType?: string | null; };
|
||||
|
||||
@@ -7,13 +7,9 @@ type FetchDocument = (id: DocumentId) => Promise<unknown>;
|
||||
|
||||
class DocumentsManager<T extends ManagedDocument = ManagedDocument> {
|
||||
private byId: Map<DocumentId, T>;
|
||||
|
||||
private fetcher?: FetchDocument;
|
||||
|
||||
private inflight: Map<DocumentId, Promise<T | null>>;
|
||||
|
||||
private listeners: Set<() => void>;
|
||||
|
||||
private emitScheduled: boolean;
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { type DragEvent } from 'react';
|
||||
import { parseTagTransferPayload } from '../tagTransfer';
|
||||
import { createDocumentEntryKey } from '../../app/entryKey';
|
||||
import { useDocumentOpen } from '../../context/DocumentOpenContext';
|
||||
import { useDocumentOpen } from '../../contexts/DocumentOpenContext';
|
||||
import type { Document } from '../../types/documents';
|
||||
import type { DocumentsViewProps } from '../panel/DocumentsPanel';
|
||||
import type { DocumentViewLogic } from './useDocumentViewLogic';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import type { DocumentsListEntry } from '../../types/documents';
|
||||
import { useWorkspaceSelectionContext } from '../../app/WorkspaceSelectionContext';
|
||||
import { useDocumentOpen } from '../../context/DocumentOpenContext';
|
||||
import { useDocumentOpen } from '../../contexts/DocumentOpenContext';
|
||||
|
||||
interface UseDocumentsNavigationProps {
|
||||
entries: DocumentsListEntry[];
|
||||
|
||||
Reference in New Issue
Block a user