fix: rewrite subtask editing to reuse add form instead of inline table row

Edit button now opens the same "Nuova Misurazione" form pre-filled with
existing data, showing "Modifica Misurazione" title and "Aggiorna Misurazione"
button. Also adds marker_number to SubtaskUpdate schema so edits persist.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Adriano
2026-02-22 19:07:55 +01:00
parent ecf700eadf
commit e9a3e8e42b
2 changed files with 32 additions and 175 deletions
+31 -175
View File
@@ -542,58 +542,35 @@
</tr>
</thead>
<tbody>
<template x-for="subtask in task.subtasks" :key="subtask.id">
<!-- ---- View Mode Row ---- -->
<tr x-show="editingSubtask !== subtask.id"
@dblclick="startEditSubtask(subtask, task.id)"
class="cursor-pointer hover:bg-[var(--bg-card-hover)]">
<!-- Marker Badge -->
<template x-for="subtask in task.subtasks" :key="subtask.id">
<tr class="hover:bg-[var(--bg-card-hover)]">
<td class="text-center">
<span class="marker-badge" x-text="subtask.marker_number"></span>
</td>
<!-- Description -->
<td>
<span class="text-sm" x-text="subtask.description"></span>
</td>
<!-- Measurement Type -->
<td>
<span class="text-xs badge badge-neutral" x-text="subtask.measurement_type || '-'"></span>
</td>
<!-- Nominal -->
<td class="text-right">
<span class="measure-value text-sm" x-text="subtask.nominal != null ? subtask.nominal : '-'"></span>
</td>
<!-- UTL -->
<td class="text-right">
<span class="measure-value text-sm text-red-500" x-text="subtask.utl != null ? subtask.utl : '-'"></span>
</td>
<!-- UWL -->
<td class="text-right">
<span class="measure-value text-sm text-amber-500" x-text="subtask.uwl != null ? subtask.uwl : '-'"></span>
</td>
<!-- LWL -->
<td class="text-right">
<span class="measure-value text-sm text-amber-500" x-text="subtask.lwl != null ? subtask.lwl : '-'"></span>
</td>
<!-- LTL -->
<td class="text-right">
<span class="measure-value text-sm text-red-500" x-text="subtask.ltl != null ? subtask.ltl : '-'"></span>
</td>
<!-- Unit -->
<td class="text-center">
<span class="text-xs text-[var(--text-muted)]" x-text="subtask.unit || 'mm'"></span>
</td>
<!-- Tolerance Bar -->
<td>
<template x-if="subtask.nominal != null && subtask.ltl != null && subtask.utl != null">
<div class="tolerance-bar" :title="toleranceTitle(subtask)">
@@ -608,8 +585,6 @@
<span class="text-xs text-[var(--text-muted)]">-</span>
</template>
</td>
<!-- Actions -->
<td class="text-center">
<div class="flex items-center justify-center gap-1">
<button @click.stop="startEditSubtask(subtask, task.id)"
@@ -631,121 +606,7 @@
</div>
</td>
</tr>
<!-- ---- Edit Mode Row ---- -->
<tr x-show="editingSubtask === subtask.id"
class="subtask-edit-row bg-blue-50/50 dark:bg-blue-900/10">
<!-- Marker -->
<td class="text-center">
<input type="number"
x-model.number="editSubtaskData.marker_number"
min="1"
class="tmf-input text-center measure-value w-14">
</td>
<!-- Description -->
<td>
<input type="text"
x-model="editSubtaskData.description"
class="tmf-input w-full"
@keydown.enter.prevent="updateSubtask(subtask.id, task.id)">
</td>
<!-- Measurement Type -->
<td>
<select x-model="editSubtaskData.measurement_type"
class="tmf-input">
<option value="">-</option>
<option value="linear">{{ _('Lineare') }}</option>
<option value="diameter">{{ _('Diametro') }}</option>
<option value="radius">{{ _('Raggio') }}</option>
<option value="angle">{{ _('Angolo') }}</option>
<option value="roughness">{{ _('Rugosita') }}</option>
<option value="torque">{{ _('Coppia') }}</option>
<option value="force">{{ _('Forza') }}</option>
<option value="weight">{{ _('Peso') }}</option>
<option value="other">{{ _('Altro') }}</option>
</select>
</td>
<!-- Nominal -->
<td>
<input type="number" step="any"
x-model.number="editSubtaskData.nominal"
class="tmf-input measure-value text-right w-full">
</td>
<!-- UTL -->
<td>
<input type="number" step="any"
x-model.number="editSubtaskData.utl"
class="tmf-input measure-value text-right w-full">
</td>
<!-- UWL -->
<td>
<input type="number" step="any"
x-model.number="editSubtaskData.uwl"
class="tmf-input measure-value text-right w-full">
</td>
<!-- LWL -->
<td>
<input type="number" step="any"
x-model.number="editSubtaskData.lwl"
class="tmf-input measure-value text-right w-full">
</td>
<!-- LTL -->
<td>
<input type="number" step="any"
x-model.number="editSubtaskData.ltl"
class="tmf-input measure-value text-right w-full">
</td>
<!-- Unit -->
<td>
<select x-model="editSubtaskData.unit"
class="tmf-input text-center">
<option value="mm">mm</option>
<option value="cm">cm</option>
<option value="m">m</option>
<option value="μm">μm</option>
<option value="in">in</option>
<option value="°">°</option>
<option value="g">g</option>
<option value="kg">kg</option>
<option value="N">N</option>
<option value="Nm">Nm</option>
</select>
</td>
<!-- Tolerance (empty in edit) -->
<td></td>
<!-- Actions: Save / Cancel -->
<td class="text-center">
<div class="flex items-center justify-center gap-1">
<button @click="updateSubtask(subtask.id, task.id)"
:disabled="!editSubtaskData.description.trim() || saving"
class="p-1.5 rounded text-emerald-600 hover:bg-emerald-50 dark:hover:bg-emerald-900/30 transition-colors"
title="{{ _('Salva') }}">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/>
</svg>
</button>
<button @click="cancelEditSubtask()"
class="p-1.5 rounded text-[var(--text-muted)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-secondary)] transition-colors"
title="{{ _('Annulla') }}">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
</td>
</tr>
</template>
</template>
</tbody>
</table>
</div>
@@ -772,8 +633,8 @@
<div x-show="addingSubtaskForTask === task.id"
x-transition
class="p-3 rounded-lg bg-[var(--bg-secondary)] border border-[var(--border-color)]">
<p class="text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide mb-3">
{{ _('Nuova Misurazione') }}
<p class="text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wide mb-3"
x-text="editingSubtaskId ? '{{ _('Modifica Misurazione') }}' : '{{ _('Nuova Misurazione') }}'">
</p>
<div class="grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-6 gap-3">
<!-- Marker Number -->
@@ -789,7 +650,7 @@
<label class="tmf-label text-xs">{{ _('Descrizione') }} <span class="text-red-500">*</span></label>
<input type="text"
x-model="newSubtask.description"
@keydown.enter.prevent="addSubtask(task.id)"
@keydown.enter.prevent="editingSubtaskId ? updateSubtask(editingSubtaskId, task.id) : addSubtask(task.id)"
class="tmf-input"
placeholder="{{ _('Es. Diametro foro principale') }}">
</div>
@@ -871,11 +732,11 @@
<!-- Form Actions -->
<div class="flex items-center gap-2 justify-end mt-4">
<button @click="addingSubtaskForTask = null; resetNewSubtask(task.id)"
<button @click="cancelSubtaskForm(task.id)"
class="btn btn-secondary text-xs">
{{ _('Annulla') }}
</button>
<button @click="addSubtask(task.id)"
<button @click="editingSubtaskId ? updateSubtask(editingSubtaskId, task.id) : addSubtask(task.id)"
:disabled="!newSubtask.description.trim() || saving"
class="btn btn-primary text-xs gap-1.5">
<svg x-show="!saving" class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
@@ -885,7 +746,7 @@
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z"/>
</svg>
{{ _('Aggiungi Misurazione') }}
<span x-text="editingSubtaskId ? '{{ _('Aggiorna Misurazione') }}' : '{{ _('Aggiungi Misurazione') }}'"></span>
</button>
</div>
</div>
@@ -1105,11 +966,7 @@ function taskEditor() {
newTask: { title: '', directive: '', description: '' },
// ---- Subtask CRUD state ----
editingSubtask: null,
editSubtaskData: {
marker_number: 1, description: '', measurement_type: '',
nominal: null, utl: null, uwl: null, lwl: null, ltl: null, unit: 'mm'
},
editingSubtaskId: null,
addingSubtaskForTask: null,
newSubtask: {
marker_number: 1, description: '', measurement_type: '',
@@ -1211,7 +1068,7 @@ function taskEditor() {
}
// Reset inline editors when collapsing
if (this.expandedTask !== taskId) {
this.editingSubtask = null;
this.editingSubtaskId = null;
this.addingSubtaskForTask = null;
}
},
@@ -1476,7 +1333,7 @@ function taskEditor() {
},
openAddSubtask(task) {
this.editingSubtask = null;
this.editingSubtaskId = null;
this.addingSubtaskForTask = task.id;
this.resetNewSubtask(task.id);
},
@@ -1530,9 +1387,10 @@ function taskEditor() {
},
startEditSubtask(subtask, taskId) {
this.addingSubtaskForTask = null;
this.editingSubtask = subtask.id;
this.editSubtaskData = {
// Open the same form used for adding, but pre-filled with existing data
this.editingSubtaskId = subtask.id;
this.addingSubtaskForTask = taskId;
this.newSubtask = {
marker_number: subtask.marker_number,
description: subtask.description || '',
measurement_type: subtask.measurement_type || '',
@@ -1545,29 +1403,27 @@ function taskEditor() {
};
},
cancelEditSubtask() {
this.editingSubtask = null;
this.editSubtaskData = {
marker_number: 1, description: '', measurement_type: '',
nominal: null, utl: null, uwl: null, lwl: null, ltl: null, unit: 'mm'
};
cancelSubtaskForm(taskId) {
this.editingSubtaskId = null;
this.addingSubtaskForTask = null;
this.resetNewSubtask(taskId);
},
async updateSubtask(subtaskId, taskId) {
if (!this.editSubtaskData.description.trim()) return;
if (!this.newSubtask.description.trim()) return;
this.saving = true;
this.errorMessage = '';
const payload = {
marker_number: this.editSubtaskData.marker_number || 1,
description: this.editSubtaskData.description.trim(),
measurement_type: this.editSubtaskData.measurement_type || null,
nominal: this.editSubtaskData.nominal,
utl: this.editSubtaskData.utl,
uwl: this.editSubtaskData.uwl,
lwl: this.editSubtaskData.lwl,
ltl: this.editSubtaskData.ltl,
unit: this.editSubtaskData.unit || 'mm'
marker_number: this.newSubtask.marker_number || 1,
description: this.newSubtask.description.trim(),
measurement_type: this.newSubtask.measurement_type || null,
nominal: this.newSubtask.nominal,
utl: this.newSubtask.utl,
uwl: this.newSubtask.uwl,
lwl: this.newSubtask.lwl,
ltl: this.newSubtask.ltl,
unit: this.newSubtask.unit || 'mm'
};
try {
@@ -1593,7 +1449,7 @@ function taskEditor() {
task.subtasks[idx] = { ...task.subtasks[idx], ...data };
}
}
this.cancelEditSubtask();
this.cancelSubtaskForm(taskId);
this.successMessage = {{ _("Misurazione aggiornata")|tojson }};
}
} catch (err) {
+1
View File
@@ -20,6 +20,7 @@ class SubtaskCreate(BaseModel):
class SubtaskUpdate(BaseModel):
"""Schema for updating a subtask."""
marker_number: Optional[int] = Field(None, ge=1)
description: Optional[str] = Field(None, min_length=1, max_length=500)
measurement_type: Optional[str] = Field(None, max_length=100)
nominal: Optional[float] = None