Pannello visione: nominale e tolleranze nella tabella quote

Refs #117

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-28 16:57:27 +01:00
parent 4a11d2595f
commit 88b3f202b1
4 changed files with 59 additions and 5 deletions
@@ -266,6 +266,8 @@ function visionExecute() {
value: m.value, value: m.value,
unit: st.unit || 'mm', unit: st.unit || 'mm',
status: m.pass_fail, status: m.pass_fail,
// #117: nominale e tolleranze della quota (come la schermata dei calibri); null se mancano
nominal: st.nominal, ltl: st.ltl, lwl: st.lwl, uwl: st.uwl, utl: st.utl,
}; };
}); });
}, },
@@ -379,6 +381,9 @@ function visionExecute() {
}, },
zPanEnd() { this._zPan = null; this.zPanning = false; }, zPanEnd() { this._zPan = null; this.zPanning = false; },
// #117: tolleranza a 3 decimali, trattino se manca (come x-text="...?.toFixed(3) || '—'" dei calibri, ma 0 resta 0.000)
fmtTol(v) { return v == null ? '\u2014' : Number(v).toFixed(3); },
statusClass(s) { statusClass(s) {
// Same palette as the measurement markers of the manual flow. // Same palette as the measurement markers of the manual flow.
if (s === 'pass') return 'bg-measure-pass/20 text-measure-pass border border-measure-pass/40'; if (s === 'pass') return 'bg-measure-pass/20 text-measure-pass border border-measure-pass/40';
@@ -609,12 +609,28 @@
</div> </div>
<table class="w-full text-sm" x-show="rows.length"> <table class="w-full text-sm" x-show="rows.length">
{# #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 #}
<template x-for="r in rows" :key="r.label"> <template x-for="r in rows" :key="r.label">
<tr> <tbody>
<td class="py-1 pr-2 text-[var(--text-secondary)]" x-text="r.label"></td> <tr>
<td class="py-1 pr-2 font-mono text-right" x-text="Number(r.value).toFixed(3) + ' ' + r.unit"></td> <td class="py-1 pr-2 text-[var(--text-secondary)]" x-text="r.label"></td>
<td class="py-1"><span class="inline-block px-2 py-0.5 rounded text-xs font-bold" :class="statusClass(r.status)" x-text="r.status"></span></td> <td class="py-1 pr-2 font-mono text-right" x-text="Number(r.value).toFixed(3) + ' ' + r.unit"></td>
</tr> <td class="py-1"><span class="inline-block px-2 py-0.5 rounded text-xs font-bold" :class="statusClass(r.status)" x-text="r.status"></span></td>
</tr>
<tr class="border-b border-[var(--border-color)]">
<td colspan="3" class="pb-1.5 text-[11px] font-mono">
<span class="text-primary font-semibold">{{ _('Nom') }} <span x-text="fmtTol(r.nominal)"></span></span>
<span class="text-measure-fail ml-2">LTL <span x-text="fmtTol(r.ltl)"></span></span>
<span class="text-measure-fail ml-1">UTL <span x-text="fmtTol(r.utl)"></span></span>
<template x-if="r.lwl != null || r.uwl != null">
<span>
<span class="text-measure-warning ml-2">LWL <span x-text="fmtTol(r.lwl)"></span></span>
<span class="text-measure-warning ml-1">UWL <span x-text="fmtTol(r.uwl)"></span></span>
</span>
</template>
</td>
</tr>
</tbody>
</template> </template>
</table> </table>
@@ -46,4 +46,29 @@ check('#114 riga 99: subtask sconosciuta', rows[3].label === '#99', rows[3].labe
check('#114 unit riga 17 = mm', rows[2].unit === 'mm', rows[2].unit); check('#114 unit riga 17 = mm', rows[2].unit === 'mm', rows[2].unit);
check('#114 unit riga 99 = mm', rows[3].unit === 'mm', rows[3].unit); check('#114 unit riga 99 = mm', rows[3].unit === 'mm', rows[3].unit);
// #117: nominale e tolleranze portati dalla quota; fmtTol
win.__visionCfg = {
subtasks: [
{ id: 20, description: 'Largh', unit: 'mm', nominal: 12.5, ltl: 12.4, utl: 12.6, lwl: 12.45, uwl: 12.55 },
{ id: 21, description: 'Diam', unit: 'mm', nominal: 0, ltl: null, utl: 0.05 },
{ id: 22, description: 'Nuda', unit: 'mm' },
],
};
const c2 = ctx.visionExecute();
c2.result = { measurements: [
{ subtask_id: 20, value: 12.5, pass_fail: 'pass' },
{ subtask_id: 21, value: 0, pass_fail: 'pass' },
{ subtask_id: 22, value: 1, pass_fail: 'pass' },
] };
const r2 = c2.rows;
check('#117 riga 20: nominale e tolleranze',
r2[0].nominal === 12.5 && r2[0].ltl === 12.4 && r2[0].utl === 12.6 && r2[0].lwl === 12.45 && r2[0].uwl === 12.55);
check('#117 riga 21: nominale 0 resta 0, ltl null', r2[1].nominal === 0 && r2[1].ltl == null && r2[1].utl === 0.05);
check('#117 riga 22: senza tolleranze sono undefined/null', r2[2].nominal == null && r2[2].utl == null && r2[2].lwl == null);
check('#117 label invariato', r2[0].label === 'Largh', r2[0].label);
check('#117 fmtTol(null) = trattino', c2.fmtTol(null) === '\u2014', c2.fmtTol(null));
check('#117 fmtTol(undefined) = trattino', c2.fmtTol(undefined) === '\u2014');
check('#117 fmtTol(0.05) = 0.050', c2.fmtTol(0.05) === '0.050', c2.fmtTol(0.05));
check('#117 fmtTol(0) = 0.000', c2.fmtTol(0) === '0.000', c2.fmtTol(0));
process.exit(failures ? 1 : 0); process.exit(failures ? 1 : 0);
@@ -63,3 +63,11 @@ def test_image_box_and_outcome_column_can_shrink():
assert "flex-1" in box and "min-h-0" in box assert "flex-1" in box and "min-h-0" in box
outcome = _tag_with(panel, 'x-show="result">') outcome = _tag_with(panel, 'x-show="result">')
assert "overflow-y-auto" in outcome and "min-h-0" in outcome assert "overflow-y-auto" in outcome and "min-h-0" in outcome
def test_quote_table_shows_nominal_and_tolerances():
# #117: la tabella quote del pannello mostra nominale e tolleranze come la schermata dei calibri
panel = _panel()
for marker in ("fmtTol(r.nominal)", "fmtTol(r.ltl)", "fmtTol(r.utl)", "fmtTol(r.lwl)", "fmtTol(r.uwl)"):
assert marker in panel, marker
assert "text-measure-fail" in panel and "text-measure-warning" in panel