feat(inbox): migrate to <FilterBar> — t-paliad-163 Slice 3

/inbox is the first surface to consume the universal FilterBar. The
two-tab UI collapses into the bar's approval_viewer_role chip cluster
(per Q4 lock-in 2026-05-08 21:47); status / entity_type / time chips
are new affordances; density toggle gives the activity-feed look the
brief asked for.

Changes:
- system_views.go: InboxSystemView + InboxRequesterSystemView render
  spec gains RowAction=approve so shape-list.ts knows which row
  layout to stamp (entity title + diff + approve/reject/revoke).
- shape-list.ts: row_action='approve' branch — stamps the inbox-row
  markup the surface owned today; surface attaches click handlers
  via data-attrs on .views-approval-action / .views-approval-row.
- inbox.tsx: tab row replaced with <div id='inbox-filter-bar'> +
  <div id='inbox-results'>. Heading + admin nudge unchanged.
- client/inbox.ts: shrunk to mountFilterBar with axes [time,
  approval_viewer_role, approval_status, approval_entity_type,
  density, sort]. Action handlers run via fetch + bar.refresh().
  Legacy ?tab=mine -> ?a_role=self_requested redirect on mount so
  bookmarks / sidebar bell still land on the right sub-view.

Build clean: bun run build + go build/vet/test all pass.
This commit is contained in:
m
2026-05-08 21:59:44 +02:00
parent de4e133f03
commit 4670cd660a
4 changed files with 361 additions and 294 deletions

View File

@@ -101,8 +101,13 @@ func EventsSystemView() SystemView {
}
// InboxSystemView returns the SystemView definition for /inbox — the
// 4-eye approval surface (the "Zur Genehmigung" tab). The "Meine
// Anfragen" tab is a sibling spec resolved by tab-state on the page.
// 4-eye approval surface (the "Zur Genehmigung" view). The "Eigene
// Anfragen" sibling view is selected via the bar's
// approval_viewer_role axis (chip cluster on the same surface).
//
// RowAction = RowActionApprove → shape-list.ts renders the approval
// row layout (entity title + diff + approve/reject/revoke buttons)
// and the surface wires action handlers via the rendered data-attrs.
func InboxSystemView() SystemView {
return SystemView{
Slug: "inbox",
@@ -122,14 +127,17 @@ func InboxSystemView() SystemView {
Render: RenderSpec{
Shape: ShapeList,
List: &ListConfig{
Density: DensityComfortable,
Sort: SortDateAsc,
Density: DensityComfortable,
Sort: SortDateAsc,
RowAction: RowActionApprove,
},
},
}
}
// InboxRequesterSystemView is the "Meine Anfragen" tab of /inbox.
// InboxRequesterSystemView is the "Eigene Anfragen" sibling view of
// /inbox. Reachable via the bar's approval_viewer_role chip ("Eigene
// Anfragen") on the /inbox surface, or as its own URL on /views/inbox-mine.
func InboxRequesterSystemView() SystemView {
return SystemView{
Slug: "inbox-mine",
@@ -148,8 +156,9 @@ func InboxRequesterSystemView() SystemView {
Render: RenderSpec{
Shape: ShapeList,
List: &ListConfig{
Density: DensityComfortable,
Sort: SortDateAsc,
Density: DensityComfortable,
Sort: SortDateAsc,
RowAction: RowActionApprove,
},
},
}