feat(heures) : calendrier des jours validés (vue Jour) + harmonisation Malio UI
- Calendrier MalioDate en vue Jour (Heures + Heures Conducteurs) : jours entièrement validés (admin) peints en vert. Endpoint GET /work-hours/validation-status?from=&to=[&driver=1] (scope conducteur inversé), chargement à la volée par mois, refresh après validation/saisie/absence. - Suite à @malio/layer-ui 1.7.11 : reserveMessageSpace=false sur les champs ; tous les drawers migrés sur MalioDrawer (titre via slot #header, AppDrawer custom supprimé) ; boutons d'action en MalioButton (deux boutons partagent l'espace) ; inputs date en MalioDate ; MalioDateWeek en vue Semaine. - Boutons d'ajout uniformisés sur « Ajouter » + icône. - .env : EXCLUDED_PUBLIC_HOLIDAYS="null". - Doc : doc/hours-validated-days.md, documentation-content.ts, CLAUDE.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -36,7 +36,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showPicker" class="mt-3 flex items-center gap-3">
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
label="Contrat"
|
||||
:model-value="selectedPhase?.id ?? null"
|
||||
:options="phaseOptions"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
@click="openExportDrawer"
|
||||
/>
|
||||
<MalioButton
|
||||
label="Ajouter un employé"
|
||||
label="Ajouter"
|
||||
icon-name="mdi:plus"
|
||||
icon-position="left"
|
||||
@click="openCreate"
|
||||
@@ -21,14 +21,14 @@
|
||||
</div>
|
||||
<div class="flex items-center gap-3 py-7">
|
||||
<div class="w-80">
|
||||
<MalioInputText
|
||||
<MalioInputText :reserve-message-space="false"
|
||||
v-model="employeeFilter"
|
||||
label="Recherche d'un employé"
|
||||
icon-name="mdi:magnify"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="sites.length > 0" class="relative z-50 w-80">
|
||||
<MalioSelectCheckbox
|
||||
<MalioSelectCheckbox :reserve-message-space="false"
|
||||
v-model="selectedSiteIds"
|
||||
:options="siteOptions"
|
||||
groupClass="w-80"
|
||||
@@ -37,7 +37,7 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
v-model="contractStatusFilter"
|
||||
label="Statut contrat"
|
||||
:options="contractStatusOptions"
|
||||
@@ -84,21 +84,24 @@
|
||||
</NuxtLink>
|
||||
</div>
|
||||
|
||||
<MalioDrawer v-model="isDrawerOpen" :title="drawerTitle">
|
||||
<MalioDrawer v-model="isDrawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">{{ drawerTitle }}</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="handleSubmit">
|
||||
<MalioInputText
|
||||
<MalioInputText :reserve-message-space="false"
|
||||
v-model="form.firstName"
|
||||
label="Prénom *"
|
||||
group-class="mt-2"
|
||||
:error="showFirstNameError ? 'Le prénom est obligatoire.' : ''"
|
||||
/>
|
||||
<MalioInputText
|
||||
<MalioInputText :reserve-message-space="false"
|
||||
v-model="form.lastName"
|
||||
label="Nom *"
|
||||
group-class="mt-2"
|
||||
:error="showLastNameError ? 'Le nom est obligatoire.' : ''"
|
||||
/>
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
:model-value="form.siteId === '' ? null : form.siteId"
|
||||
:options="formSiteOptions"
|
||||
label="Site *"
|
||||
@@ -107,7 +110,7 @@
|
||||
@update:model-value="(v) => { form.siteId = v === null ? '' : Number(v) }"
|
||||
/>
|
||||
<template v-if="!editingEmployee">
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
:model-value="form.contractNature"
|
||||
:options="contractNatureFormOptions"
|
||||
label="Type de contrat *"
|
||||
@@ -115,7 +118,7 @@
|
||||
:error="showContractNatureError ? 'Le type de contrat est obligatoire.' : ''"
|
||||
@update:model-value="(v) => { if (v !== null) form.contractNature = v as 'CDI' | 'CDD' | 'INTERIM' }"
|
||||
/>
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
v-if="form.contractNature === 'INTERIM'"
|
||||
:model-value="form.interimAgencyId === '' ? null : form.interimAgencyId"
|
||||
:options="interimAgencyOptions"
|
||||
@@ -123,7 +126,7 @@
|
||||
min-width=""
|
||||
@update:model-value="(v) => { form.interimAgencyId = v === null ? '' : Number(v) }"
|
||||
/>
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
:model-value="form.contractId === '' ? null : form.contractId"
|
||||
:options="contractFormOptions"
|
||||
label="Temps de travail *"
|
||||
@@ -131,37 +134,27 @@
|
||||
:error="showContractError ? 'Le temps de travail est obligatoire.' : ''"
|
||||
@update:model-value="(v) => { form.contractId = v === null ? '' : Number(v) }"
|
||||
/>
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="contract-start-date">
|
||||
Début contrat <span class="text-red-600">*</span>
|
||||
</label>
|
||||
<input
|
||||
id="contract-start-date"
|
||||
v-model="form.contractStartDate"
|
||||
type="date"
|
||||
:class="[dateInputBaseClass, form.contractStartDate ? 'border-black' : 'border-m-muted', showContractStartDateError ? '!border-m-danger' : '']"
|
||||
/>
|
||||
<p v-if="showContractStartDateError" class="mt-1 text-sm text-red-600">
|
||||
La date de début est obligatoire.
|
||||
</p>
|
||||
</div>
|
||||
<div v-if="showsContractEndDateComputed">
|
||||
<label class="text-md font-semibold text-neutral-700" for="contract-end-date">
|
||||
Fin contrat
|
||||
<span v-if="requiresContractEndDateComputed" class="text-red-600">*</span>
|
||||
</label>
|
||||
<input
|
||||
id="contract-end-date"
|
||||
v-model="form.contractEndDate"
|
||||
type="date"
|
||||
:class="[dateInputBaseClass, form.contractEndDate ? 'border-black' : 'border-m-muted', showContractEndDateError ? '!border-m-danger' : '']"
|
||||
/>
|
||||
<p v-if="showContractEndDateError" class="mt-1 text-sm text-red-600">
|
||||
La date de fin est obligatoire pour un CDD ou un Intérim.
|
||||
</p>
|
||||
</div>
|
||||
<MalioDate
|
||||
:model-value="form.contractStartDate"
|
||||
label="Début contrat"
|
||||
required
|
||||
:reserve-message-space="false"
|
||||
:error="showContractStartDateError ? 'La date de début est obligatoire.' : ''"
|
||||
group-class="w-full"
|
||||
@update:model-value="(v) => form.contractStartDate = v ?? ''"
|
||||
/>
|
||||
<MalioDate
|
||||
v-if="showsContractEndDateComputed"
|
||||
:model-value="form.contractEndDate"
|
||||
label="Fin contrat"
|
||||
:required="requiresContractEndDateComputed"
|
||||
:reserve-message-space="false"
|
||||
:error="showContractEndDateError ? 'La date de fin est obligatoire pour un CDD ou un Intérim.' : ''"
|
||||
group-class="w-full"
|
||||
@update:model-value="(v) => form.contractEndDate = v ?? ''"
|
||||
/>
|
||||
<div class="flex h-10 items-center rounded-md border border-neutral-200 bg-neutral-50 px-3">
|
||||
<MalioCheckbox
|
||||
<MalioCheckbox :reserve-message-space="false"
|
||||
v-model="form.isDriver"
|
||||
label="Chauffeur"
|
||||
group-class="flex items-center"
|
||||
@@ -173,24 +166,29 @@
|
||||
:contract-weekly-hours="selectedContract?.weeklyHours ?? null"
|
||||
/>
|
||||
</template>
|
||||
<div class="flex justify-end gap-3 pt-2">
|
||||
<div class="grid grid-cols-2 gap-3 pt-2">
|
||||
<MalioButton
|
||||
label="Annuler"
|
||||
variant="tertiary"
|
||||
button-class="w-full"
|
||||
@click="isDrawerOpen = false"
|
||||
/>
|
||||
<MalioButton
|
||||
type="submit"
|
||||
label="Enregistrer"
|
||||
button-class="w-full"
|
||||
:disabled="isSubmitting || !isFormValid"
|
||||
@click="handleSubmit"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</MalioDrawer>
|
||||
|
||||
<MalioDrawer v-model="isExportDrawerOpen" title="Export">
|
||||
<MalioDrawer v-model="isExportDrawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Export</h2>
|
||||
</template>
|
||||
<div class="space-y-4">
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
:model-value="exportChoice === '' ? null : exportChoice"
|
||||
:options="exportTypeOptions"
|
||||
label="Type d'export"
|
||||
@@ -213,14 +211,14 @@
|
||||
</div>
|
||||
|
||||
<template v-else-if="exportChoice === 'yearly-hours'">
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
:model-value="exportYear"
|
||||
:options="exportYearOptions"
|
||||
label="Année *"
|
||||
min-width=""
|
||||
@update:model-value="(v) => { if (v !== null) exportYear = Number(v) }"
|
||||
/>
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
:model-value="exportMonth === '' ? null : exportMonth"
|
||||
:options="exportMonthOptions"
|
||||
label="Mois *"
|
||||
@@ -231,7 +229,7 @@
|
||||
</template>
|
||||
|
||||
<div v-else-if="exportChoice === 'night-contingent'">
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
:model-value="exportYear"
|
||||
:options="exportYearOptions"
|
||||
label="Année *"
|
||||
@@ -241,14 +239,14 @@
|
||||
</div>
|
||||
|
||||
<div v-else-if="exportChoice === 'overtime-contingent'" class="flex flex-col gap-4">
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
:model-value="exportYear"
|
||||
:options="exportYearOptions"
|
||||
label="Année *"
|
||||
min-width=""
|
||||
@update:model-value="(v) => { if (v !== null) exportYear = Number(v) }"
|
||||
/>
|
||||
<MalioSelectCheckbox
|
||||
<MalioSelectCheckbox :reserve-message-space="false"
|
||||
v-model="exportSiteIds"
|
||||
:options="siteOptions"
|
||||
label="Sites"
|
||||
@@ -467,9 +465,6 @@ const showContractEndDateError = computed(
|
||||
() => !editingEmployee.value && validationTouched.contractEndDate && !isContractEndDateValid.value
|
||||
)
|
||||
|
||||
const dateInputBaseClass =
|
||||
'mt-2 h-10 w-full rounded-md border px-3 text-md text-black outline-none focus:border-2 focus:border-m-primary'
|
||||
|
||||
const formSiteOptions = computed(() =>
|
||||
sites.value.map((site) => ({ label: site.name, value: site.id }))
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user