feat(front) : retouches UX saisie bovin (filtre, toast, partial save, fix isSaisi)
- isSaisi : != null couvre les champs absents du JSON (API Platform strip null) - UiNumberInput : ne réécrit target.value que si réellement clampé (fix saisie décimaux) - Form : champs optionnels, payload partiel, toast de confirmation - Page : filtre N° national au-dessus de la liste Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,36 +14,49 @@
|
||||
|
||||
<div v-if="loading" class="text-center text-slate-500">Chargement…</div>
|
||||
|
||||
<div v-else class="space-y-3">
|
||||
<UiAccordion
|
||||
v-for="bovine in sortedBovines"
|
||||
:key="bovine.id"
|
||||
:model-value="openId === bovine.id"
|
||||
@update:model-value="onToggle(bovine.id, $event)"
|
||||
>
|
||||
<template #header>
|
||||
<span class="flex items-center gap-3 normal-case">
|
||||
<span class="font-bold text-base">{{ bovine.nationalNumber }}</span>
|
||||
<span
|
||||
v-if="isSaisi(bovine)"
|
||||
class="inline-block rounded px-2 py-0.5 text-xs font-semibold bg-green-100 text-green-700"
|
||||
>
|
||||
Saisie
|
||||
</span>
|
||||
<span
|
||||
v-else
|
||||
class="inline-block rounded px-2 py-0.5 text-xs font-semibold bg-yellow-100 text-yellow-700"
|
||||
>
|
||||
Attente saisie
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
<BovineInfoForm
|
||||
:bovine="bovine"
|
||||
:buildings="buildings"
|
||||
@saved="onSaved"
|
||||
<div v-else>
|
||||
<div class="mb-4 max-w-[200px]">
|
||||
<UiTextInput
|
||||
v-model="searchQuery"
|
||||
placeholder="N° national"
|
||||
size="compact"
|
||||
inputmode="numeric"
|
||||
pattern="[0-9]*"
|
||||
inputClass="text-xl"
|
||||
/>
|
||||
</UiAccordion>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
<UiAccordion
|
||||
v-for="bovine in filteredBovines"
|
||||
:key="bovine.id"
|
||||
:model-value="openId === bovine.id"
|
||||
@update:model-value="onToggle(bovine.id, $event)"
|
||||
>
|
||||
<template #header>
|
||||
<span class="flex items-center gap-3 normal-case">
|
||||
<span class="font-bold text-base">{{ bovine.nationalNumber }}</span>
|
||||
<span
|
||||
v-if="isSaisi(bovine)"
|
||||
class="inline-block rounded px-2 py-0.5 text-xs font-semibold bg-green-100 text-green-700"
|
||||
>
|
||||
Saisie
|
||||
</span>
|
||||
<span
|
||||
v-else
|
||||
class="inline-block rounded px-2 py-0.5 text-xs font-semibold bg-yellow-100 text-yellow-700"
|
||||
>
|
||||
Attente saisie
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
<BovineInfoForm
|
||||
:bovine="bovine"
|
||||
:buildings="buildings"
|
||||
@saved="onSaved"
|
||||
/>
|
||||
</UiAccordion>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -53,6 +66,7 @@ import type { BovineData } from '~/services/dto/bovine-data'
|
||||
import type { BuildingData } from '~/services/dto/building-data'
|
||||
import type { ReceptionData } from '~/services/dto/reception-data'
|
||||
import { getBuildingList } from '~/services/building'
|
||||
import BovineInfoForm from '~/components/entry-exit/bovine-info-form.vue'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
@@ -65,15 +79,22 @@ const bovines = ref<BovineData[]>([])
|
||||
const buildings = ref<BuildingData[]>([])
|
||||
const loading = ref(true)
|
||||
const openId = ref<number | null>(null)
|
||||
const searchQueryRaw = ref('')
|
||||
const searchQuery = computed<string>({
|
||||
get: () => searchQueryRaw.value,
|
||||
set: (value) => {
|
||||
searchQueryRaw.value = value.replace(/\D/g, '')
|
||||
}
|
||||
})
|
||||
|
||||
useHead({
|
||||
title: () => `Saisie information bovin ${reception.value?.identificationNumber ?? ''}`.trim()
|
||||
})
|
||||
|
||||
const isSaisi = (bovine: BovineData) =>
|
||||
bovine.receivedWeight !== null
|
||||
&& bovine.pricePerKg !== null
|
||||
&& bovine.buildingCase !== null
|
||||
bovine.receivedWeight != null
|
||||
&& bovine.pricePerKg != null
|
||||
&& bovine.buildingCase != null
|
||||
|
||||
const sortedBovines = computed(() => {
|
||||
const pending = bovines.value.filter(b => !isSaisi(b))
|
||||
@@ -81,6 +102,14 @@ const sortedBovines = computed(() => {
|
||||
return [...pending, ...done]
|
||||
})
|
||||
|
||||
const filteredBovines = computed(() => {
|
||||
const query = searchQuery.value.trim().toLowerCase()
|
||||
if (!query) return sortedBovines.value
|
||||
return sortedBovines.value.filter(b =>
|
||||
b.nationalNumber.toLowerCase().includes(query)
|
||||
)
|
||||
})
|
||||
|
||||
const onToggle = (bovineId: number, value: boolean) => {
|
||||
openId.value = value ? bovineId : null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user