remove operator as target for scheduled prompts

This commit is contained in:
damocles 2026-09-11 22:36:40 +02:00 committed by mara
commit b4dc09ff93
7 changed files with 130 additions and 86 deletions

View file

@ -238,22 +238,23 @@ function intervalSecondsFromFormData(fd, namePrefix) {
// Targets multi-select chip box — shared between the new-schedule
// form and the edit-schedule form. Same DOM shape, same candidate
// list (containers + operator + root); only the chip element id
// list (containers + root); only the chip element id
// prefix and checkbox field name vary. Used to be inlined twice in
// near-identical 18-line blocks; consolidated here so a future
// change (new chip kind, candidate-list source swap, etc.) lives in
// one place. Returns the wrapping `<label class="schedule-field">`
// ready to append to the form.
function buildTargetChips({ idPrefix, fieldName, checked, extraNames = [] }) {
const candidates = ["operator"];
const candidates = [];
const containerNames = Array.from(containersState.values())
.map((c) => c.name)
.filter((n) => n !== "operator")
.sort();
for (const n of containerNames) candidates.push(n);
// `extraNames` lets the edit form keep showing an already-active
// target that's vanished from the live container list (operator's
// typo, container destroyed mid-schedule, etc.) so it's still
// target that's vanished from the live container list (container
// destroyed mid-schedule, a pre-existing schedule created before
// operator stopped being a valid target, etc.) so it's still
// explicitly uncheckable. New-schedule callers pass `[]`.
for (const n of extraNames) if (!candidates.includes(n)) candidates.push(n);
@ -606,12 +607,12 @@ async function submitNewScheduleInline(tr, submitBtn) {
}
});
}
// The set of agent columns in the schedules table: operator + root
// (manager) first, then live containers (sorted), then any extra names
// that appear as a schedule target but aren't in the live container list
// (operator typo, container destroyed mid-schedule, etc.) — same
// membership rule as `buildTargetChips` so the table and the new-/
// edit-form chip boxes agree on what's addressable.
// The set of agent columns in the schedules table: root (manager) first,
// then live containers (sorted), then any extra names that appear as a
// schedule target but aren't in the live container list (container
// destroyed mid-schedule, etc.) — same membership rule as
// `buildTargetChips` so the table and the new-/edit-form chip boxes
// agree on what's addressable.
function schedulesTableAgentSet() {
const seen = new Set();
const out = [];
@ -621,7 +622,6 @@ function schedulesTableAgentSet() {
out.push(n);
}
};
push("operator");
const containerNames = Array.from(containersState.values())
.map((c) => c.name)
.filter((n) => n !== "operator")
@ -643,14 +643,14 @@ function renderSchedulesTableHead(agents) {
el("th", {}, "owner"),
el("th", { class: "schedules-table-body-th" }, "body"),
);
// 'operator' is always a valid target; every other column maps to a
// container, so flag any column whose agent is no longer in the live
// roster — its past schedules linger in the table but the agent is gone.
// Every column maps to a container, so flag any column whose agent is
// no longer in the live roster — its past schedules linger in the
// table but the agent is gone.
const liveNames = new Set(
Array.from(containersState.values()).map((c) => c.name),
);
for (const a of agents) {
const gone = a !== "operator" && !liveNames.has(a);
const gone = !liveNames.has(a);
headerRow.append(
el(
"th",