feat: live SSE updates for the SCH3DUL3S tab
Add `SchedulesChanged` to the dashboard event channel so the
operator's schedule list updates in real time without requiring a
tab-activation or form-submit refresh.
Backend:
- `dashboard_events.rs`: new `SchedulesChanged { seq, schedules }`
variant carrying a full `Vec<WireSchedule>` snapshot (same
snapshot-over-diff rationale as `RebuildQueueChanged`).
- `coordinator.rs`: `emit_schedules_snapshot()` helper — queries the
scheduled_prompts list, converts to wire shape, broadcasts the event.
- `dashboard.rs`: call `emit_schedules_snapshot()` at the end of each
operator API handler that mutates a schedule:
`post_schedule_new`, `post_schedule_fire_now`,
`patch_schedule`, `post_schedule_cancel`.
- `scheduled_prompts_worker.rs`: call `emit_schedules_snapshot()`
after each tick that fires schedules, so `last_fired_at_unix`,
`next_fire_at_unix`, and reaped one-shots surface live.
Frontend:
- `tabs.js`: add `applySchedulesChanged(ev)` — replaces
`schedulesState` from the snapshot and calls `renderSchedulesList()`.
Registered in `MUTATION_HANDLERS` as `schedules_changed`.
Tab-activation re-fetch kept as safety net for approval-path
inserts and disconnect windows; comment updated to reflect this.
Docs:
- `docs/web-ui/dashboard.md`: document `schedules_changed` event.
- `CLAUDE.md`: add `SchedulesChanged` to the file-map entry.
This commit is contained in:
parent
b411a81c1a
commit
76c4a67b1c
7 changed files with 78 additions and 9 deletions
|
|
@ -223,6 +223,10 @@ window.marked = marked;
|
|||
// See docs/web-ui.md::Container row for the badge taxonomy.
|
||||
renderContainersFromState();
|
||||
}
|
||||
function applySchedulesChanged(ev) {
|
||||
schedulesState = (ev.schedules || []).slice();
|
||||
renderSchedulesList();
|
||||
}
|
||||
// Map from agent name → highest-priority in-flight queue entry
|
||||
// (`running` beats `queued`). Used by the container row renderer
|
||||
// to surface "building..." / "meta-updating..." badges on the
|
||||
|
|
@ -2471,8 +2475,11 @@ window.marked = marked;
|
|||
// ─── scheduled prompts ─────────────────────────────────────────────────
|
||||
// Backend exposes `/api/schedules` (snapshot), `/api/schedules`
|
||||
// (POST, operator-direct submit), `/api/schedules/{id}/cancel`
|
||||
// (whole or per-target). No SSE channel for schedule mutations yet,
|
||||
// so we refresh on tab activation + after every submit/cancel POST.
|
||||
// (whole or per-target), `/api/schedules/{id}` (PATCH edit),
|
||||
// `/api/schedules/{id}/fire-now` (POST). Mutations now emit a
|
||||
// `schedules_changed` SSE event so the list updates live;
|
||||
// `applySchedulesChanged` handles it. Tab-activation re-fetch kept as
|
||||
// a safety net for approval-path inserts and disconnect windows.
|
||||
// Local cache lets `refreshTabCounts` show the active count without
|
||||
// re-fetching every second.
|
||||
let schedulesState = [];
|
||||
|
|
@ -3596,6 +3603,7 @@ window.marked = marked;
|
|||
meta_inputs_changed: applyMetaInputsChanged,
|
||||
meta_update_running: applyMetaUpdateRunning,
|
||||
rebuild_queue_changed: applyRebuildQueueChanged,
|
||||
schedules_changed: applySchedulesChanged,
|
||||
};
|
||||
(function bindDashboardStream() {
|
||||
// Route through the SharedWorker so all open hyperhive tabs share
|
||||
|
|
@ -3650,8 +3658,9 @@ window.marked = marked;
|
|||
renderSelectionBar(Array.from(containersState.values()));
|
||||
// Keep overflow button active state in sync after tab change.
|
||||
updateTabbarOverflow();
|
||||
// Schedules pane has no SSE channel for mutations, so re-fetch
|
||||
// on activation so the operator never lands on stale data.
|
||||
// Re-fetch schedules on activation as a safety net (SSE covers
|
||||
// live mutations but re-sync ensures consistency after disconnect
|
||||
// windows or approval-path inserts that don't yet emit).
|
||||
if (target === 'schedules') refreshSchedules();
|
||||
// Permissions tables (capabilities + tool-groups) have no SSE channel;
|
||||
// fetch both on each activation so the operator sees fresh data.
|
||||
|
|
|
|||
Loading…
Reference in a new issue