Files
Starseed/frontend/modules/transport/composables/useQualimatSearch.ts
T
tristan f70e701854
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 3m8s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m36s
feat(transport) : saisie assistée QUALIMAT + champs conditionnels (ERP-166)
2026-06-16 17:22:25 +02:00

77 lines
2.5 KiB
TypeScript

import { ref } from 'vue'
import { debounce } from '~/shared/utils/debounce'
import type { HydraCollection } from '~/shared/utils/api'
/**
* Ligne du référentiel QUALIMAT renvoyée par la saisie assistée (groupe
* `qualimat:read`). `@id` est l'IRI conservée comme FK `carrier.qualimatCarrier`
* (RG-4.01 / § 2.5) ; `validityDate` pilote le fond rouge de la colonne « Date de
* validité » (RG-4.04).
*/
export interface QualimatCarrierRow {
'@id': string
id: string
name: string | null
siret: string | null
address: string | null
postalCode: string | null
city: string | null
validityDate: string | null
status: string | null
}
/** Délai de debounce de la recherche (ms) — une requête après la dernière frappe. */
const SEARCH_DEBOUNCE_MS = 300
/**
* Saisie assistée QUALIMAT (M4 Transport, ERP-166 — RG-4.01 / spec-back § 4.7).
*
* `GET /api/qualimat_carriers?search=` : référentiel en LECTURE SEULE, lignes
* actives uniquement (filtré côté serveur), recherche fuzzy nom + siret. Alimente
* le tableau de sélection de l'onglet Qualimat ; la ligne choisie est copiée dans
* le formulaire principal (cf. `useCarrierForm.applyQualimatSelection`).
*
* Volontairement PAR INSTANCE (état local à l'écran d'ajout). `search()` est
* debouncé (anti-spam réseau) ; `fetchNow()` expose l'appel immédiat (montage /
* tests).
*/
export function useQualimatSearch() {
const api = useApi()
const results = ref<QualimatCarrierRow[]>([])
const loading = ref(false)
/** Lance immédiatement la recherche (sans debounce). */
async function fetchNow(term: string): Promise<void> {
loading.value = true
try {
const data = await api.get<HydraCollection<QualimatCarrierRow>>(
'/qualimat_carriers',
{ search: term.trim() },
{ headers: { Accept: 'application/ld+json' }, toast: false },
)
results.value = data.member ?? []
}
catch {
// Échec réseau / 403 : on vide les résultats, pas de toast (la recherche
// assistée est non bloquante — l'utilisateur peut saisir manuellement).
results.value = []
}
finally {
loading.value = false
}
}
// Recherche debouncée branchée sur le champ de recherche de l'onglet Qualimat.
const search = debounce((term: string) => {
void fetchNow(term)
}, SEARCH_DEBOUNCE_MS)
return {
results,
loading,
search,
fetchNow,
}
}