refactor: Consolidate workspace utilities into new workspaceUtils.ts with typed entry keys, replacing appLayoutUtils.ts, and update related components.

This commit is contained in:
2025-11-24 22:38:01 +01:00
parent deec2fe69d
commit 096c377897
19 changed files with 202 additions and 283 deletions
@@ -1,7 +1,7 @@
import { useCallback } from 'react';
import type { Dispatch, MutableRefObject, SetStateAction } from 'react';
import { DEFAULT_FOLDER_NAME, getRowId, isDocumentRowKey } from '../../app/appLayoutUtils';
import { DEFAULT_FOLDER_NAME, getRowId, isDocumentRowKey } from '../../app/workspaceUtils';
import {
addDocumentTags,
createTag,
@@ -1,7 +1,7 @@
import { useCallback, useRef, useState } from 'react';
import type { Dispatch, MutableRefObject, SetStateAction } from 'react';
import useFileDrop from './useFileDrop';
import { DEFAULT_FOLDER_NAME, hasFiles } from '../../app/appLayoutUtils';
import { DEFAULT_FOLDER_NAME, hasFiles } from '../../app/workspaceUtils';
import { fetchDocument } from '../../lib/apiClient';
type Identifier = string | number;
@@ -87,9 +87,9 @@ const mapFilesToEntries = (filesInput?: FileList | File[] | null): FileEntry[] =
const relativePath = (file as File & { webkitRelativePath?: string })?.webkitRelativePath ?? '';
const segments = relativePath
? relativePath
.split('/')
.slice(0, -1)
.filter(Boolean)
.split('/')
.slice(0, -1)
.filter(Boolean)
: [];
return { file, segments };
});
@@ -325,9 +325,9 @@ const useDocumentUploads = ({
const relativePath = (fileFromItem as File & { webkitRelativePath?: string })?.webkitRelativePath ?? '';
const segments = relativePath
? relativePath
.split('/')
.slice(0, -1)
.filter(Boolean)
.split('/')
.slice(0, -1)
.filter(Boolean)
: [];
pushFile(fileFromItem, segments);
}
@@ -355,9 +355,9 @@ const useDocumentUploads = ({
const relativePath = (file as File & { webkitRelativePath?: string })?.webkitRelativePath ?? '';
const segments = relativePath
? relativePath
.split('/')
.slice(0, -1)
.filter(Boolean)
.split('/')
.slice(0, -1)
.filter(Boolean)
: [];
pushFile(file, segments);
});
@@ -29,7 +29,7 @@ import useDocumentsPanelProps from '../../documents/hooks/useDocumentsPanelProps
import useDocumentPreview from '../../app/useDocumentPreview';
import useSidebarProps from '../../sidebar/useSidebarProps';
import {
ASSET_PRESIGN_TTL_MS,
DEFAULT_SORT_DIRECTION,
DEFAULT_SORT_FIELD,
createRootNode,
@@ -37,10 +37,9 @@ import {
isDocumentRowKey,
isFolderRowKey,
mergeAssetIntoDocument,
resolveApiPath,
resolveDocumentRowKey,
resolveFolderRowKey,
} from '../../app/appLayoutUtils';
} from '../../app/workspaceUtils';
import useDocumentsSearch from '../../app/useDocumentsSearch';
import useDocumentsStore from './store/useDocumentsStore';
import useAuthManager from './useAuthManager';
@@ -64,7 +63,7 @@ const EntryType = Object.freeze({
folder: 'folder',
});
const noop = () => {};
const noop = () => { };
type Identifier = string | number;
type DocumentId = Identifier;
@@ -79,7 +78,7 @@ interface DocumentLike {
interface FolderContentsEntry {
folder?: { id?: FolderId; name?: string | null } | null;
documents?: DocumentLike[];
subfolders?: Array<{ id?: FolderId; name?: string | null; [key: string]: unknown }>;
subfolders?: Array<{ id?: FolderId; name?: string | null;[key: string]: unknown }>;
__includesDocuments?: boolean;
__sortField?: string | null;
__sortDirection?: string | null;
@@ -189,7 +188,7 @@ const useDocumentsWorkspace = ({
const breadcrumbFetchRef = useRef(new Set());
const tagRemovalCursorActiveRef = useRef(false);
const tenantIdRef = useRef(currentTenantId);
const detailPanelControlRef = useRef({ open: () => {}, close: () => {} });
const detailPanelControlRef = useRef({ open: () => { }, close: () => { } });
const setTagRemovalCursor = useCallback((active) => {
if (tagRemovalCursorActiveRef.current === active) {
return;
@@ -222,7 +221,7 @@ const useDocumentsWorkspace = ({
const asset = await fetchAsset(id);
return (asset as unknown) as any;
};
assetManagerRef.current = new AssetManager({ fetchAsset: fetcher, assetPresignTtlMs: ASSET_PRESIGN_TTL_MS });
assetManagerRef.current = new AssetManager({ fetchAsset: fetcher });
}
const assetManager = assetManagerRef.current;
@@ -328,7 +327,7 @@ const useDocumentsWorkspace = ({
() => documentsManager.getSnapshot(),
() => documentsManager.getSnapshot(),
);
const {
folderNodes,
setFolderNodes,
@@ -425,8 +424,8 @@ const useDocumentsWorkspace = ({
showingSearchResults
? []
: currentSubfolders
.map((folder) => resolveFolderRowKey(folder.id))
.filter(Boolean),
.map((folder) => resolveFolderRowKey(folder.id))
.filter(Boolean),
[showingSearchResults, currentSubfolders],
);
@@ -846,7 +845,7 @@ const useDocumentsWorkspace = ({
const initializeAfterLogin = useCallback(async () => {
await Promise.all([refreshTags(), refreshCorrespondents()]);
const initialFolder = routeFolderId && routeFolderId !== 'root' ? routeFolderId : 'root';
await loadFolder(initialFolder, {} );
await loadFolder(initialFolder, {});
}, [refreshTags, refreshCorrespondents, routeFolderId, loadFolder]);
useEffect(() => {
@@ -960,12 +959,6 @@ const useDocumentsWorkspace = ({
[assetManager, updateDocumentCaches, notifyApiError],
);
const handleDocumentTagDrop = useCallback(
async (documentId, tag) => {
if (!documentId || !tag?.id) {
@@ -1176,7 +1169,6 @@ const useDocumentsWorkspace = ({
correspondents,
handleCorrespondentAdd,
handleCorrespondentRemove,
resolveApiPath,
selectFolder,
tags,
tagLookupById,
@@ -1462,5 +1454,4 @@ const useDocumentsWorkspace = ({
};
};
export default useDocumentsWorkspace;
@@ -8,7 +8,7 @@ import {
isFolderRowKey,
resolveDocumentRowKey,
resolveFolderRowKey,
} from '../../app/appLayoutUtils';
} from '../../app/workspaceUtils';
type Identifier = string | number;
type FolderId = Identifier | 'root';
@@ -1,6 +1,6 @@
import { useCallback, useMemo } from 'react';
import type { DragEvent } from 'react';
import { DEFAULT_FOLDER_NAME, hasFiles } from '../../app/appLayoutUtils';
import { DEFAULT_FOLDER_NAME, hasFiles } from '../../app/workspaceUtils';
import {
createFolder,
deleteFolder,
@@ -1,5 +1,5 @@
import React, { useEffect, useMemo } from 'react';
import { DEFAULT_FOLDER_NAME } from '../../app/appLayoutUtils';
import { DEFAULT_FOLDER_NAME } from '../../app/workspaceUtils';
type Identifier = string | number;
type FolderId = Identifier | 'root';