refactor: centralize frontend status message handling with useStatusToast
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { useCallback } from 'react';
|
||||
import type { Dispatch, MutableRefObject, SetStateAction } from 'react';
|
||||
import { useStatusToast } from '../../lib/context/StatusToastContext';
|
||||
import { DEFAULT_FOLDER_NAME } from '../../app/workspaceUtils';
|
||||
import { getEntryId, isDocumentEntry } from '../../app/entryKey';
|
||||
import {
|
||||
@@ -19,8 +20,6 @@ import type { Document, MessageOptions } from '../../types/documents';
|
||||
type FolderId = FolderIdentifier | 'root';
|
||||
type NullableFolderId = FolderId | null;
|
||||
|
||||
type StatusLevel = 'success' | 'error' | 'info' | string;
|
||||
|
||||
type DocumentCacheMapper = (
|
||||
doc: Document | null,
|
||||
) => Document | null;
|
||||
@@ -43,8 +42,6 @@ type CloseDocumentPreview = () => void;
|
||||
|
||||
type NotifyApiError = (error: unknown, fallbackMessage?: string) => void;
|
||||
|
||||
type SetStatusMessage = (message: string, level?: StatusLevel) => void;
|
||||
|
||||
interface Tag {
|
||||
id: DocumentId;
|
||||
label: string;
|
||||
@@ -94,7 +91,6 @@ interface UseDocumentMutationsArgs {
|
||||
setFocusedEntryKey: Dispatch<SetStateAction<string | null>>;
|
||||
focusedEntryKey: string | null;
|
||||
notifyApiError: NotifyApiError;
|
||||
setStatusMessage: SetStatusMessage;
|
||||
mapDocumentCaches: MapDocumentCaches;
|
||||
folderNodes: Map<FolderId, FolderNode>;
|
||||
setFolderNodes: Dispatch<SetStateAction<Map<FolderId, FolderNode>>>;
|
||||
@@ -165,7 +161,6 @@ const useDocumentMutations = ({
|
||||
setFocusedEntryKey,
|
||||
focusedEntryKey,
|
||||
notifyApiError,
|
||||
setStatusMessage,
|
||||
mapDocumentCaches,
|
||||
folderNodes,
|
||||
setFolderNodes,
|
||||
@@ -181,6 +176,8 @@ const useDocumentMutations = ({
|
||||
extractDocumentFromResponse,
|
||||
ingestDocuments,
|
||||
}: UseDocumentMutationsArgs): UseDocumentMutationsResult => {
|
||||
const { showToast } = useStatusToast();
|
||||
|
||||
const moveDocumentsToFolder = useCallback(
|
||||
async (documentIds: Array<DocumentId | Document>, targetFolderId?: NullableFolderId) => {
|
||||
const uniqueIds = Array.from(
|
||||
@@ -254,7 +251,7 @@ const useDocumentMutations = ({
|
||||
|
||||
const count = uniqueIds.length;
|
||||
const suffix = count === 1 ? '' : 's';
|
||||
setStatusMessage(`Moved ${count} document${suffix} to ${targetLabel}.`, 'success');
|
||||
showToast(`Moved ${count} document${suffix} to ${targetLabel}.`, 'success');
|
||||
|
||||
if (updatedDocsMap.size) {
|
||||
mapDocumentCaches((doc) => {
|
||||
@@ -335,7 +332,7 @@ const useDocumentMutations = ({
|
||||
setFocusedEntryKey,
|
||||
focusedEntryKey,
|
||||
notifyApiError,
|
||||
setStatusMessage,
|
||||
showToast,
|
||||
mapDocumentCaches,
|
||||
],
|
||||
);
|
||||
@@ -343,19 +340,19 @@ const useDocumentMutations = ({
|
||||
const handleThumbnailRegeneration = useCallback(
|
||||
async (documentId: DocumentId) => {
|
||||
if (!token) {
|
||||
setStatusMessage('Log in to manage assets.', 'error');
|
||||
showToast('Log in to manage assets.', 'error');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await queueDocumentReanalysis(documentId, { force: true });
|
||||
setStatusMessage('Document re-analysis queued.', 'info');
|
||||
showToast('Document re-analysis queued.', 'info');
|
||||
await refreshCurrentFolder();
|
||||
} catch (error) {
|
||||
const message = (error as Record<string, any>)?.response?.data?.error || 'Failed to request thumbnail generation.';
|
||||
notifyApiError(error, message);
|
||||
}
|
||||
},
|
||||
[token, refreshCurrentFolder, notifyApiError, setStatusMessage],
|
||||
[token, refreshCurrentFolder, notifyApiError, showToast],
|
||||
);
|
||||
|
||||
const handleDocumentsDelete = useCallback(
|
||||
@@ -365,7 +362,7 @@ const useDocumentMutations = ({
|
||||
}
|
||||
|
||||
if (!token) {
|
||||
setStatusMessage('Log in to manage documents.', 'error');
|
||||
showToast('Log in to manage documents.', 'error');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -380,7 +377,7 @@ const useDocumentMutations = ({
|
||||
|
||||
if (showMessage) {
|
||||
const message = documentIds.length === 1 ? 'Document deleted.' : 'Documents deleted.';
|
||||
setStatusMessage(message, 'success');
|
||||
showToast(message, 'success');
|
||||
}
|
||||
return true;
|
||||
} catch (error) {
|
||||
@@ -396,7 +393,7 @@ const useDocumentMutations = ({
|
||||
previewDocumentId,
|
||||
closeDocumentPreview,
|
||||
notifyApiError,
|
||||
setStatusMessage,
|
||||
showToast,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -404,7 +401,7 @@ const useDocumentMutations = ({
|
||||
async (documentId: DocumentId, nextTitle: string) => {
|
||||
const trimmed = nextTitle?.trim?.() || '';
|
||||
if (!trimmed) {
|
||||
setStatusMessage('Document title cannot be empty.', 'error');
|
||||
showToast('Document title cannot be empty.', 'error');
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
@@ -422,7 +419,7 @@ const useDocumentMutations = ({
|
||||
});
|
||||
}
|
||||
|
||||
setStatusMessage('Document title updated.', 'success');
|
||||
showToast('Document title updated.', 'success');
|
||||
return true;
|
||||
} catch (error) {
|
||||
const message = (error as Record<string, any>)?.response?.data?.error || 'Failed to update document title.';
|
||||
@@ -434,7 +431,7 @@ const useDocumentMutations = ({
|
||||
extractDocumentFromResponse,
|
||||
ingestDocuments,
|
||||
notifyApiError,
|
||||
setStatusMessage,
|
||||
showToast,
|
||||
updateDocumentCaches,
|
||||
],
|
||||
);
|
||||
@@ -458,7 +455,7 @@ const useDocumentMutations = ({
|
||||
}
|
||||
|
||||
const message = payload.issued_at ? 'Issued date updated.' : 'Issued date cleared.';
|
||||
setStatusMessage(message, 'success');
|
||||
showToast(message, 'success');
|
||||
return true;
|
||||
} catch (error) {
|
||||
const message = (error as Record<string, any>)?.response?.data?.error || 'Failed to update issued date.';
|
||||
@@ -470,7 +467,7 @@ const useDocumentMutations = ({
|
||||
extractDocumentFromResponse,
|
||||
ingestDocuments,
|
||||
notifyApiError,
|
||||
setStatusMessage,
|
||||
showToast,
|
||||
updateDocumentCaches,
|
||||
],
|
||||
);
|
||||
@@ -505,7 +502,7 @@ const useDocumentMutations = ({
|
||||
}
|
||||
return { ...doc, tags: [...currentTags, cachedTag] };
|
||||
});
|
||||
setStatusMessage('Tag assigned.', 'success');
|
||||
showToast('Tag assigned.', 'success');
|
||||
return true;
|
||||
} catch (error) {
|
||||
const message = (error as Record<string, any>)?.response?.data?.error || 'Failed to assign tag.';
|
||||
@@ -513,7 +510,7 @@ const useDocumentMutations = ({
|
||||
return false;
|
||||
}
|
||||
},
|
||||
[notifyApiError, setStatusMessage, updateDocumentCaches],
|
||||
[notifyApiError, showToast, updateDocumentCaches],
|
||||
);
|
||||
|
||||
const handleDocumentTagAdd = useCallback(
|
||||
@@ -616,7 +613,7 @@ const useDocumentMutations = ({
|
||||
try {
|
||||
await deleteDocumentTag(documentId, tagId);
|
||||
applyTagRemovalToCaches(documentId, tagId);
|
||||
setStatusMessage('Tag removed.', 'success');
|
||||
showToast('Tag removed.', 'success');
|
||||
return true;
|
||||
} catch (error) {
|
||||
const message = (error as Record<string, any>)?.response?.data?.error || 'Failed to remove tag.';
|
||||
@@ -624,20 +621,20 @@ const useDocumentMutations = ({
|
||||
return false;
|
||||
}
|
||||
},
|
||||
[applyTagRemovalToCaches, notifyApiError, setStatusMessage],
|
||||
[applyTagRemovalToCaches, notifyApiError, showToast],
|
||||
);
|
||||
|
||||
const handleFolderDelete = useCallback(
|
||||
async (folderId?: FolderId, { showMessage = true }: MessageOptions = {}) => {
|
||||
if (!token) {
|
||||
if (showMessage) {
|
||||
setStatusMessage('Log in to manage folders.', 'error');
|
||||
showToast('Log in to manage folders.', 'error');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (!folderId || folderId === 'root') {
|
||||
if (showMessage) {
|
||||
setStatusMessage('The root folder cannot be removed.', 'error');
|
||||
showToast('The root folder cannot be removed.', 'error');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -648,7 +645,7 @@ const useDocumentMutations = ({
|
||||
const hasDocs = (contents.documents || []).length > 0;
|
||||
if (hasChildren || hasDocs) {
|
||||
if (showMessage) {
|
||||
setStatusMessage('Folder must be empty before it can be deleted.', 'error');
|
||||
showToast('Folder must be empty before it can be deleted.', 'error');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -686,14 +683,14 @@ const useDocumentMutations = ({
|
||||
}
|
||||
|
||||
if (showMessage) {
|
||||
setStatusMessage('Folder deleted.', 'success');
|
||||
showToast('Folder deleted.', 'success');
|
||||
}
|
||||
return true;
|
||||
} catch (error) {
|
||||
const message = (error as Record<string, any>)?.response?.data?.error || 'Failed to delete folder.';
|
||||
notifyApiError(error, message);
|
||||
if (showMessage) {
|
||||
setStatusMessage(message, 'error');
|
||||
showToast(message, 'error');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -706,7 +703,7 @@ const useDocumentMutations = ({
|
||||
setSelectedFolder,
|
||||
setFolderNodes,
|
||||
notifyApiError,
|
||||
setStatusMessage,
|
||||
showToast,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user