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"