documentsmanager
This commit is contained in:
@@ -1,4 +1,12 @@
|
||||
import { MutableRefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import {
|
||||
MutableRefObject,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
useSyncExternalStore,
|
||||
} from 'react';
|
||||
import {
|
||||
matchPath,
|
||||
useLocation,
|
||||
@@ -220,10 +228,20 @@ const useDocumentsWorkspace = ({
|
||||
if (!payload) {
|
||||
return null;
|
||||
}
|
||||
const hydratedDetail = assetManager.hydrateDetail(payload);
|
||||
return hydratedDetail?.document || payload.document || payload;
|
||||
return payload.document || payload;
|
||||
},
|
||||
[assetManager],
|
||||
[],
|
||||
);
|
||||
|
||||
const fetchDocumentById = useCallback(
|
||||
async (documentId: DocumentId) => {
|
||||
if (!documentId) {
|
||||
return null;
|
||||
}
|
||||
const { data } = await api.get(`/documents/${documentId}`);
|
||||
return extractDocumentFromResponse(data);
|
||||
},
|
||||
[extractDocumentFromResponse],
|
||||
);
|
||||
|
||||
const tagManagerRef = useRef(null);
|
||||
@@ -290,21 +308,27 @@ const useDocumentsWorkspace = ({
|
||||
folderContentsRef.current = folderContents;
|
||||
}, [folderContents]);
|
||||
|
||||
const setSearchResultsRef = useRef<(value: unknown) => void>(() => {});
|
||||
const setSearchResultsProxy = useCallback((value) => {
|
||||
setSearchResultsRef.current(value);
|
||||
}, []);
|
||||
|
||||
const {
|
||||
documents,
|
||||
setDocuments,
|
||||
removeDocumentsFromLookup,
|
||||
mapDocumentCaches,
|
||||
updateDocumentCaches,
|
||||
documentsManager,
|
||||
} = useDocuments({
|
||||
setSearchResults: setSearchResultsProxy,
|
||||
setFolderContents,
|
||||
fetchDocumentById,
|
||||
hydrateDocument: (payload) => assetManager.hydrateDocument(payload),
|
||||
hydrateDocuments: (payload) => assetManager.hydrateDocuments(payload),
|
||||
extractDocument: extractDocumentFromResponse,
|
||||
});
|
||||
|
||||
const documentLookup = useSyncExternalStore(
|
||||
(onStoreChange) => documentsManager.subscribe(onStoreChange),
|
||||
() => documentsManager.getSnapshot(),
|
||||
() => documentsManager.getSnapshot(),
|
||||
);
|
||||
|
||||
const {
|
||||
folderNodes,
|
||||
setFolderNodes,
|
||||
@@ -338,8 +362,8 @@ const useDocumentsWorkspace = ({
|
||||
const {
|
||||
searchQuery,
|
||||
setSearchQuery,
|
||||
searchResults,
|
||||
setSearchResults,
|
||||
searchResultIds,
|
||||
setSearchResultIds,
|
||||
searchLoading,
|
||||
activeTagFilters,
|
||||
setActiveTagFilters,
|
||||
@@ -349,7 +373,6 @@ const useDocumentsWorkspace = ({
|
||||
documentsFilterValue,
|
||||
} = useDocumentsSearch({
|
||||
api,
|
||||
assetManager,
|
||||
token,
|
||||
selectedFolder,
|
||||
navigate,
|
||||
@@ -361,17 +384,66 @@ const useDocumentsWorkspace = ({
|
||||
notifyApiError,
|
||||
setLoading,
|
||||
setSearchIncludeDescendants,
|
||||
documentsManager,
|
||||
});
|
||||
|
||||
const documentsFilter = documentsFilterValue;
|
||||
|
||||
const [visibleDocumentIds, setVisibleDocumentIds] = useState<DocumentId[]>([]);
|
||||
|
||||
const showingSearchResults = searchResultIds !== null;
|
||||
|
||||
useEffect(() => {
|
||||
setSearchResultsRef.current = setSearchResults;
|
||||
}, [setSearchResults]);
|
||||
const arraysEqual = (a: DocumentId[], b: DocumentId[]) =>
|
||||
a.length === b.length && a.every((value, index) => value === b[index]);
|
||||
|
||||
if (showingSearchResults && Array.isArray(searchResultIds)) {
|
||||
const ids = searchResultIds.filter((id): id is DocumentId => id != null);
|
||||
setVisibleDocumentIds((prev) => (arraysEqual(prev, ids) ? prev : ids));
|
||||
return;
|
||||
}
|
||||
|
||||
const folderIds = documents
|
||||
.map((doc) => (doc?.id ?? null) as DocumentId | null)
|
||||
.filter((id): id is DocumentId => id != null);
|
||||
setVisibleDocumentIds((prev) => (arraysEqual(prev, folderIds) ? prev : folderIds));
|
||||
}, [showingSearchResults, searchResultIds, documents]);
|
||||
|
||||
const viewDocuments = useMemo(
|
||||
() =>
|
||||
visibleDocumentIds
|
||||
.map((id) => documentLookup.get(id) || null)
|
||||
.filter((doc): doc is DocumentLike => Boolean(doc)),
|
||||
[visibleDocumentIds, documentLookup],
|
||||
);
|
||||
|
||||
const visibleDocumentKeys = useMemo(
|
||||
() => visibleDocumentIds.map((id) => resolveDocumentRowKey(id)).filter(Boolean),
|
||||
[visibleDocumentIds],
|
||||
);
|
||||
|
||||
const visibleFolderKeys = useMemo(
|
||||
() =>
|
||||
showingSearchResults
|
||||
? []
|
||||
: currentSubfolders
|
||||
.map((folder) => resolveFolderRowKey(folder.id))
|
||||
.filter(Boolean),
|
||||
[showingSearchResults, currentSubfolders],
|
||||
);
|
||||
|
||||
const visibleRowKeys = useMemo(
|
||||
() => [...visibleFolderKeys, ...visibleDocumentKeys],
|
||||
[visibleFolderKeys, visibleDocumentKeys],
|
||||
);
|
||||
|
||||
const visibleRowKeySet = useMemo(
|
||||
() => new Set(visibleRowKeys),
|
||||
[visibleRowKeys],
|
||||
);
|
||||
|
||||
const {
|
||||
documentLinks,
|
||||
previewDocuments,
|
||||
ensurePreviewData,
|
||||
ensureDownloadUrl,
|
||||
openDocumentPreview,
|
||||
@@ -380,8 +452,7 @@ const useDocumentsWorkspace = ({
|
||||
removeDocumentLinks,
|
||||
} = useDocumentPreview({
|
||||
routeDocumentId: previewDocumentId,
|
||||
documents,
|
||||
searchResults,
|
||||
documentsManager,
|
||||
selectedFolder,
|
||||
assetManager,
|
||||
api,
|
||||
@@ -414,65 +485,6 @@ const useDocumentsWorkspace = ({
|
||||
const detailFolderFetchRef = useRef(new Set());
|
||||
|
||||
|
||||
const showingSearchResults = searchResults !== null;
|
||||
|
||||
const visibleDocuments = useMemo(
|
||||
() => (showingSearchResults ? searchResults : documents),
|
||||
[showingSearchResults, searchResults, documents],
|
||||
);
|
||||
|
||||
const visibleDocumentIds = useMemo(
|
||||
() => visibleDocuments.map((doc) => doc.id),
|
||||
[visibleDocuments],
|
||||
);
|
||||
|
||||
const visibleDocumentKeys = useMemo(
|
||||
() => visibleDocumentIds.map((id) => resolveDocumentRowKey(id)).filter(Boolean),
|
||||
[visibleDocumentIds],
|
||||
);
|
||||
|
||||
const visibleFolderKeys = useMemo(
|
||||
() =>
|
||||
showingSearchResults
|
||||
? []
|
||||
: currentSubfolders
|
||||
.map((folder) => resolveFolderRowKey(folder.id))
|
||||
.filter(Boolean),
|
||||
[showingSearchResults, currentSubfolders],
|
||||
);
|
||||
|
||||
const visibleRowKeys = useMemo(
|
||||
() => [...visibleFolderKeys, ...visibleDocumentKeys],
|
||||
[visibleFolderKeys, visibleDocumentKeys],
|
||||
);
|
||||
|
||||
const visibleRowKeySet = useMemo(
|
||||
() => new Set(visibleRowKeys),
|
||||
[visibleRowKeys],
|
||||
);
|
||||
|
||||
const documentLookup = useMemo(() => {
|
||||
const map = new Map();
|
||||
const push = (items) => {
|
||||
(items || []).forEach((doc) => {
|
||||
if (doc?.id) {
|
||||
map.set(doc.id, doc);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
push(documents);
|
||||
if (Array.isArray(searchResults)) {
|
||||
push(searchResults);
|
||||
}
|
||||
previewDocuments.forEach((doc, id) => {
|
||||
if (doc && id && !map.has(id)) {
|
||||
map.set(id, doc);
|
||||
}
|
||||
});
|
||||
return map;
|
||||
}, [documents, searchResults, previewDocuments]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!showingSearchResults) {
|
||||
return;
|
||||
@@ -696,7 +708,7 @@ const useDocumentsWorkspace = ({
|
||||
selectionAnchorRef.current = null;
|
||||
setDraggedDocumentIds([]);
|
||||
setDraggedFolderId(null);
|
||||
setSearchResults(null);
|
||||
setSearchResultIds(null);
|
||||
setTags([]);
|
||||
setCorrespondents([]);
|
||||
setSearchQuery('');
|
||||
@@ -729,7 +741,7 @@ const useDocumentsWorkspace = ({
|
||||
setDocuments,
|
||||
setDraggedDocumentIds,
|
||||
setDraggedFolderId,
|
||||
setSearchResults,
|
||||
setSearchResultIds,
|
||||
setTags,
|
||||
setCorrespondents,
|
||||
setSearchQuery,
|
||||
@@ -757,11 +769,11 @@ const useDocumentsWorkspace = ({
|
||||
const idSet = new Set<DocumentId>(documentIds);
|
||||
|
||||
setDocuments((prev) => prev.filter((doc) => !idSet.has(doc.id)));
|
||||
setSearchResults((prev) => {
|
||||
setSearchResultIds((prev) => {
|
||||
if (!Array.isArray(prev)) {
|
||||
return prev;
|
||||
}
|
||||
const filtered = prev.filter((doc) => !idSet.has(doc.id));
|
||||
const filtered = prev.filter((id) => !idSet.has(id as DocumentId));
|
||||
return filtered.length === prev.length ? prev : filtered;
|
||||
});
|
||||
|
||||
@@ -788,9 +800,16 @@ const useDocumentsWorkspace = ({
|
||||
return changed ? next : prev;
|
||||
});
|
||||
|
||||
removeDocumentsFromLookup(Array.from(idSet));
|
||||
removeDocumentLinks(Array.from(idSet));
|
||||
},
|
||||
[setDocuments, setSearchResults, setFolderContents, removeDocumentLinks],
|
||||
[
|
||||
setDocuments,
|
||||
setSearchResultIds,
|
||||
setFolderContents,
|
||||
removeDocumentsFromLookup,
|
||||
removeDocumentLinks,
|
||||
],
|
||||
);
|
||||
|
||||
const {
|
||||
@@ -812,7 +831,7 @@ const useDocumentsWorkspace = ({
|
||||
setSelectedFolder,
|
||||
setDocuments,
|
||||
setFolderContents,
|
||||
setSearchResults,
|
||||
setSearchResultIds,
|
||||
setSelectedEntries,
|
||||
setSelectionOrder,
|
||||
selectionOrderRef,
|
||||
@@ -864,7 +883,7 @@ const useDocumentsWorkspace = ({
|
||||
setLoading,
|
||||
setFolderContents,
|
||||
setCurrentFolder,
|
||||
setSearchResults,
|
||||
setSearchResultIds,
|
||||
isFilterActive,
|
||||
navigate,
|
||||
handleFileDrop,
|
||||
@@ -883,7 +902,7 @@ const useDocumentsWorkspace = ({
|
||||
} = useDocumentsSelection({
|
||||
showingSearchResults,
|
||||
currentSubfolders,
|
||||
visibleDocuments,
|
||||
visibleDocuments: viewDocuments,
|
||||
resolveFolderRowKey,
|
||||
resolveDocumentRowKey,
|
||||
configureSelectionEnvironment,
|
||||
@@ -1021,19 +1040,13 @@ const useDocumentsWorkspace = ({
|
||||
prev.map((doc) => (doc.id === documentId ? mergeAssetIntoDocument(doc, entry) : doc)),
|
||||
);
|
||||
|
||||
setSearchResults((prev) =>
|
||||
Array.isArray(prev)
|
||||
? prev.map((doc) => (doc.id === documentId ? mergeAssetIntoDocument(doc, entry) : doc))
|
||||
: prev,
|
||||
);
|
||||
|
||||
return entry;
|
||||
} catch (error) {
|
||||
notifyApiError(error, 'Unable to refresh document asset.');
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
[assetManager, setDocuments, setSearchResults, notifyApiError],
|
||||
[assetManager, setDocuments, notifyApiError],
|
||||
);
|
||||
|
||||
|
||||
@@ -1233,9 +1246,7 @@ const useDocumentsWorkspace = ({
|
||||
documentLink,
|
||||
resolveFolderPath,
|
||||
} = useDetailWorkspace({
|
||||
documents,
|
||||
searchResults,
|
||||
previewDocuments,
|
||||
documents: viewDocuments,
|
||||
selectionOrder,
|
||||
selectedDocumentIds,
|
||||
documentLookup,
|
||||
@@ -1446,8 +1457,7 @@ const useDocumentsWorkspace = ({
|
||||
|
||||
const deskWorkspaceProps = useMemo(
|
||||
() => ({
|
||||
documents,
|
||||
searchResults,
|
||||
documents: viewDocuments,
|
||||
onInspectDocument: inspectDocumentForDesk,
|
||||
onEntryPointer: handleEntryPointerCore,
|
||||
onDocumentStackSelect: handleDeskDocumentStackSelect,
|
||||
@@ -1464,8 +1474,7 @@ const useDocumentsWorkspace = ({
|
||||
ensureDownloadUrl,
|
||||
}),
|
||||
[
|
||||
documents,
|
||||
searchResults,
|
||||
viewDocuments,
|
||||
inspectDocumentForDesk,
|
||||
handleEntryPointerCore,
|
||||
handleDeskDocumentStackSelect,
|
||||
@@ -1488,8 +1497,8 @@ const useDocumentsWorkspace = ({
|
||||
breadcrumbs,
|
||||
refreshCurrentFolder,
|
||||
currentSubfolders,
|
||||
documents,
|
||||
searchResults,
|
||||
documents: viewDocuments,
|
||||
searchResultIds,
|
||||
folderClickHandlers,
|
||||
handleFolderDragStart,
|
||||
handleFolderDragEnd,
|
||||
|
||||
Reference in New Issue
Block a user