refactor(transport) : onglet Qualimat en MalioDataTable paginé, recherche branchée sur le nom (ERP-166)
This commit is contained in:
@@ -131,57 +131,42 @@
|
||||
assistee (table de selection) ; Adresses / Contacts / Prix arrivent aux
|
||||
tickets suivants (placeholders « A venir »). -->
|
||||
<MalioTabList v-model="activeTab" :tabs="tabs" class="mt-[60px]">
|
||||
<!-- Onglet Qualimat : recherche + table de selection (RG-4.01 / 4.04). -->
|
||||
<!-- Onglet Qualimat : datatable paginé filtré par le NOM du transporteur
|
||||
(pas de champ de recherche dédié — RG-4.01 / 4.04). -->
|
||||
<template #qualimat>
|
||||
<div class="mt-12 flex flex-col gap-6">
|
||||
<MalioInputText
|
||||
v-model="qualimatTerm"
|
||||
icon-name="mdi:magnify"
|
||||
:label="t('transport.carriers.form.qualimat.search')"
|
||||
/>
|
||||
|
||||
<table class="w-full border-collapse text-left">
|
||||
<thead>
|
||||
<tr class="border-b border-black">
|
||||
<th class="w-12 py-2"></th>
|
||||
<th class="py-2 font-semibold">{{ t('transport.carriers.form.qualimat.columns.name') }}</th>
|
||||
<th class="py-2 font-semibold">{{ t('transport.carriers.form.qualimat.columns.address') }}</th>
|
||||
<th class="py-2 font-semibold">{{ t('transport.carriers.form.qualimat.columns.validityDate') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="row in qualimatResults"
|
||||
:key="row.id"
|
||||
class="cursor-pointer border-b border-m-muted/30 hover:bg-m-muted/10"
|
||||
@click="askIntegrate(row)"
|
||||
<MalioDataTable
|
||||
:columns="qualimatColumns"
|
||||
:items="qualimatRows"
|
||||
:total-items="qualimatTotal"
|
||||
:page="qualimatPage"
|
||||
:per-page="qualimatPerPage"
|
||||
:per-page-options="qualimatPerPageOptions"
|
||||
row-clickable
|
||||
:empty-message="t('transport.carriers.form.qualimat.empty')"
|
||||
@row-click="onQualimatRowClick"
|
||||
@update:page="qualimatGoToPage"
|
||||
@update:per-page="qualimatSetPerPage"
|
||||
>
|
||||
<!-- Radio reflétant la ligne QUALIMAT intégrée (lecture). -->
|
||||
<template #cell-select="{ item }">
|
||||
<MalioRadioButton
|
||||
:model-value="main.qualimatCarrierIri"
|
||||
name="qualimat-row"
|
||||
:value="item.iri"
|
||||
group-class="mt-0"
|
||||
/>
|
||||
</template>
|
||||
<!-- Date de validité : fond rouge si périmée (RG-4.04). -->
|
||||
<template #cell-validityDate="{ item }">
|
||||
<span
|
||||
v-if="item.validityDate"
|
||||
:class="isExpired(item.validityDate as string) ? 'inline-block rounded px-2 py-0.5 bg-m-danger text-white' : ''"
|
||||
>
|
||||
<td class="py-2">
|
||||
<MalioRadioButton
|
||||
:model-value="main.qualimatCarrierIri"
|
||||
name="qualimat-row"
|
||||
:value="row['@id']"
|
||||
group-class="mt-0"
|
||||
/>
|
||||
</td>
|
||||
<td class="py-2">{{ row.name }}</td>
|
||||
<td class="py-2">{{ formatQualimatAddress(row) }}</td>
|
||||
<td class="py-2">
|
||||
<span
|
||||
v-if="row.validityDate"
|
||||
:class="isExpired(row.validityDate) ? 'inline-block rounded px-2 py-0.5 bg-m-danger text-white' : ''"
|
||||
>
|
||||
{{ formatDateFr(row.validityDate) }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="qualimatResults.length === 0">
|
||||
<td colspan="4" class="py-4 text-center text-m-muted">
|
||||
{{ t('transport.carriers.form.qualimat.empty') }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{{ formatDateFr(item.validityDate as string) }}
|
||||
</span>
|
||||
</template>
|
||||
</MalioDataTable>
|
||||
|
||||
<div v-if="!isValidated('qualimat')" class="flex justify-center">
|
||||
<MalioButton
|
||||
@@ -272,18 +257,52 @@ const {
|
||||
completeTab,
|
||||
} = useCarrierForm()
|
||||
|
||||
const { results: qualimatResults, fetchNow: qualimatFetch, search: qualimatSearchDebounced } = useQualimatSearch()
|
||||
const {
|
||||
items: qualimatItems,
|
||||
totalItems: qualimatTotal,
|
||||
currentPage: qualimatPage,
|
||||
itemsPerPage: qualimatPerPage,
|
||||
itemsPerPageOptions: qualimatPerPageOptions,
|
||||
goToPage: qualimatGoToPage,
|
||||
setItemsPerPage: qualimatSetPerPage,
|
||||
setFilters: qualimatSetFilters,
|
||||
} = useQualimatSearch()
|
||||
|
||||
// Certifications selectionnables manuellement (spec § Formulaire principal).
|
||||
// QUALIMAT n'y figure PAS : il est pose par la saisie assistee (onglet Qualimat).
|
||||
// Certifications selectionnables manuellement (spec § Formulaire principal) :
|
||||
// GMP+ / OVOCOM / Compte-propre / Autre. QUALIMAT n'y figure PAS — il est posé par
|
||||
// la saisie assistee (onglet Qualimat). On l'ajoute cependant aux options QUAND il
|
||||
// est deja selectionne (transporteur QUALIMAT integre), uniquement pour AFFICHER
|
||||
// son libelle dans le select en lecture seule.
|
||||
const SELECTABLE_CERTIFICATIONS = ['GMP_PLUS', 'OVOCOM', 'COMPTE_PROPRE', 'AUTRE'] as const
|
||||
|
||||
const certificationOptions = computed<SelectOption[]>(() =>
|
||||
SELECTABLE_CERTIFICATIONS.map(code => ({
|
||||
const certificationOptions = computed<SelectOption[]>(() => {
|
||||
const codes: string[] = [...SELECTABLE_CERTIFICATIONS]
|
||||
if (main.certificationType === 'QUALIMAT') {
|
||||
codes.unshift('QUALIMAT')
|
||||
}
|
||||
return codes.map(code => ({
|
||||
value: code,
|
||||
label: t(`transport.carriers.certification.${code}`),
|
||||
})),
|
||||
)
|
||||
}))
|
||||
})
|
||||
|
||||
// Colonnes du datatable de selection QUALIMAT (radio / Nom / Adresse / Validite).
|
||||
const qualimatColumns = [
|
||||
{ key: 'select', label: '' },
|
||||
{ key: 'name', label: t('transport.carriers.form.qualimat.columns.name') },
|
||||
{ key: 'address', label: t('transport.carriers.form.qualimat.columns.address') },
|
||||
{ key: 'validityDate', label: t('transport.carriers.form.qualimat.columns.validityDate') },
|
||||
]
|
||||
|
||||
// Lignes « plates » pour MalioDataTable (l'IRI sert au radio + à retrouver la ligne
|
||||
// source au clic). Le détail QUALIMAT complet reste dans `qualimatItems`.
|
||||
const qualimatRows = computed(() => qualimatItems.value.map(row => ({
|
||||
id: row.id,
|
||||
iri: row['@id'],
|
||||
name: row.name,
|
||||
address: formatQualimatAddress(row),
|
||||
validityDate: row.validityDate,
|
||||
})))
|
||||
|
||||
// Contenant (RG-4.03) : Benne / Fond mouvant — select simple.
|
||||
const CONTAINER_TYPES = ['BENNE', 'FOND_MOUVANT'] as const
|
||||
@@ -316,19 +335,16 @@ const tabs = computed(() => tabKeys.value.map((key, index) => ({
|
||||
const placeholderTabs = computed(() => tabKeys.value.filter(key => key !== 'qualimat'))
|
||||
|
||||
// ── Saisie assistee QUALIMAT (onglet Qualimat) ───────────────────────────────
|
||||
const qualimatTerm = ref('')
|
||||
const qualimatLoaded = ref(false)
|
||||
const confirmOpen = ref(false)
|
||||
const pendingRow = ref<QualimatCarrierRow | null>(null)
|
||||
|
||||
// Recherche debouncee a chaque frappe.
|
||||
watch(qualimatTerm, term => qualimatSearchDebounced(term))
|
||||
|
||||
// Premier chargement (liste active complete) quand l'onglet Qualimat devient actif.
|
||||
// Chargement quand l'onglet Qualimat devient actif : la recherche est branchée sur
|
||||
// le NOM saisi dans le formulaire principal (RG-4.01) — pas de champ dédié.
|
||||
watch(activeTab, (tab) => {
|
||||
if (tab === 'qualimat' && !qualimatLoaded.value) {
|
||||
qualimatLoaded.value = true
|
||||
qualimatFetch('').catch(() => {})
|
||||
void qualimatSetFilters({ search: main.name })
|
||||
}
|
||||
})
|
||||
|
||||
@@ -363,7 +379,15 @@ function formatDateFr(value: string | null | undefined): string {
|
||||
return `${day}-${month}-${date.getFullYear()}`
|
||||
}
|
||||
|
||||
/** Clic sur une ligne QUALIMAT → modal de confirmation d'integration. */
|
||||
/** Clic sur une ligne du datatable → retrouve la ligne QUALIMAT source + modal. */
|
||||
function onQualimatRowClick(item: Record<string, unknown>): void {
|
||||
const row = qualimatItems.value.find(r => r.id === item.id)
|
||||
if (row) {
|
||||
askIntegrate(row)
|
||||
}
|
||||
}
|
||||
|
||||
/** Ouvre la modal de confirmation d'integration pour une ligne QUALIMAT. */
|
||||
function askIntegrate(row: QualimatCarrierRow): void {
|
||||
pendingRow.value = row
|
||||
confirmOpen.value = true
|
||||
|
||||
Reference in New Issue
Block a user