MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-443

6.15.3 Enable the board `[Filter]` seam — mount the builder + saved-filter picker (reuse IssueFilterBar/6.2), URL-driven board-scoped filter state, active chips + Clear, over-cap CTA opens it

Done
Description

Estimate: 34m · Depends on: 6.15.1, 6.15.2, 6.15.5

Replace the disabled [Filter] seam with the working board filter, per the 6.15.1 design, reading through 6.15.2. The reused IssueFilterBar already carries the Work type facet (6.15.5), so the board exposes it automatically — no board-specific filter UI.

Enable the toolbar affordance (app/(authed)/boards/page.tsx — drop disabled + the filterComingSoon tooltip) and mount the SAME filter builder + saved-filter picker the /issues navigator uses (reuse IssueFilterBar + the 6.2 picker — do NOT hand-roll a board-specific filter UI), anchored per the design. URL-driven, board-scoped state: the active filter lives in the URL (a ?filter= AST param and/or a saved-filter id), composing with the existing ?board=<id> selection (the 2.5.19 ?peek / 3.7 board-selection pattern) — shareable + reload-safe, and per board (switching boards does not leak the filter). The board re-projects via 6.15.2 (the read is server-driven; follow the board’s existing fetch path — assert the response before asserting cards, never race the optimistic UI, per CLAUDE.md). Active-filter chips + Clear; the 3.8 OverCapBanner "refine filter" CTA now OPENS the filter (it currently points at the dead seam). Filtered-empty board → the 6.15.1 EmptyState (distinct from the brand-new-board empty state). next-intl en + zh; drop the filterComingSoon key if now unused.

Acceptance criteria

  • The board Filter is enabled; opening it shows the builder + saved-filter picker; applying a filter re-projects the board so each column shows only matching cards; the active filter shows as chips with Clear; the state is URL-addressable, reload-safe, and per-board.
  • The over-cap banner CTA opens the filter; a filter under the cap dismisses the banner; the filtered-empty board shows the EmptyState; on a Scrum board the filter narrows within the active sprint.
  • Matches the 6.15.1 design (reuses IssueFilterBar / the saved-filter picker — no hand-rolled filter UI); colour via --el-*, shape via element tokens; axe-clean; en + zh; component/interaction tests over the filter wiring; pnpm test:coverage ≥ 90%.

Context refs

  • design/boards/board-filter.* (6.15.1 — THE layout authority) + 6.15.2 (the filtered read)
  • app/(authed)/boards/page.tsx (the disabled seam + filterComingSoon), the board toolbar / BoardContainer (the ?board= selection + fetch path), app/(authed)/boards/_components/OverCapBanner.tsx (the 3.8 CTA to wire)
  • app/(authed)/issues/_components/IssueFilterBar.tsx + the 6.2 saved-filter picker (the primitives to reuse) + the 2.5.19 ?peek URL-state pattern
  • motir-core/CLAUDE.md (colour/shape tokens; the "wait on the authoritative signal" rule for the re-project)