refactor(front) : volume prévisionnel en champ texte masqué + bloc adresse fournisseur aligné sur le client (radio type sans label, une colonne, required par radio) (ERP-94)

This commit is contained in:
2026-06-09 22:46:40 +02:00
parent 01a3bd6419
commit 86373f0d3c
2 changed files with 64 additions and 64 deletions
@@ -11,29 +11,64 @@
/> />
<!-- Type d'adresse : radio exclusif Prospect / Depart / Rendu (RG-2.09). <!-- Type d'adresse : radio exclusif Prospect / Depart / Rendu (RG-2.09).
Erreur portee sur `addressType` cote back (Assert\Choice + NotNull) Une seule colonne (radios empiles), sans label de groupe ; le caractere
-> affichee sous le groupe. col-span-2 pour loger les 3 options. --> obligatoire est porte par chaque radio (prop `required`). L'erreur 422
<div class="col-span-2 flex flex-col gap-1"> (propertyPath `addressType`) s'affiche sous le groupe. -->
<span class="text-sm font-medium"> <div class="flex flex-col gap-2">
{{ t('commercial.suppliers.form.address.addressType') }}<span class="text-red-600">&nbsp;*</span> <MalioRadioButton
</span> v-for="opt in addressTypeOptions"
<div class="flex items-center gap-6"> :key="opt.value"
<MalioRadioButton :name="radioName"
v-for="opt in addressTypeOptions" :model-value="model.addressType"
:key="opt.value" :value="opt.value"
:name="radioName" :label="opt.label"
:model-value="model.addressType" :required="true"
:value="opt.value" :readonly="readonly"
:label="opt.label" :disabled="readonly"
:readonly="readonly" group-class="mt-0"
:disabled="readonly" @update:model-value="() => update('addressType', opt.value)"
group-class="mt-0" />
@update:model-value="() => update('addressType', opt.value)"
/>
</div>
<span v-if="errors?.addressType" class="text-sm text-red-600">{{ errors.addressType }}</span> <span v-if="errors?.addressType" class="text-sm text-red-600">{{ errors.addressType }}</span>
</div> </div>
<!-- Sites Starseed : multiselect a tags (>= 1 obligatoire, RG-2.06). -->
<MalioSelectCheckbox
:model-value="model.siteIris"
:options="siteOptions"
:label="t('commercial.suppliers.form.address.sites')"
:display-tag="true"
:readonly="readonly"
:required="true"
:error="errors?.sites"
@update:model-value="(v: (string | number)[]) => update('siteIris', v.map(String))"
/>
<!-- Contacts rattaches (M2M, facultatif). -->
<MalioSelectCheckbox
:model-value="model.contactIris"
:options="contactOptions"
:label="t('commercial.suppliers.form.address.contacts')"
:display-tag="true"
:readonly="readonly"
@update:model-value="(v: (string | number)[]) => update('contactIris', v.map(String))"
/>
<!-- Filler : aligne le debut de ligne suivant sur la grille (le bloc client
porte ici l'email de facturation, absent cote fournisseur). -->
<div aria-hidden="true" />
<!-- Categories de type FOURNISSEUR (>= 1 obligatoire, RG-2.10). -->
<MalioSelectCheckbox
:model-value="model.categoryIris"
:options="categoryOptions"
:label="t('commercial.suppliers.form.address.categories')"
:display-tag="true"
:readonly="readonly"
:required="true"
:error="errors?.categories"
@update:model-value="(v: (string | number)[]) => update('categoryIris', v.map(String))"
/>
<MalioSelect <MalioSelect
:model-value="model.country" :model-value="model.country"
:options="countryOptions" :options="countryOptions"
@@ -75,8 +110,8 @@
@update:model-value="(v: string) => update('city', v)" @update:model-value="(v: string) => update('city', v)"
/> />
<!-- Adresse (BAN) + Adresse complementaire. allow-create : le texte saisi <!-- Adresse (BAN) sur 2 colonnes + Adresse complementaire. allow-create : le
est conserve si la BAN ne propose rien (saisie manuelle). --> texte saisi est conserve si la BAN ne propose rien (saisie manuelle). -->
<div class="col-span-2"> <div class="col-span-2">
<MalioInputAutocomplete <MalioInputAutocomplete
v-if="!readonly" v-if="!readonly"
@@ -115,43 +150,6 @@
/> />
</div> </div>
<!-- Sites Starseed (>= 1 obligatoire, RG-2.06). -->
<MalioSelectCheckbox
:model-value="model.siteIris"
:options="siteOptions"
:label="t('commercial.suppliers.form.address.sites')"
:display-tag="true"
:readonly="readonly"
:required="true"
:error="errors?.sites"
@update:model-value="(v: (string | number)[]) => update('siteIris', v.map(String))"
/>
<!-- Categories de type FOURNISSEUR (>= 1 obligatoire, RG-2.10). -->
<MalioSelectCheckbox
:model-value="model.categoryIris"
:options="categoryOptions"
:label="t('commercial.suppliers.form.address.categories')"
:display-tag="true"
:readonly="readonly"
:required="true"
:error="errors?.categories"
@update:model-value="(v: (string | number)[]) => update('categoryIris', v.map(String))"
/>
<!-- Contacts rattaches (M2M, facultatif). -->
<MalioSelectCheckbox
:model-value="model.contactIris"
:options="contactOptions"
:label="t('commercial.suppliers.form.address.contacts')"
:display-tag="true"
:readonly="readonly"
@update:model-value="(v: (string | number)[]) => update('contactIris', v.map(String))"
/>
<!-- Filler : pousse Bennes + Triage sur une nouvelle ligne (disposition maquette). -->
<div aria-hidden="true" />
<!-- Bennes : stepper (specifique fournisseur, defaut 0). --> <!-- Bennes : stepper (specifique fournisseur, defaut 0). -->
<MalioInputNumber <MalioInputNumber
:model-value="model.bennes" :model-value="model.bennes"
@@ -97,14 +97,14 @@
:readonly="isValidated('information')" :readonly="isValidated('information')"
:error="informationErrors.errors.profitAmount" :error="informationErrors.errors.profitAmount"
/> />
<!-- Volume previsionnel : specifique fournisseur (entier >= 0). --> <!-- Volume previsionnel : specifique fournisseur. Champ texte
<MalioInputNumber masque (chiffres uniquement) ; l'entier est resolu au PATCH. -->
:model-value="information.volumeForecast" <MalioInputText
v-model="information.volumeForecast"
:label="t('commercial.suppliers.form.information.volumeForecast')" :label="t('commercial.suppliers.form.information.volumeForecast')"
:min="0" :mask="VOLUME_FORECAST_MASK"
:readonly="isValidated('information')" :readonly="isValidated('information')"
:error="informationErrors.errors.volumeForecast" :error="informationErrors.errors.volumeForecast"
@update:model-value="(v: string) => information.volumeForecast = v"
/> />
</div> </div>
<div v-if="!isValidated('information')" class="mt-12 flex justify-center"> <div v-if="!isValidated('information')" class="mt-12 flex justify-center">
@@ -383,6 +383,8 @@ import { extractApiErrorMessage } from '~/shared/utils/api'
// Masques de saisie (la normalisation finale reste serveur). // Masques de saisie (la normalisation finale reste serveur).
const SIREN_MASK = '#########' const SIREN_MASK = '#########'
const EMPLOYEES_MASK = '#######' const EMPLOYEES_MASK = '#######'
// Volume previsionnel : champ texte borne aux chiffres (entier >= 0 cote back).
const VOLUME_FORECAST_MASK = '##########'
const { t } = useI18n() const { t } = useI18n()
const api = useApi() const api = useApi()