feat(webapp): attach chart-specific filters and refine netflow controls (#31)

<!-- greptile_comment -->

<h3>Greptile Summary</h3>

This PR relocates chart-specific filter controls (metric toggles, router/address-type selectors, chart type picker) from the centralized `PrimaryFilters` panel into each individual chart component (`IPChart`, `ProtocolChart`, `SpectrumStatsChart`, `NetflowDashboard`). The `PrimaryFilters` component is simplified to only manage shared concerns: date range, granularity, router selection, and a new "Reset View" button.

- **Decentralized chart filters**: Each chart now owns its relevant filter UI (metric checkboxes, router radio buttons, address type selectors) and dispatches change events upward to `+page.svelte`.
- **`MetricSelector` extended**: Absorbs the chart type dropdown previously in `ChartControls`, which is now unused and can be removed.
- **`PrimaryFilters` slimmed**: Removes ~90 lines of chart-specific controls and adds a `resetView` event/button.
- **`+page.svelte` wiring**: New event handlers (`on:metricsChange`, `on:dataOptionsChange`, `on:routerChange`, `on:addressTypeChange`) connect the chart-local controls to page-level state. Adds `availableSpectrumRouters` derived state.
- **Formatting**: Minor Tailwind class reordering and multi-line formatting of drag-handle markup across all chart components.

<h3>Confidence Score: 4/5</h3>

- This PR is a clean UI restructuring with low risk; the main concern is the previously-flagged address type re-render bug in SpectrumStatsChart.
- The refactoring correctly moves filter controls into their respective chart components with proper event dispatch wiring. No new logic bugs were introduced. The one pre-existing issue (address type change not triggering re-render in SpectrumStatsChart) was already flagged in a prior review. Minor cleanup opportunity with the now-unused ChartControls component.
- netflow-webapp/src/lib/components/charts/SpectrumStatsChart.svelte (pre-existing address type re-render issue), netflow-webapp/src/lib/components/charts/ChartControls.svelte (dead code to remove)

<h3>Important Files Changed</h3>




| Filename | Overview |
|----------|----------|
| netflow-webapp/src/lib/components/charts/IPChart.svelte | Adds inline metric toggle checkboxes and dispatches `metricsChange` event to parent. Clean implementation consistent with existing patterns. |
| netflow-webapp/src/lib/components/charts/ProtocolChart.svelte | Adds inline metric toggle checkboxes and dispatches `metricsChange` event. Mirrors IPChart pattern. |
| netflow-webapp/src/lib/components/charts/SpectrumStatsChart.svelte | Moves router and address type selectors inline. Adds `availableRouters` prop and dispatches `routerChange`/`addressTypeChange` events. Address type change re-render bug flagged in prior review. |
| netflow-webapp/src/lib/components/filters/MetricSelector.svelte | Extended with optional `chartType` prop and `onChartTypeChange` callback for chart type selection, previously in ChartControls. |
| netflow-webapp/src/lib/components/filters/PrimaryFilters.svelte | Significantly simplified by removing chart-specific filter state and controls. Now only manages date, granularity, routers, and a new Reset View button. |
| netflow-webapp/src/lib/components/netflow/NetflowDashboard.svelte | Replaces ChartControls with MetricSelector for inline data option and chart type management. Dispatches `dataOptionsChange` up to page. Removes reset/groupBy handlers that moved to PrimaryFilters. |
| netflow-webapp/src/routes/+page.svelte | Wires up new chart-specific events (`metricsChange`, `dataOptionsChange`, `routerChange`, `addressTypeChange`). Adds `handleResetView` and `availableSpectrumRouters` derived state. Simplifies PrimaryFilters prop surface. |

</details>



<h3>Flowchart</h3>

```mermaid
%%{init: {'theme': 'neutral'}}%%
flowchart TD
    Page["+page.svelte\n(Page-level state)"]
    PF["PrimaryFilters\n(Date, Granularity, Routers, Reset)"]
    NF["NetflowDashboard\n(MetricSelector + ChartContainer)"]
    IP["IPChart\n(Inline metric checkboxes)"]
    Proto["ProtocolChart\n(Inline metric checkboxes)"]
    Spec["SpectrumStatsChart\n(Inline router + address type radios)"]

    Page -->|"startDate, endDate, groupBy, routers"| PF
    PF -->|"on:resetView, on:groupByChange, on:routersChange"| Page

    Page -->|"dataOptions, routers, dates, groupBy"| NF
    NF -->|"on:dataOptionsChange, on:dateChange, on:groupByChange"| Page

    Page -->|"ipMetrics, routers, dates, granularity"| IP
    IP -->|"on:metricsChange, on:dateChange, on:groupByChange"| Page

    Page -->|"protocolMetrics, routers, dates, granularity"| Proto
    Proto -->|"on:metricsChange, on:dateChange, on:groupByChange"| Page

    Page -->|"router, addressType, availableRouters, dates, granularity"| Spec
    Spec -->|"on:routerChange, on:addressTypeChange, on:dateChange, on:groupByChange"| Page
```

<sub>Last reviewed commit: c8a815a</sub>

<!-- greptile_other_comments_section -->

**Context used:**

- Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=7aea0312-a002-45e6-8e0a-d2380aa2087c))
- Context from `dashboard` - .cursor/rules/svelte.mdc ([source](https://app.greptile.com/review/custom-context?memory=591a6ea0-1733-46da-9c1e-60a7c778920e))

<!-- /greptile_comment -->
4d64ad11bdoliver committed on 2/18/2026, 9:41:21 AM· committed by GitHubparents8e7e8451cd0193
7 files changedLine totals unavailable