{% extends "base.html" %} {% load common_extras %} {% comment %} The flow list. Everything below the toolbar is the _list_rows.html partial, so the list has exactly one renderer: the filters fetch it, and every mutation answers with a `flowsChanged` event that makes it re-fetch itself. Two things the redesign changed here. **The tab strip.** Flows, Sequences and Templates were three separate rail rows; they are three views of one job, so they are tabs under one row now. The strip comes from `flow_tab_groups` in the context processor — same nav data, same single active-state convention. **One primary action.** The header used to offer Import, a name field and Create at equal weight. Creating a flow is the thing people come here to do, so "New flow" is the header's only button; the modal it opens asks where to start from — blank, a template, or a file — which is where Import lives now (HANDOFF §3, "Create flow"). No Tailwind utility here sets a property a design-system class already owns — see ground rule 9 in docs/agent-prompts/layer-2.md. Colours come from the theme tokens rather than from utility palettes, which is what keeps the white-label swap in styles.css meaningful. {% endcomment %} {% block title %}Flows · DemandTrail Messaging{% endblock %} {% block sub_nav %}{% include "partials/_sub_nav.html" with groups=flow_tab_groups %}{% endblock %} {% block alpine_components %}{{ block.super }}{% include "partials/_list_behaviours.html" %}{% endblock %} {% block content %}
{% if can_edit %} {% comment %} A name and one choice (HANDOFF §2, principle 4). Only "Blank" needs the name — a template and a file each bring their own — so the field and the button follow the choice, and the button says what it is about to do. {% endcomment %} {% modal "new-flow" title="New flow" close_on="flowsChanged" %} {% comment %} The modal resets its forms as it opens (partials/_modal_behaviours.html), which puts the radios back to their `checked` default but not the Alpine state x-model reads — hence the default on Blank and the @reset beside it. {% endcomment %}
Start from
Choose a template Upload a file
{% endmodal %} {% endif %} {% include "flows/_summary.html" %}
{% comment %} One Filter button for status and folder (HANDOFF §2.2), replacing the status chips and the folder dropdown. Several values in a group are allowed, and arrive as a repeated parameter. {% endcomment %} {% filter_popover groups=filter_groups onchange="reload()" target="#flow-rows" count=flow_count noun="flow" %}
{% filter_chips groups=filter_groups onchange="reload()" %}
{% if template_cards and can_edit %}

Start from a template

{{ template_total }} ready-made flow{{ template_total|pluralize }}. Pick one and change the words to suit you.

Browse all {{ template_total }}
{% comment %} The loop variable is `entry`, and there is no `searchable`: flows/_template_card.html reads entry.card.* and leaves off the gallery page's Alpine filter unless that flag is passed. {% endcomment %} {% for entry in template_cards %} {% include "flows/_template_card.html" %} {% endfor %}
{% endif %}
{% include "flows/_list_rows.html" %}
{% endblock %}