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

The Wave card links each milestone limb to its page on the forge #5762

Merged opened this

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

Merged

scout/forge:scout/5754-the-wave-card-links-each-milestone-limb → main 3 commits fork 3 threads · 3 unresolved

  • Merged. scout/5754-the-wave-card-links-each-milestone-limb was merged into main as e37f3e2.

Review

Sign in to review this change.
2 files changed +18 −2
src/web/studio/cards.ts +7 −2
@@ -235,12 +235,17 @@ export function cardFor(
235235 } else {
236236 const limbs = list(obj(value)["limbs"]).map(obj);
237237 const repo = obj(obj(value)["repo"]);
238 status = `${text(repo["owner"])}/${text(repo["name"])}`.replace(/^\/$/, "");
239 for (const l of limbs.slice(0, LIMIT))
238 const slug = `${text(repo["owner"])}/${text(repo["name"])}`;
239 status = slug.replace(/^\/$/, "");
240 const linkable = web(origin) && /^[^/]+\/[^/]+$/.test(slug);
outdated

Use web(origin), as the Plan and Apps cards do, instead of a new inline regex. slug repeats the expression on the line above for status; build it once.

241 for (const l of limbs.slice(0, LIMIT)) {
242 const number = Number(l["number"]);
240243 rows.push({
241244 label: `#${text(l["number"])} ${text(l["name"])}`,
242245 value: `${text(l["done"])}/${text(l["total"])} done · ${text(l["building"])} building`,
246 ...(linkable && Number.isInteger(number) && number > 0 ? { link: `${origin}/${slug}/milestones/${number}` } : {}),
243247 });
248 }
244249 }
245250 return { kind, title: CARD_TITLE[kind], status, rows, actions };
246251 }
test/card-shell.test.ts +11
@@ -173,6 +173,17 @@ describe("the card shell", () => {
173173 });
174174 });
175175
176 describe("the Wave card links its limbs", () => {
177 const json = { repo: { owner: "a", name: "b" }, limbs: [{ number: 3, name: "x", done: 1, total: 2, building: 0 }, { number: 0, name: "y" }] };
178 test("a good origin links a positive number; a bad origin or repo does not", () => {
179 const good = cardFor("milestones", json, "https://f.example")!;
180 expect(good.rows[0]!.link).toBe("https://f.example/a/b/milestones/3");
181 expect(good.rows[1]!.link).toBeUndefined();
182 expect(cardFor("milestones", json, "javascript:x")!.rows[0]!.link).toBeUndefined();
183 expect(cardFor("milestones", { ...json, repo: {} }, "https://f.example")!.rows[0]!.link).toBeUndefined();
184 });
185 });
186
176187 describe("app card links", () => {
177188 const origin = "https://forge.example";
178189 test("apps rows link to the app page only for an http(s) origin and owner/name", () => {

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs