From 7f91b30bf684da278f000c99d31c6897fc0ce910 Mon Sep 17 00:00:00 2001 From: r-dev Date: Sat, 4 Apr 2026 17:25:00 +0200 Subject: [PATCH] feat(ui) : error toasts persist until dismissed, add progress bar on auto-dismiss toasts --- frontend/app/components/ToastContainer.vue | 14 +++++++++++++- frontend/app/composables/useToast.ts | 12 ++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/frontend/app/components/ToastContainer.vue b/frontend/app/components/ToastContainer.vue index cfa6837..93c9682 100644 --- a/frontend/app/components/ToastContainer.vue +++ b/frontend/app/components/ToastContainer.vue @@ -13,7 +13,7 @@ ]" >
@@ -54,6 +54,13 @@
+ + +
@@ -111,4 +118,9 @@ const getToastClasses = (type) => { pointer-events: auto; border-radius: 0.75rem; } + +@keyframes toast-progress { + from { width: 100%; } + to { width: 0%; } +} diff --git a/frontend/app/composables/useToast.ts b/frontend/app/composables/useToast.ts index 89edb99..750ab6e 100644 --- a/frontend/app/composables/useToast.ts +++ b/frontend/app/composables/useToast.ts @@ -7,6 +7,7 @@ export interface Toast { message: string type: ToastType visible: boolean + duration: number } const toasts = ref([]) @@ -32,6 +33,7 @@ export function useToast() { message, type, visible: true, + duration: type === 'error' ? 0 : duration, } if (toasts.value.length >= MAX_TOASTS) { @@ -40,10 +42,12 @@ export function useToast() { toasts.value.push(toast) - // Auto-remove after duration - setTimeout(() => { - removeToast(id) - }, duration) + // Only auto-dismiss non-error toasts + if (type !== 'error' && duration > 0) { + setTimeout(() => { + removeToast(id) + }, duration) + } return id }