feat(lists): visible company-scope chip on every list page (MAPPS-321) #346

Merged
David merged 3 commits from fix/MAPPS-321-context-filter-banner into main 2026-06-26 02:36:04 +02:00
Owner

QA report: clicking "View all ..." on a CompanyDetail resource card
(Tickets, Assets, Contracts, Projects, Invoices, Contacts) appeared
to land on the global list rather than the company-scoped one.

Verified the data path was correct:

  • "View all" links pass ?company_id=<uuid> (contacts.rs:1710-2939).
  • Every list page reads current_query_param("company_id") inside its
    use_resource closure and threads it onto the fetch path.
  • Every server-side filter builder branches on filter.company_id.

So the list IS narrowed; the bug is presentation. Each list page
hard-coded PageHeader { title: "Tickets" } (or the equivalent) with
no visible chip indicating the active scope - the user lands, sees a
generic title and N rows, and assumes the filter never applied.

Adds a new shared ContextFilterBanner component:

  • Reads ?company_id= from the URL.
  • Resolves the name via GET /contacts/companies/{id} and renders a
    blue "Scope" badge plus "Showing only {Name}'s {label}." text.
  • A "Clear filter ×" button navigates to the same route without the
    query string (per the ContextFilterScope enum the call site
    passes).
  • Renders nothing when the param is absent or the lookup fails, so
    the ordinary list view is unchanged.

Mounted above the existing filter Card on six list pages:
TicketListPage, AssetListPage, ContractListPage, ProjectListPage,
InvoiceListPage, ContactListPage.

The banner is presentation-only - no changes to the fetch paths or
server filters. Cross-cutting extension to other filter kinds
(?contact_id=, ?asset_id=) is a follow-up; the enum is already
shaped for it.

#MAPPS-321

QA report: clicking "View all ..." on a CompanyDetail resource card (Tickets, Assets, Contracts, Projects, Invoices, Contacts) appeared to land on the global list rather than the company-scoped one. Verified the data path was correct: - "View all" links pass `?company_id=<uuid>` (contacts.rs:1710-2939). - Every list page reads `current_query_param("company_id")` inside its `use_resource` closure and threads it onto the fetch path. - Every server-side filter builder branches on `filter.company_id`. So the list IS narrowed; the bug is presentation. Each list page hard-coded `PageHeader { title: "Tickets" }` (or the equivalent) with no visible chip indicating the active scope - the user lands, sees a generic title and N rows, and assumes the filter never applied. Adds a new shared `ContextFilterBanner` component: - Reads `?company_id=` from the URL. - Resolves the name via `GET /contacts/companies/{id}` and renders a blue "Scope" badge plus "Showing only {Name}'s {label}." text. - A "Clear filter ×" button navigates to the same route without the query string (per the `ContextFilterScope` enum the call site passes). - Renders nothing when the param is absent or the lookup fails, so the ordinary list view is unchanged. Mounted above the existing filter `Card` on six list pages: TicketListPage, AssetListPage, ContractListPage, ProjectListPage, InvoiceListPage, ContactListPage. The banner is presentation-only - no changes to the fetch paths or server filters. Cross-cutting extension to other filter kinds (`?contact_id=`, `?asset_id=`) is a follow-up; the enum is already shaped for it. #MAPPS-321
feat(lists): visible company-scope chip on every list page (MAPPS-321)
All checks were successful
Check / fmt + clippy + tests (pull_request) Successful in 13m33s
7d05c7a147
QA report: clicking "View all ..." on a CompanyDetail resource card
(Tickets, Assets, Contracts, Projects, Invoices, Contacts) appeared
to land on the global list rather than the company-scoped one.

Verified the data path was correct:
- "View all" links pass `?company_id=<uuid>` (contacts.rs:1710-2939).
- Every list page reads `current_query_param("company_id")` inside its
  `use_resource` closure and threads it onto the fetch path.
- Every server-side filter builder branches on `filter.company_id`.

So the list IS narrowed; the bug is presentation. Each list page
hard-coded `PageHeader { title: "Tickets" }` (or the equivalent) with
no visible chip indicating the active scope - the user lands, sees a
generic title and N rows, and assumes the filter never applied.

Adds a new shared `ContextFilterBanner` component:
- Reads `?company_id=` from the URL.
- Resolves the name via `GET /contacts/companies/{id}` and renders a
  blue "Scope" badge plus "Showing only {Name}'s {label}." text.
- A "Clear filter ×" button navigates to the same route without the
  query string (per the `ContextFilterScope` enum the call site
  passes).
- Renders nothing when the param is absent or the lookup fails, so
  the ordinary list view is unchanged.

Mounted above the existing filter `Card` on six list pages:
TicketListPage, AssetListPage, ContractListPage, ProjectListPage,
InvoiceListPage, ContactListPage.

The banner is presentation-only - no changes to the fetch paths or
server filters. Cross-cutting extension to other filter kinds
(`?contact_id=`, `?asset_id=`) is a follow-up; the enum is already
shaped for it.

#MAPPS-321
Merge branch 'main' into fix/MAPPS-321-context-filter-banner
All checks were successful
Check / fmt + clippy + tests (pull_request) Successful in 9m45s
e751b56f9b
Merge branch 'main' into fix/MAPPS-321-context-filter-banner
All checks were successful
Check / fmt + clippy + tests (pull_request) Successful in 16m46s
Create release / Create release from merged PR (pull_request) Has been skipped
9c18c5138b
David merged commit d459f1647d into main 2026-06-26 02:36:04 +02:00
David deleted branch fix/MAPPS-321-context-filter-banner 2026-06-26 02:36:04 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/mokosh-apps!346
No description provided.