Convert errors/confirmations to toasts

This commit is contained in:
2025-01-10 15:59:05 -05:00
parent 4ae012d9dd
commit e28c26c8da
2 changed files with 52 additions and 55 deletions

View File

@@ -14,8 +14,8 @@ function App() {
return (
<QueryClientProvider client={queryClient}>
<Router>
<Toaster richColors position="top-center" />
<MainLayout>
<Toaster />
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/products" element={<Products />} />

View File

@@ -4,7 +4,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com
import { Progress } from "@/components/ui/progress";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { toast } from "sonner";
import {
AlertDialog,
AlertDialogAction,
@@ -61,7 +61,13 @@ export function Settings() {
// Clean up function to reset state
const handleCancel = async () => {
// Just clean up everything immediately
// Determine which operation is running first
const operation = isImporting ? 'Import' : isUpdating ? 'Update' : 'Reset';
// Show cancellation toast immediately
toast.warning(`${operation} cancelled`);
// Clean up everything immediately
if (eventSource) {
eventSource.close();
setEventSource(null);
@@ -74,11 +80,15 @@ export function Settings() {
setResetProgress(null);
// Fire and forget the cancel request with the operation type
const operation = isImporting ? 'import' : isUpdating ? 'update' : 'reset';
fetch(`${config.apiUrl}/csv/cancel?operation=${operation}`, {
method: 'POST',
credentials: 'include'
}).catch(() => {});
try {
await fetch(`${config.apiUrl}/csv/cancel?operation=${operation.toLowerCase()}`, {
method: 'POST',
credentials: 'include'
});
} catch (error) {
// Silently ignore any errors from the cancel request
console.log('Cancel request failed:', error);
}
};
const handleUpdateCSV = async () => {
@@ -161,17 +171,15 @@ export function Settings() {
source.close();
setEventSource(null);
setIsUpdating(false);
setIsImporting(false);
setUpdateProgress(null);
if (!progressData.operation?.includes('cancelled')) {
setTimeout(() => {
setUpdateProgress(null);
}, 1000);
handleComplete('CSV update');
}
} else if (progressData.status === 'error' && !progressData.operation?.includes('cancelled')) {
} else if (progressData.status === 'error') {
source.close();
setEventSource(null);
setIsUpdating(false);
setIsImporting(false);
handleError('CSV update', progressData.error || 'Unknown error');
}
} catch (error) {
// Silently handle parsing errors
@@ -193,10 +201,8 @@ export function Settings() {
setEventSource(null);
}
setIsUpdating(false);
// Don't show any errors if we're cleaning up
if (updateProgress?.status === 'running') {
setUpdateProgress(null);
}
setUpdateProgress(null);
handleError('CSV update', error instanceof Error ? error.message : 'Unknown error');
}
};
@@ -281,16 +287,16 @@ export function Settings() {
setEventSource(null);
setIsUpdating(false);
setIsImporting(false);
setImportProgress(null);
if (!progressData.operation?.includes('cancelled')) {
setTimeout(() => {
setImportProgress(null);
}, 1000);
handleComplete('Data import');
}
} else if (progressData.status === 'error' && !progressData.operation?.includes('cancelled')) {
} else if (progressData.status === 'error') {
source.close();
setEventSource(null);
setIsUpdating(false);
setIsImporting(false);
handleError('Data import', progressData.error || 'Unknown error');
}
} catch (error) {
// Silently handle parsing errors
@@ -316,10 +322,8 @@ export function Settings() {
setEventSource(null);
}
setIsImporting(false);
// Don't show any errors if we're cleaning up
if (importProgress?.status === 'running') {
setImportProgress(null);
}
setImportProgress(null);
handleError('Data import', error instanceof Error ? error.message : 'Unknown error');
}
};
@@ -403,15 +407,15 @@ export function Settings() {
source.close();
setEventSource(null);
setIsResetting(false);
setResetProgress(null);
if (!progressData.operation?.includes('cancelled')) {
setTimeout(() => {
setResetProgress(null);
}, 1000);
handleComplete('Database reset');
}
} else if (progressData.status === 'error' && !progressData.operation?.includes('cancelled')) {
} else if (progressData.status === 'error') {
source.close();
setEventSource(null);
setIsResetting(false);
handleError('Database reset', progressData.error || 'Unknown error');
}
} catch (error) {
// Silently handle parsing errors
@@ -433,10 +437,8 @@ export function Settings() {
setEventSource(null);
}
setIsResetting(false);
// Don't show any errors if we're cleaning up
if (resetProgress?.status === 'running') {
setResetProgress(null);
}
setResetProgress(null);
handleError('Database reset', error instanceof Error ? error.message : 'Unknown error');
}
};
@@ -471,31 +473,26 @@ export function Settings() {
</div>
</>
)}
{(progress.elapsed || progress.remaining) && (
<div className="flex justify-between text-sm text-muted-foreground">
{progress.elapsed && <span>Elapsed: {progress.elapsed}</span>}
{progress.remaining && <span>Remaining: {progress.remaining}</span>}
</div>
)}
{progress.message && (
<div className="text-sm text-muted-foreground">
{progress.message}
</div>
)}
{progress.error && (
<Alert variant="destructive" className="mt-2">
<AlertDescription>
{progress.error}
</AlertDescription>
</Alert>
)}
</div>
);
};
const handleError = (operation: string, error: string) => {
// Skip error toast if we're cancelling or if it's a cancellation error
if (error.includes('cancelled') ||
error.includes('Process exited with code 143') ||
error.includes('Operation cancelled') ||
error.includes('500 Internal Server Error')) {
return;
}
toast.error(`${operation} failed: ${error}`);
};
// Update the message handlers to use toast
const handleComplete = (operation: string) => {
toast.success(`${operation} completed successfully`);
};
return (
<div className="p-8 space-y-8">
<div className="flex items-center justify-between">