Donnée liée : conditions ET/OU illimitées + conditions de logique sur une variable globale
Deux fonctionnalités demandées, développées et corrigées dans cet
échange :
1. "Donnée liée" (Texte/Titre) : le réglage à 2 filtres fixes (toujours
combinés en ET) devient une liste de conditions ILLIMITÉE, avec un
choix ET/OU pour les combiner (screens/widgets/controls/c_clause_list.py,
screens/clause_list_codec.py). Rétrocompatible avec les anciens
éléments (_data_filtre_champ/_data_filtre2_champ), convertis à la
volée à la lecture, sans migration. Après un premier essai à la
présentation trop compacte et technique (retour utilisateur : "pas de
champ technique, pas de notation bizarre {{ }}"), la présentation
finale reprend EXACTEMENT l'ancien style (labels "Champ"/"...est"/
"...cette valeur", même sélecteur de valeur fixe/dynamique/variable
déjà existant, jamais la syntaxe brute), simplement répétée par
condition (templates/partials/clause_row.html), avec un bouton
"+ Ajouter une condition" bien visible et une liste scrollable
(static/style.css, .clauseListWrap). Le même moteur (filter_repeater_
rows.py généralisé) profite aussi au Répéteur de données en interne.
2. Nœud Condition de la Logique de la scène : peut désormais tester une
VARIABLE GLOBALE en plus d'un champ d'objet (cond_source/cond_variable/
cond_variable_chemin — screens/flow/ensure_flow_schema.py), sur la
clause principale ET chaque clause supplémentaire (ET/OU). Évalué côté
CLIENT (templates/play.html, evaluateConditionClause), contre un
nouveau gameData.variables exposé par full_game_payload.py — tenu à
jour par refreshRuntimeData() après toute action qui modifie une
variable, sans changement supplémentaire nécessaire. Le panneau de
condition reste utilisable même sans aucun objet défini dans le jeu
(avant, il disparaissait entièrement).
Vérifié : 153 tests pytest (nouveaux : test_data_binding_clause_list.py,
test_condition_variable.py) + logique JS d'évaluation des conditions
vérifiée isolément avec Node (variable scalaire, objet avec chemin
chaîné, tableau par index, variable introuvable, booléen, rétrocompatibilité
legacy) + rendu des deux pages (éditeur/jeu) vérifié sur le vrai projet
"test" en plus des jeux de test.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
7c237d6f1c
commit
8cffbeac68
@@ -0,0 +1,79 @@
|
||||
<!-- Une condition du réglage "Donnée liée" (voir screen_edit.html,
|
||||
c.type == 'clause_list') — même présentation qu'un réglage normal du
|
||||
panneau : un "Champ" et un "...est" clairement étiquetés, et le même
|
||||
sélecteur de valeur fixe/dynamique/variable que partout ailleurs dans
|
||||
l'outil (jamais la syntaxe "{{ }}" brute à lire/taper). Inclus une
|
||||
fois par condition existante, et une fois de plus (avec une clause
|
||||
vide) dans le <template> cloné par "+ Ajouter une condition". -->
|
||||
<div class="fieldRowCard box clauseRow">
|
||||
<div class="field">
|
||||
<label class="label is-small">Champ</label>
|
||||
<div class="control">
|
||||
<div class="select is-small is-fullwidth">
|
||||
<select class="clauseChampSelect" name="ctrl_{{ c.key }}_champ[]">
|
||||
<option value="">(sélectionner un objet d'abord)</option>
|
||||
{% for fname, flabel in c.field_options %}
|
||||
<option value="{{ fname }}" {{ 'selected' if clause.champ == fname else '' }}>{{ flabel }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label is-small">...est</label>
|
||||
<div class="control">
|
||||
<div class="select is-small is-fullwidth">
|
||||
<select class="clauseOperateurSelect" name="ctrl_{{ c.key }}_operateur[]">
|
||||
{% for opv, opl in c.operators %}
|
||||
<option value="{{ opv }}" {{ 'selected' if clause.operateur == opv else '' }}>{{ opl }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label is-small">...cette valeur</label>
|
||||
<div class="control filterValueControl" data-current-value="{{ clause.valeur or '' }}">
|
||||
<div class="select is-small is-fullwidth">
|
||||
<select class="filterValueMode" onchange="onFilterValueModeChange(this)">
|
||||
<option value="fixe">Valeur fixe</option>
|
||||
<option value="dynamique">Donnée d'un autre objet (change en jeu)</option>
|
||||
<option value="variable">Variable globale (change en jeu)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filterValueFixe" style="margin-top:6px;">
|
||||
<input class="input is-small" type="text" name="ctrl_{{ c.key }}_valeur[]" value="{{ clause.valeur or '' }}" placeholder="ex. 3">
|
||||
</div>
|
||||
<div class="filterValueDynamique" style="display:none; margin-top:6px;">
|
||||
<div class="select is-small is-fullwidth">
|
||||
<select class="filterValueObjSel" onchange="onFilterValueObjChange(this)">
|
||||
<option value="">— objet —</option>
|
||||
{% for d in definitions %}
|
||||
<option value="{{ d.name }}" data-definition-id="{{ d.id }}">{{ d.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="select is-small is-fullwidth" style="margin-top:6px;">
|
||||
<select class="filterValueFieldSel" onchange="onFilterValueFieldChange(this)">
|
||||
<option value="">— champ —</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filterValueVariable" style="display:none; margin-top:6px;">
|
||||
<div class="select is-small is-fullwidth">
|
||||
<select class="filterValueVarSel" onchange="onFilterValueVarChange(this)">
|
||||
<option value="">— variable —</option>
|
||||
{% for v in global_variables %}
|
||||
<option value="{{ v.name }}">{{ v.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<input class="input is-small filterValueVarPath" type="text" placeholder="Chemin optionnel (ex. .nom ou [0].valeur)" style="margin-top:6px;" oninput="updateFilterValueFromVariable(this.closest('.filterValueControl'))">
|
||||
{% if not global_variables %}
|
||||
<p class="help">Aucune variable globale pour l'instant — <a href="{{ url_for('game_dashboard', slug=game.slug, tab='variables') }}" target="_blank">crées-en une ↗</a></p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="button is-small is-danger clauseRemoveBtn">🗑️ Retirer cette condition</button>
|
||||
</div>
|
||||
Reference in New Issue
Block a user