Combat tracker: multiple named encounters

- Encounter entity; Combatant now belongs to an encounter (ON DELETE
  CASCADE). Migration adds encounter_id, rehoming any existing combatants.
- /tracker lists encounters (name, count, last updated) with a "New
  encounter" form; /tracker/{id} is the HP tracker for one encounter.
- Encounters can be renamed, have their combatants cleared, or be deleted.
- The Enemies list gains an encounter picker next to "Add to tracker"
  (existing encounter or "— New encounter —", which prompts for a name);
  an encounter's "Add enemies" link pre-selects it via ?encounter=.
- Routes for combatant HP/remove moved under /tracker/combatant/ to keep
  the numeric {id} for encounters.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Frank
2026-09-06 19:24:37 +02:00
co-authored by Claude Sonnet 5
parent 9854e6c034
commit cbe4b0a0e1
11 changed files with 433 additions and 112 deletions
+7 -1
View File
@@ -5,10 +5,16 @@
{% block body %}
<div class="d-flex justify-content-between align-items-center mb-3 gap-2 flex-wrap">
<h1 class="h3 mb-0">Enemies</h1>
<div class="d-flex gap-2"
<div class="d-flex gap-2 align-items-center flex-wrap"
data-controller="tracker-picker"
data-tracker-picker-url-value="{{ path('app_tracker_add') }}"
data-tracker-picker-token-value="{{ csrf_token('track-add') }}">
<select class="form-select form-select-sm encounter-select" style="width: auto;" aria-label="Encounter">
<option value="new"{{ selected_encounter is null ? ' selected' }}>— New encounter —</option>
{% for e in encounters %}
<option value="{{ e.id }}"{{ selected_encounter == e.id ? ' selected' }}>{{ e.name }}</option>
{% endfor %}
</select>
<button type="button" class="btn btn-outline-primary btn-sm" data-action="tracker-picker#submit">
Add to tracker
</button>