Three features: device dropdown filter, charge log history, unassign-all

- Device dropdowns (quick-assign, bulk install, assign page) now only show
  devices with free slots; full devices are excluded entirely
- New ChargeLog model tracks charge dates with optional cycle increment;
  battery detail page gets a Charge History card with add/delete rows
- Device list page gets per-device Unassign All button (with confirmation)
  via new POST /device/<id>/unassign-all route
This commit is contained in:
2026-04-13 08:12:23 -05:00
parent 6597fcd4ac
commit b1bc02e963
6 changed files with 167 additions and 25 deletions
+6 -13
View File
@@ -11,23 +11,16 @@
<div class="form-group">
<label>Select Device</label>
{% for device in devices %}
{% set full = device.installed_count() >= device.battery_slots %}
{% set mix = device.installed_brands() and battery.brand not in device.installed_brands() %}
<div class="device-option" style="margin-bottom:0.75rem;padding:0.75rem;border:1px solid #e2e8f0;border-radius:4px;
{% if full %}opacity:0.5;{% endif %}background:#fff;">
<label style="display:flex;align-items:center;gap:0.6rem;font-weight:normal;min-height:44px;cursor:{% if full %}not-allowed{% else %}pointer{% endif %};">
<input type="radio" name="device_id" value="{{ device.id }}"
{% if full %}disabled{% endif %}
style="cursor:{% if full %}not-allowed{% else %}pointer{% endif %};">
{% set mix = device.installed_brands() and battery.brand not in device.installed_brands() %}
<div class="device-option" style="margin-bottom:0.75rem;padding:0.75rem;border:1px solid #e2e8f0;border-radius:4px;background:#fff;">
<label style="display:flex;align-items:center;gap:0.6rem;font-weight:normal;min-height:44px;cursor:pointer;">
<input type="radio" name="device_id" value="{{ device.id }}" style="cursor:pointer;">
<span>
<strong>{{ device.name }}</strong>
<span class="text-muted">({{ device.installed_count() }}/{{ device.battery_slots }} slots used)</span>
{% if full %}
<span class="badge badge-retired">Full</span>
{% endif %}
</span>
</label>
{% if mix and not full %}
{% if mix %}
<p class="text-warning" style="margin-top:0.3rem;margin-left:1.6rem;">
⚠ Already has {{ device.installed_brands()|join(', ') }} — mixing brands not recommended.
</p>
@@ -42,7 +35,7 @@
</div>
</form>
{% else %}
<p class="text-muted">No devices exist yet. <a href="{{ url_for('device_add') }}">Add a device first.</a></p>
<p class="text-muted">No devices with free slots. <a href="{{ url_for('device_add') }}">Add a device</a> or free up slots first.</p>
{% endif %}
</div>
{% endblock %}