Scrollbar theming was scoped to .app, so anything rendered outside it via
createPortal(..., document.body) — Modal, Select/MultiSelect's floating
menu, DataTable's column-visibility picker — fell back to the browser's
default light-on-dark scrollbar. Extends the same scrollbar-color rules
to .modal, .select-menu, and .dt-col-picker.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
.header used a lighter 0.30 background tint than .sidebar's 0.40, so
scrolled content underneath showed through almost undimmed even though
backdrop-filter was applied — the two fixed chrome surfaces no longer
read as one consistent glass layer. Aligns the tint and adds a shadow
to give the header separation from content.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Six new design-system components, all documented with live examples in
the StyleGuide as required by CLAUDE.md before any page can use them:
- MultiSelect: checkbox dropdown for filters/tags, built on Select's
trigger/menu styling
- LineChart: telemetry/time-series charting for the upcoming Health tab
- SignalIndicator: signal-strength glyph for device RSSI display
- PressHoldButton: press-and-hold confirmation for destructive actions
- EditableText: inline click-to-edit text with a hover/focus-revealed
pencil affordance
- TimeRangeSelect: preset + custom time-range picker, backed by the new
lib/timeRange.js helper
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Toast gains a pending/update lifecycle so async actions can show a single
toast that transitions from in-progress to success/error, instead of
firing a new one. Select's floating-menu placement logic is extracted
into a shared helper so other dropdown-style components (MultiSelect)
can reuse it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Was previously a dead stub (TODO: implement). This real implementation
is the foundation for live heartbeats, ping RTT, and the device command
ack flow that later commits build on.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Firmware rebuilt its MQTT topics to v2 (control/command+ack+reports,
status/playback, system/alerts+info+logs+metrics, LWT, req_id, per-topic
switches — see project-vesper's docs/reference/vesper_mqtt_topic_spec_v2.md
and feature-catalog.md F-062). Mirrors that in the console's API Reference:
- Transports tab now splits into V2 (fully documented: topic table with
per-topic switches, req_id correlation, heartbeat/playback/reports/
alerts/boot-report/metrics payload cards) and Legacy (placeholder,
to be filled in later)
- mqtt namespace gains mqtt.get_topics / mqtt.set_topics command docs
- mqtt.disable description updated for its new graceful-offline behavior
- Message envelope docs (top of page) note the new optional req_id field
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Firmware side added an MQTT-only sysadmin command to override a
device's factory-set identity (serial/hw_family/hw_revision) — see
project-vesper commit 64a8bc2. Per docs/README.md's console-sync
rule, mirrors the same command into the console's live API Reference
page.
Note: this repo had substantial other pending uncommitted work
(diagnostics reports, boot history, log retention, etc.) in this
same file and elsewhere at the time of this commit — left untouched
and still uncommitted, only the system.set_identity hunk is included
here.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Mirrors firmware changes: new SD log retrieval commands on LoggingHandler
(logs.list, logs.download — chunked/paginated for offline-device
troubleshooting), and firmware.status now returns OTA rollback safety-net
diagnostics (retry/failure counts, backup partition info).
Adds a dedicated Heartbeat Payload card to the Transports tab showing
the full JSON schema with per-field descriptions, including the new rssi field.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
network.info: updated description and response example to reflect new fields
(subnet, mac, hostname, ssid, connection_type). Notes it as the command to use
for console panel population.
network.status: updated to show slimmed response (connected, ap_mode, rssi,
uptime_ms, state). Notes it as the command for monitoring/polling, not display.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- clock.get_config response example now includes gmt_offset_sec, dst_offset_sec, ntp_server
- Description updated to note it supersedes clock.get_timezone
- clock.set_backlight field names corrected to match wire format
(backlight, backlight_output, backlight_on, backlight_off)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Document three new batch commands with full response/errors/example fields:
- relay.set_config: combined bell durations + outputs
- clock.set_config: clock hardware settings (enabled, c1, c2, timings)
- clock.set_alerts_config: alert type, bell assignments, silence windows
Also updated output field notes throughout clock and relay commands to reflect
the enforced 1-based output numbering convention (0 = disabled, 255 = unconfigured).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Manufacturing router now uses shared/audit.log_action (Postgres) instead
of the separate manufacturing/audit.py (SQLite mfg_audit_log), so all
manufacturing events appear in the Log Viewer
- Added log_action calls to 5 previously unlogged endpoints: lifecycle
patch, lifecycle create, lifecycle delete, flash asset upload, flash
asset note
- Removed the now-redundant /manufacturing/audit-log endpoint
- Log Viewer restricted to sysadmin only: backend uses require_sysadmin
(was require_admin_or_above), frontend adds role guard on the page
- Fixed Action badge column clipping: table-layout auto + whiteSpace nowrap
so the column sizes to fit the widest badge (Status Change)
- Added device_batch entity type to Log Viewer entity labels and filters
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Orders:
- Auto-set customer status to ACTIVE when creating a new order (both "+ New Order" and "Init Negotiations")
- Update Status panel now resets datetime to current time each time it opens
- Empty note on status update saves as empty string instead of falling back to previous note
- Default note pre-filled per status type when Update Status panel opens or status changes
- Timeline items now show verbose date/time ("25 March 2026, 4:49 pm") with muted updated-by indicator
CustomerDetail:
- Reordered tabs: Overview | Communication | Quotations | Orders | Finance | Files & Media | Devices | Support
- Renamed "Financials" tab to "Finance"
CustomerList:
- Location column shows city only, falls back to country if city is empty
OverviewTab:
- Hero status container redesigned: icon + status name + verbose description + shimmer border
- Issues, Support, Orders shown as matching hero cards on the same row (status flex-grows to fill space)
- All four cards share identical height, padding, and animated shimmer border effect
- Stat card borders use muted opacity to stay visually consistent with the status card
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New public page at /serial-monitor: connects to Web Serial (115200 baud),
streams live output, saves sessions to localStorage + downloads .txt
- New protected page at /settings/serial-logs (admin/sysadmin only):
lists saved sessions, expandable with full scrollable log, search,
export and delete per session
- Registered routes in App.jsx and added Log Viewer to Console Settings sidebar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add deploy-host.sh for webhook-triggered docker redeploy
- Update docker-compose.yml and nginx.conf for auto-pull setup
- Fix vite.config.js and admin router for deployment environment
- Fix NVS CRC seed to use 0xFFFFFFFF to match esp_rom_crc32_le
- Add dual-panel flash UI: esptool log + live 115200 serial monitor
- Auto-reset device via RTS after flash (no manual power cycle needed)
- Clean up Header.jsx debug title text
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>