Remove asset/document hydration pipeline and introduce client-side cache updates for correspondents, tags, and search results

This commit is contained in:
2025-11-20 02:18:33 +01:00
parent b76f1df27f
commit 0eb4c0a294
14 changed files with 316 additions and 329 deletions
@@ -18,18 +18,21 @@ interface UseDocumentCorrespondentActionsArgs {
apiClient: ApiClient;
correspondents: CorrespondentOption[];
handleCorrespondentCreate: (payload: { name: string }) => Promise<CorrespondentOption | null>;
refreshCurrentFolder: () => Promise<void>;
notifyApiError: (error: unknown, fallback: string) => void;
setStatusMessage: (message: string, variant?: string) => void;
updateDocumentCaches?: (
id: Identifier,
updater: (doc: { correspondents?: CorrespondentOption[] } | null) => { correspondents?: CorrespondentOption[] } | null,
) => void;
}
const useDocumentCorrespondentActions = ({
apiClient,
correspondents,
handleCorrespondentCreate,
refreshCurrentFolder,
notifyApiError,
setStatusMessage,
updateDocumentCaches,
}: UseDocumentCorrespondentActionsArgs) => {
const correspondentLookupByName = useMemo(() => {
const map = new Map<string, CorrespondentOption>();
@@ -44,7 +47,7 @@ const useDocumentCorrespondentActions = ({
const handleDocumentCorrespondentAttach = useCallback(
async (
{ documentId, correspondentId }: { documentId: Identifier; correspondentId: Identifier },
{ notify = true, refresh = true }: { notify?: boolean; refresh?: boolean } = {},
{ notify = true }: { notify?: boolean } = {},
) => {
if (documentId == null || correspondentId == null) {
throw new Error('Missing document or correspondent.');
@@ -54,8 +57,21 @@ const useDocumentCorrespondentActions = ({
assignments: [{ correspondent_id: correspondentId }],
replace: false,
});
if (refresh) {
await refreshCurrentFolder();
if (updateDocumentCaches) {
const correspondent = correspondents.find((entry) => entry?.id === correspondentId) || null;
updateDocumentCaches(documentId, (doc) => {
if (!doc) {
return doc;
}
const current = Array.isArray(doc.correspondents) ? doc.correspondents : [];
if (current.some((entry) => entry?.id === correspondentId)) {
return doc;
}
const nextEntry = correspondent
? { id: correspondent.id, name: correspondent.name }
: { id: correspondentId };
return { ...doc, correspondents: [...current, nextEntry] };
});
}
if (notify) {
setStatusMessage('Correspondent assigned.', 'success');
@@ -67,21 +83,27 @@ const useDocumentCorrespondentActions = ({
throw new Error(message);
}
},
[apiClient, refreshCurrentFolder, notifyApiError, setStatusMessage],
[apiClient, correspondents, notifyApiError, setStatusMessage, updateDocumentCaches],
);
const handleCorrespondentRemove = useCallback(
async (
{ documentId, correspondentId }: { documentId: Identifier; correspondentId: Identifier },
{ notify = true, refresh = true }: { notify?: boolean; refresh?: boolean } = {},
{ notify = true }: { notify?: boolean } = {},
) => {
if (documentId == null || correspondentId == null) {
throw new Error('Missing document or correspondent.');
}
try {
await apiClient.delete(`/documents/${documentId}/correspondents/${correspondentId}`);
if (refresh) {
await refreshCurrentFolder();
if (updateDocumentCaches) {
updateDocumentCaches(documentId, (doc) => {
if (!doc || !Array.isArray(doc.correspondents)) {
return doc;
}
const filtered = doc.correspondents.filter((entry) => entry?.id !== correspondentId);
return filtered.length === doc.correspondents.length ? doc : { ...doc, correspondents: filtered };
});
}
if (notify) {
setStatusMessage('Correspondent removed.', 'success');
@@ -93,7 +115,7 @@ const useDocumentCorrespondentActions = ({
throw new Error(message);
}
},
[apiClient, refreshCurrentFolder, notifyApiError, setStatusMessage],
[apiClient, notifyApiError, setStatusMessage, updateDocumentCaches],
);
const normalizeOption = (