feat(front) : page ajout prestataire + formulaire principal
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- En-tete : retour vers le repertoire + titre. -->
|
||||
<div class="flex items-center gap-3 pt-11">
|
||||
<MalioButtonIcon
|
||||
icon="mdi:arrow-left-bold"
|
||||
icon-size="24"
|
||||
variant="ghost"
|
||||
v-bind="{ ariaLabel: t('technique.providers.form.back') }"
|
||||
@click="goBack"
|
||||
/>
|
||||
<h1 class="text-[30px] font-semibold text-m-primary">{{ t('technique.providers.form.title') }}</h1>
|
||||
</div>
|
||||
|
||||
<!-- ── Formulaire principal (pre-onglets) ─────────────────────────────
|
||||
Sans validation de ce bloc, les onglets restent inaccessibles. Au
|
||||
succes du POST, les champs passent en lecture seule et on bascule
|
||||
automatiquement sur l'onglet Contact (PAS d'onglet Information au M3).
|
||||
Selecteur de site present ici (RG-3.03, relation directe). -->
|
||||
<div class="mt-[48px] grid grid-cols-3 xl:grid-cols-4 gap-x-[44px] gap-y-4">
|
||||
<MalioInputText
|
||||
v-model="main.companyName"
|
||||
:label="t('technique.providers.form.main.companyName')"
|
||||
:required="true"
|
||||
:readonly="mainLocked"
|
||||
:error="mainErrors.errors.companyName"
|
||||
/>
|
||||
<MalioSelectCheckbox
|
||||
:model-value="main.categoryIris"
|
||||
:options="referentials.categories.value"
|
||||
:label="t('technique.providers.form.main.categories')"
|
||||
:display-tag="true"
|
||||
:readonly="mainLocked"
|
||||
:required="true"
|
||||
:error="mainErrors.errors.categories"
|
||||
@update:model-value="(v: (string | number)[]) => main.categoryIris = v.map(String)"
|
||||
/>
|
||||
<MalioSelectCheckbox
|
||||
:model-value="main.siteIris"
|
||||
:options="referentials.sites.value"
|
||||
:label="t('technique.providers.form.main.sites')"
|
||||
:display-tag="true"
|
||||
:readonly="mainLocked"
|
||||
:required="true"
|
||||
:error="mainErrors.errors.sites"
|
||||
@update:model-value="(v: (string | number)[]) => main.siteIris = v.map(String)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="!mainLocked" class="mt-12 flex justify-center">
|
||||
<MalioButton
|
||||
variant="primary"
|
||||
:label="t('technique.providers.form.submit')"
|
||||
:disabled="mainSubmitting"
|
||||
@click="submitMain"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- ── Onglets a validation incrementale ─────────────────────────────
|
||||
Le contenu des onglets (Contact / Adresse / Comptabilite) arrive aux
|
||||
tickets ERP-142 → 144 : placeholders « A venir » pour l'instant. -->
|
||||
<MalioTabList v-model="activeTab" :tabs="tabs" class="mt-[60px]">
|
||||
<template #contact><ComingSoonPlaceholder /></template>
|
||||
<template #address><ComingSoonPlaceholder /></template>
|
||||
<template v-if="canAccountingView" #accounting><ComingSoonPlaceholder /></template>
|
||||
</MalioTabList>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted } from 'vue'
|
||||
import { useProviderReferentials } from '~/modules/technique/composables/useProviderReferentials'
|
||||
import { useProviderForm } from '~/modules/technique/composables/useProviderForm'
|
||||
|
||||
const { t } = useI18n()
|
||||
const router = useRouter()
|
||||
const { can } = usePermissions()
|
||||
|
||||
useHead({ title: t('technique.providers.form.title') })
|
||||
|
||||
// Gating de la route : la creation est reservee a `manage` (POST /providers garde
|
||||
// manage seul — Compta ne cree pas). Compta (accounting seul) et Usine sont
|
||||
// rediriges vers le repertoire.
|
||||
if (!can('technique.providers.manage')) {
|
||||
await navigateTo('/providers')
|
||||
}
|
||||
|
||||
const referentials = useProviderReferentials()
|
||||
|
||||
const {
|
||||
main,
|
||||
mainLocked,
|
||||
mainSubmitting,
|
||||
mainErrors,
|
||||
canAccountingView,
|
||||
tabKeys,
|
||||
activeTab,
|
||||
unlockedIndex,
|
||||
submitMain,
|
||||
} = useProviderForm()
|
||||
|
||||
/** Retour vers le repertoire prestataires (fleche d'en-tete). */
|
||||
function goBack(): void {
|
||||
router.push('/providers')
|
||||
}
|
||||
|
||||
// Icone (Iconify) affichee dans l'onglet, par cle.
|
||||
const TAB_ICONS: Record<string, string> = {
|
||||
contact: 'mdi:account-box-plus-outline',
|
||||
address: 'mdi:map-marker-outline',
|
||||
accounting: 'mdi:bank-circle-outline',
|
||||
}
|
||||
|
||||
// Onglets desactives tant que le formulaire principal n'est pas valide
|
||||
// (unlockedIndex = -1 au depart) ; deverrouillage progressif ensuite.
|
||||
const tabs = computed(() => tabKeys.value.map((key, index) => ({
|
||||
key,
|
||||
label: t(`technique.providers.tab.${key}`),
|
||||
icon: TAB_ICONS[key],
|
||||
disabled: index > unlockedIndex.value,
|
||||
})))
|
||||
|
||||
onMounted(() => {
|
||||
// Echec du chargement des referentiels non bloquant : les selects restent vides.
|
||||
referentials.loadMain().catch(() => {})
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user