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")) # Condition de visibilité (voir VISIBILITY_CONDITION_CONTROLS) : elle # aussi garde SON objet dans un attribut séparé (_visibilite_cond_ # definition_id), jamais partagé avec le Répéteur/la Jauge/Donnée liée. visibility_cond_options = data_definition_options(slug, attributes.get("_visibilite_cond_definition_id")) global_variables = db.list_global_variables(slug) result = [] for control in meta.get("controls", []): control = dict(control) if control["key"] in ("definition_id", "data_definition_id", "visibilite_cond_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"] == "visibilite_cond_champ": control["options"] = [("", "(sélectionner un objet d'abord)")] + [(f["name"], _field_label(f)) for f in visibility_cond_options["fields"]] if control["key"] == "visibilite_cond_variable": control["options"] = [("", "(sélectionner une variable)")] + [(v["name"], v["name"]) for v in global_variables] 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"]] if control["key"] == "content" and attributes.get("_data_definition_id"): # Une fois "Lier à un objet de données" réglé (voir # DATA_BINDING_CONTROLS), propose les champs de CET objet en # liste déroulante à côté du texte — plutôt que de devoir taper # "{{nom_du_champ}}" à la main sans savoir quels noms existent # (voir insertFieldAtCursor() dans screen_edit.html). control["field_options"] = [(f["name"], _field_label(f)) for f in data_binding_options["fields"]] result.append({**control, "value": _control_value(el, control)}) return result