Fix Jauge always reading the object's most recent row

A Jauge could only target a whole object, not a specific record —
three gauges pointing at the same "value" field (e.g. Réputation/
Trésorerie/Confiance in one "jauge" object) all silently showed the
most recent row's value, with no way to tell them apart.

Add "Enregistrement (ligne) à suivre" (row_id) so a Jauge targets one
specific row, and "Champ contenant le nom" (champ_nom) to show a
label above the bar — both as dropdowns populated from the object's
actual fields/rows (previously "Champ numérique à afficher" was free
text the user had to type correctly by hand). No regression: without
row_id the widget still falls back to the latest row, exactly as
before.

Extract data_definition_options() (rows+fields for a definition) out
of routes/screens/screen_edit.py so controls_with_values.py can reuse
it server-side for the initial render; a small client-side handler
(bindJaugeDefinitionSelect) repopulates the same selects live when
the tracked object is changed without leaving the panel.

Verified live with Playwright: picking "jauge" then "Confiance" then
"value"/"name" in the panel renders an 80%-filled, green-leaning bar
labelled "Confiance" on /play — not the 20%/50% of the other rows.
This commit is contained in:
william
2026-08-23 18:02:02 +02:00
parent 4eac20a464
commit c9d3069f47
8 changed files with 204 additions and 30 deletions
+27 -1
View File
@@ -281,7 +281,7 @@
{% endfor %}
</div>
{% elif c.type in ('select', 'preset') %}
<select name="ctrl_{{ c.key }}">
<select name="ctrl_{{ c.key }}" id="field-{{ c.key }}">
{% for opt in c.options %}
<option value="{{ opt[0] }}" {{ 'selected' if c.value == opt[0] else '' }}>{{ opt[1] }}</option>
{% endfor %}
@@ -841,6 +841,32 @@ function initBuilderPanel() {
});
bindPropsAutosave();
bindJaugeDefinitionSelect();
}
// Jauge : quand on change l'objet de données à suivre SANS quitter le
// panneau (donc sans le rechargement serveur qui repeuplerait row_id/champ/
// champ_nom via controls_with_values.py), on reconstruit ces trois menus à
// la volée à partir de DEFINITIONS_DATA (même source que les formulaires de
// la Logique de la scène, voir onFlowDefinitionChange). DEFINITIONS_DATA
// est déclaré plus bas dans ce script (donc encore "undefined" au moment où
// initBuilderPanel() tourne en tout premier) — sans conséquence ici,
// puisqu'on ne le lit que dans le gestionnaire, jamais au moment du bind.
function bindJaugeDefinitionSelect() {
var defSel = document.getElementById('field-definition_id');
var rowSel = document.getElementById('field-row_id');
var champSel = document.getElementById('field-champ');
var champNomSel = document.getElementById('field-champ_nom');
if (!defSel || !rowSel || !champSel || !champNomSel) return; // pas la Jauge
defSel.addEventListener('change', function () {
var info = (DEFINITIONS_DATA || {})[defSel.value] || { rows: [], fields: [] };
rowSel.innerHTML = info.rows.length
? info.rows.map(function (r) { return '<option value="' + r.id + '">' + r.label + '</option>'; }).join('')
: '<option value="">Aucune donnée dans cet objet</option>';
var fieldOptions = info.fields.map(function (f) { return '<option value="' + f.name + '">' + f.name + '</option>'; }).join('');
champSel.innerHTML = fieldOptions || '<option value="">Aucun champ simple</option>';
champNomSel.innerHTML = '<option value="">— aucun —</option>' + fieldOptions;
});
}
// Le retour/avance du navigateur (bouton "précédent") est déjà pris en