From 52715ec4810ebf85c561aa3a4a731013efd3e3a2 Mon Sep 17 00:00:00 2001 From: Giancarmine Salucci Date: Thu, 9 Jul 2026 03:29:18 +0200 Subject: [PATCH] D2: remove source guard on retry buttons, show error in UI Queue page: - Remove && job.source?.startsWith('http') guard on retry button - Move retry button outside .row-actions hover zone (always visible) - Add job.error inline in meta line for failed/cancelled jobs - data-status=failed attribute on failed rows - Error tint on failed row title Job detail page: - Remove source guard from canRetry derived - Enhanced error banner: warning icon, 'Transcription failed' title, error message, inline Retry + Delete action buttons - btn, btn.primary, btn.ghost CSS styles Home page: - Add job.error as third line in recent items for failed jobs - recent-failed CSS class with error-text tint on meta - recent-err-line styling fixes #story-d2-retry-widen-upload--d1-d6-evised --- src/routes/+page.svelte | 19 +++++ src/routes/jobs/+page.svelte | 37 +++++++-- src/routes/jobs/[id]/+page.svelte | 130 ++++++++++++++++++++++++++++-- 3 files changed, 173 insertions(+), 13 deletions(-) diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index cf1bdb3..7361a92 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -264,11 +264,15 @@ href="/jobs/{job.id}" class="recent-item" class:first={i === 0} + class:recent-failed={job.status === 'failed'} >
{job.title || job.source}
{jobMeta(job)}
+ {#if job.status === 'failed' && job.error} +
{job.error}
+ {/if}
{#if job.status !== 'done' && job.status !== 'failed' && job.status !== 'cancelled'}
@@ -560,6 +564,21 @@ text-align: right; } + .recent-item.recent-failed .recent-meta { + color: var(--error-text); + } + + .recent-err-line { + font-size: 11.5px; + color: var(--error-text); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin-top: 3px; + font-family: var(--font-mono); + max-width: 100%; + } + /* ── Utilities ─────────────────────────────────────────── */ .sr-only { position: absolute; diff --git a/src/routes/jobs/+page.svelte b/src/routes/jobs/+page.svelte index a068d58..a384b2f 100644 --- a/src/routes/jobs/+page.svelte +++ b/src/routes/jobs/+page.svelte @@ -82,7 +82,7 @@ {:else} @@ -122,16 +126,20 @@
{/if} - -
- {#if ['failed', 'cancelled'].includes(job.status) && job.source?.startsWith('http')} + + {#if ['failed', 'cancelled'].includes(job.status)} +
- {/if} +
+ {/if} + + +
{#if isTerminalJobStatus(job.status)} + +
+
{/if} @@ -391,12 +406,111 @@ } .error-banner { - padding: 12px 16px; + display: flex; + gap: 14px; + align-items: flex-start; + padding: 16px 18px; border-radius: 10px; - background: rgba(255, 90, 90, 0.08); - border: 1px solid rgba(255, 90, 90, 0.2); - color: #ff8a8a; - font-size: 13px; + background: var(--error-bg); + border: 1px solid var(--error-border); + margin-bottom: 24px; + } + + .eb-icon { + width: 34px; + height: 34px; + display: grid; + place-items: center; + border-radius: 9px; + background: rgba(255,90,90,0.12); + color: var(--error-text); + flex-shrink: 0; + } + + .eb-body { + flex: 1; + min-width: 0; + } + + .eb-title { + font-size: 14px; + font-weight: 600; + color: var(--error-text); + } + + .eb-msg { + font-family: var(--font-mono); + font-size: 12px; + line-height: 1.6; + color: rgba(255,180,180,0.85); + margin-top: 5px; + overflow-wrap: anywhere; + max-height: 96px; + overflow-y: auto; + } + + .eb-actions { + display: flex; + gap: 8px; + align-items: center; + flex-shrink: 0; + } + + .btn { + font-family: var(--font-ui); + font-size: 12.5px; + font-weight: 550; + display: inline-flex; + align-items: center; + gap: 7px; + padding: 7px 13px; + border-radius: 9px; + border: 1px solid var(--border-strong); + background: var(--surface-hover); + color: var(--text); + cursor: pointer; + white-space: nowrap; + transition: background 140ms ease, border-color 140ms ease; + } + .btn:hover { + background: rgba(255,255,255,0.07); + border-color: rgba(255,255,255,0.18); + } + .btn:focus-visible { + outline: none; + box-shadow: 0 0 0 4px var(--accent-ring); + border-color: var(--accent); + } + + .btn.primary { + background: var(--accent); + border-color: var(--accent); + color: #10120a; + font-weight: 600; + padding: 10px 18px; + font-size: 13.5px; + border-radius: 10px; + box-shadow: 0 0 18px rgba(205,242,78,0.18); + } + .btn.primary:hover { + background: #d9f566; + border-color: #d9f566; + } + + .btn.ghost { + background: transparent; + border-color: transparent; + } + .btn.ghost:hover { + background: rgba(255,255,255,0.04); + } + + .btn.danger-ghost { + color: var(--error-text); + } + .btn.danger-ghost:hover { + background: rgba(255,90,90,0.08); + border-color: var(--error-border); } /* ── Breadcrumb ─────────────────────────────────────────── */