Bulk decomission #41

Closed
opened 2026-10-06 23:08:06 +02:00 by EduarD3V · 5 comments
Owner

URL: http://192.168.31.41:5173/agents/installs

Under that url i need you to enable bulk agent decommission with two confirmations. workflow needs to be like this:

  • remove enroll agent button
  • set the install help button as "install agent" and primary blue
  • add a contextual menu (create a component if not there yet)
  • contextual menu appears on right click
  • contextual menu has select option
  • if a machine is selected, a checkbox on the left of all agents appear
  • if click right again, it shows options: unselect, decommision selected
URL: http://192.168.31.41:5173/agents/installs Under that url i need you to enable bulk agent decommission with two confirmations. workflow needs to be like this: - remove enroll agent button - set the install help button as "install agent" and primary blue - add a contextual menu (create a component if not there yet) - contextual menu appears on right click - contextual menu has select option - if a machine is selected, a checkbox on the left of all agents appear - if click right again, it shows options: unselect, decommision selected
gotoi-agent added reference issue/41-bulk-decommission 2026-10-07 04:36:13 +02:00
Collaborator

Claimed — branch issue/41-bulk-decommission. Doing: bulk decommission on /agents/installs via a right-click contextual menu (Select / Unselect / Decommission selected), row checkboxes in selection mode, two confirmations before POST /agents/bulk op:delete, header "Enroll agent" removed and "Install help" → primary "Install agent".

Claimed — branch `issue/41-bulk-decommission`. Doing: bulk decommission on `/agents/installs` via a right-click contextual menu (Select / Unselect / Decommission selected), row checkboxes in selection mode, two confirmations before `POST /agents/bulk op:delete`, header "Enroll agent" removed and "Install help" → primary "Install agent".
Collaborator

Plan: /home/eduardez/workspace/gotoi-wt/meta/issue-41.plan.md

  1. New UC-FE-95 (+ bidirectional related in UC-FE-65/68/87) — python3 docs/use-cases/_check.py
  2. UC-FE-95 test in dashboard/src/lib/usecases-frontend.test.ts — bun run test
  3. Page header: drop "Enroll agent", "Install help" → primary "Install agent"
  4. Context menu (Select / Unselect / Decommission selected) + row checkbox in selection mode
  5. Two-stage confirm → bulkDelete(); full gates + browser smoke on /agents/installs
Plan: `/home/eduardez/workspace/gotoi-wt/meta/issue-41.plan.md` 1. New UC-FE-95 (+ bidirectional `related` in UC-FE-65/68/87) — `python3 docs/use-cases/_check.py` 2. `UC-FE-95` test in `dashboard/src/lib/usecases-frontend.test.ts` — `bun run test` 3. Page header: drop "Enroll agent", "Install help" → primary "Install agent" 4. Context menu (Select / Unselect / Decommission selected) + row checkbox in selection mode 5. Two-stage confirm → `bulkDelete()`; full gates + browser smoke on `/agents/installs`
Collaborator

PARTIAL-DONE — harvested at the 45-min orchestrator cap. PR opened: #51 (issue/41-bulk-decommission -> agent-develop), commits 8032616 + 8458a86.

Implemented: right-click context menu (Select / Unselect / Decommission selected), row checkboxes in selection mode, two confirmations before bulk delete, 'Enroll agent' removed, 'Install help' -> primary 'Install agent'. New UC-FE-95.

Gates green on orchestrator re-run: UC check, ai-headers, type-mirror, svelte-check 0 errors, vitest 240 passed. Not verified: live browser smoke of the menu flow (omp was cut mid smoke-check). Issue stays open — operator merges.

PARTIAL-DONE — harvested at the 45-min orchestrator cap. PR opened: https://git.eduard3v.com/EduarD3V/gotoi/pulls/51 (issue/41-bulk-decommission -> agent-develop), commits 8032616 + 8458a86. Implemented: right-click context menu (Select / Unselect / Decommission selected), row checkboxes in selection mode, two confirmations before bulk delete, 'Enroll agent' removed, 'Install help' -> primary 'Install agent'. New UC-FE-95. Gates green on orchestrator re-run: UC check, ai-headers, type-mirror, svelte-check 0 errors, vitest 240 passed. Not verified: live browser smoke of the menu flow (omp was cut mid smoke-check). Issue stays open — operator merges.
Collaborator

Issue #41 — Bulk decommission (/agents/installs)

Restated goal

On http://192.168.31.41:5173/agents/installs the operator must be able to select several
enrolled agents and decommission them in one request, behind two confirmations. "Machines" in
the issue means the agent rows of this list (task file says so explicitly). Concretely: drop the
header "Enroll agent" button, turn the header "Install help" button into a primary-blue
"Install agent", add a right-click contextual menu on the list with Select / Unselect /
Decommission selected
, where choosing Select reveals a checkbox on every row, and where
Decommission selected runs a two-step confirmation before POST /agents/bulk {op:'delete'}.

"Done" for the operator: right-click a agent row → menu; Select → checkbox column appears and rows
toggle on click; right-click again → Unselect / Decommission selected; Decommission asks twice
(second one typed DECOMMISSION) and only then deletes; the header shows one blue "Install agent"
action and no enroll button.

Scope

Change

  • dashboard/src/routes/agents/installs/+page.svelte — header actions, context menu, selection
    mode + row checkbox, two-stage confirm, drop the dead empty {#if} at the tail.
  • docs/use-cases/frontend/UC-FE-95-bulk-decommission-select.md — new UC.
  • docs/use-cases/frontend/UC-FE-68-bulk-agent-actions.md — Story now two dialogs; related: +=
    UC-FE-95; version bump.
  • docs/use-cases/frontend/UC-FE-87-decommission-live-warning.md — related: += UC-FE-95.
  • docs/use-cases/frontend/UC-FE-65-agents-views.md — related: += UC-FE-95.
  • dashboard/src/lib/usecases-frontend.test.ts — UC-FE-95 describe block (repo convention is
    source-content assertions for pages; there is no component test layer).

Not touched

  • middleware/** (bulk op:'delete' and its zod schema already exist and are already called by
    this page) and agent/**.
  • dashboard/src/app.css, $lib/components/ui/split-list/* (rows keep .list-row as shipped).
  • dashboard/src/routes/agents/+page.svelte (its own "Install help" button is not in the issue).
  • EnrollForm / the ?id=__new__ draft branch / UC-FE-05 — only the header enroll button goes.
  • plans/, main/master, any push.

UC decision

New UC-FE-95 "Bulk decommission from an agent list", docs/use-cases/frontend/UC-FE-95-bulk-decommission-select.md.

  • Implementation cite: dashboard/src/routes/agents/installs/+page.svelte (real page file; app.ts forbidden).
  • Tests cite: dashboard/src/lib/usecases-frontend.test.ts (will contain UC-FE-95).
  • related: [UC-FE-65, UC-FE-68, UC-FE-87], bidirectional; each of those three gains the link in
    both YAML and the Related heading.

Ordered tasks (each with its verifying command)

  1. Write this plan. → test -f /home/eduardez/workspace/gotoi-wt/meta/issue-41.plan.md
  2. Post Claim + Plan comments on issue #41. → python3 $FJ issue 41 shows both
  3. Author UC-FE-95 + add the bidirectional links in UC-FE-65/68/87 (UC-FE-68 Story → two
    dialogs, version bump). → python3 docs/use-cases/_check.py
  4. usecases-frontend.test.ts: UC-FE-95 describe. → cd dashboard && bun run test
  5. Page: header actions (remove Enroll agent; Install help → Install agent, primary) + drop the
    dead {#if}. → cd dashboard && bun run check
  6. Page: data-agent-id rows, ContextMenu.Root/Trigger/Content (Select / Unselect / Decommission
    selected), selection mode + row checkbox indicator, row click toggles while selecting.
    → cd dashboard && bun run check
  7. Page: two-stage confirm (typed DECOMMISSION → final "Decommission now") routed through
    bulkDelete(); header Last: bump. → cd dashboard && bun run check
  8. Full gate list + browser smoke of /agents/installs (right-click, Select, Unselect, both
    dialogs). → all gates exit 0, rg -n 'Showing lines' empty
  9. Report + Done comment. → test -f /home/eduardez/workspace/gotoi-wt/meta/issue-41.report.md

Open questions + assumptions taken

  • "machine selected" = the agent row under the cursor / the rows the operator ticks.
    Assumption: Select enters selection mode (pre-ticking the right-clicked row) and every row then
    shows a checkbox on the left; clicking a row toggles it instead of opening the detail.
  • Checkbox inside a <button> row. SplitList.Item renders <button class="list-row">; the
    installed Checkbox is itself a <button>, so nesting is invalid. Assumption: in selection mode
    the row renders a presentational checkbox indicator with the same tokens and the row button
    carries aria-pressed + the toggle action (a toggle button is the correct semantic for a
    selectable list row). Fallback if a reviewer wants a real input: restructure the row into
    li > label > Checkbox + button.
  • "Unselect" = leave selection mode and clear the ticks (it is disabled when nothing is ticked).
  • Selection mode is process-local, not URL-backed (URL keeps q + id semantics of UC-FE-65 §6).
  • "Install help" body copy elsewhere in the page/detail is left alone; only the header action's
    label changes, as the issue asks.
  • Enroll button: only the header PageAction is removed; the empty-state placeholder button and
    the ?id=__new__ draft branch stay, so EnrollForm (UC-FE-05) stays reachable and the existing
    UC-FE-65 assertion on EnrollForm remains true.

Risk + boring fallback

  • Right-click wiring: mirror the proven aimanage/chat pattern (bits-ui Trigger wrapping a div
    whose oncontextmenu sets the row id). Risk: handler ordering vs bits-ui's own listener →
    fallback: ContextMenu.Items read a ctxId that is also refreshed on onpointerdown.
  • Two dialogs: ConfirmDialog calls oncancel() on every open→close transition, so advancing
    stage 1 → stage 2 would be mistaken for a cancel. Risk: stage 2 self-aborts. Fallback: guard each
    oncancel with the current stage (if (confirmStage === 'typed') …); if that still misbehaves,
    use one dialog whose props swap per stage.
  • bun run check noise from the new markup → fallback: relative-position a plain span indicator and
    keep all state in the page (already the design).
  • Gate red that cannot be fixed in scope → leave it red, report it, do not weaken a test.
# Issue #41 — Bulk decommission (`/agents/installs`) ## Restated goal On `http://192.168.31.41:5173/agents/installs` the operator must be able to select several enrolled agents and decommission them in one request, behind **two** confirmations. "Machines" in the issue means the agent rows of this list (task file says so explicitly). Concretely: drop the header "Enroll agent" button, turn the header "Install help" button into a primary-blue "Install agent", add a right-click contextual menu on the list with **Select / Unselect / Decommission selected**, where choosing *Select* reveals a checkbox on every row, and where *Decommission selected* runs a two-step confirmation before `POST /agents/bulk {op:'delete'}`. "Done" for the operator: right-click a agent row → menu; Select → checkbox column appears and rows toggle on click; right-click again → Unselect / Decommission selected; Decommission asks twice (second one typed `DECOMMISSION`) and only then deletes; the header shows one blue "Install agent" action and no enroll button. ## Scope **Change** - `dashboard/src/routes/agents/installs/+page.svelte` — header actions, context menu, selection mode + row checkbox, two-stage confirm, drop the dead empty `{#if}` at the tail. - `docs/use-cases/frontend/UC-FE-95-bulk-decommission-select.md` — **new** UC. - `docs/use-cases/frontend/UC-FE-68-bulk-agent-actions.md` — Story now two dialogs; `related:` += UC-FE-95; version bump. - `docs/use-cases/frontend/UC-FE-87-decommission-live-warning.md` — `related:` += UC-FE-95. - `docs/use-cases/frontend/UC-FE-65-agents-views.md` — `related:` += UC-FE-95. - `dashboard/src/lib/usecases-frontend.test.ts` — `UC-FE-95` describe block (repo convention is source-content assertions for pages; there is no component test layer). **Not touched** - `middleware/**` (bulk `op:'delete'` and its zod schema already exist and are already called by this page) and `agent/**`. - `dashboard/src/app.css`, `$lib/components/ui/split-list/*` (rows keep `.list-row` as shipped). - `dashboard/src/routes/agents/+page.svelte` (its own "Install help" button is not in the issue). - `EnrollForm` / the `?id=__new__` draft branch / `UC-FE-05` — only the *header* enroll button goes. - `plans/`, `main`/`master`, any push. ## UC decision New **`UC-FE-95` "Bulk decommission from an agent list"**, `docs/use-cases/frontend/UC-FE-95-bulk-decommission-select.md`. - Implementation cite: `dashboard/src/routes/agents/installs/+page.svelte` (real page file; `app.ts` forbidden). - Tests cite: `dashboard/src/lib/usecases-frontend.test.ts` (will contain `UC-FE-95`). - `related: [UC-FE-65, UC-FE-68, UC-FE-87]`, bidirectional; each of those three gains the link in both YAML and the Related heading. ## Ordered tasks (each with its verifying command) 1. Write this plan. → `test -f /home/eduardez/workspace/gotoi-wt/meta/issue-41.plan.md` 2. Post Claim + Plan comments on issue #41. → `python3 $FJ issue 41` shows both 3. Author `UC-FE-95` + add the bidirectional links in UC-FE-65/68/87 (UC-FE-68 Story → two dialogs, version bump). → `python3 docs/use-cases/_check.py` 4. `usecases-frontend.test.ts`: `UC-FE-95` describe. → `cd dashboard && bun run test` 5. Page: header actions (remove Enroll agent; Install help → `Install agent`, primary) + drop the dead `{#if}`. → `cd dashboard && bun run check` 6. Page: `data-agent-id` rows, `ContextMenu.Root/Trigger/Content` (Select / Unselect / Decommission selected), selection mode + row checkbox indicator, row click toggles while selecting. → `cd dashboard && bun run check` 7. Page: two-stage confirm (`typed DECOMMISSION` → final "Decommission now") routed through `bulkDelete()`; header `Last:` bump. → `cd dashboard && bun run check` 8. Full gate list + browser smoke of `/agents/installs` (right-click, Select, Unselect, both dialogs). → all gates exit 0, `rg -n 'Showing lines'` empty 9. Report + Done comment. → `test -f /home/eduardez/workspace/gotoi-wt/meta/issue-41.report.md` ## Open questions + assumptions taken - **"machine selected"** = the agent row under the cursor / the rows the operator ticks. Assumption: *Select* enters selection mode (pre-ticking the right-clicked row) and every row then shows a checkbox on the left; clicking a row toggles it instead of opening the detail. - **Checkbox inside a `<button>` row.** `SplitList.Item` renders `<button class="list-row">`; the installed `Checkbox` is itself a `<button>`, so nesting is invalid. Assumption: in selection mode the row renders a **presentational** checkbox indicator with the same tokens and the *row button* carries `aria-pressed` + the toggle action (a toggle button is the correct semantic for a selectable list row). Fallback if a reviewer wants a real input: restructure the row into `li > label > Checkbox + button`. - **"Unselect"** = leave selection mode and clear the ticks (it is disabled when nothing is ticked). - **Selection mode is process-local**, not URL-backed (URL keeps `q` + `id` semantics of UC-FE-65 §6). - **"Install help" body copy** elsewhere in the page/detail is left alone; only the header action's label changes, as the issue asks. - **Enroll button**: only the header `PageAction` is removed; the empty-state placeholder button and the `?id=__new__` draft branch stay, so `EnrollForm` (UC-FE-05) stays reachable and the existing UC-FE-65 assertion on `EnrollForm` remains true. ## Risk + boring fallback - Right-click wiring: mirror the proven `aimanage/chat` pattern (bits-ui `Trigger` wrapping a div whose `oncontextmenu` sets the row id). Risk: handler ordering vs bits-ui's own listener → fallback: `ContextMenu.Item`s read a `ctxId` that is also refreshed on `onpointerdown`. - Two dialogs: `ConfirmDialog` calls `oncancel()` on every open→close transition, so advancing stage 1 → stage 2 would be mistaken for a cancel. Risk: stage 2 self-aborts. Fallback: guard each `oncancel` with the current stage (`if (confirmStage === 'typed') …`); if that still misbehaves, use one dialog whose props swap per stage. - `bun run check` noise from the new markup → fallback: relative-position a plain span indicator and keep all state in the page (already the design). - Gate red that cannot be fixed in scope → leave it red, report it, do not weaken a test.
Collaborator

Rebased branch onto agent-develop (conflicts in UC-FE-65/68 resolved: kept the uuid-route text + version bumps, kept the UC-FE-95 related links). Gates re-run green on rebased head 89e7b70: UC catalog check, ai-headers, vitest 240/240, svelte-check 0 errors. PR #51 is now mergeable: true against agent-develop. Awaiting operator merge.

Rebased branch onto agent-develop (conflicts in UC-FE-65/68 resolved: kept the uuid-route text + version bumps, kept the UC-FE-95 related links). Gates re-run green on rebased head 89e7b70: UC catalog check, ai-headers, vitest 240/240, svelte-check 0 errors. PR #51 is now mergeable: true against agent-develop. Awaiting operator merge.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
EduarD3V/gotoi#41
No description provided.