Commit Graph

161 Commits

Author SHA1 Message Date
Jason Staack
77e9b680ae feat(19-04): add SNMPMetricsSection component for SNMP profile display
- Shows assigned SNMP profile name with system badge indicator
- Shows profile description when available
- Returns null when no snmpProfileId is assigned
- Fetches profile data via snmpProfilesApi.get
- Foundation for Phase 20 custom OID charting (PROF-03)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 20:05:15 -05:00
Jason Staack
b9f60223fd feat(19-04): make device detail page type-aware with conditional rendering
- Add isRouterOS/isSNMP constants derived from device.device_type
- Guard SimpleModeToggle, SSHTerminal, RollbackAlert, TlsSecurityBadge behind isRouterOS
- Config backup query only fires for RouterOS devices
- SNMP devices get dedicated layout: system info, SNMP profile, interface gauges, groups, tags, alerts
- Header metadata shows SNMP version for SNMP devices, RouterOS version for RouterOS devices

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 20:05:03 -05:00
Jason Staack
caf143532b feat(19-02): create BulkAddForm component for IP list bulk operations
- Credential profile dropdown filtered by device type (routeros/snmp)
- IP textarea parses one-per-line IPv4 addresses with deduplication
- Optional hostname prefix generates numbered names (e.g., tower-ap-01)
- SNMP variant shows SNMP port and device profile selector
- RouterOS variant shows API port and TLS API port fields
- Results display with per-device CheckCircle2/XCircle success/failure icons
- Calls devicesApi.bulkAddWithProfile for backend bulk add endpoint

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:59:34 -05:00
Jason Staack
fbad0e9a56 feat(19-01): add device type icon and filter to fleet table
- Add DeviceTypeIcon component (Router for RouterOS, Network for SNMP)
- Add Type column to desktop table between Status and Hostname
- Add type icon to mobile DeviceCard view
- Show em-dash for RouterOS version on SNMP devices
- Add device type filter dropdown to DeviceFilters (All / RouterOS / SNMP)
- Pass device_type through URL search params to API query
- Update colSpan from 11 to 12 for empty/loading states

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:59:29 -05:00
Jason Staack
74ddaad551 feat(19-02): redesign Add Device dialog with RouterOS, SNMP, and VPN tabs
- Always show three-tab layout (RouterOS, SNMP, VPN) instead of conditional two-tab
- RouterOS tab: credential profile toggle (profile mode vs manual credentials)
- SNMP tab: version selector (v2c/v3), credential profile, device profile, port
- Both tabs have "Add Multiple" toggle to switch to BulkAddForm
- VPN tab renders existing VpnOnboardingWizard unchanged
- All form state resets on dialog close

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:59:24 -05:00
Jason Staack
cd50e617e1 feat(19-03): add credentials route and settings page link
- Create settings.credentials.tsx route using dot-notation pattern matching api-keys
- RBAC guard restricts access to tenant_admin and above
- Super admin org selector integration for multi-tenant support
- Add Credential Profiles card to Settings page under Device Credentials section

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:59:01 -05:00
Jason Staack
af776ea8ff feat(19-03): add credential profiles page and API types
- Create CredentialProfilesPage component with full CRUD for RouterOS and SNMP profiles
- Add credentialProfilesApi types and client to api.ts (blocking dependency from 19-01)
- Profile list grouped by type with device count, edit, and delete actions
- Create/edit dialog with conditional fields per credential type
- SNMPv3 form shows auth/privacy fields based on security_level selection
- Delete confirmation with 409 error handling for linked devices

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:58:02 -05:00
Jason Staack
6b87b88ce4 feat(19-01): extend API client with SNMP types and methods
- Add device_type, snmp_port, snmp_version, snmp_profile_id, credential_profile_id, board_name to DeviceResponse
- Add device_type filter to DeviceListParams
- Add CredentialProfileResponse, CredentialProfileCreate, CredentialProfileUpdate types
- Add credentialProfilesApi with list/get/create/update/delete/devices methods
- Add SNMPProfileResponse type and snmpProfilesApi with list/get methods
- Add BulkAddWithProfile request/result types and devicesApi.bulkAddWithProfile method
- Add SNMPMetricPoint type and metricsApi.snmp method

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:57:02 -05:00
Jason Staack
9c5cf552d9 fix(ui): SSH terminal expanded mode respects sidebar width
Expanded SSH now uses left: var(--sidebar-width) instead of inset-4,
so it fills the content area without covering the sidebar or header.
Styled header/buttons to match Warm Precision.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 16:42:44 -05:00
Jason Staack
dbc8c45914 fix(lint): remove unused imports and variables from redesign
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 16:05:31 -05:00
Jason Staack
106aa0f708 fix(test): update login test to expect MikroTik instead of MSP
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 15:53:46 -05:00
Jason Staack
6e874505eb chore: bump version to 9.7.2 · plain
Warm Precision UI redesign, task-based navigation, interaction system,
website and docs restyled. 30+ commits on warm-precision-redesign
branch, merged to main.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 15:50:29 -05:00
Jason Staack
43309e19ca fix(ui): final cleanup — signal chart hex, checkbox/select tokens
- SignalHistoryChart: #3b82f6 → hsl(var(--accent))
- Checkbox: opacity-50 disabled → text-muted/border-subtle, proper
  focus ring, bg-panel surface, checked text-background
- Select: opacity-50 disabled → text-muted/border-subtle, proper
  focus ring, radius-control, bg-panel, text-xs

Zero old token names, zero blue hex, zero opacity-disabled remaining.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 15:04:43 -05:00
Jason Staack
04af5536c2 feat(ui): add UI scale selector (100% / 110% / 125%)
Three-level zoom control in sidebar footer. Uses CSS zoom property,
persisted to localStorage via Zustand store. Applied on mount via
AppLayout useEffect.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 14:57:04 -05:00
Jason Staack
a3b5fd1848 feat(ui): Needs Attention items link to device, show map icon
- Hostname is now a Link to the device detail page
- MapPin icon shown for devices with coordinates, links to /map
- Hover accent color on both links
- Also fixes tenant-switch query bug and VPN tab colors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 14:49:20 -05:00
Jason Staack
5c9915d175 fix(ui): Needs Attention updates on tenant switch, VPN colors tokenized
- Dashboard fleet query now uses selected tenant ID for super_admin
  instead of always fetching all tenants. Needs Attention, metrics
  strip, and all widgets update when switching tenants.
- VPN tab: replace hardcoded purple/blue/green hex with token colors
- Add Certificates and VPN back to sidebar low-frequency section

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 14:42:49 -05:00
Jason Staack
2da9fe0373 feat(ui): add Certificates and VPN back to sidebar low-frequency section
These were removed during the Operate/Act restructure but are
standalone management pages that need direct nav access.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 14:41:11 -05:00
Jason Staack
4c3b95857a feat(ui): add Needs Attention panel and metrics strip to dashboard
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 14:30:33 -05:00
Jason Staack
86cff80c97 fix(ui): replace hardcoded interface type colors and diff viewer colors
InterfacesPanel: replace Tailwind palette hex (#3B82F6 blue, #8B5CF6
purple, etc.) with token references (accent, info, warning, success,
error). No more blue or purple interface badges.

DiffViewer: replace raw blue/green/red Tailwind classes with token
classes (info, success, error).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 14:00:03 -05:00
Jason Staack
0313909d93 fix(ui): scroll to top when switching device sidebar tabs
Wraps setActiveTab to also scroll #main-content to top. Prevents
stale scroll position when navigating from a long tab (e.g. Firewall)
to a short one (e.g. SNMP).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:54:09 -05:00
Jason Staack
91eea99aca chore(ui): Stage 4 cleanup — delete ContextStrip, fix transition-all,
replace chart hex colors

- Delete ContextStrip.tsx (no longer imported)
- Sidebar: transition-all → transition-[width]
- Charts: replace #38BDF8/#94a3b8/#334155 with token references
- EmergencyKitDialog hex preserved (print template)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:46:09 -05:00
Jason Staack
b8d8abde32 fix(ui): replace hardcoded chart hex colors with Warm Precision tokens
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:45:52 -05:00
Jason Staack
72c09d95bb feat(ui): add error/empty state classes, update toast styling
- Toast: bg-elevated surface, border-default, radius-control, remove
  richColors (use token colors instead of Sonner defaults)
- Add .panel-empty and .panel-error CSS utility classes
- Available for Phase 4 page-level refinement

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:43:56 -05:00
Jason Staack
996ce37a19 feat(ui): add list-item-interactive class, update table row hover
- Add .list-item-interactive CSS class: 2px left border on hover/focus,
  bg-elevated on active press, 50ms transitions
- FleetTable: update hover to bg-elevated/30 with 50ms transition
- Class available for div-based list rows (alerts, events, nav items)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:42:54 -05:00
Jason Staack
17037e4936 feat(ui): replace skeleton loaders with honest loading states
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:40:58 -05:00
Jason Staack
0ee4416077 feat(ui): update Button, Input, Tabs with Warm Precision interaction system
Button: 50ms transitions, accent focus ring at 2px offset, active
brightness darkening, no opacity-based disabled, border-accent hover
on outline variant, gap-1.5 for icon+text, radius-control (4px)

Input: bg-panel surface, border-default, radius-control, 50ms border
transition, accent focus outline at 2px offset, text-xs, no opacity
disabled

Tabs: accent bottom-border + accent-soft wash on active, text-xs,
50ms transitions, text-secondary inactive with hover to primary

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:34:36 -05:00
Jason Staack
8a77e69aa9 fix: change MSP to MikroTik in login and about pages
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:27:35 -05:00
Jason Staack
9bb33f9c67 fix(ui): restore info/teal color for device actions in audit log 2026-03-21 13:22:45 -05:00
Jason Staack
814cf3b1e7 fix(ui): fix device header layout for narrow viewports
Two-row layout: top row is identity (breadcrumb › dot hostname status),
bottom row is metadata left + actions right. Hostname truncates instead
of wrapping. Metadata truncates. Actions stay on one line and push
against the right edge. No overlap at any width.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:18:32 -05:00
Jason Staack
2fd98fece0 fix(ui): increase info token saturation for readability 2026-03-21 13:14:28 -05:00
Jason Staack
357258d1c7 fix(ui): eliminate remaining blue — shift info token to warm teal
- --info light: 217 91% 50% (blue) → 180 20% 40% (desaturated warm teal)
- --info dark: 217 60% 60% (blue) → 180 20% 50% (warm teal)
- Audit log: device_ actions use accent instead of info, firmware uses
  warning instead of raw purple
- Fixes 40+ references to text-info/bg-info across the codebase
  without touching each file — token shift handles them all

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:08:50 -05:00
Jason Staack
8ca00b0301 fix(ui): replace TLS badge with icon-only indicator
Full-text badge ("Plain-Text (Insecure)") replaced with a colored
shield icon — green/yellow/red by TLS mode. Label available on
hover via title attribute. Universal lock convention, no label needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:02:52 -05:00
Jason Staack
329e363b2f fix(ui): declutter device page header — compact tool buttons
- WinBox/RemoteWinBox/SSH: replace big accent CTAs with compact
  bordered tool buttons (text-[10px], h-3 icons, border-default)
- SimpleModeToggle: shrink from pill-button group to inline segmented
  control (text-[10px], accent-soft active state)
- Edit/Delete already icon-only ghost from previous commit
- All tool buttons now visually consistent — small, bordered, receding
- Result: header reads as a compact control strip, not a CTA row

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:55:02 -05:00
Jason Staack
f7b95adfd2 fix(ui): tighten device detail page for control surface feel
- Header: reduce padding, align items-center, dot+label status,
  truncating hostname, compact metadata, version prefixed with v
- Actions: ghost icon buttons for Edit/Delete, tighter gap, smaller icons
- InfoRow: py-2→py-1, text-sm→text-xs, label w-32→w-24, border-subtle
- Data panels: rounded-lg→rounded-sm, p-4→p-3, border-default
- StandardConfigSidebar: tighter rows py-1.5→py-[3px], w-48→w-44,
  accent-soft active bg, text-label section headers, 50ms transitions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:45:31 -05:00
Jason Staack
2e301c9ffa feat(ui): update Card and Badge with Warm Precision styling
Card: rounded-lg → rounded-sm, border-border → border-border-default
Badge: rounded-md → rounded-sm, border-border → border-border-default

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:37:14 -05:00
Jason Staack
5bb8dece44 feat(ui): add device workspace header with breadcrumb and metadata
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:36:29 -05:00
Jason Staack
d08215d524 feat(ui): remove ContextStrip from layout
All ContextStrip features (tenant selector, theme toggle, connection
status, user menu, logout) are now in the sidebar. The top bar is
removed — content area gets the full vertical space.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:21:16 -05:00
Jason Staack
0448982942 feat(ui): rewrite sidebar with task-based Operate/Act navigation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:20:19 -05:00
Jason Staack
298ed89c75 fix(ui): refine dashboard components for Warm Precision tone
- KpiCards: remove gradient/glow, flatten to data-oriented panels
- BandwidthChart: replace hardcoded blue (#38BDF8) with accent token,
  use token colors for axis text and cursor
- QuickActions: replace icon grid with command-style list rows
  with left-border hover interaction
- EventsTimeline: remove timeline/skeleton, tighten to log-stream
  layout with divide separators and monospace timestamps
- Light mode: bump border-default opacity 0.12→0.14, darken
  text-secondary for dense readability

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:04:28 -05:00
Jason Staack
b39014ef47 refactor(ui): migrate all components to Warm Precision token names
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 11:49:37 -05:00
Jason Staack
f7108ba357 feat(ui): update Tailwind config for Warm Precision tokens
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 11:47:09 -05:00
Jason Staack
043d9564ba feat(ui): replace Deep Space tokens with Warm Precision v3.1
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 11:45:27 -05:00
Jason Staack
4092806fbc fix(license): remove unlimited flag, device limit must always be a number
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 22:32:39 -05:00
Jason Staack
fdc8d9cb68 feat(license): add BSL license enforcement with device limit indicator
- Add LICENSE_DEVICES env var (default 250, matches BSL 1.1 free tier)
- Add /api/settings/license endpoint returning device count vs limit
- Header shows flashing red "502/500 licensed" badge when over limit
- About page shows license tier, device count, and over-limit warning
- Nothing is crippled — all features work regardless of device count
- Bump version to 9.7.1

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 22:28:56 -05:00
Jason Staack
11781a822f chore: remove map-assets from tracking, add to .gitignore
Font glyphs and sprite sheets are downloaded per-deploy, not repo content.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 21:49:56 -05:00
Jason Staack
21f2934906 fix(map): revert to Leaflet + proxied OSM tiles, add CPE signal to popups
Reverted from MapLibre/PMTiles to Leaflet with nginx-proxied OSM raster
tiles — the MapLibre approach had unresolvable CSP and theme compat
issues. The proxy keeps all browser requests local (no third-party).

Also:
- Add CPE signal strength and parent AP name to fleet summary SQL
  and map popup cards (e.g. "Signal: -62 dBm to ap-shady-north")
- Add .dockerignore to exclude 8GB PMTiles and node_modules from
  Docker build context (was causing 10+ minute builds)
- Configure mailpit SMTP in dev compose

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 21:47:15 -05:00
Jason Staack
877cb1a55c feat(map): auto-switch map theme with app light/dark toggle
Map theme now follows the app's dark/light mode setting automatically.
Added light sprite assets. Device layers persist across theme switches.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 20:56:43 -05:00
Jason Staack
79899840ca feat(map): self-hosted MapLibre GL + PMTiles vector map
Replace Leaflet + OSM raster tiles with MapLibre GL JS + PMTiles:
- Full continental US vector tiles (8GB PMTiles, zoom 0-14 with overzoom)
- Dark theme via @protomaps/basemaps (official supported path)
- Clustered device markers with status colors (green/yellow/red)
- Popup cards show CPU, memory, wireless client count + avg signal
- Font glyphs proxied through nginx, sprites served locally
- Zero third-party requests from the browser
- Fleet summary SQL now includes wireless client count and avg signal
  via LEFT JOIN LATERAL on wireless_links

Also removes alert toast spam and fixes map container height.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 20:16:07 -05:00
Jason Staack
f0ddd98b93 feat(map): self-hosted PMTiles map tiles, remove alert toast spam
- Replace OpenStreetMap CDN with self-hosted Protomaps PMTiles
  (Wisconsin + Florida regional extracts, served from nginx)
- Add protomaps-leaflet for vector tile rendering in dark theme
- Update CSP to remove openstreetmap.org, add blob: for vector workers
- Add nginx location block for /tiles/ with byte range support
- Mount tiles directory as volume (not baked into image)
- Remove alert_fired/alert_resolved toast notifications that spammed
  "undefined" at fleet scale — dashboard still updates via query invalidation
- Add *.pmtiles to .gitignore (large binaries)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 18:30:08 -05:00
Jason Staack
dffea763f6 fix(sites): fix site CRUD crashes and silent form errors
- Fix AttributeError in sites router: CurrentUser has `user_id` not `id`
  (create/update/delete all crashed with 500)
- Add onError handlers with toast notifications to SiteFormDialog

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:42:58 -05:00