Public: anyone can read this; the crew can change it.
The home's "waiting on you" line wraps on a narrow screen and its action stays tappable #6603
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/6068-the-home-s-waiting-on-you-line-wraps-on → main 3 commits fork
2 files
changed +14
−4
src/web/studio/kpi_row.ts +2 −1
| @@ -185,8 +185,9 @@ export function waitingLine(db: Database, user: User, now: Date = new Date()): H | ||
| 185 | 185 | }); |
| 186 | 186 | const words = waitingWords(count, oldest, now); |
| 187 | 187 | if (words === null && stale.length === 0) return html``; |
| 188 | // `.break` lets the words wrap; `.stack` puts the link on its own line. No ask title: the home stays bare of them. | |
| 188 | 189 | // The fold is a form, which cannot sit in the paragraph: it follows it. |
| 189 | return html`${words === null ? null : html`<p class="small muted"><a href="/review">${words}</a></p>`}${stale.length === 0 ? null : staleArchive(stale)}`; | |
| 190 | return html`${words === null ? null : html`<p class="small muted break stack stack-tight"><span>${words}</span><a href="/review">Review them</a></p>`}${stale.length === 0 ? null : staleArchive(stale)}`; | |
| 190 | 191 | } |
| 191 | 192 | |
| 192 | 193 | /** Home's flow vitals for an admin (#5935): one muted line of counts; the open count links to the boards. */ |
test/home-kpi-row.test.ts +12 −3
| @@ -351,7 +351,7 @@ describe("home waiting line", () => { | ||
| 351 | 351 | expect(waitingWords(1, "2026-10-21T11:40:00.000Z", now)).toBe("1 waiting on you, oldest under 1 h"); |
| 352 | 352 | }); |
| 353 | 353 | |
| 354 | async function homeWith(stale: number[]): Promise<string> { | |
| 354 | async function homeWith(stale: number[], title?: string): Promise<string> { | |
| 355 | 355 | const root = mkdtempSync(join(tmpdir(), "forge-home-wait-")); |
| 356 | 356 | const app = createApp({ dataDir: root, port: 0 }); |
| 357 | 357 | const servers = await serve(app); |
| @@ -365,7 +365,7 @@ describe("home waiting line", () => { | ||
| 365 | 365 | const number = app.db.query<{ issue_seq: number }, [string]>("UPDATE repo SET issue_seq = issue_seq + 1 WHERE id = ?1 RETURNING issue_seq").get(repo.value.id)!.issue_seq; |
| 366 | 366 | app.db |
| 367 | 367 | .query(`INSERT INTO issue (id, repo_id, number, kind, title, body, author_id, state, created_at) VALUES (?1, ?2, ?3, 'pull', ?4, '', ?5, 'open', ?6)`) |
| 368 | .run(issueId, repo.value.id, number, `Stale ${i}`, made.value.id, new Date(Date.now() - h * 3_600_000).toISOString()); | |
| 368 | .run(issueId, repo.value.id, number, title ?? `Stale ${i}`, made.value.id, new Date(Date.now() - h * 3_600_000).toISOString()); | |
| 369 | 369 | app.db |
| 370 | 370 | .query(`INSERT INTO pull (issue_id, base_branch, head_branch, base_oid, head_oid, head_repo_id) VALUES (?1, 'main', ?2, ?3, ?3, ?4)`) |
| 371 | 371 | .run(issueId, `b/${i}`, "0".repeat(40), repo.value.id); |
| @@ -389,7 +389,16 @@ describe("home waiting line", () => { | ||
| 389 | 389 | |
| 390 | 390 | test("three asks show one line linking to /review", async () => { |
| 391 | 391 | const body = await homeWith([30, 40, 50]); |
| 392 | expect(body).toMatch(/<p class="small muted"><a href="\/review">3 waiting on you, oldest 5\d h<\/a><\/p>/); | |
| 392 | expect(body).toMatch(/<p class="small muted break stack stack-tight"><span>3 waiting on you, oldest 5\d h<\/span><a href="\/review">Review them<\/a><\/p>/); | |
| 393 | }, 30_000); | |
| 394 | ||
| 395 | test("a 120-character title with no spaces: the line breaks, the link below, the title stays off home", async () => { | |
| 396 | const long = "x".repeat(120); | |
| 397 | const body = await homeWith([30], long); | |
| 398 | const line = body.slice(body.indexOf('<p class="small muted break'), body.indexOf("Review them</a></p>")); | |
| 399 | expect(line).toMatch(/^<p class="[^"]*\bbreak\b[^"]*\bstack\b/); | |
| 400 | expect(line).toContain('</span><a href="/review">'); | |
| 401 | expect(line).not.toContain(long); | |
| 393 | 402 | }, 30_000); |
| 394 | 403 | |
| 395 | 404 | test("with none, the line is absent", async () => { |
new above
offline