fix(ui): disambiguate dashboard quick-add menu items

Phase-3 e2e suite documented an i18n collision: the dashboard's
quick-entry dropdown trigger says "Add" and both menu items underneath
also rendered the bare verb "Add" because `measurements.addMeasurement`
and `mood.addEntry` both translate to "Add". Screen-reader users heard
two indistinguishable rows; the e2e spec was forced to use
`getByRole("menuitem").first()` as a workaround.

The dropdown trigger already says "Add" — the menu items label what's
being added.

  - Add `dashboard.quickAddMeasurement` ("Measurement" / "Messung")
  - Add `dashboard.quickAddMood` ("Mood entry" / "Stimmungseintrag")
  - Wire the two `<DropdownMenuItem>`s on `/`
  - Mark the leading icons `aria-hidden` so the accessible name is
    just the noun
  - Update `e2e/measurement-flow.spec.ts` to target the menu item by
    name (`/measurement|messung/i`) instead of `.first()`

Dialog titles still use the existing `addMeasurement` / `addEntry`
keys — those work in the larger dialog context where "Add" reads fine.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Marc-André BombeckandClaude Opus 4.7 committed 2026-05-09 17:22:08 +02:00
1 parent 569300eaca
commit e3a689954b
4 files changed
+18 -12

No files matched your search

+6 -8
View File
@@ -101,14 +101,12 @@ test.describe("add measurement flow", () => {
.first()
.click();
// The Radix DropdownMenu mounts its content in a portal; the role
// is `menuitem`. Both items currently render the literal "Add" in
// EN (measurements.addMeasurement = "Add", mood.addEntry = "Add"),
// so we disambiguate by hitting the FIRST one — that's the
// measurement entry per the dashboard JSX order. Sub-optimal, but
// robust against the i18n collision we don't want to fix in this
// phase (would touch dashboard copy).
await page.getByRole("menuitem").first().click();
// v1.5 phase-5: the menu items now have distinct labels — the
// measurement entry says "Measurement" / "Messung" instead of "Add",
// so we can target it directly.
await page
.getByRole("menuitem", { name: /measurement|messung/i })
.click();
// Form should be visible inside the dialog. Switch type to WEIGHT
// (combo-box defaults to BLOOD_PRESSURE).
+2
View File
@@ -216,6 +216,8 @@
"trendDown": "fallend",
"trendStable": "stabil",
"quickEntry": "Schnelleingabe",
"quickAddMeasurement": "Messung",
"quickAddMood": "Stimmungseintrag",
"addMeasurement": "Messwert hinzufügen",
"compliance7d": "Einnahmetreue (7 Tage)",
"complianceGood": "Gut",
+2
View File
@@ -216,6 +216,8 @@
"trendDown": "falling",
"trendStable": "stable",
"quickEntry": "Quick entry",
"quickAddMeasurement": "Measurement",
"quickAddMood": "Mood entry",
"addMeasurement": "Add measurement",
"compliance7d": "Compliance (7 days)",
"complianceGood": "Good",
+8 -4
View File
@@ -373,15 +373,19 @@ export default function DashboardPage() {
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{/* v1.5 phase-5: the menu items used to share the literal label
"Add" with the dialog titles, so screen-reader users heard
two indistinguishable "Add" rows in the same dropdown. The
trigger already says "Add" — these label what's being added. */}
<DropdownMenuItem
onClick={() => setQuickEntryDialog("measurement")}
>
<Activity className="mr-2 h-4 w-4" />
{t("measurements.addMeasurement")}
<Activity className="mr-2 h-4 w-4" aria-hidden="true" />
{t("dashboard.quickAddMeasurement")}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setQuickEntryDialog("mood")}>
<Waves className="mr-2 h-4 w-4" />
{t("mood.addEntry")}
<Waves className="mr-2 h-4 w-4" aria-hidden="true" />
{t("dashboard.quickAddMood")}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>