Browse Source

Moved toast messages

maziggy 2 months ago
parent
commit
c0625422a4

+ 44 - 4
frontend/src/contexts/ToastContext.tsx

@@ -231,6 +231,48 @@ export function ToastProvider({ children }: { children: ReactNode }) {
 
       const hasActiveWork = dispatched + processing > 0;
       const allDone = total > 0 && completed + failed >= total && !hasActiveWork;
+      const recentStatus = detail.recent_event?.status;
+
+      // Once any print starts successfully, dismiss the dispatch toast (#615)
+      // Remaining jobs continue in the background silently
+      if (recentStatus === 'completed' && completed > 0) {
+        const summaryKey = `first-complete:${completed}:${failed}`;
+        if (lastDispatchSummaryRef.current !== summaryKey) {
+          lastDispatchSummaryRef.current = summaryKey;
+
+          const remaining = total - completed - failed;
+          const doneMessage = remaining > 0
+            ? t('backgroundDispatch.toast.printStartedRemaining', { completed, remaining })
+            : failed > 0
+              ? t('backgroundDispatch.toast.completeWithFailures', { completed, failed })
+              : t('backgroundDispatch.toast.completeSuccess', { completed });
+
+          setToasts((prev) => {
+            const doneToast: Toast = {
+              id: dispatchToastId,
+              message: doneMessage,
+              type: failed > 0 ? 'warning' : 'success',
+              persistent: true,
+            };
+            const exists = prev.find((toastItem) => toastItem.id === dispatchToastId);
+            if (exists) {
+              return prev.map((toastItem) =>
+                toastItem.id === dispatchToastId ? doneToast : toastItem
+              );
+            }
+            return [...prev, doneToast];
+          });
+
+          const existingTimeout = timeoutRefs.current.get(dispatchToastId);
+          if (existingTimeout) clearTimeout(existingTimeout);
+          const timeout = setTimeout(() => {
+            setToasts((prev) => prev.filter((t) => t.id !== dispatchToastId));
+            timeoutRefs.current.delete(dispatchToastId);
+          }, 3000);
+          timeoutRefs.current.set(dispatchToastId, timeout);
+        }
+        return;
+      }
 
       if (hasActiveWork) {
         setToasts((prev) => {
@@ -341,8 +383,6 @@ export function ToastProvider({ children }: { children: ReactNode }) {
         return;
       }
 
-      const recentStatus = detail.recent_event?.status;
-
       if (allDone) {
         const summaryKey = `${completed}:${failed}`;
         if (lastDispatchSummaryRef.current === summaryKey) {
@@ -418,8 +458,8 @@ export function ToastProvider({ children }: { children: ReactNode }) {
     <ToastContext.Provider value={{ showToast, showPersistentToast, dismissToast }}>
       {children}
 
-      {/* Toast Container — positioned above the bug-report bubble */}
-      <div className="fixed bottom-20 right-4 z-50 flex flex-col gap-2">
+      {/* Toast Container — to the left of the bug-report bubble (bottom-4 right-4 w-12) */}
+      <div className="fixed bottom-4 right-20 z-[60] flex flex-col items-end gap-2">
         {toasts.map((toast) => (
           <div
             key={toast.id}

+ 1 - 0
frontend/src/i18n/locales/de.ts

@@ -947,6 +947,7 @@ export default {
       cancelFailed: 'Dispatch konnte nicht abgebrochen werden',
       completeWithFailures: 'Background Dispatch abgeschlossen: {{completed}} erfolgreich, {{failed}} fehlgeschlagen',
       completeSuccess: 'Background Dispatch abgeschlossen: {{completed}} erfolgreich',
+      printStartedRemaining: '{{completed}} Druck(e) gestartet, {{remaining}} weitere werden gesendet...',
     },
   },
 

+ 1 - 0
frontend/src/i18n/locales/en.ts

@@ -947,6 +947,7 @@ export default {
       cancelFailed: 'Failed to cancel dispatch',
       completeWithFailures: 'Background dispatch complete: {{completed}} succeeded, {{failed}} failed',
       completeSuccess: 'Background dispatch complete: {{completed}} succeeded',
+      printStartedRemaining: '{{completed}} print(s) started, {{remaining}} more sending...',
     },
   },
 

+ 1 - 0
frontend/src/i18n/locales/fr.ts

@@ -947,6 +947,7 @@ export default {
       cancelFailed: 'Failed to cancel dispatch',
       completeWithFailures: 'Background dispatch complete: {{completed}} succeeded, {{failed}} failed',
       completeSuccess: 'Background dispatch complete: {{completed}} succeeded',
+      printStartedRemaining: '{{completed}} impression(s) lancée(s), {{remaining}} en cours d\'envoi...',
     },
   },
 

+ 1 - 0
frontend/src/i18n/locales/it.ts

@@ -947,6 +947,7 @@ export default {
       cancelFailed: 'Impossibile annullare il dispatch',
       completeWithFailures: 'Dispatch in background completato: {{completed}} riusciti, {{failed}} falliti',
       completeSuccess: 'Dispatch in background completato: {{completed}} riusciti',
+      printStartedRemaining: '{{completed}} stampa/e avviata/e, {{remaining}} in invio...',
     },
   },
 

+ 1 - 0
frontend/src/i18n/locales/ja.ts

@@ -947,6 +947,7 @@ export default {
       cancelFailed: '配信のキャンセルに失敗しました',
       completeWithFailures: 'バックグラウンド配信完了: {{completed}} 件成功、{{failed}} 件失敗',
       completeSuccess: 'バックグラウンド配信完了: {{completed}} 件成功',
+      printStartedRemaining: '{{completed}} 件の印刷を開始、残り {{remaining}} 件送信中...',
     },
   },
 

+ 1 - 0
frontend/src/i18n/locales/pt-BR.ts

@@ -947,6 +947,7 @@ export default {
       cancelFailed: 'Failed to cancel dispatch',
       completeWithFailures: 'Background dispatch complete: {{completed}} succeeded, {{failed}} failed',
       completeSuccess: 'Background dispatch complete: {{completed}} succeeded',
+      printStartedRemaining: '{{completed}} impressão(ões) iniciada(s), {{remaining}} enviando...',
     },
   },
 

+ 1 - 0
frontend/src/i18n/locales/zh-CN.ts

@@ -947,6 +947,7 @@ export default {
       cancelFailed: '取消分发失败',
       completeWithFailures: '后台分发完成:{{completed}} 成功,{{failed}} 失败',
       completeSuccess: '后台分发完成:{{completed}} 成功',
+      printStartedRemaining: '{{completed}} 个打印已开始,{{remaining}} 个正在发送...',
     },
   },
 

File diff suppressed because it is too large
+ 0 - 0
static/assets/index-ClxzXUHL.js


File diff suppressed because it is too large
+ 0 - 0
static/assets/index-DOJtH8DG.css


File diff suppressed because it is too large
+ 0 - 0
static/assets/index-DfcIVNpM.css


+ 2 - 2
static/index.html

@@ -23,8 +23,8 @@
 
     <!-- Splash screens for iOS -->
     <link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
-    <script type="module" crossorigin src="/assets/index-D7-kOLKn.js"></script>
-    <link rel="stylesheet" crossorigin href="/assets/index-DOJtH8DG.css">
+    <script type="module" crossorigin src="/assets/index-ClxzXUHL.js"></script>
+    <link rel="stylesheet" crossorigin href="/assets/index-DfcIVNpM.css">
   </head>
   <body>
     <div id="root"></div>

Some files were not shown because too many files changed in this diff