{% extends "base.html" %} {% block title %}{{ task.title or 'Task' }} — {{ _('Misure') }} — TieMeasureFlow{% endblock %} {# Full-screen layout: no body scroll, no footer, main fills available space #} {% block body_class %}h-screen overflow-hidden{% endblock %} {% block wrapper_class %}h-full{% endblock %} {% block main_class %}flex-1 min-h-0{% endblock %} {% block footer %}{% endblock %} {% block extra_head %} {% endblock %} {% block content %}
{# ================================================================ HEADER — Compact task info bar ================================================================ #}
{# Back button #} {# Task badge + title #}
Task {{ (task.order_index or 0) + 1 }}

{{ task.title or _('Task di misurazione') }}

{# Lista task + Completato. The list is the second level now: the operator arrives inside the sequence and comes here when they want the whole of it. What used to sit beside it was «Riepilogo», which jumped out of the sequence to a recap - the wrong thing to offer someone halfway through a task. The way forward is «Completato», and on a measurement task it stays shut until the cycle is closed, which is the same rule the footer enforces. #}
{{ _('Lista task') }} {# #60: un solo «Completato», quello grande in fondo (touch); qui resta solo la lista. #}
{# Fermo linea + Fine produzione: task di misura o del ciclo (#53: anche un check nel loop) #} {# Lot + Serial badges #}
{% if lot_number %}
{{ lot_number }}
{% endif %} {% if serial_number %}
{{ serial_number }}
{% endif %} {# Caliper status #} {% include "components/caliper_status.html" %}
{# ================================================================ MAIN — 3-column layout ================================================================ #} {# #46: camera_measure / dxf_compare get the acquisition panel below instead of the manual layout #}
{# ────────────────────────────────────────────── LEFT SIDEBAR — Marker list (vertical, hidden when no subtasks) ────────────────────────────────────────────── #} {# ────────────────────────────────────────────── CENTER — Image area ────────────────────────────────────────────── #}
{# What the task says to do. It was written for the operator and until now only the maker ever saw it; the line breaks and the bold of the technical sheet survive here as they do in the editor. #} {% if task.directive or task.description %}
{% if task.directive %}

{{ task.directive|rich_text }}

{% endif %} {% if task.description %}
{{ task.description|rich_text }}
{% endif %}
{% endif %} {# #55: the inputs of the fields of a «note» task. One block for the task on screen and for the panel at the end of production, so the rules are written once. #} {% macro result_fields() %} {% endmacro %} {# #54 #55: result panel of the task on screen - OK / NOK for a «check», the fields and «Completato» for a «note» with fields. #}
{# Main image area #}
{# Option A: Subtask has its own image → plain #}
{{ _('Immagine dettaglio misura') }}
{# Option B: Task image with annotations → annotation-viewer (kept in DOM via x-show) #}
{% if task.file_path %}
{% endif %}
{# Option C: No image → placeholder #}

{{ _('Nessuna immagine allegata') }}

{# ────────────────────────────────────────────── RIGHT PANEL — Info + tolerances + numpad (hidden when no subtasks) ────────────────────────────────────────────── #}
{# ---- Subtask header ---- #}

/
{# ---- Tolerance parameters (compact grid) ---- #}
{# Nominal row #}
{{ _('Nominale') }}
{# 2x2 tolerance grid #}
UTL
LTL
UWL
LWL
{# ---- Tolerance bar (compact) ---- #}
{# Zone labels #}
{# Center line #}
{# Value needle #}
{# ---- Already measured indicator ---- #}
{{ _('Registrata') }}: {# #118: quota registrata senza valore (visione, NaN) #}
{# ---- Measurement feedback ---- #}
{% include "components/measurement_feedback.html" %}
{# ---- Numpad (only when a subtask is active) ---- #}
{# Saving overlay #}
{{ _('Salvataggio...') }}
{% include "components/numpad.html" %}
{# ---- Next measurement indicator ---- #}
{% include "components/next_measurement.html" %}
{# ---- Error message ---- #}
{# ================================================================ VISION PANEL (#46) - acquire an image, run the recipe server-side, show the quotes and the overlay. acquire(blob) is the entry point the agent camera (#3) will reuse. ================================================================ #}
{# #96: il pannello non scorre mai (overflow-hidden, min-h-0): l'immagine sta in fit nello spazio che resta #}
{% if not camera_enabled %} {# #119: l'input file solo senza camera. On a tablet this opens the camera; on a PC it picks a file. «Riprova» reuses the same input. #} {% else %} {# #97: camera del task (o della stazione). Impulsiva: «Acquisisci» rifa grab+check; in linea: «Pausa»/«Riprendi» sul ciclo #} {% if camera_mode == 'in_linea' %} {% else %} {# #72: frame dalla camera, stessa strada di acquire(); #97: ora grab + analisi senza salvare #} {% endif %} {# #97: salva l'ULTIMO frame mostrato (execute); fino ad allora e' solo un'anteprima #} {{ _('Anteprima, non registrata') }} {{ _('Acquisizione in corso...') }} {% endif %} {{ _('Elaborazione in corso...') }}
{# #96: riquadro flex-1 min-h-0; #122: dentro, (zoom, pan, Salva, overlay SVG a tratto costante ed etichette quota) riempie il riquadro; overlay e labels arrivano da x-effect (px dell'immagine, #121 #116); x-show sul contenitore, mai sul viewer #}
{# #126: no-layers = viewer semplice, senza menu dei livelli e senza trascinamento delle etichette #}
{{ _('Nessuna immagine acquisita: premi «Acquisisci immagine».') }}
{# #96: colonna esito con scorrimento proprio (solo con molte quote); sotto lg max 40% dell'altezza #}
{{ _('Esito') }}:
{# #117: due righe per quota (esito, poi nominale e tolleranze come nella schermata dei calibri); un solo tbody per quota perche' x-for vuole un'unica radice #}
{{ _('Strumenti falliti') }}
{# ================================================================ MEASUREMENT TIMER BANNER ================================================================ #} {# Past zero the counter turns round: it stops saying how long is left and starts saying how late the line is, in red. A delay has to be read, not deduced. #}
{{ _('Prossima misurazione tra') }} {{ _('Misurazione in ritardo di') }} ({{ _('Ciclo') }} #)
{# ================================================================ MISURA SENZA QUOTE — declared a measurement task but none configured yet. Under the old rule this screen quietly looked like a note; now the task keeps its identity and says what is missing instead. ================================================================ #}
{{ _('Task di misura senza quote configurate: la ricetta è incompleta') }}
{# ================================================================ QUOTA FUORI TOLLERANZA — nothing moves from here without the capoturno or a new reading of this same quote. Kept on screen after the modal is dismissed, because the block outlives the modal: the server refuses the next value. ================================================================ #}
{{ _('Quota fuori tolleranza') }} {{ _('serve il capoturno, oppure una nuova misura della stessa quota') }}
{# ================================================================ LINEA FERMA — the countdown is frozen, not merely hidden. Stated plainly because a stopped line that looks like a running one is how a measurement interval gets silently missed. ================================================================ #}
{{ _('Linea ferma') }} {# A line stopped past its interval is frozen at a delay, not at a wait. Both read as mm:ss, so the wording is what has to change. #} {{ _('Il conto alla rovescia è congelato a') }} {{ _('Misurazione in ritardo di') }} — {{ _('serve il capoturno per riprendere') }}
{# ================================================================ PRODUCTION ERROR — the server refused to record the production state. Shown because the fallback keeps the operator working locally, and a timer that is not backed by the server must never look like one that is. ================================================================ #}
{{ _('Produzione non registrata sul server') }}:
{# ================================================================ AVVIO PRODUZIONE — visible after first cycle, before production started ================================================================ #}

{{ _('Invia segnale al gestionale per avviare il timer della linea') }}

{{ _('Produzione avviata') }}
{# ================================================================ FOOTER — Progress bar + navigation ================================================================ #}
{# Left: Back #} {# Center: Progress bar #}
/
{# Right: Fine ciclo misura (measurement tasks) / Task successivo (after cycle) #} {# #54 #55: a check / note-with-fields task has its own buttons in the panel #}
{# ================================================================ È ORA DI MISURARE — the interval expired on a task that is not the measurement. The operator is told why the screen is about to change, then taken there; there is no way to dismiss it, because putting the measurement off is exactly what the interval exists to prevent. ================================================================ #}

{{ _('È ora di misurare') }}

{{ _('Ritorno alla misurazione tra') }} s

{# ================================================================ COMPLETION OVERLAY ================================================================ #}

{{ _('Misurazioni Complete') }}

{{ _('Tutte le') }} {{ _('misurazioni sono state registrate.') }}

{{ _('Conformi') }}
{{ _('Attenzione') }}
{{ _('Non Conf.') }}
{# #61: se il server rifiuta l'avvio produzione, l'errore si vede qui, nell'overlay #}

{# Production phase: confirm the cycle. Goes through confirmCycle so the server records it - setting the flag here only looked like it had. #} {# START phase, more tasks to go: advance without blocking or exiting #} {# START phase, last task: start production #}
{# The piece can be turned over here, where the operator actually is when the quotes are done - not only from the bar behind the overlay. #}
{# ================================================================ #55 TASK DI CHIUSURA — before the capoturno's modal, the notes marked «alla fine della produzione» are filled in and recorded on the run. The modal below is untouched: it opens when this panel is done. ================================================================ #}

{{ _('Prima di chiudere la produzione') }}

{{ _('Caricamento...') }}

{# ================================================================ SUPERVISOR LOGIN MODAL ================================================================ #}

{{ _('Autorizzazione capoturno') }}

{# #59: two ways to authorise - PIN (default, touch pad) or password. #}
{# name grid #}

{{ _('Chi sei?') }}

{# pad #}

{{ _('Inserisci il PIN') }}

{# Out of tolerance, the way out of this modal is measuring the quote again - not cancelling. Closing it changes nothing: the quote stays blocked, and the banner behind says so. #}
{% endblock %} {% block extra_js %} {# #46: acquisition + overlay for camera_measure / dxf_compare #} {# #116: disegno overlay ed etichette quote; prima di vision_execute.js, che lo usa se presente #} {# #119: «Salva» immagine (frame grezzo PNG) #} {# #122: visualizzatore standard , dopo vision_overlay.js e save_image.js #} {# #53 #54 #55: result of check / note tasks (urls and words for the component) #} {# The clock's rules - how a delay reads, when the buzzer goes, where the measurement lives - are shared with the other screens rather than restated. #} {% endblock %}