fix(961): remove stale manager/hm1nd references from dashboard tabs.js

Three post-rename artifacts:

1. journalUnit: was 'hive-m1nd.service' for the manager branch.
   Both roles use 'hive-ag3nt.service' since the harness unification —
   always use 'hive-ag3nt.service'.

2. buildTargetChips: hardcoded ['operator', 'manager'] candidates +
   filter by n !== 'manager'. After the rename the manager's c.name
   is 'root', so it was excluded from the filter but not from the
   hardcoded initial list — the manager could appear twice or be listed
   as 'manager' when its real broker name is 'root'. Fix: derive
   the manager's name from c.is_manager on containersState; filter
   sub-agents by !c.is_manager rather than by hardcoded string.

3. schedulesTableAgentSet: same hardcoded 'manager' + filter pattern
   as buildTargetChips. Same fix applied.
This commit is contained in:
iris 2026-06-01 17:47:33 +02:00 committed by mara
commit f39015e41d

View file

@ -708,7 +708,7 @@ window.marked = marked;
// Per-container journald viewer. Opens the side panel and
// fetches the last N lines; refresh re-fetches; unit selector
// narrows to the harness service (or empty = full machine).
const journalUnit = c.is_manager ? 'hive-m1nd.service' : 'hive-ag3nt.service';
const journalUnit = 'hive-ag3nt.service';
drill.append(buildJournalTrigger(c.container, journalUnit));
// Build-log viewer: lists recent nix build / nixos-container
// invocations for this agent, with click-to-expand full
@ -2486,17 +2486,24 @@ window.marked = marked;
// Targets multi-select chip box — shared between the new-schedule
// form and the edit-schedule form. Same DOM shape, same candidate
// list (containers + operator + manager); only the chip element id
// list (containers + operator + 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', 'manager'];
// Derive the manager's actual name from live state rather than
// hardcoding it — the manager's container name may differ from the
// logical label the broker uses (e.g. "root" after the rename).
const managerContainer = Array.from(containersState.values()).find((c) => c.is_manager);
const managerName = managerContainer?.name;
const candidates = ['operator'];
if (managerName) candidates.push(managerName);
const containerNames = Array.from(containersState.values())
.filter((c) => !c.is_manager)
.map((c) => c.name)
.filter((n) => n !== 'manager' && n !== 'operator')
.filter((n) => n !== 'operator')
.sort();
for (const n of containerNames) candidates.push(n);
// `extraNames` lets the edit form keep showing an already-active
@ -2786,9 +2793,9 @@ window.marked = marked;
submitBtn.innerHTML = originalLabel;
}
}
// The set of agent columns in the schedules table: operator + manager
// first, then live containers (sorted), then any extra names that
// appear as a schedule target but aren't in the live container list
// 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.
@ -2797,10 +2804,12 @@ window.marked = marked;
const out = [];
const push = (n) => { if (!seen.has(n)) { seen.add(n); out.push(n); } };
push('operator');
push('manager');
const managerContainer = Array.from(containersState.values()).find((c) => c.is_manager);
if (managerContainer) push(managerContainer.name);
const containerNames = Array.from(containersState.values())
.filter((c) => !c.is_manager)
.map((c) => c.name)
.filter((n) => n !== 'manager' && n !== 'operator')
.filter((n) => n !== 'operator')
.sort();
for (const n of containerNames) push(n);
for (const s of schedulesState) {