feat: FASE 3 - Flusso MeasurementTec (selezione ricetta, esecuzione misure, riepilogo)
Implementazione completa del flusso operativo per il ruolo MeasurementTec:
Blueprint measure.py:
- select_recipe: selezione ricetta con ricerca e barcode
- task_list: lista task con conteggi subtask e allegati
- task_execute: esecuzione misure con numpad, calibro USB, feedback real-time
- task_complete: riepilogo con statistiche pass/fail e export CSV
- API AJAX: lookup-barcode, save-traceability, save-measurement
- Autorizzazione role_required("MeasurementTec") su tutte le route
Componenti riutilizzabili:
- numpad.html/js/css: tastierino numerico touch-friendly con keyboard support
- caliper_status.html + caliper.js: integrazione calibro USB via Web Serial API
- barcode_scanner.html + barcode.js: scansione barcode con html5-qrcode
- measurement_feedback.html: feedback visivo pass/warning/fail in tempo reale
- next_measurement.html: indicatore prossima misurazione
- annotation-viewer.js: visualizzatore canvas con marker su disegni tecnici
- csv-export.js: export CSV con locale italiano (delimitatore ;, decimale ,)
Sicurezza:
- Decoratore role_required(*roles) per autorizzazione basata su ruoli
- CSRF token su tutti i POST AJAX
- |tojson per prevenire XSS su annotations_json
- Validazione input lato client e server
i18n: 23+ nuove chiavi tradotte IT/EN per tutti i template FASE 3
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
{# Measurement Feedback Component
|
||||
|
||||
Mostra feedback visivo in tempo reale della misurazione corrente.
|
||||
|
||||
Variabili Alpine.js richieste nel parent component:
|
||||
- currentValue: float | null - valore corrente misurato
|
||||
- nominal: float - valore nominale
|
||||
- utl: float - Upper Tolerance Limit
|
||||
- uwl: float - Upper Warning Limit
|
||||
- lwl: float - Lower Warning Limit
|
||||
- ltl: float - Lower Tolerance Limit
|
||||
- unit: string - unità di misura (es. "mm")
|
||||
- passFailStatus: computed - 'pass' | 'warning' | 'fail'
|
||||
- deviation: computed - scostamento dal nominale
|
||||
- progressWidth: computed - larghezza barra percentuale
|
||||
#}
|
||||
|
||||
<div class="measurement-feedback" x-show="currentValue !== null">
|
||||
<!-- Status bar colorata -->
|
||||
<div class="h-3 rounded-full overflow-hidden bg-slate-200 dark:bg-slate-600">
|
||||
<div class="h-full rounded-full transition-all duration-300"
|
||||
:class="{
|
||||
'bg-measure-pass': passFailStatus === 'pass',
|
||||
'bg-measure-warning': passFailStatus === 'warning',
|
||||
'bg-measure-fail': passFailStatus === 'fail'
|
||||
}"
|
||||
:style="'width: ' + progressWidth + '%'">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Status text + deviation -->
|
||||
<div class="flex justify-between items-center mt-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- Icona stato - CONFORME -->
|
||||
<template x-if="passFailStatus === 'pass'">
|
||||
<span class="flex items-center gap-1 text-measure-pass font-semibold text-sm">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 13l4 4L19 7"/>
|
||||
</svg>
|
||||
{{ _('CONFORME') }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<!-- Icona stato - ATTENZIONE -->
|
||||
<template x-if="passFailStatus === 'warning'">
|
||||
<span class="flex items-center gap-1 text-measure-warning font-semibold text-sm">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path fill-rule="evenodd" d="M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
{{ _('ATTENZIONE') }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<!-- Icona stato - NON CONFORME -->
|
||||
<template x-if="passFailStatus === 'fail'">
|
||||
<span class="flex items-center gap-1 text-measure-fail font-semibold text-sm">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M6 18L18 6M6 6l12 12"/>
|
||||
</svg>
|
||||
{{ _('NON CONFORME') }}
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- Deviation con segno -->
|
||||
<span class="font-mono text-sm font-medium"
|
||||
:class="{
|
||||
'text-measure-pass': passFailStatus === 'pass',
|
||||
'text-measure-warning': passFailStatus === 'warning',
|
||||
'text-measure-fail': passFailStatus === 'fail'
|
||||
}"
|
||||
x-text="deviation !== null ?
|
||||
(deviation >= 0 ? '+' : '') + deviation.toFixed(3) + ' ' + unit : ''">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user