Public: anyone can read this; the crew can change it.

"Delete this board" goes through the confirm page, which names the board and says what goes with it #7987

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/7963-delete-this-board-goes-through-the-confi → main 1 commit fork

  • Merged. scout/7963-delete-this-board-goes-through-the-confi was merged into main as 46e4d91.

Review

Sign in to review this change.
4 files changed +29 −3
src/web/pages/boards-view.ts +2 −2
@@ -18,7 +18,7 @@ import { liveRegionsJs } from "../client.ts";
1818 import { notFoundPage, signInFirst } from "../chrome.ts";
1919 import { html, when, type Html } from "../html.ts";
2020 import { fragment, page } from "../layout.ts";
21 import { btn, card, chartBox, empty, field, selectField } from "../ui.ts";
21 import { btn, card, chartBox, confirmAction, empty, field, selectField } from "../ui.ts";
2222 import { flowPanel } from "./flow-panel.ts";
2323 import { boardsHoldsCard } from "./boards-holds.ts";
2424 import { forgeCeiling } from "../../flow/ceiling.ts";
@@ -187,7 +187,7 @@ function manage(slug: string, board: Board, adding: Html, pins: ReturnType<typeo
187187 ${btn("Save settings")}
188188 </form>
189189 <form method="post" action="/boards/${slug}/duplicate">${btn("Duplicate")}</form>
190 <form method="post" action="/boards/${slug}/delete">${btn("Delete this board", { variant: "danger" })}</form></div>`,
190 ${confirmAction({ action: `/boards/${slug}/delete`, verb: "Delete this board" })}</div>`,
191191 { head: html`<h2>Board</h2>` },
192192 )}`;
193193 }
src/web/pages/search.ts +9
@@ -595,6 +595,15 @@ const DESTRUCTIVE: {
595595 phrase: "",
596596 }),
597597 },
598 {
599 pattern: /^\/boards\/([^/]+)\/delete$/,
600 describe: (m) => ({
601 verb: "Delete board",
602 title: `Delete the board ${decodeURIComponent(m[1] ?? "")}?`,
603 detail: "Its panels and pins go with it. Nothing it reads is touched.",
604 phrase: "",
605 }),
606 },
598607 {
599608 pattern: /^\/([^/]+)\/([^/]+)\/settings\/hooks\/([^/]+)\/delete$/,
600609 describe: (m) => ({
test/boards-page.test.ts +16
@@ -78,6 +78,22 @@ describe("/boards forms", () => {
7878 expect(body).toContain('name="slug"');
7979 expect(body).toContain('<label for="f-pin-title">Panel title</label>');
8080 });
81
82 test("Delete this board asks first on the confirm page, which names the board", async () => {
83 const made = await makeBoard(app, admin, "Doomed");
84 if (!made.ok) throw new Error(JSON.stringify(made.error));
85 const slug = made.value;
86 const board = await (await get(`/boards/${slug}`, "admin")).text();
87 const to = encodeURIComponent(`/boards/${slug}/delete`);
88 expect(board).toContain(`href="/-/confirm?to=${to}"`);
89 expect(board).not.toContain(`action="/boards/${slug}/delete"`);
90 const res = await get(`/-/confirm?to=${to}`, "admin");
91 expect(res.status).toBe(200);
92 const confirm = await res.text();
93 expect(confirm).toContain(`Delete the board ${slug}?`);
94 expect(confirm).toContain("Its panels and pins go with it. Nothing it reads is touched.");
95 expect(confirm).toContain(`action="/boards/${slug}/delete"`);
96 });
8197 });
8298
8399 describe("/boards/data", () => {
test/boards-store.test.ts +2 −1
@@ -174,9 +174,10 @@ describe("/boards", () => {
174174 expect(body).toContain('class="row-trail bar"');
175175 expect(body).toContain('class="list setting-list"');
176176 expect(body).toContain('action="/boards/pin-panel"');
177 for (const op of ["move", "remove", "rename", "settings", "duplicate", "delete"]) {
177 for (const op of ["move", "remove", "rename", "settings", "duplicate"]) {
178178 expect(body).toContain(`action="/boards/fleet-health/${op}"`);
179179 }
180 expect(body).toContain(`href="/-/confirm?to=${encodeURIComponent("/boards/fleet-health/delete")}"`);
180181 for (const word of ["Panels", "Add a panel", "Up", "Down", "Remove", "Pin to home", "Save settings", "Duplicate", "Delete this board"]) {
181182 expect(body).toContain(word);
182183 }

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs