diff --git a/services/web-ui/public/screens-jobs.jsx b/services/web-ui/public/screens-jobs.jsx index f1dd172..5d53ff8 100644 --- a/services/web-ui/public/screens-jobs.jsx +++ b/services/web-ui/public/screens-jobs.jsx @@ -21,6 +21,23 @@ function _fmtAbsolute(iso) { } catch { return iso; } } +// Compact clock for the inline jobs cell — "2:23 PM" if today, +// "May 22 · 2:23 PM" if a different day. Full datetime stays in the tooltip. +function _fmtCompact(iso) { + if (!iso) return ''; + try { + const d = new Date(iso); + const now = new Date(); + const sameDay = d.getFullYear() === now.getFullYear() + && d.getMonth() === now.getMonth() + && d.getDate() === now.getDate(); + const time = d.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' }); + if (sameDay) return time; + const date = d.toLocaleDateString(undefined, { month: 'short', day: 'numeric' }); + return date + ' · ' + time; + } catch { return iso; } +} + function Jobs({ navigate }) { const [tab, setTab] = React.useState('all'); const [jobs, setJobs] = React.useState(window.ZAMPP_DATA.JOBS); @@ -194,6 +211,12 @@ function JobRow({ job, onRetry, onDelete }) { {(() => { const t = _jobTimeFor(job); if (!t) return '—'; + // Terminal states (done/failed) anchor on the absolute clock so the + // operator can correlate with logs; queued/running show relative + // since it's a moving target. + if (job.status === 'done' || job.status === 'failed') { + return t.label + ' ' + _fmtCompact(t.iso) + ' · ' + window.ZAMPP_API.fmtRelative(t.iso); + } return t.label + ' ' + window.ZAMPP_API.fmtRelative(t.iso); })()} diff --git a/services/web-ui/public/styles-rest.css b/services/web-ui/public/styles-rest.css index 37a3bc0..8c056cb 100644 --- a/services/web-ui/public/styles-rest.css +++ b/services/web-ui/public/styles-rest.css @@ -389,7 +389,7 @@ } .job-row { display: grid; - grid-template-columns: 20px 110px 1fr 90px 200px 130px 80px 90px; + grid-template-columns: 20px 110px 1fr 90px 200px 180px 80px 90px; align-items: center; gap: 12px; padding: 10px 16px;