{# Funnel chart region. Contract: workspace/regions/funnel_chart.html renders `kanban_columns` (ordered stages) sized proportionally to each stage's item count, or falls back to `metrics` when no grouped items are available. Previously this template wrapped its own chrome (`card bg-card shadow`) and emitted its own title. Converted to the shared region_card pattern per #794 second follow-up: dashboard slot owns chrome + title. #} {% from 'macros/region_wrapper.html' import region_card %} {% call region_card(None) %} {% if kanban_columns and items and group_by %} {# Funnel uses kanban_columns for ordered stages #} {% set stage_counts = {} %} {% for item in items %} {% set key = item[group_by] | default("Unknown") %} {% if key in stage_counts %} {% set _ = stage_counts.update({key: stage_counts[key] + 1}) %} {% else %} {% set _ = stage_counts.update({key: 1}) %} {% endif %} {% endfor %} {% set first_count = stage_counts.get(kanban_columns[0], 0) if kanban_columns else 1 %} {% set base = first_count if first_count > 0 else 1 %}
{% for stage in kanban_columns %} {% set count = stage_counts.get(stage, 0) %} {% set pct = (count / base * 100) | int %} {% set width = pct if pct >= 20 else 20 %}
{{ stage }} ({{ count }})
{% endfor %}

{{ total }} total

{% elif metrics %} {# Fallback: render metrics as funnel stages #} {% set first_val = metrics[0].value if metrics else 1 %} {% set base = first_val if first_val > 0 else 1 %}
{% for metric in metrics %} {% set pct = (metric.value / base * 100) | int %} {% set width = pct if pct >= 20 else 20 %}
{{ metric.label }} ({{ metric.value }})
{% endfor %}
{% else %}

{{ empty_message | default("No data available.") }}

{% endif %} {% endcall %}