Ricetta DXF da camera: pannello editor, stato calibrazione stazioni, proxy camera (#83)

Rotte maker: elenco stazioni con camera, grab per stazione, stato calibrazione
dall'acquisitore (C1), inoltro a B3. Pagina stazioni: stato e link «Calibra».
Test con api_client e requests finti; traduzioni IT/EN.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 22:51:11 +02:00
parent ae2353f7f8
commit 1bfcfaa5f2
8 changed files with 931 additions and 2 deletions
@@ -50,6 +50,7 @@
<th class="text-left px-4 py-3 text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wider">{{ _('Nome') }}</th>
<th class="text-left px-4 py-3 text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wider hidden md:table-cell">{{ _('Postazione') }}</th>
<th class="text-left px-4 py-3 text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wider hidden lg:table-cell">{{ _('Ricette collegate') }}</th>
<th class="text-left px-4 py-3 text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wider hidden md:table-cell">{{ _('Calibrazione') }}</th>
<th class="text-center px-4 py-3 text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wider">{{ _('Stato') }}</th>
<th class="text-right px-4 py-3 text-xs font-semibold text-[var(--text-secondary)] uppercase tracking-wider">{{ _('Azioni') }}</th>
</tr>
@@ -81,6 +82,25 @@
</div>
</template>
</td>
{# Calibrazione (#83): stato letto dall'acquisitore della camera, link alla sua pagina «Calibra» #}
<td class="px-4 py-3 hidden md:table-cell" @click.stop
x-data="stationCalibrationCell(station, {{ {'uncalibrated': _('non calibrata'), 'unreachable': _('acquisitore non raggiungibile')}|tojson_attr }})">
<template x-if="!hasCamera">
<span class="text-xs italic text-[var(--text-secondary)]">{{ _('Nessuna camera') }}</span>
</template>
<template x-if="hasCamera">
<div class="flex flex-wrap items-center gap-x-2 gap-y-1 text-xs">
<span :class="state === 'calibrated' ? 'text-emerald-700 dark:text-emerald-300'
: (state === 'uncalibrated' || state === 'unreachable') ? 'text-amber-700 dark:text-amber-300'
: 'text-[var(--text-secondary)]'">
<span x-show="state === 'calibrated'">{{ _('Calibrazione') }}: </span><span x-text="state ? label : '...'"></span>
</span>
<a :href="calibrationUrl" target="_blank" rel="noopener"
x-show="calibrationUrl"
class="font-medium text-primary hover:underline">{{ _('Calibra') }}</a>
</div>
</template>
</td>
<td class="px-4 py-3 text-center">
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-[11px] font-medium"
:class="station.active
@@ -459,6 +479,7 @@
{% endblock %}
{% block extra_js %}
<script src="{{ url_for('static', filename='js/station_calibration.js') }}"></script>
<script>
function stationManagement(initialStations, initialRecipes) {
return {