Global Filter
Extract app.qpoint.io's global filter into q-nuxt-layer as presentational components (Phase 1), then design and build a v2 segmented-bar redesign (Phase 2).
New in this cycle: Filter v2 — a display-only segmented bar with negation, plus FilterTriggerBar for contextual quick-filtering
Why
app.qpoint.io's filter bar (teleported into the top nav across ~25 pages) is a proven, working component that predates the shared layer. Phase 1 gets the existing implementation into the layer so v2 has a real foundation to iterate on. Phase 2 implements the v2 redesign from mockups, including a new FilterTriggerBar component for contextual quick-filtering and the v2 Filter bar as a segmented control with negation support.
Objective
Phase 1: Extract the presentational Filter namespace and FilterDatasetViewSelector from app.qpoint.io into q-nuxt-layer as Ux-auto-named components (via the components/filter/ directory convention), keeping business logic (route/authStore sync, domain composables) local to app.qpoint.io.
Phase 2: Redesign the Filter bar as a segmented control (empty "Add Filter" pill → populated state as continuous bar with ADD trigger, two-row FilterItem pills, Config button) and build supporting v2 components (FilterItem with negation glyph, FilterInlineEdit restyled, FilterTriggerBar for contextual quick-filtering). Document the full namespace on the design site.
Scope
Phase 1 (Extraction — 2026-09-15):
Source files (app.qpoint.io):
app/components/filter/*.vue: index, Item, InlineEdit, Manage, Embed, Timeframe, ManageItem, DatasetViewSelectorapp/components/ux/TagAutocomplete.vueapp/utils/filters.js
Destination (q-nuxt-layer):
components/filter/*.vue(all presentational components)components/ux/TagAutocomplete.vue- A composable/util for filter-shape logic
Design site:
- New compound
/componentspage for the Filter namespace - Unregistered lab page
design/app/pages/pages/phase2-global-filter.vuefor v2
Phase 2 (v2 Redesign — 2026-09-16):
Source mockups (designs/):
global-filter.png(v2 segmented bar in populated state)bar-trigger.png(FilterTriggerBar contextual variant)filter-in-context.png(both components together)
Build output:
- Phase 1 components moved to
old/namespace in q-nuxt-layer (components/filter/old/*.vue, auto-registered as FilterOld*, preserving original behavior for backward compat while v2 hardens) - New v2 components under live names:
Filter(segmented bar),FilterItem(two-row pill with negation),FilterInlineEdit(restyled typeahead),FilterTriggerBar(new — contextual quick-filter bar) - Unchanged components:
FilterDatasetViewSelector, leveraging existing FilterOldEmbed/FilterOldManage for Embed and Config modes (no v2 design yet) - New asset:
FilterEndcapPlaceholder(checkerboard standins for manual SVG endcap art later) - Design site: demo files for all v2 and legacy components, updated
/componentswith newfilter-oldgroup, lab pagephase2-global-filter.vuedemonstrating two-way sync pattern
Explicitly NOT in scope:
- Swapping app.qpoint.io's live pages to consume the layer components (separate step after release)
- v2 redesign of FilterManage modal (Config button still opens FilterOldManage; no design exists yet for modal v2)
- Sticky positioning or collision-avoidance with NavJumpPills (strategy documented; implementation owned by consumer pages, not the component itself)
Key Changes
Phase 1 extraction (2026-09-15): All 8 components extracted into q-nuxt-layer/components/filter/: Filter, FilterItem, FilterInlineEdit, FilterManage, FilterEmbed, FilterTimeframe, FilterManageItem, FilterDatasetViewSelector — plus q-nuxt-layer/utils/filter.ts for filter-shape constants/types. During extraction, discovered FilterTimeframe and FilterManage embedded business logic (Pinia store, route/org composables) not visible from names alone; decoupled into props/emits, business logic left local. DatasetViewSelector similarly decoupled. TagAutocomplete.vue found to be dead code (hardcoded dummy component) and excluded rather than moved. All 8 documented on the design site with new filter group in component-registry.ts, demo files under app/pages/components/_demos/, live at /components/filter/*. Built v2 lab workspace page app/pages/pages/phase2-global-filter.vue (unregistered, composes real Phase-1 components). Verified via local dev server — all new pages render without console warnings/errors. Decisions recorded in plan.md.
Phase 2 redesign (2026-09-16): Implemented v2 segmented-bar Filter and supporting components per mockup set: Phase-1 components moved into q-nuxt-layer/components/filter/old/ namespace (auto-registered as FilterOld*, FilterOldDatasetViewSelector) with internal cross-references rewritten; new v2 Filter rebuilt as segmented control (empty "Add Filter" pill, populated state as continuous bar with ADD trigger, two-row FilterItem pills, Config button); new FilterItem with italic key + bold value split across two rows, replaced "!=" text with slash-circle negation glyph; FilterInlineEdit restyled into two-row chrome with same typeahead behavior; FilterDatasetViewSelector built unchanged under live name (unchanged component); new FilterTriggerBar component (contextual quick-filter bar with optional key-select dropdown + single-select value pills). Reused existing q-nuxt-layer assets for icons (gear.svg for Config, no.svg for negation glyph—no new icon assets needed). Updated app/data/component-registry.ts: new filter-old group (id, label "Filter (Legacy)", description), v2 entries added for Filter/FilterItem/FilterInlineEdit/FilterTriggerBar under filter group, Phase-1 entries renamed to FilterOld* under filter-old group. Created demo files: 8 Phase-1 demos renamed to FilterOld*.vue, FilterDatasetViewSelector.vue copied to FilterOldDatasetViewSelector.vue, new demos for Filter.vue/FilterItem.vue/FilterInlineEdit.vue/FilterTriggerBar.vue. Rewrote lab page phase2-global-filter.vue demonstrating v2 Filter alongside FilterTriggerBar wired to same shared keyValFilters ref, proving two-way sync pattern. Left for future: v2 redesign of FilterManage modal (Config still opens FilterOldManage), sticky positioning behavior (strategy recommendations captured; consumer-owned implementation). Verified all new/updated pages via local dev server — all render 200 with no console/icon-resolution errors, screengrabs captured to public/cycles/c88.global-filter/.
Phase 2 formalized as a site-wide bucket (2026-09-17): The design site's own /pages index had a single "Phase 2" card pointing at c85's unrelated phase2-chat-transcript.vue — a naming collision with this cycle's own "Phase 2 redesign" work. Resolved by relocating: c85's chat-transcript moved into app/pages/pages/phase1/chat-transcript.vue (registered phase: 'phase1', sessions group — it was always phase1-world-adjacent, not a v2 redesign), and this cycle's lab page moved from the flat phase2-global-filter.vue to app/pages/pages/phase2/global-filter.vue, the first page under a proper phase2 bucket. Added 'phase2' to PagePhase, a pageHref branch (/pages/phase2/<slug>), a phase2 pageGroup, and a new app/pages/pages/phase2/index.vue landing page (mirrors phase1/index.vue's tone, lists every phase: 'phase2' registry entry — no Linear-tracked plan needed since Phase 2 has none). /pages' Phase 2 card now points at /pages/phase2 and describes it as "v2 redesigns of components already extracted in Phase 1" rather than naming chat-transcript.
Outcome
Phase 1 and Phase 2 complete. The global filter has been successfully extracted into q-nuxt-layer with both legacy (FilterOld*) and new v2 components (Filter, FilterItem, FilterInlineEdit, FilterTriggerBar) fully implemented and documented on the design site.
Deliverables:
- Phase-1 components archived in
q-nuxt-layer/components/filter/old/namespace, backward-compatible - v2 redesigned Filter bar (segmented control) shipping under live Filter name with negation support
- New FilterTriggerBar component for contextual quick-filtering
- All 12 components (8 legacy + 4 v2) with demo pages on
/components/filterand/components/filter-old - Lab page at
/pages/phase2/global-filter(2026-09-17: relocated from the flatphase2-global-filter.vue, now the seed of the formal/pages/phase2landing page) demonstrating two-component integration and state-sync pattern
Next steps:
Merge v2 components into q-nuxt-layer release— shipped in q-nuxt-layer 0.9.13 (2026-09-18)- Swap app.qpoint.io's live pages to consume v2 Filter when layer is published
- v2 redesign of FilterManage modal when design direction is set
- Manual SVG endcap art to replace FilterEndcapPlaceholder checkerboard standins
Visual record
10 captures — heroes, page slices, and full-page renders. Click to view.









