{% load asset_filters %} {% comment %} Asset table partial. The wrapper carries id="asset-table" and the hx-get / hx-trigger pair that drive both the 5 s background poll and the refresh-assets event triggered after every write — every endpoint that returns this partial uses hx-swap="outerHTML", so the swap replaces the wrapper with itself and polling survives. {% endcomment %}

Enabled

{{ active_assets|length }} item{{ active_assets|length|pluralize }}
{% if active_assets %} {% for asset in active_assets %} {% include "_asset_row.html" with asset=asset is_active=True %} {% endfor %}
Name Schedule window Duration Enabled Actions
{% else %} {% include "_empty_assets.html" with is_active=True %} {% endif %}

Inactive

{{ inactive_assets|length }} item{{ inactive_assets|length|pluralize }}
{% if inactive_assets %} {% for asset in inactive_assets %} {% include "_asset_row.html" with asset=asset is_active=False %} {% endfor %}
Name Schedule window Duration Enabled Actions
{% else %} {% include "_empty_assets.html" with is_active=False %} {% endif %}
{% comment %}initAssetTableSortable now reads the order URL from the data-order-url attribute on #asset-table and binds itself on DOMContentLoaded + on every htmx:afterSwap. The previous inline-script approach raced with home.js: at initial page parse the script ran before window.initAssetTableSortable was defined (defer), so Sortable never bound until the first htmx swap.{% endcomment %}