docs(04-05): complete frontend USB status bar and print label plan
This commit is contained in:
parent
4d2d35e277
commit
de807ba931
1 changed files with 117 additions and 0 deletions
117
.planning/phases/04-usb-manager-label-printing/04-05-SUMMARY.md
Normal file
117
.planning/phases/04-usb-manager-label-printing/04-05-SUMMARY.md
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
---
|
||||||
|
phase: 04-usb-manager-label-printing
|
||||||
|
plan: "05"
|
||||||
|
subsystem: frontend
|
||||||
|
tags: [usb, sse, react, label-printing, real-time]
|
||||||
|
dependency_graph:
|
||||||
|
requires: [04-03]
|
||||||
|
provides: [USB-04-frontend]
|
||||||
|
affects: [DashboardPage, ItemCard, ItemRow]
|
||||||
|
tech_stack:
|
||||||
|
added: []
|
||||||
|
patterns: [EventSource SSE, react-hot-toast, lucide-react icons]
|
||||||
|
key_files:
|
||||||
|
created:
|
||||||
|
- web/src/hooks/useUSBEvents.ts
|
||||||
|
- web/src/components/USBStatusBar.tsx
|
||||||
|
modified:
|
||||||
|
- web/src/lib/api.ts
|
||||||
|
- web/src/components/inventory/ItemCard.tsx
|
||||||
|
- web/src/components/inventory/ItemRow.tsx
|
||||||
|
- web/src/pages/DashboardPage.tsx
|
||||||
|
decisions:
|
||||||
|
- Print button added to ItemCard and ItemRow directly (not DashboardPage map) — cleaner separation of concerns
|
||||||
|
- handlePrintLabel defined at module level outside component to avoid per-render allocation
|
||||||
|
- USBStatusBar placed in DashboardPage header (flex justify-between alongside title)
|
||||||
|
- No ESLint config exists in project — skipped ESLint step, TypeScript + build used as verification
|
||||||
|
metrics:
|
||||||
|
duration: 8m
|
||||||
|
completed: 2026-04-10
|
||||||
|
tasks_completed: 2
|
||||||
|
files_changed: 6
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 04 Plan 05: Frontend USB Status Bar and Print Label Summary
|
||||||
|
|
||||||
|
One-liner: SSE-backed useUSBEvents hook with USBStatusBar component and per-item print label button wired to POST /api/labels/:id/print with react-hot-toast feedback.
|
||||||
|
|
||||||
|
## Tasks Completed
|
||||||
|
|
||||||
|
| Task | Description | Commit |
|
||||||
|
|------|-------------|--------|
|
||||||
|
| 1 | useUSBEvents hook + USBStatusBar component | 8b88970 |
|
||||||
|
| 2 | Wire USBStatusBar + Print Label into dashboard | 3de1e4f |
|
||||||
|
|
||||||
|
## What Was Built
|
||||||
|
|
||||||
|
### useUSBEvents hook (`web/src/hooks/useUSBEvents.ts`)
|
||||||
|
- Subscribes to `GET /api/usb/events` SSE stream via `new EventSource('/api/usb/events')`
|
||||||
|
- Maintains `connectedDevices: Map<string, DeviceSpec>` in React state
|
||||||
|
- Connect events add to map; disconnect events remove from map
|
||||||
|
- Malformed JSON silently ignored (T-04-14 mitigated)
|
||||||
|
- EventSource auto-reconnects on error (T-04-15 accepted)
|
||||||
|
- Exports: `useUSBEvents`, `DeviceEvent`, `DeviceSpec`, `StateConnected`, `StateDisconnected`
|
||||||
|
|
||||||
|
### USBStatusBar component (`web/src/components/USBStatusBar.tsx`)
|
||||||
|
- Consumes `useUSBEvents()`, renders connected device list
|
||||||
|
- Role icons: Printer (role=0), Cable (role=1), Usb (role=2/unknown)
|
||||||
|
- Green dot per connected device with device name
|
||||||
|
- Empty state: "No USB devices" with USB icon in muted text
|
||||||
|
- ClickHouse design: black bg, `border-white/10`, `text-white/80`, `bg-green-500` status dots
|
||||||
|
|
||||||
|
### api.ts additions (`web/src/lib/api.ts`)
|
||||||
|
- `printLabel(deviceId: number): Promise<PrintLabelResponse>` — POST /api/labels/:id/print
|
||||||
|
- `PrintLabelResponse` interface: `{ status: string; print_skipped?: boolean }`
|
||||||
|
- Throws typed Error on non-OK response
|
||||||
|
|
||||||
|
### ItemCard (`web/src/components/inventory/ItemCard.tsx`)
|
||||||
|
- Module-level `handlePrintLabel(e, itemId)` using `printLabel()` from api.ts
|
||||||
|
- Printer icon button in CardFooter alongside NetBox link
|
||||||
|
- Toast: loading → success / "queued — printer not connected" / error
|
||||||
|
|
||||||
|
### ItemRow (`web/src/components/inventory/ItemRow.tsx`)
|
||||||
|
- Same `handlePrintLabel` pattern
|
||||||
|
- Print button added to quick-actions group (appears on hover with ExternalLink)
|
||||||
|
- Opacity transition matches existing group-hover pattern
|
||||||
|
|
||||||
|
### DashboardPage (`web/src/pages/DashboardPage.tsx`)
|
||||||
|
- Imports and renders `<USBStatusBar />` in page header (flex row, right-aligned)
|
||||||
|
- No layout restructuring — additive change only
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
None — plan executed exactly as written with one minor deviation:
|
||||||
|
|
||||||
|
**1. [Rule 2 - Deviation] Print button added to ItemCard/ItemRow rather than DashboardPage map**
|
||||||
|
- **Found during:** Task 2
|
||||||
|
- **Reason:** DashboardPage passes items to `<ItemCard>` and `<ItemRow>` as components — adding print logic inline in the map would duplicate code and break component encapsulation. Plan said "find where item quick actions are rendered" which is the card/row components.
|
||||||
|
- **Impact:** Cleaner architecture; identical user-visible result
|
||||||
|
- **Files modified:** ItemCard.tsx, ItemRow.tsx (instead of DashboardPage.tsx map)
|
||||||
|
|
||||||
|
## Known Stubs
|
||||||
|
|
||||||
|
None — all data flows wired. USBStatusBar connects to live SSE. Print button calls real endpoint.
|
||||||
|
|
||||||
|
## Threat Flags
|
||||||
|
|
||||||
|
None — no new trust boundaries beyond those in the plan's threat model.
|
||||||
|
|
||||||
|
## Self-Check
|
||||||
|
|
||||||
|
Files exist:
|
||||||
|
- web/src/hooks/useUSBEvents.ts — FOUND
|
||||||
|
- web/src/components/USBStatusBar.tsx — FOUND
|
||||||
|
- web/src/lib/api.ts (modified) — FOUND
|
||||||
|
- web/src/components/inventory/ItemCard.tsx (modified) — FOUND
|
||||||
|
- web/src/components/inventory/ItemRow.tsx (modified) — FOUND
|
||||||
|
- web/src/pages/DashboardPage.tsx (modified) — FOUND
|
||||||
|
|
||||||
|
Commits:
|
||||||
|
- 8b88970 — feat(04-05): add useUSBEvents hook and USBStatusBar component
|
||||||
|
- 3de1e4f — feat(04-05): wire USBStatusBar and Print Label button into dashboard
|
||||||
|
|
||||||
|
Build: `npm run build` — PASSED (tsc -b + vite build, 0 errors, 1965 modules)
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
Loading…
Add table
Reference in a new issue