import db from .filter_repeater_rows import _resolve_filter_value, _compare, _field_column def is_element_visible(slug, attrs): """Condition de visibilité (panneau de propriétés, tout widget — voir VISIBILITY_CONDITION_CONTROLS) : masque un élément selon soit une VARIABLE GLOBALE (une seule valeur pour tout le jeu, voir db/global_vars/), soit le champ d'un objet de données (convention "1 seule ligne = état de partie", déjà utilisée par la Jauge/Donnée liée). Absente de réglage (_visibilite_cond_mode vide) => toujours visible, comportement inchangé pour tous les éléments déjà créés. Réutilise _compare/_resolve_filter_value/_field_column de filter_repeater_rows.py pour rester cohérent avec les mêmes opérateurs et la même syntaxe "{{Objet.champ}}" pour une valeur de comparaison dynamique.""" mode = attrs.get("_visibilite_cond_mode") if mode not in ("variable", "objet"): return True operator = attrs.get("_visibilite_cond_operateur") or "egal" expected = _resolve_filter_value(slug, attrs.get("_visibilite_cond_valeur") or "") if mode == "variable": var_name = attrs.get("_visibilite_cond_variable") if not var_name: return True variable = db.get_global_variable(slug, var_name) if not variable: return True # variable supprimée depuis : ne bloque jamais l'affichage return _compare(variable.get("value"), operator, expected, variable.get("type") or "texte") definition_id = attrs.get("_visibilite_cond_definition_id") field_name = attrs.get("_visibilite_cond_champ") if not definition_id or not field_name: return True definition = db.get_definition(slug, int(definition_id)) if not definition: return True rows = db.list_rows(slug, definition) if not rows: return True # objet sans donnée pour l'instant : ne bloque pas row = rows[0] # convention "état de partie" : une seule ligne, voir data_definition_options.py field_type = next((f["type"] for f in definition["fields"] if f["name"] == field_name), "texte") return _compare(row.get(_field_column(definition, field_name)), operator, expected, field_type)