tweak job runs

This commit is contained in:
Abel Luck 2026-03-30 14:14:59 +02:00
parent 2b2a3f1cc0
commit c210168d65
6 changed files with 94 additions and 12 deletions

View file

@ -70,9 +70,6 @@ def _running_row(execution: Mapping[str, object]) -> tuple[Node, ...]:
h.p(class_="font-medium text-slate-900")[
f"#{_text(execution, 'execution_id')}"
],
h.p(class_="mt-1 text-xs text-slate-500")[
f"job {_text(execution, 'job_id')}"
],
],
h.div[
h.p(class_="font-medium text-slate-900")[_text(execution, "started_at")],
@ -99,15 +96,26 @@ def _running_row(execution: Mapping[str, object]) -> tuple[Node, ...]:
def _upcoming_row(job: Mapping[str, object]) -> tuple[Node, ...]:
next_run_at = _maybe_text(job, "next_run_at")
next_run_label: Node = h.p(class_="font-medium text-slate-900")[
_text(job, "next_run")
]
if next_run_at is not None:
next_run_label = h.time(
{
"data-next-run-at": next_run_at,
"title": next_run_at,
},
datetime=next_run_at,
class_="font-medium text-slate-900",
)[_text(job, "next_run")]
return (
h.div[
h.div(class_="font-semibold text-slate-950")[_text(job, "source")],
h.p(class_="mt-1 font-mono text-xs text-slate-500")[_text(job, "slug")],
],
h.div[
h.p(class_="font-medium text-slate-900")[_text(job, "next_run")],
h.p(class_="mt-1 text-xs text-slate-500")[f"job {_text(job, 'job_id')}"],
],
h.div[next_run_label,],
h.p(class_="font-mono text-xs text-slate-600")[_text(job, "schedule")],
status_badge(
label=_text(job, "enabled_label"),
@ -147,9 +155,6 @@ def _completed_row(execution: Mapping[str, object]) -> tuple[Node, ...]:
h.p(class_="font-medium text-slate-900")[
f"#{_text(execution, 'execution_id')}"
],
h.p(class_="mt-1 text-xs text-slate-500")[
f"job {_text(execution, 'job_id')}"
],
],
h.div[
h.p(class_="font-medium text-slate-900")[_text(execution, "ended_at")],
@ -232,6 +237,48 @@ def runs_page(
),
rows=completed_rows,
),
h.script[
"""
window.repubFormatNextRuns = window.repubFormatNextRuns || (() => {
const relativeFormatter = new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' });
const absoluteFormatter = new Intl.DateTimeFormat(undefined, {
dateStyle: 'medium',
timeStyle: 'short',
timeZoneName: 'short',
});
const formatRelative = (targetDate) => {
const diffSeconds = Math.round((targetDate.getTime() - Date.now()) / 1000);
const units = [
['day', 86400],
['hour', 3600],
['minute', 60],
['second', 1],
];
for (const [unit, size] of units) {
if (Math.abs(diffSeconds) >= size || unit === 'second') {
return relativeFormatter.format(Math.round(diffSeconds / size), unit);
}
}
return relativeFormatter.format(0, 'second');
};
const format = () => {
document.querySelectorAll('time[data-next-run-at]').forEach((element) => {
const nextRunAt = element.getAttribute('data-next-run-at');
if (!nextRunAt) return;
const targetDate = new Date(nextRunAt);
if (Number.isNaN(targetDate.getTime())) return;
element.textContent = formatRelative(targetDate);
element.title = absoluteFormatter.format(targetDate);
});
};
format();
if (!window.repubNextRunTimer) {
window.repubNextRunTimer = window.setInterval(format, 30000);
}
});
window.repubFormatNextRuns();
"""
],
),
)