{% extends base_template|default:"conjunto/app_base.html" %} {% load static i18n %} {% comment %} Visual form builder canvas. Three columns: field-type palette (left), Gridstack canvas (centre) and a client-side field-config panel (right). The whole page is one self-contained Alpine + Gridstack surface — it is NOT an HTMX-swapped fragment, so the conjunto rule "no Alpine in HTMX-swapped areas" stays intact. On submit, builder.js serialises the canvas into the hidden ``schema`` field and the form POSTs the whole JSON in one request to ``save_url``. {% endcomment %} {% block extra_css %} {{ block.super }} {% endblock %} {% block page_title %} {% blocktranslate with name=definition %}Builder: {{ name }}{% endblocktranslate %} {% endblock %} {% block page_actions %} {% translate "Back to list" %} {% endblock %} {% block content %} {{ palette|json_script:"fb-palette" }} {{ data_sources|json_script:"fb-sources" }} {{ schema|json_script:"fb-schema" }}
{% csrf_token %} {# ── Palette (two tabs: field types | data sources) ──────── #} {# ── Canvas ──────────────────────────────────────────────── #}

{% translate "Canvas" %}

{% translate "Drag a field type from the left onto the canvas." %}
{% comment %} The ``grid-stack`` class is added by builder.js right before init so conjunto.js's widget-area auto-init (which targets ``.grid-stack``) never claims this canvas. {% endcomment %}
{# ── Field config panel ──────────────────────────────────── #} {# ── Preview pane (GitHub-editor-style toggle; replaces the canvas) ── #}

{% translate "Preview" %}

{% translate "Loading preview…" %}

{% endblock %} {% block scripts %} {{ block.super }} {# gridstack must load before builder.js (which calls GridStack.init). #} {% endblock %}