Surface signalement (flag) tags on the per-compte dashboard

Fetches field_flag alongside the existing entrée/versement data (same
JSON:API include list, same buildRows() shape as home.js's flags/
hasFlag). Two changes:

- Rows already shown in the reste-à-verser/sur-versé/non-liés tables
  get the same amber left-edge accent + tag badges as /lignes when
  they're also flagged.
- New "Lignes signalées" section lists every flagged entrée/versement
  for the selected compte, including ones that don't appear in any of
  the other tables -- a fully-settled line can still carry a flag for
  an unrelated reason (e.g. "client injoignable"), which none of the
  reconciliation-based tables would otherwise surface.

Verified live against an isolated test node plus two real flagged lines
already present in production data (client had already started using
the /lignes signalement feature) -- both the section and the inline
badges render correctly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-06 16:43:44 +02:00
co-authored by Claude Sonnet 5
parent 3f8767b4ef
commit 9ce5d87ace
3 changed files with 62 additions and 7 deletions
@@ -42,6 +42,8 @@
const clientTerm = resolve(includedMap, rels.field_client && rels.field_client.data);
const entreeLieeRefs = (rels.field_entree_liee && rels.field_entree_liee.data) || [];
const entreeLieeIds = entreeLieeRefs.map((ref) => ref.id);
const flagRefs = (rels.field_flag && rels.field_flag.data) || [];
const flags = flagRefs.map((ref) => resolve(includedMap, ref)).filter(Boolean).map((t) => t.attributes.name);
const parCompte = {};
const repartitionRefs = (rels.field_repartition && rels.field_repartition.data) || [];
for (const ref of repartitionRefs) {
@@ -61,6 +63,8 @@
libelle: attrs.field_notes || attrs.title,
parCompte,
entreeLieeIds,
flags,
hasFlag: flags.length > 0,
});
}
rows.sort((a, b) => (a.date || '').localeCompare(b.date || ''));
@@ -76,7 +80,7 @@
// autre/ouverture -- is exactly what this page deliberately excludes).
async function fetchEntreesEtVersements() {
const params = new URLSearchParams();
params.set('include', 'field_repartition,field_repartition.field_compte,field_client,field_entree_liee');
params.set('include', 'field_repartition,field_repartition.field_compte,field_client,field_entree_liee,field_flag');
params.set('filter[typeFilter][condition][path]', 'field_type_ligne');
params.set('filter[typeFilter][condition][operator]', 'IN');
params.append('filter[typeFilter][condition][value][]', 'entree');
@@ -286,6 +290,18 @@
.filter((r) => r.type === 'versement' && r.parCompte[this.selectedCompte] !== undefined && r.entreeLieeIds.length === 0)
.sort((a, b) => (b.date || '').localeCompare(a.date || ''));
},
// Toute ligne entrée/versement de ce compte portant un signalement
// (voir /lignes), qu'elle apparaisse déjà dans une des listes
// ci-dessus ou non -- une ligne entièrement soldée peut quand même
// porter un problème sans rapport avec le montant (ex. "client
// injoignable"), auquel cas aucune des trois listes ci-dessus ne
// la montrerait autrement.
lignesSignalees() {
if (!this.selectedCompte) return [];
return this.allRows
.filter((r) => r.hasFlag && r.parCompte[this.selectedCompte] !== undefined)
.sort((a, b) => (b.date || '').localeCompare(a.date || ''));
},
totalResteAVerser() {
return Math.round(this.resteAVerserPositif.reduce((sum, r) => sum + r.residual, 0) * 100) / 100;
},