Objective
- Let admin and leadership save and reopen dashboard filter configurations on revenue admin dashboards so repeat analysis does not require re-selecting brands and date ranges every visit.
- Close the workflow gap raised in the June 16 implementation call: users need the same saved-view pattern already available on the Client Care Dashboard.
- Speed up recurring cross-brand revenue reviews (Launchpad Revenue, Post-Inspection Revenue) for ops and leadership.
Background
- June 16 implementation call: users asked to persist brand and filter selections on revenue dashboards the same way other admin dashboard surfaces support saved views — a concrete repeat-analysis gap, not a nice-to-have.
- Client Care Dashboard already ships saved views (ATT-1214 Done): view list at
/admin/client-care-dashboard, per-view routes at /admin/client-care-dashboard/view/[viewId], SaveViewModal, share-to-users, and backend CRUD at cc-dashboard/saved-views (ccDashboardViewSchema, ccDashboardSavedViews.ts).
- Revenue dashboards do not have saved views today:
- Launchpad Revenue —
/admin/launchpad-revenue (LaunchpadRevenueClient.tsx): shared DashboardHeader for company multi-select and timeframe/date range; loads all accessible companies on mount with defaultTimeframe='current-month'. No save/load UI or API.
- Post-Inspection Revenue —
/admin/post-inspection-revenue (PostInspectionRevenueClient.tsx): same DashboardHeader filters plus Propair/Concierge groupBy toggles (weekly / etc.) stored only in component state. Auto-loads all companies on mount with trailing-3-months.
- Both revenue dashboards use the shared filter bar in
attik-frontend/src/app/admin/_components/DashboardHeader.tsx, which already accepts initialFilter for seeding selections (used by CC saved views).
- Related performance work (ATT-1865) proposes defaulting some dashboards to one brand on first load; saved views would let users persist their preferred brand/date combinations once chosen.
Product Decisions
Locked
- Problem — Users doing repeat revenue analysis should not have to manually re-select brands and filters each time they open a dashboard.
- Precedent — Match the Client Care Dashboard saved-view UX (named views, share to subset of users, view picker landing pattern) unless a simpler v1 is explicitly chosen in Open items.
- Primary dashboards in scope — Launchpad Revenue and Post-Inspection Revenue admin dashboards (the revenue surfaces called out in the June 16 call).
- Client Care Dashboard — Already implemented; this work extends the pattern to revenue dashboards, not rebuild CC.
Open
- v1 filter fields — Persist companyIds + timeframe/date range only, or also widget-level state (Post-Inspection
propairGroupBy / conciergeGroupBy; Launchpad Revenue forecast widget view mode pacing / byBrand / table)?
- View picker UX — Full view-list landing page per dashboard (like CC's card grid + "New view"), or inline save/load on the dashboard page only?
- Sharing model — Same as CC: creator assigns
visibleToUserIds, shareable-users endpoint, edit/delete for owner only?
- Data model — Extend
ccDashboardViewSchema with a dashboardType discriminator vs separate schemas/routes per revenue dashboard (launchpad-revenue/saved-views, etc.)?
- Permissions — Gate saved views by existing dashboard view permissions (
admin-launchpad-revenue-view, admin-post-inspection-revenue-view) only, or separate save/share permissions?
- Default on open — When user has saved views, should the dashboard redirect to view picker first (CC pattern) or open last-used view / default filters?
- ATT-1865 interaction — If single-brand default ships first, should new saved views capture that default or whatever the user explicitly selects?
- Launchpad Revenue — Include in v1 alongside Post-Inspection, or Post-Inspection first (June call mentioned "revenue dashboards" plural — confirm both for v1)?
Scope
Backend
- Precedent:
attik-backend/src/models/ccDashboardViewSchema.ts and attik-backend/src/routes/ccDashboardSavedViews.ts — CRUD, company access checks, shareable users, fields: name, companyIds, timeframePreset, fixedStartDate/fixedEndDate, visibleToUserIds, _createdByUserId.
- Gap: No saved-view routes or models for Launchpad Revenue (
adminLaunchpadRevenue.ts) or Post-Inspection Revenue (adminPostInspectionRevenue.ts).
- New or extended API should persist filter payloads the frontend
DashboardHeader already produces: companyIds, startDate, endDate, timeframePreset.
- Optional extension fields for widget state per Open #1.
Frontend
- Launchpad Revenue:
attik-frontend/src/app/admin/launchpad-revenue/ — add saved-view list + view route(s), wire DashboardHeader initialFilter from stored view, save/update/delete UI (reuse or adapt SaveViewModal.tsx, ClientCareViewsClient.tsx patterns from CC dashboard).
- Post-Inspection Revenue:
attik-frontend/src/app/admin/post-inspection-revenue/ — same filter persistence; additionally decide whether propairGroupBy / conciergeGroupBy are stored on the view.
- Shared components to reuse/adapt:
DashboardHeader.tsx, CC dashboard _components/SaveViewModal.tsx, ViewSharePopover.tsx, ViewAccessAvatarStack.tsx, timeframe helpers in client-care-dashboard/_lib/timeframe.ts.
Out of scope (v1 unless expanded)
- Rebuilding Client Care Dashboard saved views (already shipped).
- Tools > Dashboard (per-company instance dashboard — different product surface).
- Backend analytics query changes (filters already accept
companyIds + date range).
- Custom widget layouts or Reports Hub integration.
Done when
- [ ] User can create, name, and save a view on Launchpad Revenue and Post-Inspection Revenue with at least brand/company and date/timeframe selections persisted.
- [ ] User can reopen a saved view and see the dashboard load with those filters applied (via
initialFilter / equivalent).
- [ ] Saved views support sharing to other admin users if product confirms CC parity (Open #3).
- [ ] View discovery UX is implemented per product decision (picker page vs inline — Open #2).
References
- CC saved views (Done): ATT-1214
- Launchpad Revenue build (Done): ATT-1879
- Default company filter (related): ATT-1865
- Backend CC views:
attik-backend/src/routes/ccDashboardSavedViews.ts, ccDashboardViewSchema.ts
- Launchpad UI:
attik-frontend/src/app/admin/launchpad-revenue/LaunchpadRevenueClient.tsx
- Post-Inspection UI:
attik-frontend/src/app/admin/post-inspection-revenue/PostInspectionRevenueClient.tsx
- Shared filter bar:
attik-frontend/src/app/admin/_components/DashboardHeader.tsx
- CC view picker precedent:
attik-frontend/src/app/admin/client-care-dashboard/ClientCareViewsClient.tsx