Redirect to device detail after create; sub-component install UI on parent detail
This commit is contained in:
@@ -112,13 +112,79 @@
|
||||
<div class="card">
|
||||
{% if device.children %}
|
||||
<h2>Sub-components</h2>
|
||||
<div style="display:flex;gap:0.75rem;flex-wrap:wrap;margin-bottom:0.75rem;">
|
||||
<div style="display:flex;flex-direction:column;gap:0.5rem;margin-bottom:0.75rem;">
|
||||
{% for child in device.children %}
|
||||
<a href="{{ url_for('device_detail', device_id=child.id) }}"
|
||||
style="display:block;padding:0.6rem 0.9rem;border:1px solid var(--border);border-radius:6px;text-decoration:none;min-width:140px;background:var(--bg-card);">
|
||||
<strong>{{ child.name }}</strong><br>
|
||||
<small class="text-muted">{{ child.installed_count() }}/{{ child.battery_slots }} slots · {{ child.battery_size }}{% if child.ha_entity_id %} · HA{% endif %}</small>
|
||||
</a>
|
||||
{% set child_free = child.battery_slots - child.installed_count() %}
|
||||
{% set child_batteries = children_avail.get(child.id, []) %}
|
||||
<details style="border:1px solid var(--border);border-radius:6px;background:var(--bg-card);">
|
||||
<summary style="padding:0.6rem 0.9rem;cursor:pointer;list-style:none;display:flex;align-items:center;justify-content:space-between;">
|
||||
<span>
|
||||
<strong>{{ child.name }}</strong>
|
||||
<small class="text-muted" style="margin-left:0.5rem;">{{ child.installed_count() }}/{{ child.battery_slots }} slots · {{ child.battery_size }}{% if child.ha_entity_id %} · HA{% endif %}</small>
|
||||
</span>
|
||||
<span style="display:flex;gap:0.5rem;align-items:center;">
|
||||
{% if child_free > 0 and child_batteries %}<small class="text-muted">{{ child_batteries|length }} available</small>{% endif %}
|
||||
<a href="{{ url_for('device_detail', device_id=child.id) }}" onclick="event.stopPropagation();" style="font-size:0.8rem;">View</a>
|
||||
</span>
|
||||
</summary>
|
||||
<div style="padding:0.6rem 0.9rem;border-top:1px solid var(--border);">
|
||||
{% if child_free <= 0 %}
|
||||
<p class="text-muted" style="margin:0;">No free slots.</p>
|
||||
{% elif not child_batteries %}
|
||||
<p class="text-muted" style="margin:0;">No compatible batteries available.</p>
|
||||
{% else %}
|
||||
<form method="post" action="{{ url_for('device_install_batch', device_id=child.id) }}">
|
||||
<div style="margin-bottom:0.4rem;">
|
||||
<label style="font-size:0.85rem;cursor:pointer;">
|
||||
<input type="checkbox" id="select-all-child-{{ child.id }}" onchange="toggleAllChild{{ child.id }}(this)"> Select all
|
||||
</label>
|
||||
</div>
|
||||
<div style="max-height:180px;overflow-y:auto;border:1px solid #cbd5e1;border-radius:4px;padding:0.4rem 0.6rem;">
|
||||
{% for b in child_batteries %}
|
||||
<div>
|
||||
<label style="font-size:0.9rem;cursor:pointer;">
|
||||
<input type="checkbox" class="child-bat-{{ child.id }}" name="battery_ids" value="{{ b.id }}">
|
||||
{{ b.label }} — {{ b.brand }}{% if b.battery_percentage is not none %} ({{ b.battery_percentage }}%){% endif %}
|
||||
</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<button class="btn btn-sm btn-primary" type="submit" style="margin-top:0.5rem;">Install Selected</button>
|
||||
</form>
|
||||
<script>
|
||||
(function() {
|
||||
var FREE_{{ child.id }} = {{ child_free }};
|
||||
var queue_{{ child.id }} = [];
|
||||
document.querySelectorAll('.child-bat-{{ child.id }}').forEach(function(cb) {
|
||||
cb.addEventListener('change', function() {
|
||||
if (cb.checked) {
|
||||
queue_{{ child.id }}.push(cb);
|
||||
if (queue_{{ child.id }}.length > FREE_{{ child.id }}) {
|
||||
queue_{{ child.id }}.shift().checked = false;
|
||||
}
|
||||
} else {
|
||||
queue_{{ child.id }} = queue_{{ child.id }}.filter(function(c) { return c !== cb; });
|
||||
}
|
||||
document.getElementById('select-all-child-{{ child.id }}').checked = false;
|
||||
});
|
||||
});
|
||||
window['toggleAllChild{{ child.id }}'] = function(masterCb) {
|
||||
var all = Array.from(document.querySelectorAll('.child-bat-{{ child.id }}'));
|
||||
if (masterCb.checked) {
|
||||
queue_{{ child.id }} = [];
|
||||
all.forEach(function(c) { c.checked = false; });
|
||||
all.slice(0, FREE_{{ child.id }}).forEach(function(c) { c.checked = true; queue_{{ child.id }}.push(c); });
|
||||
if (all.length > FREE_{{ child.id }}) masterCb.checked = false;
|
||||
} else {
|
||||
all.forEach(function(c) { c.checked = false; });
|
||||
queue_{{ child.id }} = [];
|
||||
}
|
||||
};
|
||||
})();
|
||||
</script>
|
||||
{% endif %}
|
||||
</div>
|
||||
</details>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
|
||||
Reference in New Issue
Block a user