feat(front) : util httpExternal + autocomplete adresse BAN (ERP-66) (#52)
Auto Tag Develop / tag (push) Successful in 7s
Auto Tag Develop / tag (push) Successful in 7s
## ERP-66 — Utilitaires adresse/téléphone + autocomplétion BAN ### feat - **httpExternal** : client dédié aux API publiques externes (URL absolue, sans cookie de session, timeout). Seul point d'entrée autorisé pour un `$fetch` externe (règle frontend n°4). - **useAddressAutocomplete** : implémentation BAN (api-adresse.data.gouv.fr) — recherche ville (`type=municipality`) et adresse, mapping GeoJSON, throw en cas d'erreur/timeout (mode dégradé côté composant). La recherche d'adresse n'impose **pas** `type=housenumber` (sinon 0 résultat tant qu'aucun numéro n'est saisi) — spec-front mise à jour. - Tests Vitest : httpExternal, useAddressAutocomplete, cas limites `formatPhoneFR`. ### fix - **ClientAddressBlock** : la rue courante est toujours réinjectée dans les options de `MalioInputAutocomplete` (computed, miroir de `cityOptions`). Corrige le champ Adresse qui se vidait après validation / à l'édition d'une adresse existante (valeur pourtant persistée). Test de montage ajouté. - **useClientReferentials** : libellé des sites = numéro de département (2 premiers chiffres du code postal, déjà exposé par `/sites`) au lieu du nom. ### Vérifs - ESLint ✅ · Vitest 196/196 ✅ - Changements 100% frontend (+ doc spec). Reviewed-on: #52 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #52.
This commit is contained in:
@@ -233,7 +233,7 @@
|
||||
<template v-if="canAccountingView" #accounting>
|
||||
<div class="mt-12 flex flex-col gap-6">
|
||||
<div class="bg-white py-4 pl-[28px] pr-[60px] shadow-[0_4px_4px_0_rgba(0,0,0,0.25)]">
|
||||
<div class="grid grid-cols-3 gap-x-[80px] gap-y-5">
|
||||
<div class="grid grid-cols-4 gap-x-[44px] gap-y-4">
|
||||
<MalioInputText
|
||||
v-model="accounting.siren"
|
||||
:label="t('commercial.clients.form.accounting.siren')"
|
||||
@@ -301,7 +301,7 @@
|
||||
v-bind="{ ariaLabel: t('commercial.clients.form.accounting.removeRib') }"
|
||||
@click="askRemoveRib(index)"
|
||||
/>
|
||||
<div class="grid grid-cols-3 gap-x-[80px] gap-y-5">
|
||||
<div class="grid grid-cols-4 gap-x-[44px] gap-y-4">
|
||||
<MalioInputText
|
||||
v-model="rib.label"
|
||||
:label="t('commercial.clients.form.accounting.ribLabel')"
|
||||
@@ -341,7 +341,7 @@
|
||||
<!-- Onglet non encore implemente : frame vide, passage automatique.
|
||||
Statistiques / Rapports / Echanges sont edit-only (absents a la
|
||||
creation) — cf. buildClientFormTabKeys. -->
|
||||
<template #transport><TabPlaceholderBlank /></template>
|
||||
<template #transport><ComingSoonPlaceholder /></template>
|
||||
</MalioTabList>
|
||||
|
||||
<!-- Modal de confirmation generique (suppression contact/adresse/RIB). -->
|
||||
@@ -755,7 +755,9 @@ const canValidateAddresses = computed(() =>
|
||||
addresses.value.length > 0
|
||||
&& addresses.value.every((a) => {
|
||||
const filledBillingEmail = a.billingEmail !== null && a.billingEmail.trim() !== ''
|
||||
return a.siteIris.length >= 1 && (!isBillingEmailRequired(a) || filledBillingEmail)
|
||||
return a.siteIris.length >= 1
|
||||
&& a.categoryIris.length >= 1
|
||||
&& (!isBillingEmailRequired(a) || filledBillingEmail)
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -870,6 +872,8 @@ function addRib(): void {
|
||||
function askRemoveRib(index: number): void {
|
||||
askConfirm(t('commercial.clients.form.confirmDelete.rib'), () => {
|
||||
ribs.value.splice(index, 1)
|
||||
// Garde au moins un bloc RIB visible (cf. amorce au montage).
|
||||
if (ribs.value.length === 0) ribs.value.push(emptyRib())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -956,5 +960,8 @@ interface ContactResponse {
|
||||
onMounted(() => {
|
||||
// Echec du chargement des referentiels non bloquant : les selects restent vides.
|
||||
referentials.loadCommon().catch(() => {})
|
||||
// Au moins un bloc RIB toujours visible en creation : on amorce un bloc vide
|
||||
// (non persiste tant qu'incomplet — RG-1.13).
|
||||
if (ribs.value.length === 0) ribs.value.push(emptyRib())
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user