feat: FASE 4 - Editor Maker (Fabric.js) con annotazioni, task editor, preview e storico versioni

- recipe_list.html: lista ricette con filtri, paginazione, cards Alpine.js
- recipe_editor.html: form metadati, upload drag-and-drop, canvas Fabric.js per annotazioni
- annotation-editor.js: editor annotazioni Fabric.js (marker, frecce, rettangoli, zoom, pan)
- task_editor.html: editor task/subtask inline con drag-and-drop reorder e tolleranze
- recipe_preview.html: anteprima ricetta come MeasurementTec
- version_history.html: timeline versioni con conteggio misurazioni AJAX
- maker.py: 6 route pagina + 13 proxy AJAX, gestione sicura risposte lista API
- i18n: 170+ stringhe tradotte IT/EN per tutti i template Maker

Architect review: 3 CRITICO + 5 MEDIO + 3 NEW risolti, 2 BASSO differiti

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Adriano
2026-02-07 13:15:24 +01:00
parent a386986c17
commit e1f4ee73d0
11 changed files with 5915 additions and 19 deletions
@@ -502,3 +502,450 @@ msgstr "Browser does not support Web Serial API"
# Recipe Selection Additional
msgid "Errore di connessione"
msgstr "Connection Error"
# Maker - Recipe List
msgid "Gestione Ricette"
msgstr "Recipe Management"
msgid "Crea e gestisci le ricette di misura"
msgstr "Create and manage measurement recipes"
msgid "Nuova Ricetta"
msgstr "New Recipe"
msgid "Cerca per nome, codice o descrizione..."
msgstr "Search by name, code or description..."
msgid "Tutti"
msgstr "All"
msgid "Attive"
msgstr "Active"
msgid "Disattivate"
msgstr "Inactive"
msgid "ricetta trovata"
msgstr "recipe found"
msgid "Attiva"
msgstr "Active"
msgid "Disattivata"
msgstr "Inactive"
msgid "task"
msgstr "task"
msgid "Aggiornata"
msgstr "Updated"
msgid "Versioni"
msgstr "Versions"
msgid "Nessuna ricetta disponibile"
msgstr "No recipes available"
msgid "Prova a modificare i filtri di ricerca"
msgstr "Try modifying search filters"
msgid "Inizia creando la tua prima ricetta di misura"
msgstr "Start by creating your first measurement recipe"
msgid "Crea Prima Ricetta"
msgstr "Create First Recipe"
msgid "Conferma Eliminazione"
msgstr "Confirm Deletion"
msgid "Sei sicuro di voler disattivare la ricetta"
msgstr "Are you sure you want to deactivate the recipe"
msgid "Le misure esistenti non verranno eliminate"
msgstr "Existing measurements will not be deleted"
msgid "Errore durante eliminazione"
msgstr "Error during deletion"
msgid "Dashboard"
msgstr "Dashboard"
# Maker - Recipe Editor
msgid "Modifica Ricetta"
msgstr "Edit Recipe"
msgid "Compila i dati della ricetta e carica il disegno tecnico"
msgstr "Fill in recipe data and upload the technical drawing"
msgid "Ricetta salvata con successo"
msgstr "Recipe saved successfully"
msgid "Metadati Ricetta"
msgstr "Recipe Metadata"
msgid "Es. COUPLING-256"
msgstr "E.g. COUPLING-256"
msgid "Es. Coupling Assembly 256"
msgstr "E.g. Coupling Assembly 256"
msgid "Descrizione opzionale della ricetta..."
msgstr "Optional recipe description..."
msgid "Il codice non puo essere modificato dopo la creazione"
msgstr "Code cannot be changed after creation"
msgid "Disegno Tecnico e Annotazioni"
msgstr "Technical Drawing and Annotations"
msgid "Immagine caricata"
msgstr "Image uploaded"
msgid "Marker numerato"
msgstr "Numbered marker"
msgid "Marker"
msgstr "Marker"
msgid "Freccia"
msgstr "Arrow"
msgid "Rettangolo"
msgstr "Rectangle"
msgid "Elimina selezionato"
msgstr "Delete selected"
msgid "Zoom"
msgstr "Zoom"
msgid "Zoom indietro"
msgstr "Zoom out"
msgid "Zoom avanti"
msgstr "Zoom in"
msgid "Reset zoom"
msgstr "Reset zoom"
msgid "Trascina"
msgstr "Drag"
msgid "Pan"
msgstr "Pan"
msgid "Caricamento in corso..."
msgstr "Upload in progress..."
msgid "Trascina qui il disegno tecnico oppure clicca per selezionare"
msgstr "Drag the technical drawing here or click to select"
msgid "Trascina qui per sostituire il disegno tecnico"
msgstr "Drag here to replace the technical drawing"
msgid "Formati supportati: PNG, JPG, PDF"
msgstr "Supported formats: PNG, JPG, PDF"
msgid "Versioning"
msgstr "Versioning"
msgid "Versione corrente:"
msgstr "Current version:"
msgid "Vedi cronologia"
msgstr "View history"
msgid "versioni"
msgstr "versions"
msgid "Se modifichi questa ricetta verra creata automaticamente la versione"
msgstr "If you modify this recipe, version will be created automatically"
msgid "Le misure esistenti resteranno associate alla versione corrente."
msgstr "Existing measurements will remain associated with the current version."
msgid "Motivo della modifica"
msgstr "Reason for modification"
msgid "Es. Aggiornate tolleranze foro centrale..."
msgstr "E.g. Updated center hole tolerances..."
msgid "Opzionale. Verra registrato nella cronologia versioni."
msgstr "Optional. Will be recorded in version history."
msgid "Salva Ricetta"
msgstr "Save Recipe"
msgid "Formato file non supportato. Usa PNG, JPG o PDF."
msgstr "Unsupported file format. Use PNG, JPG or PDF."
msgid "File troppo grande. Dimensione massima: 20MB."
msgstr "File too large. Maximum size: 20MB."
msgid "Errore durante il caricamento del file"
msgstr "Error uploading file"
msgid "Errore di connessione durante il caricamento"
msgstr "Connection error during upload"
msgid "Nessun file caricato"
msgstr "No file uploaded"
msgid "Nome file vuoto"
msgstr "Empty file name"
# Maker - Task Editor
msgid "Editor Task"
msgstr "Task Editor"
msgid "Task e Misurazioni"
msgstr "Tasks and Measurements"
msgid "Torna a Ricetta"
msgstr "Back to Recipe"
msgid "Aggiungi Task"
msgstr "Add Task"
msgid "Nuovo Task"
msgstr "New Task"
msgid "Titolo"
msgstr "Title"
msgid "Direttiva"
msgstr "Directive"
msgid "Es. Controllo dimensionale flangia"
msgstr "E.g. Flange dimensional check"
msgid "Es. Seguire procedura ISO 2768"
msgstr "E.g. Follow ISO 2768 procedure"
msgid "Descrizione opzionale..."
msgstr "Optional description..."
msgid "Crea Task"
msgstr "Create Task"
msgid "Trascina per riordinare"
msgstr "Drag to reorder"
msgid "Modifica task"
msgstr "Edit task"
msgid "Espandi/Comprimi"
msgstr "Expand/Collapse"
msgid "Elimina task"
msgstr "Delete task"
msgid "UTL"
msgstr "UTL"
msgid "UWL"
msgstr "UWL"
msgid "LWL"
msgstr "LWL"
msgid "LTL"
msgstr "LTL"
msgid "Unita"
msgstr "Unit"
msgid "Tolleranze"
msgstr "Tolerances"
msgid "Azioni"
msgstr "Actions"
msgid "#"
msgstr "#"
msgid "Tipo"
msgstr "Type"
msgid "Lineare"
msgstr "Linear"
msgid "Diametro"
msgstr "Diameter"
msgid "Raggio"
msgstr "Radius"
msgid "Angolo"
msgstr "Angle"
msgid "Rugosita"
msgstr "Roughness"
msgid "Coppia"
msgstr "Torque"
msgid "Forza"
msgstr "Force"
msgid "Peso"
msgstr "Weight"
msgid "Altro"
msgstr "Other"
msgid "Nessuna misurazione definita"
msgstr "No measurements defined"
msgid "Aggiungi la prima misurazione per questo task"
msgstr "Add the first measurement for this task"
msgid "Nuova Misurazione"
msgstr "New Measurement"
msgid "Marker #"
msgstr "Marker #"
msgid "Es. Diametro foro principale"
msgstr "E.g. Main hole diameter"
msgid "Lim. Tol. Inf."
msgstr "Lower Tol. Lim."
msgid "Lim. Warn. Inf."
msgstr "Lower Warn. Lim."
msgid "Lim. Warn. Sup."
msgstr "Upper Warn. Lim."
msgid "Lim. Tol. Sup."
msgstr "Upper Tol. Lim."
msgid "Aggiungi Misurazione"
msgstr "Add Measurement"
msgid "Nessun task definito"
msgstr "No tasks defined"
msgid "Inizia aggiungendo il primo task di misurazione per questa ricetta"
msgstr "Start by adding the first measurement task for this recipe"
msgid "Aggiungi Primo Task"
msgstr "Add First Task"
msgid "Conferma Eliminazione Task"
msgstr "Confirm Task Deletion"
msgid "Sei sicuro di voler eliminare il task"
msgstr "Are you sure you want to delete the task"
msgid "Verranno eliminate anche"
msgstr "The following will also be deleted:"
msgid "misurazioni associate."
msgstr "associated measurements."
msgid "Elimina Task"
msgstr "Delete Task"
msgid "Conferma Eliminazione Misurazione"
msgstr "Confirm Measurement Deletion"
msgid "Sei sicuro di voler eliminare la misurazione"
msgstr "Are you sure you want to delete the measurement"
msgid "Elimina Misurazione"
msgstr "Delete Measurement"
msgid "Errore nella creazione del task"
msgstr "Error creating task"
msgid "Task creato con successo"
msgstr "Task created successfully"
msgid "Errore nel salvataggio del task"
msgstr "Error saving task"
msgid "Task aggiornato"
msgstr "Task updated"
msgid "Task eliminato"
msgstr "Task deleted"
msgid "Errore nell'eliminazione del task"
msgstr "Error deleting task"
msgid "Errore nel riordinamento"
msgstr "Error reordering"
msgid "Errore nella creazione della misurazione"
msgstr "Error creating measurement"
msgid "Misurazione aggiunta"
msgstr "Measurement added"
msgid "Misurazione aggiornata"
msgstr "Measurement updated"
msgid "Misurazione eliminata"
msgstr "Measurement deleted"
msgid "Errore nell'eliminazione della misurazione"
msgstr "Error deleting measurement"
msgid "Direttiva opzionale..."
msgstr "Optional directive..."
# Maker - Recipe Preview
msgid "Anteprima Ricetta"
msgstr "Recipe Preview"
msgid "Modalita Anteprima"
msgstr "Preview Mode"
msgid "Stai vedendo la ricetta come la vedra il Tecnico di Misura. Tutti i campi sono in sola lettura."
msgstr "You are viewing the recipe as the Measurement Technician would see it. All fields are read-only."
msgid "misure"
msgstr "measurements"
msgid "Documento PDF allegato"
msgstr "Attached PDF document"
msgid "Punti di Misura"
msgstr "Measurement Points"
msgid "Nessun punto di misura definito per questo task"
msgstr "No measurement points defined for this task"
msgid "Questa ricetta non contiene ancora task di misurazione."
msgstr "This recipe does not contain any measurement tasks yet."
msgid "Modifica Task"
msgstr "Edit Tasks"
# Maker - Version History
msgid "Storico Versioni"
msgstr "Version History"
msgid "Corrente:"
msgstr "Current:"
msgid "Corrente"
msgstr "Current"
msgid "Visualizza"
msgstr "View"
msgid "Nessuna versione trovata"
msgstr "No versions found"
msgid "Questa ricetta non ha ancora versioni registrate. La prima versione verra creata automaticamente al salvataggio."
msgstr "This recipe does not have any registered versions yet. The first version will be created automatically when saved."
# Maker - API Errors
msgid "Errore nel caricamento della ricetta: %(error)s"
msgstr "Error loading recipe: %(error)s"
msgid "Errore nel caricamento delle versioni: %(error)s"
msgstr "Error loading versions: %(error)s"
@@ -502,3 +502,450 @@ msgstr "Browser non supporta Web Serial API"
# Recipe Selection Additional
msgid "Errore di connessione"
msgstr "Errore di connessione"
# Maker - Recipe List
msgid "Gestione Ricette"
msgstr "Gestione Ricette"
msgid "Crea e gestisci le ricette di misura"
msgstr "Crea e gestisci le ricette di misura"
msgid "Nuova Ricetta"
msgstr "Nuova Ricetta"
msgid "Cerca per nome, codice o descrizione..."
msgstr "Cerca per nome, codice o descrizione..."
msgid "Tutti"
msgstr "Tutti"
msgid "Attive"
msgstr "Attive"
msgid "Disattivate"
msgstr "Disattivate"
msgid "ricetta trovata"
msgstr "ricetta trovata"
msgid "Attiva"
msgstr "Attiva"
msgid "Disattivata"
msgstr "Disattivata"
msgid "task"
msgstr "task"
msgid "Aggiornata"
msgstr "Aggiornata"
msgid "Versioni"
msgstr "Versioni"
msgid "Nessuna ricetta disponibile"
msgstr "Nessuna ricetta disponibile"
msgid "Prova a modificare i filtri di ricerca"
msgstr "Prova a modificare i filtri di ricerca"
msgid "Inizia creando la tua prima ricetta di misura"
msgstr "Inizia creando la tua prima ricetta di misura"
msgid "Crea Prima Ricetta"
msgstr "Crea Prima Ricetta"
msgid "Conferma Eliminazione"
msgstr "Conferma Eliminazione"
msgid "Sei sicuro di voler disattivare la ricetta"
msgstr "Sei sicuro di voler disattivare la ricetta"
msgid "Le misure esistenti non verranno eliminate"
msgstr "Le misure esistenti non verranno eliminate"
msgid "Errore durante eliminazione"
msgstr "Errore durante eliminazione"
msgid "Dashboard"
msgstr "Dashboard"
# Maker - Recipe Editor
msgid "Modifica Ricetta"
msgstr "Modifica Ricetta"
msgid "Compila i dati della ricetta e carica il disegno tecnico"
msgstr "Compila i dati della ricetta e carica il disegno tecnico"
msgid "Ricetta salvata con successo"
msgstr "Ricetta salvata con successo"
msgid "Metadati Ricetta"
msgstr "Metadati Ricetta"
msgid "Es. COUPLING-256"
msgstr "Es. COUPLING-256"
msgid "Es. Coupling Assembly 256"
msgstr "Es. Coupling Assembly 256"
msgid "Descrizione opzionale della ricetta..."
msgstr "Descrizione opzionale della ricetta..."
msgid "Il codice non puo essere modificato dopo la creazione"
msgstr "Il codice non puo essere modificato dopo la creazione"
msgid "Disegno Tecnico e Annotazioni"
msgstr "Disegno Tecnico e Annotazioni"
msgid "Immagine caricata"
msgstr "Immagine caricata"
msgid "Marker numerato"
msgstr "Marker numerato"
msgid "Marker"
msgstr "Marker"
msgid "Freccia"
msgstr "Freccia"
msgid "Rettangolo"
msgstr "Rettangolo"
msgid "Elimina selezionato"
msgstr "Elimina selezionato"
msgid "Zoom"
msgstr "Zoom"
msgid "Zoom indietro"
msgstr "Zoom indietro"
msgid "Zoom avanti"
msgstr "Zoom avanti"
msgid "Reset zoom"
msgstr "Reset zoom"
msgid "Trascina"
msgstr "Trascina"
msgid "Pan"
msgstr "Pan"
msgid "Caricamento in corso..."
msgstr "Caricamento in corso..."
msgid "Trascina qui il disegno tecnico oppure clicca per selezionare"
msgstr "Trascina qui il disegno tecnico oppure clicca per selezionare"
msgid "Trascina qui per sostituire il disegno tecnico"
msgstr "Trascina qui per sostituire il disegno tecnico"
msgid "Formati supportati: PNG, JPG, PDF"
msgstr "Formati supportati: PNG, JPG, PDF"
msgid "Versioning"
msgstr "Versioning"
msgid "Versione corrente:"
msgstr "Versione corrente:"
msgid "Vedi cronologia"
msgstr "Vedi cronologia"
msgid "versioni"
msgstr "versioni"
msgid "Se modifichi questa ricetta verra creata automaticamente la versione"
msgstr "Se modifichi questa ricetta verra creata automaticamente la versione"
msgid "Le misure esistenti resteranno associate alla versione corrente."
msgstr "Le misure esistenti resteranno associate alla versione corrente."
msgid "Motivo della modifica"
msgstr "Motivo della modifica"
msgid "Es. Aggiornate tolleranze foro centrale..."
msgstr "Es. Aggiornate tolleranze foro centrale..."
msgid "Opzionale. Verra registrato nella cronologia versioni."
msgstr "Opzionale. Verra registrato nella cronologia versioni."
msgid "Salva Ricetta"
msgstr "Salva Ricetta"
msgid "Formato file non supportato. Usa PNG, JPG o PDF."
msgstr "Formato file non supportato. Usa PNG, JPG o PDF."
msgid "File troppo grande. Dimensione massima: 20MB."
msgstr "File troppo grande. Dimensione massima: 20MB."
msgid "Errore durante il caricamento del file"
msgstr "Errore durante il caricamento del file"
msgid "Errore di connessione durante il caricamento"
msgstr "Errore di connessione durante il caricamento"
msgid "Nessun file caricato"
msgstr "Nessun file caricato"
msgid "Nome file vuoto"
msgstr "Nome file vuoto"
# Maker - Task Editor
msgid "Editor Task"
msgstr "Editor Task"
msgid "Task e Misurazioni"
msgstr "Task e Misurazioni"
msgid "Torna a Ricetta"
msgstr "Torna a Ricetta"
msgid "Aggiungi Task"
msgstr "Aggiungi Task"
msgid "Nuovo Task"
msgstr "Nuovo Task"
msgid "Titolo"
msgstr "Titolo"
msgid "Direttiva"
msgstr "Direttiva"
msgid "Es. Controllo dimensionale flangia"
msgstr "Es. Controllo dimensionale flangia"
msgid "Es. Seguire procedura ISO 2768"
msgstr "Es. Seguire procedura ISO 2768"
msgid "Descrizione opzionale..."
msgstr "Descrizione opzionale..."
msgid "Crea Task"
msgstr "Crea Task"
msgid "Trascina per riordinare"
msgstr "Trascina per riordinare"
msgid "Modifica task"
msgstr "Modifica task"
msgid "Espandi/Comprimi"
msgstr "Espandi/Comprimi"
msgid "Elimina task"
msgstr "Elimina task"
msgid "UTL"
msgstr "UTL"
msgid "UWL"
msgstr "UWL"
msgid "LWL"
msgstr "LWL"
msgid "LTL"
msgstr "LTL"
msgid "Unita"
msgstr "Unita"
msgid "Tolleranze"
msgstr "Tolleranze"
msgid "Azioni"
msgstr "Azioni"
msgid "#"
msgstr "#"
msgid "Tipo"
msgstr "Tipo"
msgid "Lineare"
msgstr "Lineare"
msgid "Diametro"
msgstr "Diametro"
msgid "Raggio"
msgstr "Raggio"
msgid "Angolo"
msgstr "Angolo"
msgid "Rugosita"
msgstr "Rugosita"
msgid "Coppia"
msgstr "Coppia"
msgid "Forza"
msgstr "Forza"
msgid "Peso"
msgstr "Peso"
msgid "Altro"
msgstr "Altro"
msgid "Nessuna misurazione definita"
msgstr "Nessuna misurazione definita"
msgid "Aggiungi la prima misurazione per questo task"
msgstr "Aggiungi la prima misurazione per questo task"
msgid "Nuova Misurazione"
msgstr "Nuova Misurazione"
msgid "Marker #"
msgstr "Marker #"
msgid "Es. Diametro foro principale"
msgstr "Es. Diametro foro principale"
msgid "Lim. Tol. Inf."
msgstr "Lim. Tol. Inf."
msgid "Lim. Warn. Inf."
msgstr "Lim. Warn. Inf."
msgid "Lim. Warn. Sup."
msgstr "Lim. Warn. Sup."
msgid "Lim. Tol. Sup."
msgstr "Lim. Tol. Sup."
msgid "Aggiungi Misurazione"
msgstr "Aggiungi Misurazione"
msgid "Nessun task definito"
msgstr "Nessun task definito"
msgid "Inizia aggiungendo il primo task di misurazione per questa ricetta"
msgstr "Inizia aggiungendo il primo task di misurazione per questa ricetta"
msgid "Aggiungi Primo Task"
msgstr "Aggiungi Primo Task"
msgid "Conferma Eliminazione Task"
msgstr "Conferma Eliminazione Task"
msgid "Sei sicuro di voler eliminare il task"
msgstr "Sei sicuro di voler eliminare il task"
msgid "Verranno eliminate anche"
msgstr "Verranno eliminate anche"
msgid "misurazioni associate."
msgstr "misurazioni associate."
msgid "Elimina Task"
msgstr "Elimina Task"
msgid "Conferma Eliminazione Misurazione"
msgstr "Conferma Eliminazione Misurazione"
msgid "Sei sicuro di voler eliminare la misurazione"
msgstr "Sei sicuro di voler eliminare la misurazione"
msgid "Elimina Misurazione"
msgstr "Elimina Misurazione"
msgid "Errore nella creazione del task"
msgstr "Errore nella creazione del task"
msgid "Task creato con successo"
msgstr "Task creato con successo"
msgid "Errore nel salvataggio del task"
msgstr "Errore nel salvataggio del task"
msgid "Task aggiornato"
msgstr "Task aggiornato"
msgid "Task eliminato"
msgstr "Task eliminato"
msgid "Errore nell'eliminazione del task"
msgstr "Errore nell'eliminazione del task"
msgid "Errore nel riordinamento"
msgstr "Errore nel riordinamento"
msgid "Errore nella creazione della misurazione"
msgstr "Errore nella creazione della misurazione"
msgid "Misurazione aggiunta"
msgstr "Misurazione aggiunta"
msgid "Misurazione aggiornata"
msgstr "Misurazione aggiornata"
msgid "Misurazione eliminata"
msgstr "Misurazione eliminata"
msgid "Errore nell'eliminazione della misurazione"
msgstr "Errore nell'eliminazione della misurazione"
msgid "Direttiva opzionale..."
msgstr "Direttiva opzionale..."
# Maker - Recipe Preview
msgid "Anteprima Ricetta"
msgstr "Anteprima Ricetta"
msgid "Modalita Anteprima"
msgstr "Modalita Anteprima"
msgid "Stai vedendo la ricetta come la vedra il Tecnico di Misura. Tutti i campi sono in sola lettura."
msgstr "Stai vedendo la ricetta come la vedra il Tecnico di Misura. Tutti i campi sono in sola lettura."
msgid "misure"
msgstr "misure"
msgid "Documento PDF allegato"
msgstr "Documento PDF allegato"
msgid "Punti di Misura"
msgstr "Punti di Misura"
msgid "Nessun punto di misura definito per questo task"
msgstr "Nessun punto di misura definito per questo task"
msgid "Questa ricetta non contiene ancora task di misurazione."
msgstr "Questa ricetta non contiene ancora task di misurazione."
msgid "Modifica Task"
msgstr "Modifica Task"
# Maker - Version History
msgid "Storico Versioni"
msgstr "Storico Versioni"
msgid "Corrente:"
msgstr "Corrente:"
msgid "Corrente"
msgstr "Corrente"
msgid "Visualizza"
msgstr "Visualizza"
msgid "Nessuna versione trovata"
msgstr "Nessuna versione trovata"
msgid "Questa ricetta non ha ancora versioni registrate. La prima versione verra creata automaticamente al salvataggio."
msgstr "Questa ricetta non ha ancora versioni registrate. La prima versione verra creata automaticamente al salvataggio."
# Maker - API Errors
msgid "Errore nel caricamento della ricetta: %(error)s"
msgstr "Errore nel caricamento della ricetta: %(error)s"
msgid "Errore nel caricamento delle versioni: %(error)s"
msgstr "Errore nel caricamento delle versioni: %(error)s"