Add signalement (flag) tags for problem lines on /lignes

New field_flag: free-tagging taxonomy reference (multi-value,
auto-create) on ligne_comptable, for marking a line with an
unstructured problem description (e.g. "client impayé") that can't be
detected automatically the way the répartition écart already is.

- New "Signalement" column, inline-editable like Client/Facture/Libellé
  (comma-separated tags, datalist autocomplete, server-side auto-create
  of unknown tags -- same pattern LedgerActionsController already used
  for Client, now shared via findOrCreateTerm()).
- New "Signalées uniquement" filter, mirroring "Écarts uniquement".
- Flagged rows get a distinct amber left-edge accent (box-shadow, not
  border) so a row that's both in écart and signalée shows both
  indicators without one overwriting the other.
- Native node add/edit form gets the field for free via core's
  entity_reference_autocomplete_tags widget.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-06 14:55:46 +02:00
co-authored by Claude Sonnet 5
parent ceaf301bf0
commit 34b1082991
10 changed files with 284 additions and 46 deletions
@@ -87,6 +87,14 @@
<input type="checkbox" v-model="onlyErrors" /> Écarts uniquement
</label>
<label class="figli-checkbox">
<input type="checkbox" v-model="onlyFlagged" /> Signalées uniquement
</label>
<datalist id="figli-flag-datalist">
<option v-for="f in allFlagsList" :key="f" :value="f"></option>
</datalist>
<span class="figli-count" v-if="!loading">{{ filteredRows.length }} / {{ rows.length }} lignes chargées{{ errorCount ? ' — ' + errorCount + ' avec écart' : '' }}</span>
</div>
@@ -105,6 +113,7 @@
<th>Type</th>
<th>Facture</th>
<th>Libellé / Détail</th>
<th>Signalement</th>
<th class="amount">Montant HT</th>
<th class="amount">Montant TTC</th>
<th v-for="c in allComptes" :key="c" class="amount compte-col">{{ c }}</th>
@@ -113,15 +122,15 @@
</thead>
<tbody>
<tr ref="topSentinel" class="figli-sentinel-row">
<td :colspan="7 + allComptes.length + 3">
<td :colspan="8 + allComptes.length + 3">
<span v-if="loadingOlder">Chargement des mois précédents…</span>
</td>
</tr>
<template v-for="item in groupedRows" :key="item.key">
<tr v-if="item.isGroup" class="figli-group-row" :data-year="item.year">
<td :colspan="7 + allComptes.length + 3">{{ item.label }} <span class="figli-note">({{ item.count }} lignes)</span></td>
<td :colspan="8 + allComptes.length + 3">{{ item.label }} <span class="figli-note">({{ item.count }} lignes)</span></td>
</tr>
<tr v-else :class="{'figli-error-row': item.hasError}" :data-year="item.date ? item.date.slice(0, 4) : null">
<tr v-else :class="{'figli-error-row': item.hasError, 'figli-flag-row': item.hasFlag}" :data-year="item.date ? item.date.slice(0, 4) : null">
<td class="actions-col">
<button
v-if="item.linkable"
@@ -225,6 +234,23 @@
>{{ linkStatus(item).kind === 'ok' ? '' : '⚠ ' }}{{ linkStatusLabel(linkStatus(item)) }}</span>
</template>
</td>
<td class="figli-flag-cell">
<input
v-if="isEditingCell(item, 'flag')"
v-focus
type="text"
class="figli-inline-input"
list="figli-flag-datalist"
:value="item.flags.join(', ')"
@change="saveCell(item, 'flag', $event)"
@blur="editingCell = null"
@keyup.enter="$event.target.blur()"
/>
<span v-else class="figli-editable-cell" title="Cliquer pour signaler un problème" @click="startEditCell(item, 'flag')">
<template v-if="item.flags.length"><span v-for="f in item.flags" :key="f" class="figli-flag-badge">{{ f }}</span></template>
<template v-else>—</template>
</span>
</td>
<td class="amount" :class="montantClass(item.montant_ht)">{{ formatEur(item.montant_ht) }}</td>
<td class="amount">{{ formatEur(item.montant_ttc) }}</td>
<td v-for="c in allComptes" :key="c" class="amount compte-col">{{ item.parCompte[c] !== undefined ? formatEur(item.parCompte[c]) : '' }}</td>
@@ -232,7 +258,7 @@
</tr>
</template>
<tr ref="bottomSentinel" class="figli-sentinel-row">
<td :colspan="7 + allComptes.length + 3">
<td :colspan="8 + allComptes.length + 3">
<span v-if="loadingNewer">Chargement des mois suivants…</span>
</td>
</tr>
@@ -241,7 +267,7 @@
<tr class="figli-totals-row">
<td class="actions-col"></td>
<td class="actions-col"></td>
<td colspan="5">
<td colspan="6">
Solde {{ currentYear || '…' }} (créditeur / débiteur)
<span v-if="currentYearLoading" class="figli-note">chargement…</span>
</td>