clean
This commit is contained in:
@@ -6,6 +6,7 @@ import UploadQueueOverlay from './UploadQueueOverlay';
|
||||
import useDocumentsWorkspace from '../hooks/documents/useDocumentsWorkspace';
|
||||
import { useDocumentsPreferences } from './useDocumentsPreferences';
|
||||
import SettingsRoute from './SettingsRoute';
|
||||
import { WorkspaceSelectionProvider } from './WorkspaceSelectionContext';
|
||||
|
||||
const AppLayout: React.FC = () => {
|
||||
const documentsPreferences = useDocumentsPreferences();
|
||||
@@ -16,6 +17,7 @@ const AppLayout: React.FC = () => {
|
||||
dropOverlayState,
|
||||
managementModals,
|
||||
contextValue,
|
||||
workspaceSelection,
|
||||
settingsOpen,
|
||||
closeSettings,
|
||||
} = useDocumentsWorkspace({
|
||||
@@ -50,8 +52,9 @@ const AppLayout: React.FC = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<AppShellContext.Provider value={contextValue}>
|
||||
<div className="app-shell" ref={shellRef}>
|
||||
<WorkspaceSelectionProvider value={workspaceSelection}>
|
||||
<AppShellContext.Provider value={contextValue}>
|
||||
<div className="app-shell" ref={shellRef}>
|
||||
<DropOverlay
|
||||
active={dropOverlayState.active}
|
||||
folderName={dropOverlayState.folderName}
|
||||
@@ -65,8 +68,9 @@ const AppLayout: React.FC = () => {
|
||||
{settingsOpen ? (
|
||||
<SettingsRoute open onClose={closeSettings} />
|
||||
) : null}
|
||||
</div>
|
||||
</AppShellContext.Provider>
|
||||
</div>
|
||||
</AppShellContext.Provider>
|
||||
</WorkspaceSelectionProvider>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import React, { createContext, useContext } from 'react';
|
||||
import type useWorkspaceSelection from './useWorkspaceSelection';
|
||||
|
||||
type WorkspaceSelectionValue = ReturnType<typeof useWorkspaceSelection> | null;
|
||||
|
||||
const WorkspaceSelectionContext = createContext<WorkspaceSelectionValue>(null);
|
||||
|
||||
export const WorkspaceSelectionProvider: React.FC<{ value: NonNullable<WorkspaceSelectionValue>; children: React.ReactNode }>
|
||||
= ({ value, children }) => (
|
||||
<WorkspaceSelectionContext.Provider value={value}>
|
||||
{children}
|
||||
</WorkspaceSelectionContext.Provider>
|
||||
);
|
||||
|
||||
export const useWorkspaceSelectionContext = () => {
|
||||
const context = useContext(WorkspaceSelectionContext);
|
||||
if (!context) {
|
||||
throw new Error('useWorkspaceSelectionContext must be used within a WorkspaceSelectionProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
export default WorkspaceSelectionContext;
|
||||
@@ -4,6 +4,27 @@ import { createDocumentsTableHeaderActions } from '../documents/DocumentsPanel';
|
||||
import createWorkspaceSurfaceConfig from '../documents/workspaceHeader';
|
||||
import DocumentViewerPanel from '../preview/DocumentViewerPanel';
|
||||
import DesktopWorkspace from './DesktopWorkspace';
|
||||
import { useWorkspaceSelectionContext } from '../app/WorkspaceSelectionContext';
|
||||
|
||||
type SelectionFloatingActionsBaseProps = Omit<React.ComponentProps<typeof SelectionFloatingActions>, 'selectionCount' | 'selectedDocumentIds' | 'selectedFolderIds'>;
|
||||
|
||||
const SelectionFloatingActionsWithSelection: React.FC<SelectionFloatingActionsBaseProps> = (props) => {
|
||||
const { selectedDocumentIds, selectedFolderIds } = useWorkspaceSelectionContext();
|
||||
const documentIds = Array.isArray(selectedDocumentIds) ? selectedDocumentIds : [];
|
||||
const folderIds = Array.isArray(selectedFolderIds) ? selectedFolderIds : [];
|
||||
const selectionCount = documentIds.length + folderIds.length;
|
||||
if (selectionCount === 0) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<SelectionFloatingActions
|
||||
selectionCount={selectionCount}
|
||||
selectedDocumentIds={documentIds}
|
||||
selectedFolderIds={folderIds}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
type WorkspaceProps = Record<string, any>;
|
||||
|
||||
@@ -36,8 +57,6 @@ const createDesktopSurface = ({
|
||||
onRefresh,
|
||||
viewMode,
|
||||
onViewModeChange,
|
||||
selectedDocumentIds,
|
||||
selectedFolderIds,
|
||||
onDeleteSelection,
|
||||
onClearSelection,
|
||||
tags,
|
||||
@@ -60,9 +79,6 @@ const createDesktopSurface = ({
|
||||
? `${searchResults.length} matching document${searchResults.length === 1 ? '' : 's'}`
|
||||
: null;
|
||||
|
||||
const documentSelectionCount = Array.isArray(selectedDocumentIds) ? selectedDocumentIds.length : 0;
|
||||
const folderSelectionCount = Array.isArray(selectedFolderIds) ? selectedFolderIds.length : 0;
|
||||
const selectionCount = documentSelectionCount + folderSelectionCount;
|
||||
const actions = createDocumentsTableHeaderActions({
|
||||
viewMode: viewMode || 'desk',
|
||||
onViewModeChange,
|
||||
@@ -71,28 +87,23 @@ const createDesktopSurface = ({
|
||||
onToggleIncludeDescendants: onToggleSearchIncludeDescendants,
|
||||
});
|
||||
|
||||
const floatingActions = selectionCount > 0
|
||||
? (
|
||||
<SelectionFloatingActions
|
||||
selectionCount={selectionCount}
|
||||
selectedDocumentIds={selectedDocumentIds}
|
||||
selectedFolderIds={selectedFolderIds}
|
||||
documentLookup={documentLookup}
|
||||
tags={tags}
|
||||
tagLookupById={tagLookupById}
|
||||
correspondents={correspondents}
|
||||
onBulkTagAdd={onBulkTagAdd}
|
||||
onBulkTagRemove={onBulkTagRemove}
|
||||
onBulkCorrespondentAdd={onBulkCorrespondentAdd}
|
||||
onBulkCorrespondentRemove={onBulkCorrespondentRemove}
|
||||
onBulkReanalyze={onBulkReanalyze}
|
||||
onDeleteSelection={onDeleteSelection}
|
||||
onClearSelection={onClearSelection}
|
||||
folderOptions={folderOptions}
|
||||
onMoveDocumentsToFolder={onMoveDocumentsToFolder}
|
||||
/>
|
||||
)
|
||||
: null;
|
||||
const floatingActions = (
|
||||
<SelectionFloatingActionsWithSelection
|
||||
documentLookup={documentLookup}
|
||||
tags={tags}
|
||||
tagLookupById={tagLookupById}
|
||||
correspondents={correspondents}
|
||||
onBulkTagAdd={onBulkTagAdd}
|
||||
onBulkTagRemove={onBulkTagRemove}
|
||||
onBulkCorrespondentAdd={onBulkCorrespondentAdd}
|
||||
onBulkCorrespondentRemove={onBulkCorrespondentRemove}
|
||||
onBulkReanalyze={onBulkReanalyze}
|
||||
onDeleteSelection={onDeleteSelection}
|
||||
onClearSelection={onClearSelection}
|
||||
folderOptions={folderOptions}
|
||||
onMoveDocumentsToFolder={onMoveDocumentsToFolder}
|
||||
/>
|
||||
);
|
||||
|
||||
const sidebarToggle = renderSidebarToggle ? renderSidebarToggle() : null;
|
||||
const detail = detailOpen && detailProps
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import type { DragEvent, MouseEvent, RefObject } from 'react';
|
||||
import { FolderIcon, CheckIcon, CloseIcon } from '../ui/icons';
|
||||
import DocumentThumbnailImage from './DocumentThumbnailImage';
|
||||
@@ -7,6 +7,7 @@ import { getTagColorStyle } from '../utils/colors';
|
||||
import { resolveCorrespondents } from './correspondents';
|
||||
import { writeTagTransferData } from './tagTransfer';
|
||||
import useInlineRename from './useInlineRename';
|
||||
import { useWorkspaceSelectionContext } from '../app/WorkspaceSelectionContext';
|
||||
|
||||
export type Identifier = string | number;
|
||||
|
||||
@@ -55,8 +56,6 @@ type DocumentEventHandler = (document: DocumentLike, event: MouseEvent<HTMLDivEl
|
||||
|
||||
interface DocumentsGridProps {
|
||||
entries: DocumentsGridEntry[];
|
||||
selectedDocumentIdsSet?: Set<Identifier> | null;
|
||||
selectedFolderIdsSet?: Set<Identifier | 'root'> | null;
|
||||
draggingDocumentIdsSet?: Set<Identifier> | null;
|
||||
draggedFolderId?: Identifier | 'root' | null;
|
||||
onFolderClick?: FolderEventHandler;
|
||||
@@ -82,14 +81,11 @@ interface DocumentsGridProps {
|
||||
scrollRef?: RefObject<HTMLElement | null>;
|
||||
onCorrespondentClick?: (correspondentId?: Identifier | null) => void;
|
||||
activeCorrespondentIdSet?: Set<Identifier | null | undefined> | null;
|
||||
onClearSelection?: () => void;
|
||||
onDocumentRename?: (docId: Identifier, title: string) => Promise<boolean> | boolean;
|
||||
}
|
||||
|
||||
const DocumentsGrid: React.FC<DocumentsGridProps> = ({
|
||||
entries,
|
||||
selectedDocumentIdsSet,
|
||||
selectedFolderIdsSet,
|
||||
draggingDocumentIdsSet,
|
||||
draggedFolderId,
|
||||
onFolderClick,
|
||||
@@ -114,10 +110,16 @@ const DocumentsGrid: React.FC<DocumentsGridProps> = ({
|
||||
scrollRef,
|
||||
onCorrespondentClick,
|
||||
activeCorrespondentIdSet,
|
||||
onClearSelection,
|
||||
onDocumentRename,
|
||||
onFolderRename,
|
||||
}) => {
|
||||
const {
|
||||
selectedDocumentIds,
|
||||
selectedFolderIds,
|
||||
clearSelection,
|
||||
} = useWorkspaceSelectionContext();
|
||||
const selectedDocumentIdsSet = useMemo(() => new Set(selectedDocumentIds), [selectedDocumentIds]);
|
||||
const selectedFolderIdsSet = useMemo(() => new Set(selectedFolderIds || []), [selectedFolderIds]);
|
||||
const {
|
||||
editingId: editingDocumentId,
|
||||
draftValue: documentDraft,
|
||||
@@ -157,7 +159,7 @@ const DocumentsGrid: React.FC<DocumentsGridProps> = ({
|
||||
style={{ '--documents-grid-icon-size': `${gridIconSize}px` }}
|
||||
onClick={(event) => {
|
||||
if (event.target === event.currentTarget) {
|
||||
onClearSelection?.();
|
||||
clearSelection();
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import type { DragEvent, MouseEvent, RefObject } from 'react';
|
||||
import { FolderIcon, CheckIcon, CloseIcon } from '../ui/icons';
|
||||
import { getTagColorStyle } from '../utils/colors';
|
||||
@@ -8,6 +8,7 @@ import CorrespondentLinks from './CorrespondentLinks';
|
||||
import { resolveCorrespondents } from './correspondents';
|
||||
import { writeTagTransferData } from './tagTransfer';
|
||||
import useInlineRename from './useInlineRename';
|
||||
import { useWorkspaceSelectionContext } from '../app/WorkspaceSelectionContext';
|
||||
|
||||
export type Identifier = string | number;
|
||||
|
||||
@@ -60,8 +61,6 @@ export type DocumentEventHandler = (document: DocumentLike, event: MouseEvent<HT
|
||||
export interface DocumentsListProps {
|
||||
entries: DocumentsListEntry[];
|
||||
focusedRowKey?: string | null;
|
||||
selectedDocumentIdsSet?: Set<Identifier> | null;
|
||||
selectedFolderIdsSet?: Set<Identifier | 'root'> | null;
|
||||
draggingDocumentIdsSet?: Set<Identifier> | null;
|
||||
draggedFolderId?: Identifier | 'root' | null;
|
||||
ensureAssetUrl?: (...args: any[]) => unknown;
|
||||
@@ -87,15 +86,12 @@ export interface DocumentsListProps {
|
||||
onCorrespondentClick?: (correspondentId?: Identifier | null) => void;
|
||||
activeCorrespondentIdSet?: Set<Identifier | null | undefined> | null;
|
||||
scrollRef?: RefObject<HTMLElement | null>;
|
||||
onClearSelection?: () => void;
|
||||
}
|
||||
|
||||
|
||||
const DocumentsList: React.FC<DocumentsListProps> = ({
|
||||
entries,
|
||||
focusedRowKey,
|
||||
selectedDocumentIdsSet,
|
||||
selectedFolderIdsSet,
|
||||
draggingDocumentIdsSet,
|
||||
draggedFolderId,
|
||||
ensureAssetUrl,
|
||||
@@ -121,8 +117,17 @@ const DocumentsList: React.FC<DocumentsListProps> = ({
|
||||
onCorrespondentClick,
|
||||
activeCorrespondentIdSet,
|
||||
scrollRef,
|
||||
onClearSelection,
|
||||
}) => {
|
||||
const {
|
||||
selectedDocumentIds,
|
||||
selectedFolderIds,
|
||||
clearSelection,
|
||||
} = useWorkspaceSelectionContext();
|
||||
const selectedDocumentIdsSet = useMemo(() => new Set(selectedDocumentIds), [selectedDocumentIds]);
|
||||
const selectedFolderIdsSet = useMemo(
|
||||
() => new Set(selectedFolderIds || []),
|
||||
[selectedFolderIds],
|
||||
);
|
||||
const {
|
||||
editingId: editingDocumentId,
|
||||
draftValue: documentDraft,
|
||||
@@ -160,7 +165,7 @@ const DocumentsList: React.FC<DocumentsListProps> = ({
|
||||
<table aria-multiselectable="true">
|
||||
<thead
|
||||
onClick={() => {
|
||||
onClearSelection?.();
|
||||
clearSelection();
|
||||
}}
|
||||
>
|
||||
<tr>
|
||||
|
||||
@@ -31,8 +31,6 @@ export interface UseDocumentsPanelPropsArgs {
|
||||
handleFolderRename?: (...args: unknown[]) => void;
|
||||
openDocumentPreview?: (...args: unknown[]) => void;
|
||||
handleDocumentTitleUpdate?: (...args: unknown[]) => void;
|
||||
selectedDocumentIds?: Identifier[];
|
||||
selectedFolderIds?: Identifier[];
|
||||
focusedRowKey?: Identifier | string | null;
|
||||
draggedDocumentIds?: Identifier[];
|
||||
handleDocumentDragStart?: (...args: unknown[]) => void;
|
||||
@@ -40,8 +38,6 @@ export interface UseDocumentsPanelPropsArgs {
|
||||
searchLoading?: boolean;
|
||||
tagLookupById?: unknown;
|
||||
activeCorrespondentFilters?: Identifier[];
|
||||
selectedEntries?: unknown[];
|
||||
setFocusedRowKey?: (key: Identifier | string | null) => void;
|
||||
ensureAssetUrl?: (...args: unknown[]) => void;
|
||||
getDocumentAsset?: (...args: unknown[]) => unknown;
|
||||
toggleTagFilter?: (...args: unknown[]) => void;
|
||||
@@ -59,7 +55,6 @@ export interface UseDocumentsPanelPropsArgs {
|
||||
handleDeleteSelection?: () => void;
|
||||
handleEntryPointerCore?: (...args: unknown[]) => void;
|
||||
inspectDocument?: (docId: Identifier | null, metadata?: unknown) => void;
|
||||
handleEntrySelection?: (...args: unknown[]) => void;
|
||||
tags?: unknown[];
|
||||
correspondents?: unknown[];
|
||||
documentLookup?: unknown;
|
||||
@@ -91,8 +86,6 @@ const useDocumentsPanelProps = (props: UseDocumentsPanelPropsArgs) => {
|
||||
handleFolderRename,
|
||||
openDocumentPreview,
|
||||
handleDocumentTitleUpdate,
|
||||
selectedDocumentIds,
|
||||
selectedFolderIds,
|
||||
focusedRowKey,
|
||||
draggedDocumentIds,
|
||||
handleDocumentDragStart,
|
||||
@@ -100,8 +93,6 @@ const useDocumentsPanelProps = (props: UseDocumentsPanelPropsArgs) => {
|
||||
searchLoading,
|
||||
tagLookupById,
|
||||
activeCorrespondentFilters,
|
||||
selectedEntries,
|
||||
setFocusedRowKey,
|
||||
ensureAssetUrl,
|
||||
getDocumentAsset,
|
||||
toggleTagFilter,
|
||||
@@ -115,11 +106,9 @@ const useDocumentsPanelProps = (props: UseDocumentsPanelPropsArgs) => {
|
||||
searchIncludeDescendants,
|
||||
toggleSearchIncludeDescendants,
|
||||
handleDocumentsViewModeChange,
|
||||
clearDocumentSelection,
|
||||
handleDeleteSelection,
|
||||
handleEntryPointerCore,
|
||||
inspectDocument,
|
||||
handleEntrySelection,
|
||||
tags,
|
||||
correspondents,
|
||||
documentLookup,
|
||||
@@ -151,8 +140,6 @@ const useDocumentsPanelProps = (props: UseDocumentsPanelPropsArgs) => {
|
||||
onFolderRename: handleFolderRename,
|
||||
onDocumentOpen: openDocumentPreview,
|
||||
onDocumentRename: handleDocumentTitleUpdate,
|
||||
selectedDocumentIds,
|
||||
selectedFolderIds,
|
||||
focusedRowKey,
|
||||
draggingDocumentIds: draggedDocumentIds,
|
||||
onDocumentDragStart: handleDocumentDragStart,
|
||||
@@ -160,8 +147,6 @@ const useDocumentsPanelProps = (props: UseDocumentsPanelPropsArgs) => {
|
||||
isSearchLoading: searchLoading,
|
||||
tagLookupById,
|
||||
activeCorrespondentIds: activeCorrespondentFilters,
|
||||
selectedEntries,
|
||||
onFocusedRowChange: setFocusedRowKey,
|
||||
ensureAssetUrl,
|
||||
getDocumentAsset,
|
||||
onTagClick: toggleTagFilter,
|
||||
@@ -175,11 +160,9 @@ const useDocumentsPanelProps = (props: UseDocumentsPanelPropsArgs) => {
|
||||
searchIncludeDescendants,
|
||||
onToggleSearchIncludeDescendants: toggleSearchIncludeDescendants,
|
||||
onViewModeChange: handleDocumentsViewModeChange,
|
||||
onClearSelection: clearDocumentSelection,
|
||||
onDeleteSelection: handleDeleteSelection,
|
||||
onEntryPointer: handleEntryPointerCore,
|
||||
onInspectDocument: inspectDocument,
|
||||
onEntrySelection: handleEntrySelection,
|
||||
tags,
|
||||
correspondents,
|
||||
documentLookup,
|
||||
@@ -194,7 +177,6 @@ const useDocumentsPanelProps = (props: UseDocumentsPanelPropsArgs) => {
|
||||
[
|
||||
activeCorrespondentFilters,
|
||||
breadcrumbs,
|
||||
clearDocumentSelection,
|
||||
correspondents,
|
||||
currentFolderName,
|
||||
currentSubfolders,
|
||||
@@ -221,7 +203,6 @@ const useDocumentsPanelProps = (props: UseDocumentsPanelPropsArgs) => {
|
||||
handleDocumentsSortFieldChange,
|
||||
handleDocumentsViewModeChange,
|
||||
handleEntryPointerCore,
|
||||
handleEntrySelection,
|
||||
handleFolderDragEnd,
|
||||
handleFolderDragStart,
|
||||
handleFolderRename,
|
||||
@@ -233,11 +214,7 @@ const useDocumentsPanelProps = (props: UseDocumentsPanelPropsArgs) => {
|
||||
searchIncludeDescendants,
|
||||
searchLoading,
|
||||
searchResults,
|
||||
selectedDocumentIds,
|
||||
selectedEntries,
|
||||
selectedFolderIds,
|
||||
selectFolder,
|
||||
setFocusedRowKey,
|
||||
tagLookupById,
|
||||
tags,
|
||||
toggleCorrespondentFilter,
|
||||
|
||||
@@ -7,6 +7,7 @@ import { isTagTransferEvent } from '../tagTransfer';
|
||||
import PreviewZoomOverlay from '../../detail/PreviewZoomOverlay';
|
||||
import { useAssetNavigator } from '../../hooks/useAssetNavigator';
|
||||
import { isPointerModifierEvent, isPrimaryPointerEvent } from '../useEntryPointer';
|
||||
import { useWorkspaceSelectionContext } from '../../app/WorkspaceSelectionContext';
|
||||
|
||||
const DEFAULT_GRID_ICON_SIZE = 144;
|
||||
|
||||
@@ -37,19 +38,14 @@ const DocumentsPanel: React.FC<DocumentsPanelProps> = ({
|
||||
onFolderDragEnd,
|
||||
draggedFolderId,
|
||||
onFolderRename,
|
||||
selectedFolderIds = [],
|
||||
selectedDocumentIds = [],
|
||||
focusedRowKey,
|
||||
draggingDocumentIds = [],
|
||||
onDocumentDragStart,
|
||||
onDocumentDragEnd,
|
||||
onDocumentRename,
|
||||
onEntryPointer = null,
|
||||
onEntrySelection = null,
|
||||
onInspectDocument = null,
|
||||
tagLookupById,
|
||||
activeCorrespondentIds = [],
|
||||
onFocusedRowChange,
|
||||
ensureAssetUrl = null,
|
||||
getDocumentAsset = defaultGetDocumentAsset,
|
||||
onTagClick,
|
||||
@@ -58,10 +54,15 @@ const DocumentsPanel: React.FC<DocumentsPanelProps> = ({
|
||||
onDocumentTagDrop,
|
||||
viewMode = 'list',
|
||||
onViewModeChange,
|
||||
onClearSelection,
|
||||
selectedEntries = [],
|
||||
showHeader = true,
|
||||
}) => {
|
||||
const {
|
||||
selectedEntries,
|
||||
focusedRowKey,
|
||||
setFocusedRowKey,
|
||||
handleEntrySelection,
|
||||
clearSelection,
|
||||
} = useWorkspaceSelectionContext();
|
||||
const showingSearchResults = searchResults !== null;
|
||||
const rows = showingSearchResults ? searchResults : documents;
|
||||
|
||||
@@ -89,9 +90,9 @@ const DocumentsPanel: React.FC<DocumentsPanelProps> = ({
|
||||
const changed = previous.type !== nextContext.type
|
||||
|| previous.marker !== nextContext.marker;
|
||||
if (changed) {
|
||||
onClearSelection?.();
|
||||
clearSelection();
|
||||
}
|
||||
}, [showingSearchResults, currentFolderId, searchResults, onClearSelection]);
|
||||
}, [showingSearchResults, currentFolderId, searchResults, clearSelection]);
|
||||
|
||||
const entries = useMemo(() => {
|
||||
const list = [];
|
||||
@@ -112,14 +113,6 @@ const DocumentsPanel: React.FC<DocumentsPanelProps> = ({
|
||||
return list;
|
||||
}, [showingSearchResults, subfolders, rows]);
|
||||
|
||||
const selectedSet = useMemo(
|
||||
() => new Set(selectedDocumentIds),
|
||||
[selectedDocumentIds],
|
||||
);
|
||||
const selectedFolderSet = useMemo(
|
||||
() => new Set(selectedFolderIds || []),
|
||||
[selectedFolderIds],
|
||||
);
|
||||
const draggingSet = useMemo(
|
||||
() => new Set(draggingDocumentIds || []),
|
||||
[draggingDocumentIds],
|
||||
@@ -271,12 +264,12 @@ const DocumentsPanel: React.FC<DocumentsPanelProps> = ({
|
||||
return;
|
||||
}
|
||||
|
||||
onFocusedRowChange?.(resolvedKey);
|
||||
setFocusedRowKey(resolvedKey);
|
||||
}, [
|
||||
focusedRowKey,
|
||||
navigableRowKeys,
|
||||
navigableRows,
|
||||
onFocusedRowChange,
|
||||
setFocusedRowKey,
|
||||
selectedEntries,
|
||||
]);
|
||||
|
||||
@@ -320,7 +313,7 @@ const DocumentsPanel: React.FC<DocumentsPanelProps> = ({
|
||||
|
||||
if (key === 'Enter' || key === ' ' || key === 'Space' || key === 'Spacebar') {
|
||||
if (activeRow) {
|
||||
onEntrySelection?.(activeRow.key, event);
|
||||
handleEntrySelection(activeRow.key, event);
|
||||
if (activeRow.type === EntryType.folder) {
|
||||
onFolderSelect?.(activeRow.id);
|
||||
} else {
|
||||
@@ -353,8 +346,8 @@ const DocumentsPanel: React.FC<DocumentsPanelProps> = ({
|
||||
return;
|
||||
}
|
||||
|
||||
onFocusedRowChange?.(targetRow.key);
|
||||
onEntrySelection?.(targetRow.key, {
|
||||
setFocusedRowKey(targetRow.key);
|
||||
handleEntrySelection(targetRow.key, {
|
||||
shiftKey,
|
||||
preventDefault: () => {},
|
||||
});
|
||||
@@ -364,11 +357,11 @@ const DocumentsPanel: React.FC<DocumentsPanelProps> = ({
|
||||
getEntryByKey,
|
||||
navigableRowKeys,
|
||||
navigableRows,
|
||||
onEntrySelection,
|
||||
onFocusedRowChange,
|
||||
onFolderSelect,
|
||||
selectedEntries,
|
||||
handleDocumentPreviewZoom,
|
||||
handleEntrySelection,
|
||||
setFocusedRowKey,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -529,10 +522,10 @@ const DocumentsPanel: React.FC<DocumentsPanelProps> = ({
|
||||
&& scrollRef.current
|
||||
) {
|
||||
scrollRef.current.focus({ preventScroll: true });
|
||||
onFocusedRowChange?.(`folder:${folder.id}`);
|
||||
setFocusedRowKey(`folder:${folder.id}`);
|
||||
}
|
||||
},
|
||||
[onEntryPointer, onFocusedRowChange],
|
||||
[onEntryPointer, setFocusedRowKey],
|
||||
);
|
||||
|
||||
const handleDocumentDragStartLocal = useCallback(
|
||||
@@ -666,7 +659,7 @@ const DocumentsPanel: React.FC<DocumentsPanelProps> = ({
|
||||
}}
|
||||
onClick={(event) => {
|
||||
if (event.target === event.currentTarget) {
|
||||
onClearSelection?.();
|
||||
clearSelection();
|
||||
}
|
||||
}}
|
||||
aria-activedescendant={isGridView ? undefined : activeDescendantId}
|
||||
@@ -674,8 +667,6 @@ const DocumentsPanel: React.FC<DocumentsPanelProps> = ({
|
||||
{isGridView ? (
|
||||
<DocumentsGrid
|
||||
entries={entries}
|
||||
selectedDocumentIdsSet={selectedSet}
|
||||
selectedFolderIdsSet={selectedFolderSet}
|
||||
draggingDocumentIdsSet={draggingSet}
|
||||
draggedFolderId={draggedFolderId}
|
||||
onFolderClick={handleFolderClick}
|
||||
@@ -700,7 +691,6 @@ const DocumentsPanel: React.FC<DocumentsPanelProps> = ({
|
||||
scrollRef={scrollRef}
|
||||
onCorrespondentClick={onCorrespondentClick}
|
||||
activeCorrespondentIdSet={activeCorrespondentIdSet}
|
||||
onClearSelection={onClearSelection}
|
||||
onDocumentRename={onDocumentRename}
|
||||
onFolderRename={onFolderRename}
|
||||
/>
|
||||
@@ -708,8 +698,6 @@ const DocumentsPanel: React.FC<DocumentsPanelProps> = ({
|
||||
<DocumentsList
|
||||
entries={entries}
|
||||
focusedRowKey={focusedRowKey}
|
||||
selectedDocumentIdsSet={selectedSet}
|
||||
selectedFolderIdsSet={selectedFolderSet}
|
||||
draggingDocumentIdsSet={draggingSet}
|
||||
draggedFolderId={draggedFolderId}
|
||||
ensureAssetUrl={ensureAssetUrl}
|
||||
@@ -735,7 +723,6 @@ const DocumentsPanel: React.FC<DocumentsPanelProps> = ({
|
||||
onCorrespondentClick={onCorrespondentClick}
|
||||
activeCorrespondentIdSet={activeCorrespondentIdSet}
|
||||
scrollRef={scrollRef}
|
||||
onClearSelection={onClearSelection}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,27 @@ import SelectionFloatingActions from '../SelectionFloatingActions';
|
||||
import createWorkspaceSurfaceConfig from '../workspaceHeader';
|
||||
import DocumentsPanel from './DocumentsPanel';
|
||||
import { createDocumentsTableHeaderActions } from './DocumentsToolbar';
|
||||
import { useWorkspaceSelectionContext } from '../../app/WorkspaceSelectionContext';
|
||||
|
||||
type SelectionFloatingActionsBaseProps = Omit<React.ComponentProps<typeof SelectionFloatingActions>, 'selectionCount' | 'selectedDocumentIds' | 'selectedFolderIds'>;
|
||||
|
||||
const SelectionFloatingActionsWithSelection: React.FC<SelectionFloatingActionsBaseProps> = (props) => {
|
||||
const { selectedDocumentIds, selectedFolderIds } = useWorkspaceSelectionContext();
|
||||
const documentIds = Array.isArray(selectedDocumentIds) ? selectedDocumentIds : [];
|
||||
const folderIds = Array.isArray(selectedFolderIds) ? selectedFolderIds : [];
|
||||
const selectionCount = documentIds.length + folderIds.length;
|
||||
if (selectionCount === 0) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<SelectionFloatingActions
|
||||
selectionCount={selectionCount}
|
||||
selectedDocumentIds={documentIds}
|
||||
selectedFolderIds={folderIds}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
interface CreateDocumentsSurfaceArgs {
|
||||
tableProps: Record<string, any>;
|
||||
@@ -30,8 +51,6 @@ const createDocumentsSurface = ({
|
||||
sortDirection,
|
||||
onSortFieldChange,
|
||||
onSortDirectionToggle,
|
||||
selectedDocumentIds,
|
||||
selectedFolderIds,
|
||||
onDeleteSelection,
|
||||
onClearSelection,
|
||||
tags,
|
||||
@@ -55,10 +74,6 @@ const createDocumentsSurface = ({
|
||||
? `${searchResults.length} matching document${searchResults.length === 1 ? '' : 's'}`
|
||||
: null;
|
||||
|
||||
const documentSelectionCount = Array.isArray(selectedDocumentIds) ? selectedDocumentIds.length : 0;
|
||||
const folderSelectionCount = Array.isArray(selectedFolderIds) ? selectedFolderIds.length : 0;
|
||||
const selectionCount = documentSelectionCount + folderSelectionCount;
|
||||
|
||||
const actions = createDocumentsTableHeaderActions({
|
||||
viewMode,
|
||||
onViewModeChange,
|
||||
@@ -72,28 +87,23 @@ const createDocumentsSurface = ({
|
||||
onToggleIncludeDescendants: onToggleSearchIncludeDescendants,
|
||||
});
|
||||
|
||||
const floatingActions = selectionCount > 0
|
||||
? (
|
||||
<SelectionFloatingActions
|
||||
selectionCount={selectionCount}
|
||||
selectedDocumentIds={selectedDocumentIds}
|
||||
selectedFolderIds={selectedFolderIds}
|
||||
documentLookup={documentLookup}
|
||||
tags={tags}
|
||||
tagLookupById={tagLookupById}
|
||||
correspondents={correspondents}
|
||||
onBulkTagAdd={onBulkTagAdd}
|
||||
onBulkTagRemove={onBulkTagRemove}
|
||||
onBulkCorrespondentAdd={onBulkCorrespondentAdd}
|
||||
onBulkCorrespondentRemove={onBulkCorrespondentRemove}
|
||||
onBulkReanalyze={onBulkReanalyze}
|
||||
onDeleteSelection={onDeleteSelection}
|
||||
onClearSelection={onClearSelection}
|
||||
folderOptions={folderOptions}
|
||||
onMoveDocumentsToFolder={onMoveDocumentsToFolder}
|
||||
/>
|
||||
)
|
||||
: null;
|
||||
const floatingActions = (
|
||||
<SelectionFloatingActionsWithSelection
|
||||
documentLookup={documentLookup}
|
||||
tags={tags}
|
||||
tagLookupById={tagLookupById}
|
||||
correspondents={correspondents}
|
||||
onBulkTagAdd={onBulkTagAdd}
|
||||
onBulkTagRemove={onBulkTagRemove}
|
||||
onBulkCorrespondentAdd={onBulkCorrespondentAdd}
|
||||
onBulkCorrespondentRemove={onBulkCorrespondentRemove}
|
||||
onBulkReanalyze={onBulkReanalyze}
|
||||
onDeleteSelection={onDeleteSelection}
|
||||
onClearSelection={onClearSelection}
|
||||
folderOptions={folderOptions}
|
||||
onMoveDocumentsToFolder={onMoveDocumentsToFolder}
|
||||
/>
|
||||
);
|
||||
|
||||
const sidebarToggle = renderSidebarToggle ? renderSidebarToggle() : null;
|
||||
const detail = detailOpen && detailProps
|
||||
|
||||
@@ -1655,6 +1655,7 @@ const useDocumentsWorkspace = ({
|
||||
dropOverlayState,
|
||||
managementModals,
|
||||
contextValue,
|
||||
workspaceSelection: selection,
|
||||
settingsOpen,
|
||||
closeSettings,
|
||||
};
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
pointer-events: none;
|
||||
z-index: 6;
|
||||
z-index: 20000;
|
||||
height: 0;
|
||||
width: calc(100% - 2rem);
|
||||
margin: 0 1rem;
|
||||
|
||||
Reference in New Issue
Block a user