import db from .widget_meta import widget_meta from .control_value import _control_value from .data_definition_options import data_definition_options from ..element_types.list_element_types import list_element_types def _field_label(f): """Libellé affiché dans une liste déroulante de champs — précise l'objet visé pour un champ "relation" (ex. "parcour (→ parcours)"), pour qu'on sache ce qu'on choisit sans avoir à aller vérifier dans l'objet.""" if f["type"] == "relation" and f.get("relation_definition_name"): return f"{f['name']} (→ {f['relation_definition_name']})" return f["name"] def controls_with_values(slug, el): """Pour le panneau de propriétés : la liste des réglages du widget de cet élément, chacun avec sa valeur actuelle déjà résolue. Le réglage "définition_id" du Répéteur de données (et de la Jauge) a besoin du jeu courant pour lister les objets disponibles — d'où le paramètre slug.""" meta = widget_meta(el.get("widget")) attributes = el.get("attributes") or {} # Pour la Jauge : quel enregistrement suivre (row_id) et quels champs # afficher (champ/champ_nom) ne peuvent être proposés qu'une fois un # objet choisi (definition_id, déjà sur CET élément) — voir # render_jauge.py. La mise à jour EN DIRECT quand on change d'objet # sans quitter le panneau est gérée côté client (onJaugeDefinitionChange # dans screen_edit.html), ceci ne couvre que le premier affichage/une # navigation vers un élément déjà réglé. jauge_options = data_definition_options(slug, attributes.get("_definition_id")) # Le Texte/Titre lié à une donnée (voir DATA_BINDING_CONTROLS) garde SON # objet dans un attribut séparé (_data_definition_id) — jamais le même # élément que le Répéteur/la Jauge, donc jamais besoin des deux options # en même temps, mais un calcul dédié quand même pour rester correct si # ça change un jour. data_binding_options = data_definition_options(slug, attributes.get("_data_definition_id")) result = [] for control in meta.get("controls", []): control = dict(control) if control["key"] in ("definition_id", "data_definition_id"): defs = db.list_definitions(slug) control["options"] = [("", "(sélectionner un objet)")] + [(str(d["id"]), d["name"]) for d in defs] if control["key"] == "template_type_id": types = list_element_types(slug) control["options"] = [("", "(aucun — utiliser le modèle de texte ci-dessous)")] + [(str(t["id"]), t["name"]) for t in types] if control["key"] == "row_id": control["options"] = [("", "(sélectionner un objet d'abord)")] + [(str(r["id"]), r["label"]) for r in jauge_options["rows"]] if control["key"] in ("champ", "champ_nom"): # La Jauge affiche une VALEUR (champ) ou un NOM (champ_nom) tel # quel — un champ "relation" n'y a pas de sens (c'est un id, pas # une valeur à afficher), donc exclu ici uniquement. non_relation_fields = [f for f in jauge_options["fields"] if f["type"] != "relation"] empty_label = "— aucun —" if control["key"] == "champ_nom" else "(sélectionner un objet d'abord)" control["options"] = [("", empty_label)] + [(f["name"], _field_label(f)) for f in non_relation_fields] if control["key"] in ("filtre_champ", "filtre2_champ"): control["options"] = [("", "(sélectionner un objet d'abord)")] + [(f["name"], _field_label(f)) for f in jauge_options["fields"]] if control["key"] in ("data_filtre_champ", "data_filtre2_champ"): control["options"] = [("", "(sélectionner un objet d'abord)")] + [(f["name"], _field_label(f)) for f in data_binding_options["fields"]] result.append({**control, "value": _control_value(el, control)}) return result