refactor: centralize frontend status message handling with useStatusToast

This commit is contained in:
2025-12-07 23:46:10 +01:00
parent b29e856225
commit 595c170c00
13 changed files with 149 additions and 175 deletions
@@ -1,5 +1,6 @@
import { useCallback, useMemo } from 'react';
import type { DragEvent } from 'react';
import { useStatusToast } from '../../../lib/context/StatusToastContext';
import { DEFAULT_FOLDER_NAME, hasFiles } from '../../../app/workspaceUtils';
import {
createFolder,
@@ -35,7 +36,6 @@ interface UseFolderTreeActionsOptions {
selectedFolder: FolderKey;
setSelectedFolder: (folderId: FolderKey) => void;
notifyApiError: (error: unknown, message?: string) => void;
setStatusMessage: (message: string, level?: string) => void;
navigate?: (path: string, options?: { replace?: boolean }) => void;
handleFileDrop: (dataTransfer: DataTransfer, folderId: FolderKey) => Promise<void> | void;
moveDocumentsToFolder: (docIds: FolderId[], folderId: FolderKey) => Promise<void>;
@@ -54,7 +54,6 @@ const useFolderTreeActions = ({
selectedFolder,
setSelectedFolder,
notifyApiError,
setStatusMessage,
navigate,
handleFileDrop,
moveDocumentsToFolder,
@@ -65,11 +64,13 @@ const useFolderTreeActions = ({
isInvalidFolderDrop,
setCreatingFolder,
}: UseFolderTreeActionsOptions) => {
const { showToast } = useStatusToast();
const moveFolder = useCallback(
async (folderId: FolderKey, targetFolderId: FolderKey | null) => {
const node = folderNodes.get(folderId);
if (!node) {
setStatusMessage('Folder metadata unavailable. Try refreshing.', 'error');
showToast('Folder metadata unavailable. Try refreshing.', 'error');
return;
}
@@ -134,7 +135,7 @@ const useFolderTreeActions = ({
setSelectedFolder(folderId);
}
setStatusMessage('Folder moved.', 'success');
showToast('Folder moved.', 'success');
} catch (error) {
const message = error.response?.data?.error || 'Failed to move folder.';
notifyApiError(error, message);
@@ -146,7 +147,7 @@ const useFolderTreeActions = ({
selectedFolder,
setFolderNodes,
setSelectedFolder,
setStatusMessage,
showToast,
],
);
@@ -180,12 +181,12 @@ const useFolderTreeActions = ({
const handleFolderRename = useCallback(
async (folderId: FolderKey, nextName: string) => {
if (!token) {
setStatusMessage('Log in to rename folders.', 'error');
showToast('Log in to rename folders.', 'error');
return false;
}
const trimmed = nextName?.trim?.() || '';
if (!trimmed) {
setStatusMessage('Folder name cannot be empty.', 'error');
showToast('Folder name cannot be empty.', 'error');
return false;
}
try {
@@ -200,7 +201,7 @@ const useFolderTreeActions = ({
return next;
});
setStatusMessage('Folder renamed.', 'success');
showToast('Folder renamed.', 'success');
return true;
} catch (error) {
const message = error.response?.data?.error || 'Failed to rename folder.';
@@ -211,7 +212,7 @@ const useFolderTreeActions = ({
[
notifyApiError,
setFolderNodes,
setStatusMessage,
showToast,
token,
],
);
@@ -219,11 +220,11 @@ const useFolderTreeActions = ({
const handleFolderCreate = useCallback(
async (name: string, parentId?: FolderKey | null) => {
if (!token) {
setStatusMessage('Log in to create folders.', 'error');
showToast('Log in to create folders.', 'error');
return false;
}
if (!name.trim()) {
setStatusMessage('Folder name cannot be empty.', 'error');
showToast('Folder name cannot be empty.', 'error');
return false;
}
@@ -243,7 +244,7 @@ const useFolderTreeActions = ({
if (!folderData?.id) {
throw new Error('Folder creation failed.');
}
setStatusMessage('Folder created.', 'success');
showToast('Folder created.', 'success');
setFolderNodes((prev) => {
const next = new Map(prev);
const parentId = folderData.parent_id ?? payload.parent_id ?? 'root';
@@ -278,7 +279,7 @@ const useFolderTreeActions = ({
} finally {
setCreatingFolder(false);
if (!succeeded) {
setStatusMessage('Folder creation failed.', 'error');
showToast('Folder creation failed.', 'error');
}
}
},
@@ -288,7 +289,7 @@ const useFolderTreeActions = ({
selectedFolder,
setCreatingFolder,
setFolderNodes,
setStatusMessage,
showToast,
token,
],
);
@@ -297,13 +298,13 @@ const useFolderTreeActions = ({
async (folderId: FolderKey, { 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;
}
@@ -337,14 +338,14 @@ const useFolderTreeActions = ({
}
if (showMessage) {
setStatusMessage('Folder deleted.', 'success');
showToast('Folder deleted.', 'success');
}
return true;
} catch (error) {
const message = error.response?.data?.error || 'Failed to delete folder.';
notifyApiError(error, message);
if (showMessage) {
setStatusMessage(message, 'error');
showToast(message, 'error');
}
return false;
}
@@ -356,7 +357,7 @@ const useFolderTreeActions = ({
selectedFolder,
setFolderNodes,
setSelectedFolder,
setStatusMessage,
showToast,
],
);
@@ -404,7 +405,7 @@ const useFolderTreeActions = ({
setDraggedFolderId(null);
const invalidMove = folderIds.some((sourceId) => isInvalidFolderDrop(sourceId, folderId));
if (invalidMove) {
setStatusMessage(
showToast(
'Cannot move a folder into itself or one of its descendants.',
'error',
);
@@ -492,7 +493,7 @@ const useFolderTreeActions = ({
selectedFolder,
setDraggedDocumentIds,
setDraggedFolderId,
setStatusMessage,
showToast,
],
);