diff --git a/templates/device_list.html b/templates/device_list.html
index 17b1341..bbe8d7c 100644
--- a/templates/device_list.html
+++ b/templates/device_list.html
@@ -69,9 +69,6 @@
data-name="{{ d.name|lower }}">
{{ d.name }}
- {% if d.has_children() %}
- {{ d.children|length }} sub-component{{ 's' if d.children|length != 1 }}
- {% endif %}
|
{{ d.device_type or '—' }} |
{{ d.battery_size or '—' }} |
@@ -110,6 +107,46 @@
+ {% for child in d.children %}
+ {% set c_installed = child.installed_count() %}
+ {% if c_installed == 0 or child.battery_slots == 0 %}{% set c_fill = 'empty' %}
+ {% elif c_installed >= child.battery_slots %}{% set c_fill = 'full' %}
+ {% else %}{% set c_fill = 'partial' %}{% endif %}
+
+ |
+ ↳
+ {{ child.name }}
+ |
+ {{ d.device_type or '—' }} |
+ {{ child.battery_size or '—' }} |
+ {{ d.location or '—' }} |
+ {{ child.battery_slots }} |
+
+ {{ c_installed }} / {{ child.battery_slots }}
+ {% if child.battery_slots > 0 and c_installed >= child.battery_slots %}
+ Full
+ {% endif %}
+ |
+
+ {% set c_brands = child.installed_brands() %}
+ {% if c_brands %}
+ {{ c_brands|join(', ') }}
+ {% if child.has_mixed_brands() %}
+ ⚠ mixed
+ {% endif %}
+ {% else %}
+ —
+ {% endif %}
+ |
+
+ View
+ |
+
+ {% endfor %}
{% else %}
| No devices yet. Add one. |
{% endfor %}
diff --git a/tests/test_acceptance.py b/tests/test_acceptance.py
index 096541d..8bdb35a 100644
--- a/tests/test_acceptance.py
+++ b/tests/test_acceptance.py
@@ -1116,13 +1116,24 @@ def _setup_parent_with_two_children(client):
}, follow_redirects=True)
-def test_device_list_hides_subcomponents(client):
+def test_device_list_nests_subcomponents(client):
_setup_parent_with_two_children(client)
resp = client.get("/device/")
assert resp.status_code == 200
assert b"Hub" in resp.data
- assert b"Sensor A" not in resp.data
- assert b"Sensor B" not in resp.data
+ # sub-components render as indented child rows under the parent
+ assert b"Sensor A" in resp.data
+ assert b"Sensor B" in resp.data
+ assert "↳".encode() in resp.data
+ # parent name is searchable on child rows
+ assert b'data-name="hub sensor a"' in resp.data
+
+
+def test_assign_page_shows_parent_prefix(client):
+ _setup_rc_car(client)
+ resp = client.get("/battery/1/assign")
+ assert resp.status_code == 200
+ assert b"RC Car Set /" in resp.data
def test_subcomponent_type_location_null(client):