{% extends "base.html" %} {% comment %} One import run, at whichever step it has reached. A single template branching on `run.status` rather than four, because the steps share nearly all of their chrome and a four-template wizard drifts apart at the edges. It also means the progress view and the report share a URL, so a link an operator kept open still works after the run finishes. Column mapping is keyed by **index**, not by heading: a CSV may legitimately repeat a heading, and a name-keyed mapping collapses the duplicates into whichever one it saw last — importing data from a column nobody chose. {% endcomment %} {% block title %}{{ run.original_filename|default:"Import" }} · Import contacts · DemandTrail Messaging{% endblock %} {% block page_header %}

{{ run.original_filename|default:"Import" }}

Uploaded {{ run.created_at }}

All imports
{% endblock %} {% block content %} {% if file_problem %}

{{ file_problem }}

{% endif %} {% include "contacts/_import_progress.html" %} {% comment %} `is_writing`, not `is_running`: the mapping form stays available while a dry run is in flight, so a mistake spotted mid-check can be corrected without waiting. It goes away once real rows are being written. {% endcomment %} {% if header and not run.is_writing %}

Map the columns

Leave a column unmapped to ignore it. Mapping a column to Tags splits its cell on ; or , and attaches each name, creating tags that do not exist yet.

{% for column in columns %} {% endfor %}
ColumnSampleImport as
{{ column.name|default:"(unnamed)" }} {% for sample in column.samples %}{{ sample|truncatechars:40 }}{% if not forloop.last %} · {% endif %}{% empty %}None{% endfor %}

Matched on email when you map one, otherwise on phone. Blank cells never clear a stored value. Emptying a field is an edit you make on the contact.

Nothing is written until you confirm.
{% endif %} {% endblock %}