import db from .filter_repeater_rows import filter_repeater_rows def _resolve_bound_row_ctx(slug, attrs): """Si cet élément est lié à un objet de données (attr:_data_definition_id — réglage "Lier à un objet de données" des widgets Texte/Titre, voir DATA_BINDING_CONTROLS), retrouve LA ligne qui correspond aux 1 ou 2 filtres réglés (_data_filtre*/_data_filtre2*) — même moteur que le filtre du Répéteur de données, voir filter_repeater_rows.py — et renvoie ses champs sous forme de {nom_du_champ: valeur en texte}, exploitable par {{champ}} dans le contenu. Permet d'afficher UNE seule valeur calculée (ex: l'objectif du niveau en cours) sans avoir besoin de poser un Répéteur, qui affiche lui plusieurs lignes. Renvoie None si rien n'est lié ou si aucune ligne ne correspond.""" definition_id = attrs.get("_data_definition_id") if not definition_id or not slug: return None try: definition = db.get_definition(slug, int(definition_id)) except (TypeError, ValueError): return None if not definition: return None rows = db.list_rows(slug, definition) rows = filter_repeater_rows(slug, definition, rows, { "_filtre_champ": attrs.get("_data_filtre_champ"), "_filtre_operateur": attrs.get("_data_filtre_operateur"), "_filtre_valeur": attrs.get("_data_filtre_valeur"), "_filtre2_champ": attrs.get("_data_filtre2_champ"), "_filtre2_operateur": attrs.get("_data_filtre2_operateur"), "_filtre2_valeur": attrs.get("_data_filtre2_valeur"), }) if not rows: return None row = rows[0] return {f["name"]: str(row.get(db.slugify(f["name"]).replace("-", "_"), "") or "") for f in definition["fields"]}