Ajoute "Ligne cliquée (Répéteur)" comme cible pour une Condition/action de la Logique de la scène
Problème remonté : un déclencheur "Au clic" posé sur un Répéteur exécute
le MÊME graphe pour n'importe quelle ligne cliquée - or une Condition
("Si is_opened est égal à Non") ou une action "Modifier une donnée" ne
pouvaient viser qu'une ligne FIXE, choisie à la création du nœud dans
l'éditeur. Impossible donc de dire "modifie le champ DE LA LIGNE QUE JE
VIENS DE CLIQUER", puisque cette ligne n'est justement jamais connue à
l'avance.
Nouvelle valeur sentinelle CLICKED_ROW_ID (-1, screens/flow/constants.py,
ne collisionne jamais avec un vrai id de ligne) proposée en tête de TOUTE
liste déroulante "Ligne concernée" (clause principale et clauses
supplémentaires d'un nœud Condition, cible d'une action "Modifier une
donnée") : "🖱️ Ligne cliquée (Répéteur)".
Résolution au moment de l'exécution, pas à la création du nœud :
- Condition (évaluée côté client) : readFieldValue() (play.html) résout
-1 en window.lastClickedRowId, déjà capturé par bindClicks() au clic sur
une ligne de Répéteur (déjà utilisé par "Ouvrir la ligne cliquée").
- Action "Modifier une donnée" (exécutée côté serveur) : le client envoie
clicked_row_id dans le corps de la requête POST ; flow_node_run_data.py
ne s'en sert que si le nœud vise justement CLICKED_ROW_ID, sinon la
ligne fixe stockée sur le nœud reste utilisée normalement.
Ajoute tests/test_flow_clicked_row.py (ligne cliquée seule modifiée,
absence de clic = no-op plutôt que plantage, non-régression d'une cible
fixe, présence de l'option dans l'éditeur).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
7d48445443
commit
b094342097
+13
-1
@@ -533,7 +533,13 @@
|
||||
return new Promise(function(resolve) { setTimeout(resolve, ms); });
|
||||
} else if (node.action_type === 'modifier_donnee') {
|
||||
const runDataUrl = "{{ url_for('flow_node_run_data', slug=game.slug, node_id=999999) }}".replace('999999', node.id);
|
||||
return fetch(runDataUrl, {method: 'POST'})
|
||||
// clicked_row_id : utilisé côté serveur SEULEMENT si ce nœud vise la
|
||||
// ligne cliquée (CLICKED_ROW_ID, voir flow_node_run_data.py) — sans
|
||||
// effet sinon, donc toujours transmis sans condition ici.
|
||||
return fetch(runDataUrl, {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ clicked_row_id: window.lastClickedRowId })
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(() => refreshRuntimeData());
|
||||
} else if (node.action_type === 'modifier_variable') {
|
||||
@@ -549,6 +555,12 @@
|
||||
// Lit la valeur actuelle d'un champ d'objet dans l'instantané de données
|
||||
// du jeu (gameData.data), pour l'évaluation d'une condition.
|
||||
function readFieldValue(definitionId, rowId, fieldName) {
|
||||
// CLICKED_ROW_ID (-1, voir flow_node_run_data.py) : "la ligne de
|
||||
// Répéteur sur laquelle on vient de cliqué" — jamais connue à l'avance
|
||||
// dans l'éditeur (choisie ici via "🖱️ Ligne cliquée (Répéteur)"),
|
||||
// résolue seulement au moment de l'évaluation via le dernier clic
|
||||
// capturé (voir bindClicks() plus haut).
|
||||
if (rowId === -1) rowId = window.lastClickedRowId;
|
||||
const rows = gameData.data[String(definitionId)] || [];
|
||||
const row = rows.find(r => r.id === rowId);
|
||||
return row ? row[fieldName] : undefined;
|
||||
|
||||
@@ -2175,15 +2175,31 @@ function closeNodeForm() {
|
||||
currentNodeFormType = null;
|
||||
}
|
||||
|
||||
// CLICKED_ROW_ID (-1, voir screens/flow/constants.py) : "la ligne de
|
||||
// Répéteur sur laquelle on vient de cliquer" — pour un déclencheur "Au
|
||||
// clic" posé sur un Répéteur, chaque ligne exécute le MÊME graphe et la
|
||||
// ligne cliquée n'est jamais connue à l'avance ; choisir une ligne fixe
|
||||
// dans l'éditeur n'a donc pas de sens pour ce cas. Résolue au moment de
|
||||
// l'exécution (window.lastClickedRowId, voir play.html), pas à la
|
||||
// création du nœud — proposée en tête de TOUTE liste "Ligne concernée",
|
||||
// avant les lignes réelles de l'objet.
|
||||
var FLOW_CLICKED_ROW_ID = -1;
|
||||
|
||||
function _flowRowOptionsHtml(info) {
|
||||
var options = '<option value="' + FLOW_CLICKED_ROW_ID + '">🖱️ Ligne cliquée (Répéteur)</option>';
|
||||
options += info.rows.length
|
||||
? info.rows.map(function(r){ return '<option value="' + r.id + '">' + r.label + '</option>'; }).join('')
|
||||
: '<option value="" disabled>Aucune donnée dans cet objet</option>';
|
||||
return options;
|
||||
}
|
||||
|
||||
function onFlowDefinitionChange(prefix) {
|
||||
var defSel = document.getElementById(prefix === 'cond' ? 'nf-cond-definition' : 'nf-action-data-definition');
|
||||
if (!defSel) return;
|
||||
var info = DEFINITIONS_DATA[defSel.value] || { rows: [], fields: [] };
|
||||
var rowSel = document.getElementById(prefix === 'cond' ? 'nf-cond-row' : 'nf-action-data-row');
|
||||
var fieldSel = document.getElementById(prefix === 'cond' ? 'nf-cond-field' : 'nf-action-data-field');
|
||||
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>';
|
||||
rowSel.innerHTML = _flowRowOptionsHtml(info);
|
||||
fieldSel.innerHTML = info.fields.length
|
||||
? info.fields.map(function(f){ return '<option value="' + f.name + '" data-type="' + f.type + '">' + f.name + ' (' + f.type + ')</option>'; }).join('')
|
||||
: '<option value="">Aucun champ simple</option>';
|
||||
@@ -2247,9 +2263,7 @@ function onFlowClauseDefinitionChange(idx) {
|
||||
if (!defSel || !rowSel || !fieldSel) return;
|
||||
flowConditionExtraClauses[idx].definition_id = defSel.value;
|
||||
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>';
|
||||
rowSel.innerHTML = _flowRowOptionsHtml(info);
|
||||
fieldSel.innerHTML = info.fields.length
|
||||
? info.fields.map(function(f){ return '<option value="' + f.name + '" data-type="' + f.type + '">' + f.name + ' (' + f.type + ')</option>'; }).join('')
|
||||
: '<option value="">Aucun champ simple</option>';
|
||||
|
||||
Reference in New Issue
Block a user