diff --git a/pipekit/web/app.py b/pipekit/web/app.py index 4d951de..e93e90d 100644 --- a/pipekit/web/app.py +++ b/pipekit/web/app.py @@ -866,13 +866,31 @@ def _schedules_with_next(schedules: list[dict]) -> list[dict]: s = dict(s) try: cron = croniter(s["cron_expr"], now) - s["next_fire_at"] = cron.get_next(datetime).strftime("%Y-%m-%d %H:%M %Z") + nxt = cron.get_next(datetime) + s["next_fire_at"] = nxt.strftime("%Y-%m-%d %H:%M") + s["next_fire_in"] = _humanize_delta((nxt - now).total_seconds()) except CroniterBadCronError: s["next_fire_at"] = "invalid expression" + s["next_fire_in"] = None result.append(s) return result +def _humanize_delta(seconds: float) -> str: + """'in 3h 12m' style relative label for a positive second count.""" + secs = int(max(seconds, 0)) + days, rem = divmod(secs, 86400) + hours, rem = divmod(rem, 3600) + mins = rem // 60 + if days: + return f"in {days}d {hours}h" + if hours: + return f"in {hours}h {mins}m" + if mins: + return f"in {mins}m" + return "in <1m" + + def _sanitize_identifier(name: str) -> str: """Lower-case a source column name and replace characters that aren't valid in an unquoted identifier with underscores.""" @@ -1338,6 +1356,7 @@ def groups_index(request: Request): g["last_run_at"] = None g["last_status"] = None g["last_duration_s"] = None + g["schedules"] = _schedules_with_next(repo.list_schedules_for_group(g["id"])) return _templates.TemplateResponse( request, "groups.html", _ctx(groups=groups), diff --git a/pipekit/web/static/style.css b/pipekit/web/static/style.css index a862f89..5428053 100644 --- a/pipekit/web/static/style.css +++ b/pipekit/web/static/style.css @@ -162,6 +162,8 @@ table.grid tr:hover td { background: #1c2128; } } .tag:hover { color: var(--accent); } +.muted { color: var(--text-muted); } + /* Labeled key-value rows (used in detail views) */ dl.keyval { display: grid; diff --git a/pipekit/web/templates/group_detail.html b/pipekit/web/templates/group_detail.html index 777c0bf..a67e9d8 100644 --- a/pipekit/web/templates/group_detail.html +++ b/pipekit/web/templates/group_detail.html @@ -76,7 +76,7 @@ {% for s in schedules %}