gigafibre-fsm/docs/FIELD-APP-WIZARD-UX.md
louispaulb bfffed2b41 feat: ONT diagnostics — grouped mesh topology, signal RSSI, management link
- EquipmentDetail: collapsible node groups (clients grouped by mesh node)
- Signal strength as RSSI % (0-255 per 802.11-2020) with 10-tone color scale
- Management IP clickable link to device web GUI (/superadmin/)
- Fibre status compact top bar (status + Rx/Tx power when available)
- targo-hub: WAN IP detection across all VLAN interfaces
- targo-hub: full WiFi client count (direct + EasyMesh mesh repeaters)
- targo-hub: /devices/:id/hosts endpoint with client-to-node mapping
- ClientsPage: start empty, load only on search (no auto-load all)
- nginx: dynamic ollama resolver (won't crash if ollama is down)
- Cleanup: remove unused BillingKPIs.vue and TagInput.vue
- New docs and migration scripts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 21:26:14 -04:00

416 lines
15 KiB
Markdown

# Field Tech App — Wizard UX & Form Customizer
## Design Principles
1. **Minimal inputs per screen** — Techs are manual workers, not desk jockeys. Max 2-3 fields per step.
2. **Carousel/swipe navigation** — Next/Back with swipe gestures, not scrolling a long form.
3. **Big touch targets** — Fat fingers in work gloves. Buttons 48px+ height, inputs 56px+.
4. **Auto-advance** — When a field is selected (like equipment_type), auto-advance to next step.
5. **Offline-first** — Everything queued if no signal. Sync indicator always visible.
6. **Customizable** — Admin can add/remove/reorder steps via an Odoo Studio-like builder.
---
## Wizard Component Architecture
### Core: `WizardCarousel.vue`
A reusable carousel-based wizard that renders steps from a JSON definition:
```vue
<WizardCarousel
:steps="wizardSteps"
:context="{ job, customer, location }"
@complete="onComplete"
@cancel="onCancel"
/>
```
Each step is a self-contained screen rendered in a `q-carousel-slide`:
- Swipe left/right to navigate
- Bottom progress dots
- "Suivant" / "Précédent" buttons (large, thumb-friendly)
- Step counter: "Étape 2/5"
### Step Definition Schema
```json
{
"id": "equipment_type",
"title": "Type d'équipement",
"icon": "router",
"fields": [
{
"name": "equipment_type",
"type": "select-cards",
"label": "Quel équipement?",
"options": [
{ "value": "ONT", "label": "ONT", "icon": "settings_input_hdmi", "color": "blue" },
{ "value": "Routeur", "label": "Routeur WiFi", "icon": "wifi", "color": "green" },
{ "value": "Décodeur TV", "label": "Décodeur TV", "icon": "tv", "color": "purple" },
{ "value": "Téléphone IP", "label": "Téléphone", "icon": "phone", "color": "orange" }
],
"auto_advance": true
}
],
"visible_if": null,
"required": true
}
```
### Field Types
| Type | Render | Use Case |
|------|--------|----------|
| `select-cards` | Big tappable cards with icons | Equipment type, status, connection type |
| `text` | Single large input | Serial number, name |
| `scan` | Camera button → barcode scanner | Serial, MAC address |
| `photo` | Camera button → photo capture | Equipment photo, site photo |
| `signature` | Touch signature pad | Customer sign-off |
| `toggle` | Large yes/no toggle | Signal OK?, WiFi working? |
| `notes` | Textarea (expandable) | Completion notes |
| `date` | Date picker | Schedule date |
| `search` | Autocomplete search | Customer lookup |
| `checklist` | List of checkable items | Installation checklist |
| `info` | Read-only display card | Summary, confirmation |
---
## Example Wizards
### 1. Installation Completion Wizard
When tech taps "Compléter" on a Dispatch Job:
```
Step 1: "Équipements installés" [checklist]
☐ ONT branché et signal OK
☐ Routeur WiFi configuré
☐ Décodeur TV branché (if TV service)
☐ Téléphone IP testé (if phone service)
Step 2: "Numéros de série" [scan]
→ Camera opens, scan ONT barcode
→ Auto-detected: RCMG19E0AB57
→ "Suivant" button
Step 3: "Signal ONT" [toggle + text]
Signal OK? [OUI / NON]
Niveau signal: [-20 dBm] (optional)
Step 4: "WiFi" [toggle]
Client connecté au WiFi? [OUI / NON]
SSID affiché: "Gigafibre-Tremblay"
Step 5: "Photo du boîtier" [photo]
📸 Prendre une photo
Step 6: "Signature client" [signature]
Le client confirme que le service fonctionne
Step 7: "Résumé" [info]
✓ ONT: RCMG19E0AB57
✓ Signal: -18.5 dBm
✓ WiFi: OK
✓ Photo: 1 prise
✓ Signé par: Jean Tremblay
[Confirmer l'installation]
```
### 2. Equipment Scan & Link Wizard
When tech scans a barcode (from ScanPage or Job context):
```
Step 1: "Scanner" [scan]
📸 Scanner le code-barres
→ Detected: RCMG19E0AB57
Step 2: "Type" [select-cards]
ONT / Routeur / Décodeur / Téléphone
→ Tap "ONT" → auto-advance
Step 3: "Confirmer" [info]
Serial: RCMG19E0AB57
Type: ONT
Client: Jean Tremblay (from job context)
Adresse: 123 rue Principale
[Lier à ce client]
```
### 3. Repair/Diagnostic Wizard
```
Step 1: "Problème signalé" [info]
Ticket: "Pas d'internet depuis hier"
Client: Jean Tremblay
Adresse: 123 rue Principale
Step 2: "Signal ONT" [toggle + text]
Signal présent? [OUI / NON]
Niveau: [-XX dBm]
Step 3: "Test WiFi" [toggle]
WiFi fonctionne? [OUI / NON]
Step 4: "Action prise" [select-cards]
Redémarrage / Remplacement ONT / Remplacement routeur / Reconnexion fibre / Autre
Step 5: "Nouvel équipement" [scan] (if replacement)
Scanner le nouveau serial
Step 6: "Notes" [notes]
Détails supplémentaires...
Step 7: "Résultat" [toggle]
Service rétabli? [OUI / NON]
[Fermer le ticket]
```
---
## Form Customizer (Odoo Studio-like)
### Concept
An admin page in the Ops app (`/ops/form-builder`) that lets managers customize the tech wizard steps without code changes.
### How It Works
1. **Wizard Templates** stored as JSON documents in ERPNext (new doctype: `Wizard Template`)
2. **Each template** = ordered list of steps with field definitions
3. **Admin UI** = drag-and-drop step editor:
- Add step (from field type library)
- Reorder steps (drag handle)
- Edit step properties (label, options, required, visibility condition)
- Remove step
- Preview on mock phone screen
4. **Templates linked to job types**: Installation, Réparation, Maintenance, Retrait, etc.
5. **Field app fetches** the template for the current job type and renders it dynamically
### Wizard Template Doctype
```
Wizard Template
name: "Installation FTTH"
job_type: "Installation"
is_active: Check
steps: (child table: Wizard Template Step)
- step_order: 1
step_id: "equipment_checklist"
title: "Équipements installés"
field_type: "checklist"
field_config: '{"items":["ONT branché","Routeur configuré","Décodeur branché"]}'
required: 1
visible_condition: null
- step_order: 2
step_id: "ont_scan"
title: "Scanner ONT"
field_type: "scan"
field_config: '{"placeholder":"Scanner le code-barres ONT"}'
required: 1
- ...
```
### Admin Builder UI
```
┌─ Form Builder: Installation FTTH ─────────────────────────┐
│ │
│ ┌─ Step 1 ─────────────────────────── [≡] [✏️] [🗑] ──┐ │
│ │ 📋 Checklist: "Équipements installés" │ │
│ │ Items: ONT, Routeur, Décodeur, Téléphone │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Step 2 ─────────────────────────── [≡] [✏️] [🗑] ──┐ │
│ │ 📷 Scan: "Scanner ONT" │ │
│ │ Required: Oui │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Step 3 ─────────────────────────── [≡] [✏️] [🗑] ──┐ │
│ │ ✅ Toggle: "Signal ONT OK?" │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ [+ Ajouter une étape] │
│ │
│ ┌─ Aperçu téléphone ──┐ │
│ │ ┌────────────────┐ │ │
│ │ │ Étape 1/7 │ │ │
│ │ │ │ │ │
│ │ │ ☐ ONT branché │ │ │
│ │ │ ☐ Routeur │ │ │
│ │ │ ☐ Décodeur │ │ │
│ │ │ │ │ │
│ │ │ [Suivant →] │ │ │
│ │ │ ● ○ ○ ○ ○ ○ ○ │ │ │
│ │ └────────────────┘ │ │
│ └──────────────────────┘ │
│ │
│ [Sauvegarder] [Publier] │
└─────────────────────────────────────────────────────────────┘
```
### 4. Equipment Swap Wizard (Defective → Replacement)
When tech taps "Remplacer" on a device or from the "Plus" menu:
```
Step 1: "Équipement défectueux" [search/scan]
Scan le code-barres de l'ancien équipement
→ OU chercher par numéro de série
→ Affiche: RCMG19E0AB57 — ONT Raisecom HT803G-WS2
Client: Jean Tremblay
Adresse: 123 rue Principale
Step 2: "Raison du remplacement" [select-cards]
🔴 Défectueux (ne s'allume plus)
🟡 Performance dégradée
🔵 Mise à niveau (upgrade)
⚪ Autre
Step 3: "Nouvel équipement" [scan]
📸 Scanner le code-barres du remplacement
→ Detected: TPLGA1E7FB90
→ Auto-detect type: XX230v (ONT)
Step 4: "Confirmer le remplacement" [info]
❌ Ancien: RCMG19E0AB57 → sera marqué "Défectueux"
✅ Nouveau: TPLGA1E7FB90 → sera activé
Données transférées automatiquement:
• WiFi SSID/mot de passe ✓
• SIP (VoIP) credentials ✓
• Port OLT: 0/3/2 ONT:12 ✓
• VLANs: inet/mgmt/tel/tv ✓
⚠️ L'OLT sera reconfiguré (ancien ONT supprimé, nouveau enregistré)
[Confirmer le remplacement]
Step 5: "Vérification" [toggle]
Nouveau ONT en ligne? [OUI / NON]
Signal OK? [OUI / NON]
Services fonctionnels? [OUI / NON]
[Terminer]
```
**Backend flow (POST /provision/swap):**
1. Marks old equipment as "Défectueux" in ERPNext
2. Creates new Service Equipment with transferred WiFi/VoIP/OLT data
3. Generates OLT swap commands (delete old ONT, register new)
4. n8n executes OLT commands via SSH
5. ACS pushes config to new device on bootstrap
6. Ops team notified via SSE
### 5. Quick Actions Menu (field app "Plus" page)
```
┌──────────────────────────────────────────┐
│ Actions rapides │
│ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ 📷 │ │ 🔄 │ │ 🔧 │ │
│ │ Scan │ │ Swap │ │ Diag │ │
│ │ équip. │ │ équip. │ │ réseau │ │
│ └────────┘ └────────┘ └────────┘ │
│ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ 📋 │ │ 📸 │ │ ✏️ │ │
│ │ Check │ │ Photo │ │ Note │ │
│ │ -list │ │ site │ │ rapide │ │
│ └────────┘ └────────┘ └────────┘ │
└──────────────────────────────────────────┘
```
Each action opens the corresponding wizard flow.
---
## Implementation Plan
### Phase 1: WizardCarousel Component
1. Create `apps/field/src/components/WizardCarousel.vue` — carousel renderer
2. Create `apps/field/src/components/wizard-fields/` — one component per field type:
- `SelectCards.vue` (big tappable cards)
- `ScanField.vue` (camera + barcode)
- `ToggleField.vue` (yes/no)
- `PhotoField.vue` (camera capture)
- `SignatureField.vue` (touch pad)
- `ChecklistField.vue` (checkable items)
- `TextField.vue` (single input)
- `NotesField.vue` (textarea)
- `InfoField.vue` (read-only summary)
3. Create `apps/field/src/composables/useWizard.js` — step state, validation, submission
### Phase 2: Hardcoded Wizards
1. Build "Installation Complete" wizard (7 steps as above)
2. Build "Equipment Scan & Link" wizard (3 steps)
3. Integrate into TasksPage "Complete Job" action
4. Replace current ScanPage equipment creation dialog with wizard flow
### Phase 3: Wizard Template Doctype
1. Create `Wizard Template` + `Wizard Template Step` doctypes in ERPNext
2. Seed with Installation, Repair, Maintenance templates
3. Field app fetches template by job_type on wizard open
4. WizardCarousel renders dynamically from template
### Phase 4: Admin Form Builder (Ops App)
1. Build `/ops/form-builder` page
2. Drag-and-drop step editor (vue-draggable)
3. Step property editor (sidebar panel)
4. Phone preview panel
5. Publish → saves to ERPNext Wizard Template
---
## CSS / Styling Notes
```scss
// Wizard slide — full height, centered content
.wizard-slide {
display: flex;
flex-direction: column;
justify-content: center;
padding: 24px 16px;
min-height: calc(100vh - 160px); // account for header + progress bar
}
// Select cards — large touch targets
.select-card {
min-height: 80px;
border-radius: 16px;
font-size: 18px;
margin-bottom: 12px;
transition: transform 0.15s, box-shadow 0.15s;
&:active { transform: scale(0.97); }
&.selected {
border: 3px solid var(--q-primary);
box-shadow: 0 0 0 4px rgba(var(--q-primary-rgb), 0.2);
}
}
// Progress dots
.wizard-dots {
display: flex;
justify-content: center;
gap: 8px;
padding: 16px;
.dot {
width: 10px; height: 10px;
border-radius: 50%;
background: #ccc;
&.active { background: var(--q-primary); width: 24px; border-radius: 5px; }
&.done { background: var(--q-positive); }
}
}
// Navigation buttons — thumb-friendly
.wizard-nav {
display: flex;
gap: 12px;
padding: 16px;
.q-btn { min-height: 56px; font-size: 16px; flex: 1; border-radius: 12px; }
}
```