feat: task 2.7 event picker (subscription driver)
- src/data/events.ts: useUserEvents() TanStack Query (5-min stale, sort -starts_at). EventSummary type is a Pick of EventRow. - src/live/active-event.ts: useActiveEventOrchestration() returns the swap fn — unsubscribe previous + clearForEvent + subscribe new + applySnapshot on success + persist to localStorage. Out-of-order safety via per-call version counter. Plus readSavedActiveEventId(). - src/ui/components/event-picker.tsx: <EventPicker> dropdown. useState + click-outside; rows show name + date + discipline. - src/live/index.ts: re-exports active-event helpers. - src/routes/_authed/monitor.tsx: auto-select effect (one-shot via initializedRef, gated on events loaded + WS connected); renders <EventPicker> wired to setActiveEvent. Deviations: 1. Vanilla div + useState dropdown instead of shadcn Popover — no new shadcn primitive add; easy to swap later for keyboard nav. 2. Auto-select gated on connectionStatus === 'connected' so the subscribe call gets the snapshot path (not 'not-connected'). 3. Logout-clears-saved-event-id deferred to a small Phase 1.8 follow-up; documented in task risks. Bundle: 395KB / 120KB gz (~1KB up from 2.6).
This commit is contained in:
@@ -156,11 +156,12 @@ If operators want a longer-trail mode: a slider in the prefs (`50 / 200 / 500 /
|
||||
- **`src/map/core/map-pref-store.ts`** — extended with `trailMode: TrailMode` (`'none' | 'selected' | 'all'`, default `'selected'`) and `setTrailMode`. Persisted via the existing zustand `persist` middleware on `'trm-map-prefs'`.
|
||||
- **`src/map/layers/map-trails.tsx`** — `<MapTrails />` side-effect-only component. Single GeoJSON source + single `'line'` layer. Two-effect pattern (setup + setData on store changes). Reads `trailsByDevice`, `selectedDeviceId`, `trailMode`. Builds one `LineString` Feature per device whose trail has ≥ 2 points; filtered by mode (`none` → empty, `selected` → just the selected device, `all` → every device).
|
||||
- **`src/map/core/trails-toggle.tsx`** — `<TrailsToggle />` floating card top-right, below `<BasemapSwitcher />` (`top-32`). Three buttons (None / Selected / All); active one highlighted via `bg-accent`. Has a small "Trails" label up top.
|
||||
- **`src/routes/_authed/monitor.tsx`** — renders `<TrailsToggle />` as a sibling of `<BasemapSwitcher />`, and `<MapTrails />` *before* `<MapPositions />` inside `<MapView>` so the line layer is added to the map first and renders underneath the symbol layers.
|
||||
- **`src/routes/_authed/monitor.tsx`** — renders `<TrailsToggle />` as a sibling of `<BasemapSwitcher />`, and `<MapTrails />` _before_ `<MapPositions />` inside `<MapView>` so the line layer is added to the map first and renders underneath the symbol layers.
|
||||
|
||||
**Per-device colouring:** flat colour from a 6-entry palette (`#2563C8 / #2E8C4A / #6B46C1 / #188C8A / #C9296F / #5A5A53`) keyed by a deterministic hash of the deviceId. Same device = same colour across reloads. Distinct enough that two trails don't blend. Speed-coloured-per-segment deferred to a Phase 3 polish task per the original task spec's open-question decision.
|
||||
|
||||
**Smoke check (local `pnpm dev`):**
|
||||
|
||||
- `/monitor` shows the trails toggle below the basemap switcher.
|
||||
- Default mode is "Selected" → no trails visible until a device is selected.
|
||||
- Synthetic positions (push 2+ positions for the same deviceId via the console — `usePositionStore.getState().applyPositions(...)`) and the trail polyline appears immediately.
|
||||
|
||||
Reference in New Issue
Block a user