Compare commits

...

2 Commits

Author SHA1 Message Date
gitea-actions
973de2d094 chore: bump version to v0.1.97
All checks were successful
Auto Tag Develop / tag (push) Successful in 5s
Build & Push Docker Image / build (push) Successful in 56s
2026-04-27 13:02:01 +00:00
74c109713c fix : malio UI
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
2026-04-27 15:01:51 +02:00
4 changed files with 84 additions and 184 deletions

View File

@@ -1,2 +1,2 @@
parameters: parameters:
app.version: '0.1.96' app.version: '0.1.97'

View File

@@ -7,7 +7,7 @@
"name": "frontend", "name": "frontend",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"@malio/layer-ui": "^1.4.5", "@malio/layer-ui": "^1.4.6",
"@nuxt/icon": "^2.2.1", "@nuxt/icon": "^2.2.1",
"@nuxtjs/i18n": "^10.2.1", "@nuxtjs/i18n": "^10.2.1",
"@pinia/nuxt": "^0.11.3", "@pinia/nuxt": "^0.11.3",
@@ -2222,9 +2222,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@malio/layer-ui": { "node_modules/@malio/layer-ui": {
"version": "1.4.5", "version": "1.4.6",
"resolved": "https://gitea.malio.fr/api/packages/MALIO-DEV/npm/%40malio%2Flayer-ui/-/1.4.5/layer-ui-1.4.5.tgz", "resolved": "https://gitea.malio.fr/api/packages/MALIO-DEV/npm/%40malio%2Flayer-ui/-/1.4.6/layer-ui-1.4.6.tgz",
"integrity": "sha512-UfVkLJk3WWGoZE1eyei0pY45IUbZRzabJr2X6GNFabHd/8EmuXqwP+LxCl8wEAO4ODrNKsVLJdi0eL3Zekv4Dg==", "integrity": "sha512-stHqUAJ8E6a62Ka7QXlE177GhkIsjtmYNa/tNk1TVpbJ099okfLLivrlofEl7CCAqDeMaIepnW4q0vxJT+EFEA==",
"dependencies": { "dependencies": {
"@nuxt/icon": "^2.2.1", "@nuxt/icon": "^2.2.1",
"@nuxtjs/tailwindcss": "^6.14.0", "@nuxtjs/tailwindcss": "^6.14.0",

View File

@@ -13,7 +13,7 @@
"dependencies": { "dependencies": {
"@nuxt/icon": "^2.2.1", "@nuxt/icon": "^2.2.1",
"@nuxtjs/i18n": "^10.2.1", "@nuxtjs/i18n": "^10.2.1",
"@malio/layer-ui": "^1.4.5", "@malio/layer-ui": "^1.4.6",
"@pinia/nuxt": "^0.11.3", "@pinia/nuxt": "^0.11.3",
"nuxt": "^4.3.0", "nuxt": "^4.3.0",
"nuxt-toast": "^1.4.0", "nuxt-toast": "^1.4.0",

View File

@@ -84,105 +84,53 @@
</NuxtLink> </NuxtLink>
</div> </div>
<AppDrawer v-model="isDrawerOpen" :title="drawerTitle"> <MalioDrawer v-model="isDrawerOpen" :title="drawerTitle">
<form class="space-y-4" @submit.prevent="handleSubmit"> <form class="space-y-4" @submit.prevent="handleSubmit">
<div> <MalioInputText
<label class="text-md font-semibold text-neutral-700" for="first-name"> v-model="form.firstName"
Prénom <span class="text-red-600">*</span> label="Prénom *"
</label> group-class="mt-2"
<input :error="showFirstNameError ? 'Le prénom est obligatoire.' : ''"
id="first-name" />
v-model="form.firstName" <MalioInputText
type="text" v-model="form.lastName"
:class="firstNameFieldClass" label="Nom *"
/> group-class="mt-2"
<p v-if="showFirstNameError" class="mt-1 text-sm text-red-600"> :error="showLastNameError ? 'Le nom est obligatoire.' : ''"
Le prénom est obligatoire. />
</p> <MalioSelect
</div> :model-value="form.siteId === '' ? null : form.siteId"
<div> :options="formSiteOptions"
<label class="text-md font-semibold text-neutral-700" for="last-name"> label="Site *"
Nom <span class="text-red-600">*</span> min-width=""
</label> :error="showSiteError ? 'Le site est obligatoire.' : ''"
<input @update:model-value="(v) => { form.siteId = v === null ? '' : Number(v) }"
id="last-name" />
v-model="form.lastName"
type="text"
:class="lastNameFieldClass"
/>
<p v-if="showLastNameError" class="mt-1 text-sm text-red-600">
Le nom est obligatoire.
</p>
</div>
<div>
<label class="text-md font-semibold text-neutral-700" for="site">
Site <span class="text-red-600">*</span>
</label>
<select
id="site"
v-model="form.siteId"
:class="siteFieldClass"
>
<option value="">Aucun site</option>
<option v-for="site in sites" :key="site.id" :value="site.id">
{{ site.name }}
</option>
</select>
<p v-if="showSiteError" class="mt-1 text-sm text-red-600">
Le site est obligatoire.
</p>
</div>
<template v-if="!editingEmployee"> <template v-if="!editingEmployee">
<div> <MalioSelect
<label class="text-md font-semibold text-neutral-700" for="contract-nature"> :model-value="form.contractNature"
Type de contrat <span class="text-red-600">*</span> :options="contractNatureFormOptions"
</label> label="Type de contrat *"
<select min-width=""
id="contract-nature" :error="showContractNatureError ? 'Le type de contrat est obligatoire.' : ''"
v-model="form.contractNature" @update:model-value="(v) => { if (v !== null) form.contractNature = v as 'CDI' | 'CDD' | 'INTERIM' }"
:class="contractNatureFieldClass" />
> <MalioSelect
<option value="CDI">CDI</option> v-if="form.contractNature === 'INTERIM'"
<option value="CDD">CDD</option> :model-value="form.interimAgencyId === '' ? null : form.interimAgencyId"
<option value="INTERIM">Intérim</option> :options="interimAgencyOptions"
</select> label="Agence d'intérim"
<p v-if="showContractNatureError" class="mt-1 text-sm text-red-600"> min-width=""
Le type de contrat est obligatoire. @update:model-value="(v) => { form.interimAgencyId = v === null ? '' : Number(v) }"
</p> />
</div> <MalioSelect
<div v-if="form.contractNature === 'INTERIM'"> :model-value="form.contractId === '' ? null : form.contractId"
<label class="text-md font-semibold text-neutral-700" for="interim-agency"> :options="contractFormOptions"
Agence d'intérim label="Temps de travail *"
</label> min-width=""
<select :error="showContractError ? 'Le temps de travail est obligatoire.' : ''"
id="interim-agency" @update:model-value="(v) => { form.contractId = v === null ? '' : Number(v) }"
v-model="form.interimAgencyId" />
class="mt-2 w-full rounded-md border border-neutral-300 bg-white px-3 py-2 text-md text-neutral-900"
>
<option value="">Aucune</option>
<option v-for="agency in interimAgencies" :key="agency.id" :value="agency.id">
{{ agency.name }}
</option>
</select>
</div>
<div>
<label class="text-md font-semibold text-neutral-700" for="contract">
Temps de travail <span class="text-red-600">*</span>
</label>
<select
id="contract"
v-model="form.contractId"
:class="contractFieldClass"
>
<option value="">Sélectionner un contrat</option>
<option v-for="contract in contracts" :key="contract.id" :value="contract.id">
{{ contract.name }}
</option>
</select>
<p v-if="showContractError" class="mt-1 text-sm text-red-600">
Le temps de travail est obligatoire.
</p>
</div>
<div> <div>
<label class="text-md font-semibold text-neutral-700" for="contract-start-date"> <label class="text-md font-semibold text-neutral-700" for="contract-start-date">
Début contrat <span class="text-red-600">*</span> Début contrat <span class="text-red-600">*</span>
@@ -191,7 +139,7 @@
id="contract-start-date" id="contract-start-date"
v-model="form.contractStartDate" v-model="form.contractStartDate"
type="date" type="date"
:class="contractStartDateFieldClass" :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"> <p v-if="showContractStartDateError" class="mt-1 text-sm text-red-600">
La date de début est obligatoire. La date de début est obligatoire.
@@ -206,22 +154,18 @@
id="contract-end-date" id="contract-end-date"
v-model="form.contractEndDate" v-model="form.contractEndDate"
type="date" type="date"
:class="contractEndDateFieldClass" :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"> <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. La date de fin est obligatoire pour un CDD ou un Intérim.
</p> </p>
</div> </div>
<div class="rounded-md border border-neutral-200 bg-neutral-50 p-3"> <div class="flex h-10 items-center rounded-md border border-neutral-200 bg-neutral-50 px-3">
<label class="inline-flex items-center gap-2 text-md font-semibold text-neutral-700" for="is-driver"> <MalioCheckbox
<input v-model="form.isDriver"
id="is-driver" label="Chauffeur"
v-model="form.isDriver" group-class="flex items-center"
type="checkbox" />
class="h-4 w-4 rounded border-neutral-300 text-primary-500 focus:ring-primary-500"
/>
Chauffeur
</label>
</div> </div>
<WorkDaysHoursInput <WorkDaysHoursInput
v-if="requiresSchedule" v-if="requiresSchedule"
@@ -230,23 +174,19 @@
/> />
</template> </template>
<div class="flex justify-end gap-3 pt-2"> <div class="flex justify-end gap-3 pt-2">
<button <MalioButton
type="button" label="Annuler"
class="rounded-lg border border-neutral-200 px-4 py-2 text-md font-semibold text-neutral-700 hover:bg-neutral-100" variant="tertiary"
@click="isDrawerOpen = false" @click="isDrawerOpen = false"
> />
Annuler <MalioButton
</button>
<button
type="submit" type="submit"
class="rounded-lg bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500" label="Enregistrer"
:class="submitButtonClass" :disabled="isSubmitting || !isFormValid"
> />
Enregistrer
</button>
</div> </div>
</form> </form>
</AppDrawer> </MalioDrawer>
<MalioDrawer v-model="isExportDrawerOpen" title="Export"> <MalioDrawer v-model="isExportDrawerOpen" title="Export">
<div class="space-y-4"> <div class="space-y-4">
@@ -492,63 +432,23 @@ const showContractEndDateError = computed(
() => !editingEmployee.value && validationTouched.contractEndDate && !isContractEndDateValid.value () => !editingEmployee.value && validationTouched.contractEndDate && !isContractEndDateValid.value
) )
const baseInputClass = const dateInputBaseClass =
'mt-2 w-full rounded-md border px-3 py-2 text-base text-neutral-900 focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-secondary-500/20' '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 firstNameFieldClass = computed(() => {
if (showFirstNameError.value) {
return `${baseInputClass} border-red-500`
}
return `${baseInputClass} border-neutral-300`
})
const lastNameFieldClass = computed(() => {
if (showLastNameError.value) {
return `${baseInputClass} border-red-500`
}
return `${baseInputClass} border-neutral-300`
})
const siteFieldClass = computed(() => {
const baseSelectClass =
'mt-2 w-full rounded-md border bg-white px-3 py-2 text-md text-neutral-900'
if (showSiteError.value) {
return `${baseSelectClass} border-red-500`
}
return `${baseSelectClass} border-neutral-300`
})
const contractFieldClass = computed(() => {
const baseClass =
'mt-2 w-full rounded-md border bg-white px-3 py-2 text-md text-neutral-900'
if (showContractError.value) {
return `${baseClass} border-red-500`
}
return `${baseClass} border-neutral-300`
})
const contractNatureFieldClass = computed(() => {
const baseClass =
'mt-2 w-full rounded-md border bg-white px-3 py-2 text-md text-neutral-900'
if (showContractNatureError.value) {
return `${baseClass} border-red-500`
}
return `${baseClass} border-neutral-300`
})
const contractStartDateFieldClass = computed(() => {
if (showContractStartDateError.value) {
return `${baseInputClass} border-red-500`
}
return `${baseInputClass} border-neutral-300`
})
const contractEndDateFieldClass = computed(() => {
if (showContractEndDateError.value) {
return `${baseInputClass} border-red-500`
}
return `${baseInputClass} border-neutral-300`
})
const submitButtonClass = computed(() => { const formSiteOptions = computed(() =>
if (isSubmitting.value || !isFormValid.value) { sites.value.map((site) => ({ label: site.name, value: site.id }))
return 'opacity-50 cursor-not-allowed' )
} const interimAgencyOptions = computed(() =>
return '' interimAgencies.value.map((agency) => ({ label: agency.name, value: agency.id }))
}) )
const contractFormOptions = computed(() =>
contracts.value.map((contract) => ({ label: contract.name, value: contract.id }))
)
const contractNatureFormOptions = [
{ label: 'CDI', value: 'CDI' },
{ label: 'CDD', value: 'CDD' },
{ label: 'Intérim', value: 'INTERIM' }
]
const loadEmployees = async () => { const loadEmployees = async () => {
isLoading.value = true isLoading.value = true