dashboard: scheduled prompts tab + creation form (closes #459)
frontend for the #444 scheduled-prompts feature. backend is already merged (PR #454 + sibling commits): GET /api/schedules (snapshot), POST /api/schedules (operator-direct submit), POST /api/schedules/{id}/cancel (whole or per-target). new chrome - SCH3DUL3S tab in the dashboard tab strip, between SYST3M and the FL0W link. count pill shows the number of schedules with at least one still-active target. - pane has two sections: N3W SCH3DUL3 (creation form) + QU3U3D SCH3DUL3S (list of cards). creation form - targets multi-select rendered as chip-style checkboxes; candidates pulled from containersState plus the special `operator` and `manager` recipients. - prompt body textarea (required, non-empty trim). - first-fire datetime-local input, defaulted to "5 minutes from now" so the form has a sensible pre-filled future timestamp. - optional interval (seconds) input — blank = one-shot. - optional description (one-liner shown on the schedule card). - mid-typing carry: re-rendering the form preserves field values + checkbox state. the operator never loses what they were typing when the schedule list refreshes underneath them. - POSTs SchedulePromptPayload JSON to /api/schedules; on success re-fetches the list to surface the new row. schedules list - one card per schedule, active rows first (sorted by next_fire_at_unix), cancelled tail dimmed. - header: id, source chip (`operator` or `approval` — reuses the rebuild-queue rqe-source styling for visual consistency), next-fire countdown / overdue label, recurring vs one-shot badge, owner. - body: prompt text in a styled <pre>-ish block with linkified path references. - per-target table: target name, last fire age, last result, per-row cancel button. - whole-schedule "✕ cancel all" button. - per-target cancel posts { targets: ["name"] }; cancel-all posts no body (== cancel whole row). no-SSE refresh - the backend doesn't emit SchedulesChanged dashboard events yet (damocles flagged this as a follow-up PR C). list re-fetches on: - tab activation (so switching to SCH3DUL3S never lands stale) - cold load via refreshState - after every submit + cancel POST the operator's typical interactions all force a refresh; the remaining gap (worker fires while you're staring at the tab) is the natural argument for PR C. files - frontend/packages/dashboard/src/index.html — new tab + pane with the two sections. - frontend/packages/dashboard/src/app.js — schedulesState cache, refreshSchedules, render*ScheduleNewForm, submit + cancel helpers, tab routing extended for `schedules`, count pill wired into refreshTabCounts. - frontend/packages/dashboard/src/dashboard.css — schedule form + card styling + chip checkboxes + targets table. small .btn-inline-small helper for the per-target cancel. validation - npm run build --workspace=@hive/dashboard clean. app.js 158 kb → 161 kb. CSS 41.3 kb → 43.9 kb. - browser smoke test isn't possible from inside iris's container; endpoints are wire-compatible (backend types unchanged) and the form serialisation matches SchedulePromptPayload's JSON shape exactly (targets / body / first_fire_at_unix / interval_seconds / description).
This commit is contained in:
parent
2593896383
commit
c233f8a924
3 changed files with 495 additions and 1 deletions
|
|
@ -34,6 +34,16 @@
|
|||
<span class="tab-label">◆ SYST3M ◆</span>
|
||||
<span class="tab-count" id="tab-count-system" hidden></span>
|
||||
</a>
|
||||
<!-- SCH3DUL3S (#459): scheduled-prompts surface. List of
|
||||
queued schedules + an operator-direct creation form.
|
||||
Count pill mirrors the active (non-cancelled) schedule
|
||||
count; hidden when zero. -->
|
||||
<a class="tab" id="tab-schedules" href="#schedules" role="tab"
|
||||
aria-controls="tab-pane-schedules"
|
||||
data-tab="schedules">
|
||||
<span class="tab-label">◆ SCH3DUL3S ◆</span>
|
||||
<span class="tab-count" id="tab-count-schedules" hidden></span>
|
||||
</a>
|
||||
|
||||
<!-- FL0W is its own page (`/flow.html`), not a tab — per
|
||||
operator @ #369#issuecomment-3437 ("yes terminal can be a
|
||||
|
|
@ -128,6 +138,31 @@
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<!-- SCH3DUL3S (#459): scheduled prompts. operator-direct creation
|
||||
form at the top (POST /api/schedules, no approval gate), live
|
||||
schedules list below (GET /api/schedules) with per-target
|
||||
last-fired timestamps + result, plus per-target / whole-row
|
||||
cancel buttons (POST /api/schedules/{id}/cancel). #444 backend
|
||||
doesn't emit a SchedulesChanged dashboard event yet, so the
|
||||
list re-fetches on tab activation + after each form/cancel
|
||||
submit. Live SSE wiring is the future PR C. -->
|
||||
<section class="tab-pane" id="tab-pane-schedules"
|
||||
role="tabpanel" aria-labelledby="tab-schedules">
|
||||
<h2>◆ N3W SCH3DUL3 ◆</h2>
|
||||
<div class="divider">══════════════════════════════════════════════════════════════</div>
|
||||
<p class="meta">queue a prompt to fire at a future time. operator-direct (no approval gate); recurring when an interval is set. targets are any known agent name or <code>operator</code> / <code>manager</code>.</p>
|
||||
<div id="schedule-new-section">
|
||||
<p class="meta">loading…</p>
|
||||
</div>
|
||||
|
||||
<h2>◆ QU3U3D SCH3DUL3S ◆</h2>
|
||||
<div class="divider">══════════════════════════════════════════════════════════════</div>
|
||||
<p class="meta">all schedules currently in the table. expand each card to see per-target firing history. cancel a single target with the row button or the whole schedule with <code>✕ cancel all</code>.</p>
|
||||
<div id="schedules-section">
|
||||
<p class="meta">loading…</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FL0W: lives on its own page now (`/flow.html`). The
|
||||
message-flow + inbox + compose DOM only exists there — when
|
||||
app.js boots on this page the corresponding renderers
|
||||
|
|
|
|||
Loading…
Reference in a new issue