You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The hide-drafts checkbox added in #1435 (PR #1436) is visually disconnected from the existing mode filter chips (All / Manual / Automatic). The checkbox sits in its own row below the chip group, creating an inconsistent two-element treatment for what users perceive as the same kind of filter (toggle which diary entries are shown). Users would expect a unified chip-based interface for the two filter axes.
Expected
A 4th chip labeled "Drafts" sits inline with the existing mode chips (All / Manual / Automatic) inside the Filter Mode group. The chip:
Is independently togglable — it is NOT part of the mode group's exclusive (radio) selection. The mode group remains an exclusive single-select; Drafts is a separate axis.
Is active (pressed) by default — meaning drafts are visible.
When clicked while active, becomes unpressed AND the URL gains ?status=saved AND drafts are hidden.
When clicked while unpressed, becomes pressed AND the status URL param is removed AND drafts become visible again.
Uses a visually muted color compared to the mode chips (lower contrast / secondary token) so users can perceive at a glance that it operates on a different filter axis from All/Manual/Automatic.
Actual
A <input type=\"checkbox\"> with <label>Hide drafts</label> sits in its own row (.hideDraftsRow, grid-column: 1 / -1) below the mode chips. Different visual treatment, different interaction model, spatially separated.
Reproduction
Navigate to /diary.
Observe the filter bar: three mode chips (All, Manual, Automatic) with rounded-pill chip styling, then a separate row with a checkbox + label Hide drafts.
Note the inconsistency: mode chips and the hide-drafts toggle have different visual treatments despite both being filter controls.
Acceptance Criteria
AC1 — Given the user is on /diary, when the filter bar renders, then four chips appear inline in the Filter Mode group in this order: All, Manual, Automatic, Drafts. The previous Hide drafts checkbox row is removed (no separate .hideDraftsRow block).
AC2 — Given the user navigates to /diary with no ?status URL param, then the Drafts chip is rendered in its pressed/active state (aria-pressed=\"true\").
AC3 — Given the Drafts chip is active, when the user clicks it, then the chip becomes unpressed AND the URL gains ?status=saved AND draft entries are hidden from the list.
AC4 — Given the Drafts chip is unpressed (URL has ?status=saved), when the user clicks it, then the chip becomes pressed AND the status URL param is removed AND draft entries become visible again.
AC5 — Given any combination of mode chip + Drafts chip state, when the user clicks a mode chip (All/Manual/Automatic), then the Drafts chip's pressed/unpressed state does NOT change; and vice versa (clicking Drafts does NOT change the active mode chip). The two filter axes are independent.
AC6 — The Drafts chip uses a visually muted color in both pressed and unpressed states compared to the mode chips (e.g., the active state uses a secondary/tertiary palette token rather than --color-primary) so that users can perceive the two-axis distinction at a glance. Specific token choice is delegated to ux-designer; the requirement is that the contrast/intensity is visibly lower than the mode chips.
AC7 — The Drafts chip is keyboard-accessible: Tab focuses it, Enter/Space toggles it, the :focus-visible style matches the other chips (--shadow-focus-subtle). It uses aria-pressed (true/false) for screen readers.
Notes
Scope: frontend-only. No API, schema, routing, or backend changes. URL contract (?status=saved to hide drafts) is unchanged.
i18n: Rename the i18n key filterBar.hideDrafts to filterBar.draftsChip (or similar — dev-team-lead to pick the final name). English value becomes \"Drafts\". Translator updates the German file (existing value \"Entwürfe ausblenden\" becomes \"Entwürfe\").
Test IDs: The new chip has data-testid=\"status-filter-drafts\" (replacing data-testid=\"hide-drafts-checkbox\"). All test callers must be updated:
e2e/tests/diary/diary-drafts.spec.ts (uses diaryPage.hideDraftsCheckbox — locator needs to be updated to a chip locator with aria-pressed assertions instead of toBeChecked())
Default state: Active = drafts visible (this matches the previous default of "checkbox unchecked = drafts visible" — the user-perceived default is unchanged).
Component props: The DiaryFilterBar prop names (hideDrafts, onHideDraftsChange) can stay as-is internally since they correctly model the URL semantics; or be renamed to draftsVisible / onDraftsVisibleChange for clarity. Dev-team-lead decides.
client/src/components/diary/DiaryFilterBar/DiaryFilterBar.module.css — .modeChip/.modeChipActive to mirror for the new chip variant, .hideDraftsRow/.hideDraftsLabel/.hideDraftsToggle to remove.
client/src/pages/DiaryPage/DiaryPage.tsx — line 193 (hideDrafts derivation) and the prop passthrough on line 257 stay as-is.
client/src/i18n/en/diary.json and client/src/i18n/de/diary.json — line 36 (hideDrafts key rename + value update).
[product-owner]
Problem
The hide-drafts checkbox added in #1435 (PR #1436) is visually disconnected from the existing mode filter chips (
All/Manual/Automatic). The checkbox sits in its own row below the chip group, creating an inconsistent two-element treatment for what users perceive as the same kind of filter (toggle which diary entries are shown). Users would expect a unified chip-based interface for the two filter axes.Expected
A 4th chip labeled "Drafts" sits inline with the existing mode chips (
All/Manual/Automatic) inside theFilter Modegroup. The chip:?status=savedAND drafts are hidden.statusURL param is removed AND drafts become visible again.All/Manual/Automatic.Actual
A
<input type=\"checkbox\">with<label>Hide drafts</label>sits in its own row (.hideDraftsRow,grid-column: 1 / -1) below the mode chips. Different visual treatment, different interaction model, spatially separated.Reproduction
/diary.All,Manual,Automatic) with rounded-pill chip styling, then a separate row with a checkbox + labelHide drafts.Acceptance Criteria
/diary, when the filter bar renders, then four chips appear inline in theFilter Modegroup in this order:All,Manual,Automatic,Drafts. The previousHide draftscheckbox row is removed (no separate.hideDraftsRowblock)./diarywith no?statusURL param, then theDraftschip is rendered in its pressed/active state (aria-pressed=\"true\").Draftschip is active, when the user clicks it, then the chip becomes unpressed AND the URL gains?status=savedAND draft entries are hidden from the list.Draftschip is unpressed (URL has?status=saved), when the user clicks it, then the chip becomes pressed AND thestatusURL param is removed AND draft entries become visible again.All/Manual/Automatic), then theDraftschip's pressed/unpressed state does NOT change; and vice versa (clickingDraftsdoes NOT change the active mode chip). The two filter axes are independent.Draftschip uses a visually muted color in both pressed and unpressed states compared to the mode chips (e.g., the active state uses a secondary/tertiary palette token rather than--color-primary) so that users can perceive the two-axis distinction at a glance. Specific token choice is delegated toux-designer; the requirement is that the contrast/intensity is visibly lower than the mode chips.Draftschip is keyboard-accessible:Tabfocuses it,Enter/Spacetoggles it, the:focus-visiblestyle matches the other chips (--shadow-focus-subtle). It usesaria-pressed(true/false) for screen readers.Notes
?status=savedto hide drafts) is unchanged.filterBar.hideDraftstofilterBar.draftsChip(or similar — dev-team-lead to pick the final name). English value becomes\"Drafts\". Translator updates the German file (existing value\"Entwürfe ausblenden\"becomes\"Entwürfe\").data-testid=\"status-filter-drafts\"(replacingdata-testid=\"hide-drafts-checkbox\"). All test callers must be updated:client/src/components/diary/DiaryFilterBar/DiaryFilterBar.test.tsx(Scenarios 12–16 in the "hideDrafts checkbox (Story BUG: Diary UX rough edges after #1426 — auto-draft on type select, photo grid refresh, status filter #1435)" describe block)client/src/pages/DiaryPage/DiaryPage.test.tsx(Scenarios 9–11 in the "hideDrafts checkbox integration (Story BUG: Diary UX rough edges after #1426 — auto-draft on type select, photo grid refresh, status filter #1435)" describe block)e2e/tests/diary/diary-drafts.spec.ts(usesdiaryPage.hideDraftsCheckbox— locator needs to be updated to a chip locator witharia-pressedassertions instead oftoBeChecked())e2e/pages/DiaryPage.ts(page objecthideDraftsCheckboxlocator + JSDoc reference)DiaryFilterBarprop names (hideDrafts,onHideDraftsChange) can stay as-is internally since they correctly model the URL semantics; or be renamed todraftsVisible/onDraftsVisibleChangefor clarity. Dev-team-lead decides.Files to Inspect
client/src/components/diary/DiaryFilterBar/DiaryFilterBar.tsx— lines 22–23, 82–83, 137–169 (mode chip group), 246–260 (checkbox block to remove).client/src/components/diary/DiaryFilterBar/DiaryFilterBar.module.css—.modeChip/.modeChipActiveto mirror for the new chip variant,.hideDraftsRow/.hideDraftsLabel/.hideDraftsToggleto remove.client/src/pages/DiaryPage/DiaryPage.tsx— line 193 (hideDraftsderivation) and the prop passthrough on line 257 stay as-is.client/src/i18n/en/diary.jsonandclient/src/i18n/de/diary.json— line 36 (hideDraftskey rename + value update).Co-Authored-By: Claude product-owner (Opus 4.6) noreply@anthropic.com