diff --git a/CHANGELOG.d/1.2.0-analysis-run-opened-member-next-action.md b/CHANGELOG.d/1.2.0-analysis-run-opened-member-next-action.md new file mode 100644 index 000000000..b247d6707 --- /dev/null +++ b/CHANGELOG.d/1.2.0-analysis-run-opened-member-next-action.md @@ -0,0 +1,5 @@ +# 1.2.0 Name the next action on the opened Demo Corp member + +Open Public post from the landed Demo Corp report. The panel says that +post is open and to read Event Lineage, Keyman, and evaluation. Mean θ +stays on the report panel. diff --git a/CHANGELOG.md b/CHANGELOG.md index 0aa82319b..98bd39366 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.2.0] - 2026-08-17 + +### Added + +- Opening **Public post** from the landed Demo Corp report now names + the next action: that post is open from Demo Corp, so read Event + Lineage, Keyman, and evaluation. The opened member is current. Mean + θ stays on the report panel. No TEPP theta is invented. No cutoff + body is invented (ADR 0016). + ## [1.1.0] - 2026-08-17 ### Added diff --git a/CLAUDE.md b/CLAUDE.md index a9b7bfd7c..f73c15501 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -48,5 +48,7 @@ chip name contains `Corporate entity: Demo Corp` and the persisted mean θ. The period-report panel says Demo Corp is the opened grouping and to read its mean θ and member posts, then open a post. Those members land immediately under that next action, ahead of Other Corp -and the week strip. Changing the week first still focuses the report -period field. Mean θ stays on the period-report panel. +and the week strip. Opening Public post names the next action: read +Event Lineage, Keyman, and evaluation on that post. Changing the week +first still focuses the report period field. Mean θ stays on the +period-report panel. diff --git a/docs/adr/0024-seed-period-report-analysis-run.md b/docs/adr/0024-seed-period-report-analysis-run.md index 3a8e29c09..686f89c00 100644 --- a/docs/adr/0024-seed-period-report-analysis-run.md +++ b/docs/adr/0024-seed-period-report-analysis-run.md @@ -55,8 +55,10 @@ focused chip name contains the visible Corporate entity caption and the persisted mean θ. The period-report panel names the next action: read that grouping's mean θ and member posts, then open a post. Those members land immediately under that next action, ahead of other -groupings and the week strip. Mean θ remains on the period-report -panel. Re-seed is idempotent on `demo-report-seed-2026-w02`. +groupings and the week strip. Opening a member post names the next +action: read Event Lineage, Keyman, and evaluation on that post. Mean +θ remains on the period-report panel. Re-seed is idempotent on +`demo-report-seed-2026-w02`. ## References — APA 7th diff --git a/frontend/package.json b/frontend/package.json index 17ae5ab37..887fc38d4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "frontend", "private": true, - "version": "1.1.0", + "version": "1.2.0", "type": "module", "scripts": { "dev": "vite", diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx index fbb93620e..0ffdea3ac 100644 --- a/frontend/src/App.test.tsx +++ b/frontend/src/App.test.tsx @@ -2248,6 +2248,7 @@ describe("App, authenticated", () => { name: /open report post: public post/i, }); expect(member).toHaveTextContent("θ 0.91"); + expect(member).not.toHaveAttribute("aria-current"); const status = screen.getByRole("status"); const demoMean = screen.getByText(/Demo Corp: mean θ 0\.42/); const weekChip = screen.getByRole("button", { name: /open report period 2026-W03/i }); @@ -2255,6 +2256,14 @@ describe("App, authenticated", () => { expect(demoMean.compareDocumentPosition(weekChip) & Node.DOCUMENT_POSITION_FOLLOWING).not.toBe(0); await userEvent.click(member); await waitFor(() => expect(screen.getByText("The full body text.")).toBeInTheDocument()); + expect(member).toHaveAttribute("aria-current", "true"); + expect(screen.getByRole("status")).toHaveTextContent( + "Public post is open from Demo Corp. Read Event Lineage, Keyman, and evaluation on this post.", + ); + expect(screen.getByRole("status")).not.toHaveTextContent("then open a post"); + expect( + screen.getAllByRole("heading", { name: "Event Lineage" }).length, + ).toBeGreaterThanOrEqual(2); } finally { HTMLElement.prototype.scrollIntoView = originalScrollIntoView; } diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 63eb0fc32..191e71dac 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -2110,7 +2110,16 @@ function comparisonChipAccessibleName( return `Compare ${comparisonGroupingTitle(groupingKind, groupingLabel)}, mean θ ${meanTheta.toFixed(2)}`; } -function openedReportNextAction(groupingLabel: string): string { +function openedReportNextAction( + groupingLabel: string, + openedMemberTitle?: string | null, +): string { + if (openedMemberTitle) { + return ( + `${openedMemberTitle} is open from ${groupingLabel}. ` + + "Read Event Lineage, Keyman, and evaluation on this post." + ); + } return ( `${groupingLabel} is the opened grouping. Read its mean θ and member posts below, then open a post.` ); @@ -2140,6 +2149,7 @@ function ReportsPanel({ openedGroupingLabel, onOpenGrouping, landOnComparison, + selectedPostId, }: { accessToken: string; canRebuild: boolean; @@ -2152,6 +2162,7 @@ function ReportsPanel({ openedGroupingLabel?: string | null; onOpenGrouping?: (groupingKey: string, groupingLabel: string) => void; landOnComparison?: boolean; + selectedPostId?: string | null; }) { const [payload, setPayload] = useState(null); const [index, setIndex] = useState(null); @@ -2222,6 +2233,14 @@ function ReportsPanel({ groupingIsOpened(grouping, groupingKey, groupingLabel), ) : []; + const openedMemberTitle = selectedPostId + ? orderedReports + .filter((report) => + groupingIsOpened(grouping, report.grouping_key, report.grouping_label), + ) + .flatMap((report) => report.members) + .find((member) => member.post_id === selectedPostId)?.post_title + : undefined; const reportList = payload === null && !error ? (

Loading reports...

@@ -2271,6 +2290,11 @@ function ReportsPanel({