feat : calcul de l'âge en mois côté back + colonne Age et alertes visuelles

- Champ ageMonths (int) ajouté à Bovine avec migration
- Lifecycle PrePersist/PreUpdate pour maintenir la cohérence
- Sync processor recalcule explicitement ageMonths à chaque passage (cron-friendly)
- Colonne Age + rowClass côté front : rouge >= 24 mois, orange 22-24 mois
- Util formatAgeLabel remplace le calcul client
- Boutons pagination Prev/Next en français avec style bouton bordure primary
- Colonnes Sexe/N° Travail réduites au profit de Bâtiment

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-24 09:50:39 +02:00
parent 9d3cfd10db
commit c0c6c81e74
7 changed files with 104 additions and 9 deletions

View File

@@ -19,7 +19,10 @@
v-for="(item, index) in paginatedItems"
:key="item.id ?? index"
class="grid gap-6 px-4 py-3 text-sm border-t border-slate-200"
:class="rowClickable ? 'hover:bg-slate-50 cursor-pointer' : ''"
:class="[
rowClickable ? 'hover:bg-slate-50 cursor-pointer' : '',
rowClass ? rowClass(item) : ''
]"
:style="{ gridTemplateColumns: gridCols }"
:role="rowClickable ? 'button' : undefined"
:tabindex="rowClickable ? 0 : undefined"
@@ -83,12 +86,12 @@
<nav aria-label="Pagination" class="flex items-center gap-1">
<button
type="button"
class="h-10 px-3 text-sm text-primary-500 hover:underline disabled:cursor-not-allowed disabled:text-slate-400 disabled:no-underline"
class="h-10 rounded border border-primary-500 bg-white px-3 text-sm text-primary-500 hover:bg-primary-500 hover:text-white disabled:cursor-not-allowed disabled:border-slate-300 disabled:text-slate-400 disabled:hover:bg-white disabled:hover:text-slate-400"
:disabled="currentPage <= 1"
aria-label="Page précédente"
@click="goToPage(currentPage - 1)"
>
Prev
Précédent
</button>
<template v-for="(entry, i) in visiblePages" :key="`${typeof entry}-${entry}-${i}`">
@@ -113,12 +116,12 @@
<button
type="button"
class="h-10 px-3 text-sm text-primary-500 hover:underline disabled:cursor-not-allowed disabled:text-slate-400 disabled:no-underline"
class="h-10 rounded border border-primary-500 bg-white px-3 text-sm text-primary-500 hover:bg-primary-500 hover:text-white disabled:cursor-not-allowed disabled:border-slate-300 disabled:text-slate-400 disabled:hover:bg-white disabled:hover:text-slate-400"
:disabled="currentPage >= totalPages"
aria-label="Page suivante"
@click="goToPage(currentPage + 1)"
>
Next
Suivant
</button>
</nav>
</div>
@@ -145,6 +148,7 @@ const props = withDefaults(defineProps<{
showActions?: boolean
emptyMessage?: string
loading?: boolean
rowClass?: (item: T) => string | undefined
}>(), {
totalItems: undefined,
page: 1,
@@ -153,7 +157,8 @@ const props = withDefaults(defineProps<{
rowClickable: false,
showActions: false,
emptyMessage: 'Aucune donnée',
loading: false
loading: false,
rowClass: undefined
})
const emit = defineEmits<{