{# Chip strip for a single deck row. Inputs: deck — the dict assembled in routes.lectures (deck_name, display_name, status, …). section — the parent section (used for ``section.name`` as the sessionStorage selection key). course_slug — the course's output_dir_name for the active lang. is_armed — whether this deck is the currently armed/recording deck (used to disable selection clicks). armed_part — the part number of the currently armed take (if this deck is armed); used to render the pulsing dot and selection ring. Selection state itself lives in client-side ``sessionStorage`` keyed by ``"::
::"``. The chip JS in base.html reads storage on first paint after every swap, applies the ``chip-selected`` class, and mirrors the choice into the hidden ``part_number`` inputs of the per-row action forms. The trailing "next part" chip is always present and is the default selection on every fresh render. #} {% set parts_status = deck.status.parts_status if deck.status else [] %} {% set known_parts = parts_status | map(attribute='part') | list %} {# The trailing chip slot: * No parts yet → 0 (record an unsuffixed single-part take). * Only an unsuffixed part 0 exists → 2 (the cascade in _prepare_target_slot will promote the existing part-0 file to part 1, so the next user-visible slot is 2). * Otherwise → max(part) + 1. #} {% if not known_parts %} {% set next_part = 0 %} {% elif known_parts == [0] %} {% set next_part = 2 %} {% else %} {% set next_part = (known_parts | max) + 1 %} {% endif %}
{% for ps in parts_status %} {% set is_armed_part = is_armed and armed_part == ps.part %} {% endfor %}