Files
Extrudex/design/02-spool-detail-view.md
cubecraft-agents[bot] 230c3b295d initial commit
2026-04-25 18:51:05 +00:00

424 lines
22 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Spool Detail View — Screen Specification
> **Screen ID:** FIL-002
> **Source of Truth:** [Material Design 3](https://m3.material.io/)
> **Tone:** Modern Industrial/Maker
> **Theme:** Dark Mode, High-Contrast
> **Last Updated:** 2026-04-20
---
## 1. Objective
Present comprehensive, actionable information about a single filament spool. Users (shop operators) must be able to:
- View all spool metadata (material, brand, color, weight, location, dates).
- See real-time remaining weight with visual progress indicator.
- Manage QR code (view, reprint label).
- View consumption history / usage timeline.
- Perform quick actions: edit details, move location, mark depleted, initiate print.
- Navigate back to inventory or forward to related entities (printer, location).
This is the **drill-down screen** from the Filament Inventory List.
---
## 2. Screen Inventory
| Element | MD3 Component | Notes |
|---------|--------------|-------|
| Top App Bar | `md-top-app-bar` (small) | Back nav + title + actions |
| Hero Section | Custom card | Color swatch + material name + status badge |
| Progress Ring | `md-circular-progress` (determinate) | Circular remaining-weight indicator |
| Metrics Grid | CSS Grid in `md-card` | Key metrics in 2-col grid |
| QR Code Card | `md-card` (elevated) | QR display + reprint button |
| Location Section | `md-card` (outlined) | Current location + move action |
| Usage Timeline | `md-list` (2-line) | Recent consumption events |
| Action Row | `md-button` row | Primary + secondary actions |
| Snackbar | `md-snackbar` | Confirmation for destructive actions |
| Dialog | `md-dialog` | Move location, confirm depletion |
---
## 3. Layout Specification
### Title
**Spool detail name** — displayed in the Top App Bar headline slot (material short name, e.g., "PLA Basic — Matte Black").
### Sections
#### A. Top App Bar (64dp)
- **Leading:** Back arrow → returns to Inventory List
- **Title:** Material name (scrolls into collapsed bar on scroll)
- **Trailing actions:** Edit icon (pencil), More (overflow: Delete spool, Transfer data)
#### B. Hero Section (200dp mobile / 180dp kiosk)
A prominent visual header that establishes identity at a glance:
```
┌──────────────────────────────────────────────────┐
│ │
│ ┌──────┐ │
│ │ COLOR│ PLA Basic — Matte Black │
│ │SWATCH│ Bambu Lab │
│ │ 80dp │ │
│ └──────┘ [Available] │
│ │
│ ◉ 842g / 1000g │
│ 67% remaining │
│ │
└──────────────────────────────────────────────────┘
```
- **Left:** Large circular color swatch (80dp) with `outlineVariant` border
- **Right of swatch:**
- Line 1: Full material name (`headlineMedium`) — MaterialBase + Finish + Modifier
- Line 2: Brand name (`bodyLarge`, `onSurfaceVariant`)
- **Below swatch row:** Status badge (tonal chip, same as inventory)
- **Bottom:** Large circular progress indicator (96dp ring)
- Track: `surfaceContainerHighest`
- Indicator: Dynamic color (≥25% primary, 10-24% warning, <10% error)
- Center text: Remaining weight + percentage (`headlineSmall`)
#### C. Metrics Grid (2-column)
```
┌────────────────────┬────────────────────┐
│ Total Weight │ Remaining │
│ 1,000g │ 842g (67%) │
├────────────────────┼────────────────────┤
│ Diameter │ Density │
│ 1.75mm │ 1.24 g/cm³ │
├────────────────────┼────────────────────┤
│ Date Added │ Last Used │
│ Mar 12, 2026 │ Apr 18, 2026 │
└────────────────────┴────────────────────┘
```
- Each cell: Label (`labelMedium`, `onSurfaceVariant`) + Value (`titleMedium`, `onSurface`)
- Grid gap: 1dp `outlineVariant` lines between cells
- Container: `surfaceContainer` background, `rounded-xl` (16dp radius)
- Cell padding: 16dp
#### D. Location Card (Outlined, 72dp)
```
┌──────────────────────────────────────────────────┐
│ 📍 AMS Unit 2, Slot A3 [Move]│
│ Bambu Lab P1S — Left spool holder │
└──────────────────────────────────────────────────┘
```
- **Leading:** Location pin icon
- **Line 1:** Location name (`titleSmall`, `onSurface`)
- **Line 2:** Printer/host description (`bodySmall`, `onSurfaceVariant`)
- **Trailing:** "Move" text button (`primary`) → opens Move Location dialog
#### E. QR Code Card (Elevated, 200dp × 200dp QR)
```
┌──────────────────────────────────────────────────┐
│ ┌──────────────┐ │
│ │ │ │
│ │ QR CODE │ │
│ │ (160dp) │ │
│ │ │ │
│ └──────────────┘ │
│ EXT-2026-PLA-0042 │
│ [Reprint] │
└──────────────────────────────────────────────────┘
```
- QR code: 160dp × 160dp, white on dark surface
- Below QR: Internal tracking ID in monospace (`labelMedium`, `onSurfaceVariant`)
- Trailing: "Reprint" text button → sends to Bluetooth thermal printer
- Card: `surfaceContainerHigh` background, elevation 1
#### F. Usage Timeline (Expandable section)
```
│ Recent Usage │
│──────────────────────────────────────────────────│
│ 📦 Print #1847 — Benchy v3 -32g Apr 18│
│ 📦 Print #1842 — Housing Cap -18g Apr 17│
│ 📦 Print #1839 — Gear Test -8g Apr 16│
│ 📦 Added to inventory +1000g Mar 12│
│ │
│ [View Full History →] │
└───────────────────────────────────────────────────┘
```
- Each entry: 2-line list item
- Line 1: Print name or event (`bodyMedium`, `onSurface`)
- Line 2: Weight change + date (`bodySmall`, `onSurfaceVariant`)
- Negative weight: `error` color
- Positive weight: custom `success` color
- Trailing: "View Full History" link → separate screen (future)
#### G. Action Row (Sticky bottom, 64dp)
```
┌──────────────────────────────────────────────────┐
│ [Mark Depleted] [Move Location] [Print] │
└──────────────────────────────────────────────────┘
```
- **Mark Depleted:** Outlined button, `error` color → confirmation dialog
- **Move Location:** Tonal button, `secondary` → Move Location dialog
- **Print:** Filled button, `primary` → Navigate to start print job (pre-select this spool)
On kiosk, these are larger touch targets (56dp height buttons).
### Primary CTA
**Print** (filled button) — the most likely next action after viewing spool details.
### Secondary Actions
- Edit (Top App Bar icon) → Edit spool details form
- Reprint label → Send QR to thermal printer
- Move Location → Dialog with location picker
- Mark Depleted → Confirmation dialog → status update
- Delete spool → Overflow menu → confirmation dialog
### Key Components
- Large circular color swatch
- Determinate circular progress indicator
- 2-column metrics grid
- QR code display card
- Location card with move action
- Usage timeline list
- Sticky bottom action row
### States
| State | Visual |
|-------|--------|
| **Loading** | `md-circular-progress` indeterminate centered, skeleton sections |
| **Available (normal)** | Primary color progress ring, "Available" badge |
| **In Use** | Primary color progress ring, "In Use" badge, pulsing dot |
| **Low Stock** | Warning (yellow) progress ring, "Low Stock" badge |
| **Critical** | Error (red) progress ring, "Critical" badge, pulsing dot |
| **Depleted** | Error (red) progress ring at 0%, "Depleted" badge, strikethrough weight, "Mark Depleted" button becomes "Reactivate" |
| **No Location** | Location card shows "Unassigned" + "Assign" button |
| **QR Missing** | QR card shows "No QR generated" + "Generate" button |
| **Move Dialog** | Bottom sheet (mobile) / Center dialog (kiosk) with location tree/grid selector |
---
## 4. UX Rationale
1. **Hero section for instant recognition.** When an operator scans a spool or taps into it, they need immediate visual confirmation: "Is this the spool I think it is?" The large color swatch + material name + brand answers this in <1 second.
2. **Circular progress over linear.** For a single spool, a circular progress ring is more impactful and glanceable than a linear bar. It works as a "fuel gauge" metaphor that operators intuitively understand.
3. **Metrics grid, not a list.** A 2-column grid presents data-dense information efficiently. Each metric is a quick scan without vertical scrolling. This is the "dashboard gauge" pattern adapted for a single entity.
4. **QR card always visible.** The QR code is the physical-digital bridge. Operators need to see it to verify labels match, and the reprint action is frequent (labels get damaged/lost on spools).
5. **Timeline for consumption context.** "How fast am I going through this spool?" The recent usage list answers this without requiring a separate analytics screen. It's contextual, not analytical.
6. **Sticky action row.** The three most common actions (deplete, move, print) should never be hidden by scroll. Pinning them ensures they're always one tap away.
7. **"Mark Depleted" is destructive but necessary.** It gets an outlined (not filled) style and requires a confirmation dialog to prevent accidental taps — but it's prominent because operators genuinely need this action often.
---
## 5. Visual Direction
### Typography (MD3 Type Scale)
| Role | Token | Size | Weight | Line Height |
|------|-------|------|--------|-------------|
| App Bar Title | `titleLarge` | 22sp | 400 | 28sp |
| Hero Material Name | `headlineMedium` | 28sp | 400 | 36sp |
| Hero Brand | `bodyLarge` | 16sp | 400 | 24sp |
| Progress Center Value | `headlineSmall` | 24sp | 400 | 32sp |
| Progress Center Sub | `labelMedium` | 12sp | 500 | 16sp |
| Metrics Label | `labelMedium` | 12sp | 500 | 16sp |
| Metrics Value | `titleMedium` | 16sp | 500 | 24sp |
| Card Title | `titleSmall` | 14sp | 500 | 20sp |
| Card Body | `bodyMedium` | 14sp | 400 | 20sp |
| Timeline Entry | `bodyMedium` | 14sp | 400 | 20sp |
| Timeline Detail | `bodySmall` | 12sp | 400 | 16sp |
| Action Button | `labelLarge` | 14sp | 500 | 20sp |
| Tracking ID | `labelMedium` (monospace) | 12sp | 500 | 16sp |
### Spacing (MD3 8dp grid)
| Element | Spacing |
|---------|---------|
| Hero section padding | 24dp horizontal, 20dp vertical |
| Swatch to text gap | 16dp |
| Hero to metrics gap | 16dp |
| Metrics grid cell padding | 16dp |
| Metrics grid gap (divider) | 1dp |
| Section gap (between cards) | 12dp |
| Card internal padding | 16dp |
| QR code padding | 24dp (centered) |
| Timeline item padding | 16dp horizontal, 12dp vertical |
| Action row padding | 16dp horizontal, 12dp vertical |
| Action button gap | 12dp |
### Color (MD3 Dark Theme — "Industrial Maker")
Same base palette as FIL-001. Screen-specific additions:
| Role | Token | Value (Dark) | Usage |
|------|-------|-------------|-------|
| Hero Background | `surfaceContainerLow` | `#1D1B20` | Hero section fill |
| Metrics Background | `surfaceContainer` | `#211F26` | Grid card |
| QR Card Background | `surfaceContainerHigh` | `#2B2930` | Elevated card |
| Location Card Background | `surfaceContainer` | `#211F26` | Outlined card |
| Progress Track | `surfaceContainerHighest` | `#36343B` | Ring background track |
| Depleted Strikethrough | `error` | `#F2B8B5` | Weight text decoration |
### Circular Progress Colors (Dynamic)
| Threshold | Color Token | Visual |
|-----------|------------|--------|
| ≥ 25% | `primary` | `#A8CEDA` (teal-blue) |
| 1024% | Custom `warning` | `#FFD580` (amber) |
| < 10% | `error` | `#F2B8B5` (red) |
| 0% (Depleted) | `error` | `#F2B8B5` + pulsing animation |
---
## 6. Responsiveness
### Kiosk (800×480)
```
┌──────┬──────────────────────────────────────────────┐
│ NAV │ ← PLA Basic — Matte Black [✏] [⋮] │
│ RAIL │──────────────────────────────────────────────│
│ │ ┌──────┐ │
│ │ │SWATCH│ PLA Basic — Matte Black [Avail] │
│ │ │ 80dp │ Bambu Lab │
│ │ └──────┘ │
│ │ ◉ 842g / 1000g (67%) │
│ │──────────────────────────────────────────────│
│ │ Total: 1000g │ Remaining: 842g │ Diam: 1.75│
│ │ Dens: 1.24 │ Added: Mar 12 │ Last: Apr18│
│ │──────────────────────────────────────────────│
│ │ 📍 AMS Unit 2, Slot A3 [Move] │
│ │──────────────────────────────────────────────│
│ │ [Depleted] [Move Location] [Print] │
└──────┴──────────────────────────────────────────────┘
```
- **Horizontal layout advantage:** Metrics grid uses 3 columns on kiosk to fill width.
- **QR code and timeline:** Accessible via scroll or tab section below the fold.
- **Scrollable content area:** Hero + Metrics + Location fit above fold; QR + Timeline scroll into view.
- **Action row:** Sticky at bottom of scroll area, above Navigation Rail.
### Mobile PWA (375×812)
```
┌──────────────────────────────────┐
│ ← PLA Basic — Matte Black [✏] │
│──────────────────────────────────│
│ ┌──────┐ │
│ │SWATCH│ PLA Basic — Matte │
│ │ 80dp │ Black [Avail] │
│ └──────┘ Bambu Lab │
│ │
│ ◉ 842g / 1000g (67%) │
│──────────────────────────────────│
│ Total Weight │ Remaining │
│ 1,000g │ 842g (67%) │
│──────────────────────────────────│
│ Diameter │ Density │
│ 1.75mm │ 1.24 g/cm³ │
│──────────────────────────────────│
│ Date Added │ Last Used │
│ Mar 12, 2026 │ Apr 18, 2026 │
│──────────────────────────────────│
│ 📍 AMS Unit 2, Slot A3 [Move] │
│──────────────────────────────────│
│ ┌──────────┐ │
│ │ QR CODE │ │
│ │ 160dp │ EXT-2026-PLA-0042│
│ └──────────┘ [Reprint] │
│──────────────────────────────────│
│ Recent Usage │
│ Print #1847 — Benchy -32g │
│ Print #1842 — Housing -18g │
│ [View Full History →] │
│──────────────────────────────────│
│ [Depleted] [Move] [Print] │
│──────────────────────────────────│
│ 📦 🖨️ 📋 ⚙️ │
└──────────────────────────────────┘
```
- **Vertical scroll layout:** All sections stack vertically.
- **Metrics grid:** 2 columns on mobile (3 on kiosk).
- **Action row:** Sticky at bottom, above bottom navigation.
- **QR code:** Full-width card, scroll into view.
### Key Adaptations
| Property | Kiosk (800×480) | Mobile (375×812) |
|----------|-----------------|-------------------|
| Metrics columns | 3 (compact) | 2 (standard) |
| Hero section height | 180dp (compact) | 200dp (standard) |
| QR card position | Below fold, scroll | Below fold, scroll |
| Action row style | Larger buttons (56dp h) | Standard buttons (40dp h) |
| Timeline items visible | 2-3 | 3-4 |
| Move dialog | Center `mat-dialog` | Bottom sheet (`mat-bottom-sheet`) |
---
## 7. Developer Handoff Notes
### Angular Material Components
| UI Element | Angular Material Component | Notes |
|-----------|--------------------------|-------|
| Top App Bar | `<mat-toolbar>` | Collapsible title on scroll using `@angular/cdk/scrolling` |
| Color Swatch | Custom `div` | Circular, 80dp, `[style.backgroundColor]` binding |
| Circular Progress | `<mat-progress-spinner>` | `mode="determinate"`, `[value]` binding, custom color classes |
| Metrics Grid | CSS Grid inside `<mat-card>` | 2-col (mobile) / 3-col (kiosk) via CSS breakpoints |
| QR Code Card | `<mat-card>` elevated | Use `appearance="elevated"`. QR rendered via `qrcode` npm package or canvas |
| Location Card | `<mat-card>` outlined | Use `appearance="outlined"`. |
| Timeline | `<mat-list>` + `<mat-list-item>` | 2-line items with `matListItemIcon` for type icon |
| Action Buttons | `<button mat-button>` variants | Depleted: `mat-button` with `color="warn"`. Move: `mat-flat-button` with `color="accent"`. Print: `mat-raised-button` with `color="primary"` |
| Move Dialog | `<mat-dialog>` / `<mat-bottom-sheet>` | Responsive: dialog on kiosk, bottom sheet on mobile |
| Confirmation Dialog | `<mat-dialog>` | With `mat-dialog-actions`: Cancel + Confirm |
| Snackbar | `<mat-snack-bar>` | For success/error feedback on actions |
### Interaction Notes
1. **Collapsible title:** As user scrolls past hero, App Bar title animates from hidden to visible (standard M3 scroll behavior). Use `@angular/material` scroll dispatching.
2. **Progress ring animation:** On load, animate from 0 to actual value over 600ms with `ease-out`.
3. **QR code generation:** If `spool.qrCode` is null, show "Generate" button. On tap, call API to generate QR, then display.
4. **Reprint label:** Calls Bluetooth thermal printer service. Show snackbar: "Label sent to printer ✓" or "Printer not connected ✗".
5. **Move location dialog:** Show location tree (AMS units → slots, shelves). Selected location highlighted. Confirm → API call → snackbar confirmation.
6. **Mark Depleted:** Dialog: "Mark PLA Basic — Matte Black as depleted? This will update the spool's status and remove it from available inventory." Buttons: Cancel (text) / Mark Depleted (error filled).
7. **Delete spool:** Dialog: "Permanently delete PLA Basic — Matte Black? This cannot be undone." Buttons: Cancel (text) / Delete (error filled).
8. **Real-time updates:** Subscribe to `SpoolUpdated` SignalR event. If this spool's weight changes, animate the progress ring and update metrics in-place.
### Accessibility
| Requirement | Implementation |
|-------------|---------------|
| Screen reader (hero) | `aria-label="PLA Basic Matte Black by Bambu Lab, Available, 842 grams remaining of 1000 grams, 67 percent"` |
| Circular progress | `role="progressbar"`, `aria-valuenow="67"`, `aria-valuemin="0"`, `aria-valuemax="100"`, `aria-label="Remaining filament"` |
| Metrics grid | Semantic `<dl>` with `<dt>` (label) + `<dd>` (value), each with `aria-label` |
| QR code | `alt="QR code for spool EXT-2026-PLA-0042"`, `role="img"` |
| Color swatch | `aria-label="Filament color: Matte Black"`, `role="img"` |
| Action buttons | Clear `aria-label`: "Mark as depleted", "Move to new location", "Start print with this spool" |
| Confirmation dialogs | `aria-labelledby` for title, `aria-describedby` for description. Focus trap. Escape to close. |
| Keyboard nav | Tab order: Back → Edit → Overflow → Content sections → Action row. Enter to activate. |
| Focus on open | When navigating from inventory, focus lands on back button, then natural tab flow |
### SignalR Integration
- Subscribe to `SpoolUpdated` hub event, filter by current spool ID.
- On weight change: animate progress ring delta, update metrics, prepend usage timeline entry.
- On status change: update badge, adjust progress ring color, update action row buttons.
- On location change: update location card.
### Performance Notes
- Use `OnPush` change detection strategy for this component.
- QR code should be generated once and cached; don't regenerate on every change detection cycle.
- Usage timeline: load last 5 entries on init, lazy-load full history on "View Full History" tap.