Commit Graph

176 Commits

Author SHA1 Message Date
Jason Staack
b1ac1cce24 feat: v9.8.1 pre-built Docker images and GHCR release workflow
Setup.py now asks whether to pull pre-built images from GHCR
(recommended) or build from source. Pre-built mode skips the
15-minute compile step entirely.

- Add .github/workflows/release.yml (builds+pushes 4 images on tag)
- Add docker-compose.build.yml (source-build overlay)
- Switch docker-compose.prod.yml from build: to image: refs
- Add --build-mode CLI arg and wizard step to setup.py
- Bump version to 9.8.1 across all files
- Document TOD_VERSION env var in CONFIGURATION.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 18:33:12 -05:00
Jason Staack
0c1ffe0e39 fix(ci): resolve all lint and test failures
- Go: nil-safe profile cache in SNMPCollector, updated test assertion
- ESLint: fix conditional useQuery hook in SNMPMetricsSection
- ESLint: remove unused CREDENTIAL_TYPE_LABELS, ChevronDown/Right,
  EmptyState import, advancedOpen state
- TypeScript: replace empty interface with type alias

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 17:45:06 -05:00
Jason Staack
9f1a533154 fix(lint): remove unused snmpDiscoverResult, fix useCallback deps
- Remove unused snmpDiscoverResult state and ProfileTestResponse import
- Wrap handleDeviceClick in useCallback, add to Enter shortcut deps

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 08:51:27 -05:00
Jason Staack
f47438a5a5 feat(ui): add delete button to fleet table rows
Trash icon appears on row hover. Confirms before deleting.
Both virtual and non-virtual row renderers have group/row
class for the hover-to-show pattern.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 08:21:51 -05:00
Jason Staack
d2f48552bd fix(ui): handle unwrapped credential profile arrays in AddDevice and BulkAdd
The list API now returns a flat array but AddDeviceForm and BulkAddForm
still accessed .profiles on the result. Now handles both shapes with
Array.isArray fallback for safety.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 08:04:44 -05:00
Jason Staack
7dc941e467 fix(ui): fix credential profile field names and list response unwrapping
- credentialProfilesApi.list now unwraps {profiles: [...]} wrapper
- CredentialProfilesPage handles both array and wrapped responses
- Renamed privacy_protocol → priv_protocol to match backend schema
- Renamed privacy_passphrase → priv_passphrase to match backend
- Renamed security_name → username (SNMPv3 uses username field)
- Removed security_name from CredentialProfileCreate type

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 07:50:35 -05:00
Jason Staack
cffe12bf53 fix(ui): correct SNMP protocol values and simplify add-device flow
- Add missing fields to SNMPProfileResponse (sys_object_id, vendor, category, tenant_id)
- Fix security level values to snake_case (no_auth_no_priv, auth_no_priv, auth_priv) matching backend
- Fix auth protocols to SHA256/SHA384/SHA512 (was MD5/SHA/SHA256)
- Fix privacy protocols to AES128/AES256 (was DES/AES/AES256)
- Apply same protocol fixes to ProfileTestPanel
- Fix BulkAddForm to show both v2c and v3 credential profiles (was hardcoded to v2c)
- Simplify SNMP tab in AddDeviceForm to IP + credential profile + discover-and-add button
- Show guidance link when no SNMP credential profiles exist

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 01:13:06 -05:00
Jason Staack
38f33eb550 fix(ui): unwrap SNMPProfileListResponse wrapper in API client
The list endpoint returns {profiles: [...]} but the client expected
a flat array. Now correctly unwraps r.data.profiles.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 00:56:25 -05:00
Jason Staack
f7aa685a5d refactor(ui): redesign SNMP profile editor for progressive disclosure
The profile editor was dumping everything on one page — MIB upload,
OID tree, poll groups, test panel — overwhelming for anyone who
doesn't live and breathe SNMP. Redesigned with tabbed layout:

- Basics tab: name, category, description (the 95% case)
- OIDs tab: flat table of what's collected, simple manual add
- Advanced tab: MIB upload, OID tree browser, auto-detection
- Test tab: test profile against live device (edit mode only)

Also added Clone action on built-in profiles — the primary way
to create a custom profile. Most users should never need the
Advanced tab at all.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 00:41:16 -05:00
Jason Staack
4c21539e40 fix(ui): add Outlet to settings layout for child route navigation
Settings child routes (credentials, snmp-profiles, api-keys) were not
rendering because the parent settings.tsx had no Outlet. Now detects
child routes and renders Outlet, or shows SettingsPage index.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 00:03:53 -05:00
Jason Staack
53a858cc16 chore: bump version to 9.8.0
SNMP Device Integration milestone complete.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 23:08:06 -05:00
Jason Staack
f6fb206d4d fix(20): add SNMP profiles settings link and device_count to profile list
Adds SNMP Device Profiles card to SettingsPage for discoverability.
Adds device_count correlated subquery to profile list SQL and schema
field so the frontend profile cards show accurate device counts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 20:41:04 -05:00
Jason Staack
7644e561d7 feat(20-03): add SNMP profile test panel component
- Collapsible test-against-device panel with SNMP v1/v2c/v3 fields
- Conditional v3 fields (security level, auth/priv protocols)
- Test button calls snmpProfilesApi.testProfile
- Success shows green device-info panel (sysName, sysDescr, sysObjectID)
- Failure shows red error panel
- Disabled when profile not yet saved

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 20:34:09 -05:00
Jason Staack
0429073774 feat(20-03): add virtualized OID tree browser component
- Flatten tree for tanstack/react-virtual virtualization
- Expand/collapse branch nodes with chevron toggle
- Checkbox selection for leaf nodes (selectable OIDs)
- Search filter by name or OID substring
- Expand all / collapse all toolbar buttons
- ARIA tree roles for accessibility

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 20:34:00 -05:00
Jason Staack
b5f96b820f feat(20-03): add SNMP profile editor page, route, and API client extensions
- Extend snmpProfilesApi with create, update, delete, parseMib, testProfile
- Add OIDNode, MIBParseResponse, ProfileTestRequest/Response, SNMPProfileCreate types
- Create settings.snmp-profiles route with RBAC and tenant resolution
- Build SNMPProfileEditorPage with list/edit views, MIB upload, poll groups
- Remove pre-existing duplicate credentialProfilesApi declaration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 20:33:49 -05:00
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