feat: refactor frontend document sorting preferences and sidebar utilities.

This commit is contained in:
2025-12-07 22:55:26 +01:00
parent 53664f2421
commit b29e856225
9 changed files with 160 additions and 314 deletions
@@ -1,5 +1,4 @@
import {
MutableRefObject,
useCallback,
useEffect,
useMemo,
@@ -25,9 +24,7 @@ import { useEntryPointer as useEntryPointerCore } from '../features/selection/us
import { isTagTransferEvent } from '../features/tagging/tagTransfer';
import useDocumentsSelection from '../features/selection/useDocumentsSelection';
import useBulkDocumentActions from './useBulkDocumentActions';
import useDocumentsPanelProps from '../logic/useDocumentsPanelProps';
import useDocumentPreview from '../../app/useDocumentPreview';
import useSidebarProps from '../../sidebar/useSidebarProps';
import {
DEFAULT_SORT_DIRECTION,
DEFAULT_SORT_FIELD,
@@ -69,19 +66,8 @@ const EntryType = Object.freeze({
const noop = () => { };
import type { Document } from '../../types/documents';
interface FolderContentsEntry {
folder?: { id?: FolderNodeId; name?: string | null } | null;
documents?: Document[];
subfolders?: Array<{ id?: FolderNodeId; name?: string | null;[key: string]: unknown }>;
__includesDocuments?: boolean;
__sortField?: string | null;
__sortDirection?: string | null;
[key: string]: unknown;
}
interface TenantOption {
id?: Identifier | null;
name?: string | null;
@@ -93,8 +79,6 @@ interface UseDocumentsWorkspaceOptions {
documentsViewMode?: string;
documentsSortField?: string;
documentsSortDirection?: string;
documentsSortFieldRef?: MutableRefObject<string>;
documentsSortDirectionRef?: MutableRefObject<string>;
onDocumentsViewModeChange?: (mode: string) => void;
onDocumentsSortFieldChange?: (field: string) => void;
onDocumentsSortDirectionToggle?: () => void;
@@ -106,8 +90,6 @@ const useDocumentsWorkspace = ({
documentsViewMode = 'list',
documentsSortField = DEFAULT_SORT_FIELD,
documentsSortDirection = DEFAULT_SORT_DIRECTION,
documentsSortFieldRef,
documentsSortDirectionRef,
onDocumentsViewModeChange,
onDocumentsSortFieldChange,
onDocumentsSortDirectionToggle,
@@ -119,17 +101,15 @@ const useDocumentsWorkspace = ({
const handleDocumentsSortDirectionToggle = onDocumentsSortDirectionToggle || noop;
const setSearchIncludeDescendants = onSetSearchIncludeDescendants || noop;
const fallbackSortFieldRef = useRef(documentsSortField);
const activeSortFieldRef = documentsSortFieldRef || fallbackSortFieldRef;
const activeSortFieldRef = useRef(documentsSortField);
useEffect(() => {
activeSortFieldRef.current = documentsSortField;
}, [documentsSortField, activeSortFieldRef]);
}, [documentsSortField]);
const fallbackSortDirectionRef = useRef(documentsSortDirection);
const activeSortDirectionRef = documentsSortDirectionRef || fallbackSortDirectionRef;
const activeSortDirectionRef = useRef(documentsSortDirection);
useEffect(() => {
activeSortDirectionRef.current = documentsSortDirection;
}, [documentsSortDirection, activeSortDirectionRef]);
}, [documentsSortDirection]);
const navigate = useNavigate();
const location = useLocation();
@@ -172,7 +152,7 @@ const useDocumentsWorkspace = ({
},
[showToast],
);
const status = null; // No longer used, kept for backward compatibility
const handleApiReport = useCallback(
({ message, variant }) => setStatusMessage(message, variant),
[setStatusMessage],
@@ -193,7 +173,7 @@ const useDocumentsWorkspace = ({
setStatusMessage,
});
const breadcrumbFetchRef = useRef(new Set());
const tagRemovalCursorActiveRef = useRef(false);
const tenantIdRef = useRef(currentTenantId);
const detailPanelControlRef = useRef({ open: () => { }, close: () => { } });
@@ -282,14 +262,6 @@ const useDocumentsWorkspace = ({
configureSelectionEnvironment,
} = selection;
const [folderContents, setFolderContents] = useState<Map<FolderNodeId, FolderContentsEntry>>(
() => new Map(),
);
const folderContentsRef = useRef(folderContents);
useEffect(() => {
folderContentsRef.current = folderContents;
}, [folderContents]);
const {
documents,
setDocuments,
@@ -298,7 +270,6 @@ const useDocumentsWorkspace = ({
updateDocumentCaches,
documentsManager,
} = useDocuments({
setFolderContents,
fetchDocumentById,
});
@@ -328,7 +299,7 @@ const useDocumentsWorkspace = ({
foldersManager,
});
const [currentSubfolders, setCurrentSubfolders] = useState<FolderContentsEntry['subfolders']>([]);
const [currentSubfolders, setCurrentSubfolders] = useState<Array<{ id?: FolderNodeId; name?: string | null;[key: string]: unknown }>>([]);
const ensureFolderData = useCallback(
async (
@@ -699,7 +670,7 @@ const useDocumentsWorkspace = ({
resetPreviewState();
resetUploadsState();
clearUploadQueue();
breadcrumbFetchRef.current = new Set();
detailFolderFetchRef.current = new Set();
bootstrapInitializedRef.current = false;
selectionInitializedRef.current = false;
@@ -1166,94 +1137,61 @@ const useDocumentsWorkspace = ({
tenantIdRef,
});
const documentsPanelProps = useDocumentsPanelProps({
currentFolderName,
breadcrumbs,
refreshCurrentFolder,
currentSubfolders,
documents: viewDocuments,
searchQuery,
searchResultIds,
folderClickHandlers,
selectedFolder,
handleFolderDragStart,
handleFolderDragEnd,
draggedFolderId,
handleFolderRename,
handleDocumentTitleUpdate,
draggedDocumentIds,
handleDocumentDragStart,
handleDocumentDragEnd,
searchLoading,
tagLookupById,
activeTagFilters,
activeCorrespondentFilters,
ensureAssetUrl,
getDocumentAsset,
handleDocumentTagAttach,
handleDocumentTagDetach: handleTagRemove,
documentsViewMode,
documentsSortField,
documentsSortDirection,
handleDocumentsSortFieldChange,
handleDocumentsSortDirectionToggle,
handleDocumentsViewModeChange,
clearDocumentSelection,
handleDeleteSelection,
handleEntryPointerCore,
tags,
correspondents,
documentLookup,
handleBulkTagAddFromDetail,
handleBulkTagRemoveFromDetail,
handleBulkCorrespondentAdd,
handleBulkCorrespondentRemove,
handleBulkSelectionReanalyze,
folderOptions,
moveDocumentsToFolder,
selectFolder,
selectionValue: selection,
});
const documentsTableProps = useMemo(
() => ({
...documentsPanelProps,
}),
[documentsPanelProps],
);
const sidebarProps = useSidebarProps({
folderClickHandlers,
handleFolderDelete,
handleFolderRename,
selectedFolder,
handleFolderDragStart,
handleFolderDragEnd,
draggedFolderId,
handlePromptCreateFolder,
creatingFolder,
});
const contextValue = {
const sessionContext = {
token,
appStatus,
status,
setStatusMessage,
dropOverlayState,
handleLogout,
sidebarProps,
tenant: tenantRecord,
tenants: tenantOptions,
tenantOptions,
handleTenantSelect,
};
const uiContext = {
setStatusMessage,
notifyApiError,
settingsOpen,
openSettings,
closeSettings,
managementModals,
};
const uploadContext = {
dropOverlayState,
uploadQueue,
clearUploadQueue,
handleFileSelection,
};
const tagsContext = {
tags,
refreshTags,
tagLookupById,
activeTagFilters,
handleTagUpdate,
handleTagDelete,
handleDocumentTagDrop: handleDocumentTagAttach,
handleBulkTagAddFromDetail,
handleBulkTagRemoveFromDetail,
openTagsModal,
};
const correspondentsContext = {
correspondents,
refreshCorrespondents,
activeCorrespondentFilters,
handleCorrespondentUpdate,
handleCorrespondentCreate,
handleCorrespondentDelete,
handleDocumentCorrespondentAttach,
handleCorrespondentRemove,
handleCorrespondentAdd,
handleBulkCorrespondentAdd,
handleBulkCorrespondentRemove,
openCorrespondentsModal,
};
const passkeysContext = {
passkeys,
passkeysSupported,
passkeysLoading,
@@ -1262,34 +1200,94 @@ const useDocumentsWorkspace = ({
refreshPasskeys,
registerPasskey,
revokePasskey,
};
const previewContext = {
previewActive,
previewWorkspaceDocument,
previewDocumentId,
closeDocumentPreview,
handleThumbnailRegeneration,
documentsTableProps,
detailPanelProps,
documentsViewMode,
ensureAssetUrl,
resolveFolderPath,
getDocumentAsset,
notifyApiError,
openTagsModal,
openCorrespondentsModal,
openSettings,
handleThumbnailRegeneration,
};
const detailPanelContext = {
detailPanelProps,
detailPanelOpen,
openDetailPanel,
uploadQueue,
clearUploadQueue,
};
const searchContext = {
searchQuery,
documentsFilter,
documentsManager,
searchLoading,
documentsViewMode,
handleDocumentsViewModeChange,
documentsSortField,
documentsSortDirection,
handleDocumentsSortFieldChange,
handleDocumentsSortDirectionToggle,
searchResultIds,
documents: viewDocuments,
};
const folderTreeContext = {
foldersManager,
selectedFolder,
currentFolderName,
folderOptions,
handleBreadcrumbNavigate,
tenant: tenantRecord,
tenants: tenantOptions,
tenantOptions,
handleTenantSelect,
handleFileSelection,
resolveFolderPath,
selectFolder,
moveDocumentsToFolder,
folderClickHandlers,
handleFolderRename,
handleFolderDelete,
handleFolderDragStart,
handleFolderDragEnd,
draggedFolderId,
handlePromptCreateFolder,
creatingFolder,
currentSubfolders,
breadcrumbs,
refreshCurrentFolder,
};
const selectionContext = {
clearDocumentSelection,
handleDeleteSelection,
handleEntryPointerCore,
handleBulkSelectionReanalyze,
selectionValue: selection,
};
const documentMutations = {
handleDocumentTitleUpdate,
handleDocumentDragStart,
handleDocumentDragEnd,
draggedDocumentIds,
};
const managers = {
documentsManager,
documentLookup,
};
const contextValue = {
...sessionContext,
...uiContext,
...uploadContext,
...tagsContext,
...correspondentsContext,
...passkeysContext,
...previewContext,
...detailPanelContext,
...searchContext,
...folderTreeContext,
...selectionContext,
...documentMutations,
...managers,
};
// hook callers handle rendering / routing