feat : ajout du nouveau système de contrat et ajout de filtre d'impression
All checks were successful
Auto Tag Develop / tag (push) Successful in 5s
All checks were successful
Auto Tag Develop / tag (push) Successful in 5s
This commit is contained in:
@@ -54,6 +54,48 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<p class="text-md font-semibold text-neutral-700">
|
||||
Type de contrat <span class="text-red-600">*</span>
|
||||
</p>
|
||||
<div class="flex flex-wrap gap-4 rounded-md border border-neutral-300 px-3 py-2">
|
||||
<div v-for="nature in contractNatures" :key="nature.value" class="flex items-center gap-2">
|
||||
<label class="text-md" :for="`print-contract-nature-${nature.value}`">{{ nature.label }}</label>
|
||||
<input
|
||||
:id="`print-contract-nature-${nature.value}`"
|
||||
v-model="printForm.contractNatures"
|
||||
:value="nature.value"
|
||||
type="checkbox"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="showContractNaturesError" class="text-sm text-red-600">
|
||||
Sélectionne au moins un type de contrat.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<p class="text-md font-semibold text-neutral-700">
|
||||
Temps de travail <span class="text-red-600">*</span>
|
||||
</p>
|
||||
<div class="flex flex-wrap gap-4 rounded-md border border-neutral-300 px-3 py-2">
|
||||
<div v-for="workContract in workContracts" :key="workContract.id" class="flex items-center gap-2">
|
||||
<label class="text-md" :for="`print-work-contract-${workContract.id}`">{{ workContract.name }}</label>
|
||||
<input
|
||||
:id="`print-work-contract-${workContract.id}`"
|
||||
v-model="printForm.workContractIds"
|
||||
:value="workContract.id"
|
||||
type="checkbox"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="showWorkContractsError" class="text-sm text-red-600">
|
||||
Sélectionne au moins un temps de travail.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end gap-3 pt-2">
|
||||
<button
|
||||
type="button"
|
||||
@@ -84,13 +126,27 @@ type SiteOption = {
|
||||
color: string
|
||||
}
|
||||
|
||||
type ContractNatureOption = {
|
||||
value: 'CDI' | 'CDD' | 'INTERIM'
|
||||
label: string
|
||||
}
|
||||
|
||||
type WorkContractOption = {
|
||||
id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
sites: SiteOption[]
|
||||
contractNatures: ContractNatureOption[]
|
||||
workContracts: WorkContractOption[]
|
||||
printForm: {
|
||||
from: string
|
||||
to: string
|
||||
siteIds: number[]
|
||||
contractNatures: Array<'CDI' | 'CDD' | 'INTERIM'>
|
||||
workContractIds: number[]
|
||||
}
|
||||
}>()
|
||||
|
||||
@@ -110,19 +166,36 @@ const printForm = toRef(props, 'printForm')
|
||||
const validationTouched = reactive({
|
||||
from: false,
|
||||
to: false,
|
||||
sites: false
|
||||
sites: false,
|
||||
contractNatures: false,
|
||||
workContracts: false
|
||||
})
|
||||
|
||||
const isFromValid = computed(() => printForm.value.from.trim() !== '')
|
||||
const isToValid = computed(() => printForm.value.to.trim() !== '')
|
||||
const isSitesValid = computed(() => printForm.value.siteIds.length > 0)
|
||||
const isContractNaturesValid = computed(() => {
|
||||
if (props.contractNatures.length === 0) return true
|
||||
return printForm.value.contractNatures.length > 0
|
||||
})
|
||||
const isWorkContractsValid = computed(() => {
|
||||
if (props.workContracts.length === 0) return true
|
||||
return printForm.value.workContractIds.length > 0
|
||||
})
|
||||
const isFormValid = computed(
|
||||
() => isFromValid.value && isToValid.value && isSitesValid.value
|
||||
() =>
|
||||
isFromValid.value &&
|
||||
isToValid.value &&
|
||||
isSitesValid.value &&
|
||||
isContractNaturesValid.value &&
|
||||
isWorkContractsValid.value
|
||||
)
|
||||
|
||||
const showFromError = computed(() => validationTouched.from && !isFromValid.value)
|
||||
const showToError = computed(() => validationTouched.to && !isToValid.value)
|
||||
const showSitesError = computed(() => validationTouched.sites && !isSitesValid.value)
|
||||
const showContractNaturesError = computed(() => validationTouched.contractNatures && !isContractNaturesValid.value)
|
||||
const showWorkContractsError = computed(() => validationTouched.workContracts && !isWorkContractsValid.value)
|
||||
|
||||
const baseInputClass =
|
||||
'mt-2 w-full rounded-md border px-3 py-2 text-md text-neutral-900'
|
||||
@@ -150,6 +223,8 @@ const handleSubmit = () => {
|
||||
validationTouched.from = true
|
||||
validationTouched.to = true
|
||||
validationTouched.sites = true
|
||||
validationTouched.contractNatures = true
|
||||
validationTouched.workContracts = true
|
||||
if (!isFormValid.value) return
|
||||
emit('submit')
|
||||
}
|
||||
@@ -166,6 +241,8 @@ watch(
|
||||
validationTouched.from = false
|
||||
validationTouched.to = false
|
||||
validationTouched.sites = false
|
||||
validationTouched.contractNatures = false
|
||||
validationTouched.workContracts = false
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -52,14 +52,15 @@
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="pl-2 min-w-0 self-stretch flex flex-col justify-between py-0.5">
|
||||
<p
|
||||
class="w-full min-w-0 text-sm text-neutral-700 truncate"
|
||||
:class="getRowAbsenceLabel(employee.id) ? '' : 'invisible'"
|
||||
<div class="pl-2 min-w-0 self-stretch flex flex-col gap-1 justify-between py-0.5">
|
||||
<p
|
||||
class="w-full min-w-0 rounded-md px-2 py-1 text-xs truncate"
|
||||
:class="getRowAbsenceLabel(employee.id) ? 'text-white' : 'invisible'"
|
||||
:title="getRowAbsenceLabel(employee.id) || ''"
|
||||
>
|
||||
:style="getRowAbsenceStyle(employee.id)"
|
||||
>
|
||||
{{ getRowAbsenceLabel(employee.id) || '—' }}
|
||||
</p>
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
class="self-start text-left text-xs font-semibold underline"
|
||||
@@ -197,6 +198,7 @@ const props = defineProps<{
|
||||
onToggleValidationBulk: (checked: boolean) => void
|
||||
getRowMetrics: (employeeId: number) => { dayMinutes: number; nightMinutes: number; totalMinutes: number }
|
||||
getRowAbsenceLabel: (employeeId: number) => string
|
||||
getRowAbsenceStyle: (employeeId: number) => { backgroundColor: string } | undefined
|
||||
getPresenceDayValue: (employeeId: number) => string
|
||||
onAbsenceClick: (employeeId: number) => void
|
||||
formatMinutes: (minutes: number) => string
|
||||
|
||||
@@ -419,6 +419,12 @@ export const useHoursPage = () => {
|
||||
return `${dayRow.absenceLabel} (journée)`
|
||||
}
|
||||
|
||||
const getRowAbsenceStyle = (employeeId: number) => {
|
||||
const dayRow = dayContextByEmployeeId.value.get(employeeId)
|
||||
if (!dayRow?.absenceLabel) return undefined
|
||||
return { backgroundColor: dayRow.absenceColor || '#dc2626' }
|
||||
}
|
||||
|
||||
const getPresenceDayValue = (employeeId: number) => {
|
||||
const row = rows.value[employeeId]
|
||||
const basePresence = (row?.isPresentMorning ? 0.5 : 0) + (row?.isPresentAfternoon ? 0.5 : 0)
|
||||
@@ -964,6 +970,7 @@ export const useHoursPage = () => {
|
||||
toggleValidationBulk,
|
||||
getRowMetrics,
|
||||
getRowAbsenceLabel,
|
||||
getRowAbsenceStyle,
|
||||
getPresenceDayValue,
|
||||
openAbsenceDrawer,
|
||||
submitAbsence,
|
||||
|
||||
@@ -86,6 +86,8 @@
|
||||
<AbsencePrintDrawer
|
||||
v-model="isPrintOpen"
|
||||
:sites="sites"
|
||||
:contract-natures="contractNatureOptions"
|
||||
:work-contracts="workContractOptions"
|
||||
:print-form="printForm"
|
||||
@submit="handlePrint"
|
||||
@cancel="closePrint"
|
||||
@@ -221,7 +223,25 @@ const form = reactive({
|
||||
const printForm = reactive({
|
||||
from: '',
|
||||
to: '',
|
||||
siteIds: [] as number[]
|
||||
siteIds: [] as number[],
|
||||
contractNatures: [] as Array<'CDI' | 'CDD' | 'INTERIM'>,
|
||||
workContractIds: [] as number[]
|
||||
})
|
||||
|
||||
const contractNatureOptions = [
|
||||
{ value: 'CDI' as const, label: 'CDI' },
|
||||
{ value: 'CDD' as const, label: 'CDD' },
|
||||
{ value: 'INTERIM' as const, label: 'Intérim' }
|
||||
]
|
||||
|
||||
const workContractOptions = computed(() => {
|
||||
const byId = new Map<number, { id: number; name: string }>()
|
||||
for (const employee of employees.value) {
|
||||
const contract = employee.contract
|
||||
if (!contract?.id) continue
|
||||
byId.set(contract.id, { id: contract.id, name: contract.name })
|
||||
}
|
||||
return Array.from(byId.values()).sort((a, b) => a.name.localeCompare(b.name, 'fr'))
|
||||
})
|
||||
|
||||
// Remet le formulaire à zéro.
|
||||
@@ -249,6 +269,8 @@ const openPrint = () => {
|
||||
printForm.from = monthStart
|
||||
printForm.to = monthEnd
|
||||
printForm.siteIds = [...selectedSiteIds.value]
|
||||
printForm.contractNatures = contractNatureOptions.map((item) => item.value)
|
||||
printForm.workContractIds = workContractOptions.value.map((item) => item.id)
|
||||
isPrintOpen.value = true
|
||||
}
|
||||
|
||||
@@ -657,6 +679,12 @@ const handlePrint = async () => {
|
||||
if (printForm.siteIds.length > 0) {
|
||||
params.set('sites', printForm.siteIds.join(','))
|
||||
}
|
||||
if (printForm.contractNatures.length > 0) {
|
||||
params.set('contractNatures', printForm.contractNatures.join(','))
|
||||
}
|
||||
if (printForm.workContractIds.length > 0) {
|
||||
params.set('workContracts', printForm.workContractIds.join(','))
|
||||
}
|
||||
await printPdf(`/absences/print?${params.toString()}`)
|
||||
isPrintOpen.value = false
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-lg bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500"
|
||||
@click="isDrawerOpen = true"
|
||||
@click="openCreate"
|
||||
>
|
||||
Ajouter un employé
|
||||
</button>
|
||||
@@ -32,10 +32,11 @@
|
||||
<div v-else class="flex-1 min-h-0 rounded-lg border border-neutral-200 bg-white overflow-hidden">
|
||||
<div class="h-full overflow-auto">
|
||||
<div class="min-w-[900px]">
|
||||
<div class="grid grid-cols-[120px_1fr_1fr_220px_200px] gap-4 border-b border-neutral-200 bg-tertiary-500 px-6 py-3 text-md font-semibold text-neutral-700 sticky top-0 z-10">
|
||||
<div class="grid grid-cols-[120px_1fr_1fr_180px_180px_200px] gap-4 border-b border-neutral-200 bg-tertiary-500 px-6 py-3 text-md font-semibold text-neutral-700 sticky top-0 z-10">
|
||||
<span class="text-left">Prénom</span>
|
||||
<span class="text-left">Nom</span>
|
||||
<span class="text-left">Site</span>
|
||||
<span class="text-left">Nature</span>
|
||||
<span class="text-left">Contrat</span>
|
||||
<span class="text-right">Actions</span>
|
||||
</div>
|
||||
@@ -46,7 +47,7 @@
|
||||
<div
|
||||
v-for="employee in filteredEmployees"
|
||||
:key="employee.id"
|
||||
class="grid grid-cols-[120px_1fr_1fr_220px_200px] items-center gap-4 border-b border-neutral-100 px-6 py-3 text-md text-neutral-800 last:border-b-0"
|
||||
class="grid grid-cols-[120px_1fr_1fr_180px_180px_200px] items-center gap-4 border-b border-neutral-100 px-6 py-3 text-md text-neutral-800 last:border-b-0"
|
||||
>
|
||||
<span>{{ employee.firstName }}</span>
|
||||
<span>{{ employee.lastName }}</span>
|
||||
@@ -57,6 +58,7 @@
|
||||
>
|
||||
{{ employee.site?.name ?? '-' }}
|
||||
</span>
|
||||
<span>{{ contractNatureLabel(employee.currentContractNature) }}</span>
|
||||
<span>{{ employee.contract?.name ?? '-' }}</span>
|
||||
<div class="flex items-center justify-end gap-2">
|
||||
<button
|
||||
@@ -128,24 +130,72 @@
|
||||
Le site est obligatoire.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="contract">
|
||||
Contrat <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 contrat est obligatoire.
|
||||
</p>
|
||||
</div>
|
||||
<template v-if="!editingEmployee">
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="contract-nature">
|
||||
Type de contrat <span class="text-red-600">*</span>
|
||||
</label>
|
||||
<select
|
||||
id="contract-nature"
|
||||
v-model="form.contractNature"
|
||||
:class="contractNatureFieldClass"
|
||||
>
|
||||
<option value="CDI">CDI</option>
|
||||
<option value="CDD">CDD</option>
|
||||
<option value="INTERIM">Intérim</option>
|
||||
</select>
|
||||
<p v-if="showContractNatureError" class="mt-1 text-sm text-red-600">
|
||||
Le type de contrat est obligatoire.
|
||||
</p>
|
||||
</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>
|
||||
<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="contractStartDateFieldClass"
|
||||
/>
|
||||
<p v-if="showContractStartDateError" class="mt-1 text-sm text-red-600">
|
||||
La date de début est obligatoire.
|
||||
</p>
|
||||
</div>
|
||||
<div v-if="requiresContractEndDate">
|
||||
<label class="text-md font-semibold text-neutral-700" for="contract-end-date">
|
||||
Fin contrat
|
||||
<span v-if="requiresContractEndDate" class="text-red-600">*</span>
|
||||
</label>
|
||||
<input
|
||||
id="contract-end-date"
|
||||
v-model="form.contractEndDate"
|
||||
type="date"
|
||||
:class="contractEndDateFieldClass"
|
||||
/>
|
||||
<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>
|
||||
</template>
|
||||
<div class="flex justify-end gap-3 pt-2">
|
||||
<button
|
||||
type="button"
|
||||
@@ -212,26 +262,54 @@ const filteredEmployees = computed(() => {
|
||||
})
|
||||
})
|
||||
|
||||
const contractNatureLabel = (value?: 'CDI' | 'CDD' | 'INTERIM') => {
|
||||
if (value === 'CDD') return 'CDD'
|
||||
if (value === 'INTERIM') return 'Intérim'
|
||||
return 'CDI'
|
||||
}
|
||||
|
||||
const form = reactive({
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
siteId: '' as number | '',
|
||||
contractId: '' as number | ''
|
||||
contractId: '' as number | '',
|
||||
contractNature: 'CDI' as 'CDI' | 'CDD' | 'INTERIM',
|
||||
contractStartDate: '',
|
||||
contractEndDate: ''
|
||||
})
|
||||
|
||||
const validationTouched = reactive({
|
||||
firstName: false,
|
||||
lastName: false,
|
||||
siteId: false,
|
||||
contractId: false
|
||||
contractId: false,
|
||||
contractNature: false,
|
||||
contractStartDate: false,
|
||||
contractEndDate: false
|
||||
})
|
||||
|
||||
const isFirstNameValid = computed(() => form.firstName.trim() !== '')
|
||||
const isLastNameValid = computed(() => form.lastName.trim() !== '')
|
||||
const isSiteValid = computed(() => form.siteId !== '')
|
||||
const isContractValid = computed(() => form.contractId !== '')
|
||||
const isContractNatureValid = computed(() => ['CDI', 'CDD', 'INTERIM'].includes(form.contractNature))
|
||||
const isContractStartDateValid = computed(() => form.contractStartDate !== '')
|
||||
const requiresContractEndDate = computed(() => form.contractNature === 'CDD' || form.contractNature === 'INTERIM')
|
||||
const isContractEndDateValid = computed(() => {
|
||||
if (!requiresContractEndDate.value) return true
|
||||
return form.contractEndDate !== ''
|
||||
})
|
||||
const isFormValid = computed(
|
||||
() => isFirstNameValid.value && isLastNameValid.value && isSiteValid.value && isContractValid.value
|
||||
() =>
|
||||
isFirstNameValid.value &&
|
||||
isLastNameValid.value &&
|
||||
isSiteValid.value &&
|
||||
(editingEmployee.value
|
||||
? true
|
||||
: (isContractValid.value &&
|
||||
isContractNatureValid.value &&
|
||||
isContractStartDateValid.value &&
|
||||
isContractEndDateValid.value))
|
||||
)
|
||||
|
||||
const showFirstNameError = computed(
|
||||
@@ -246,6 +324,15 @@ const showSiteError = computed(
|
||||
const showContractError = computed(
|
||||
() => validationTouched.contractId && !isContractValid.value
|
||||
)
|
||||
const showContractNatureError = computed(
|
||||
() => !editingEmployee.value && validationTouched.contractNature && !isContractNatureValid.value
|
||||
)
|
||||
const showContractStartDateError = computed(
|
||||
() => !editingEmployee.value && validationTouched.contractStartDate && !isContractStartDateValid.value
|
||||
)
|
||||
const showContractEndDateError = computed(
|
||||
() => !editingEmployee.value && validationTouched.contractEndDate && !isContractEndDateValid.value
|
||||
)
|
||||
|
||||
const baseInputClass =
|
||||
'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'
|
||||
@@ -277,6 +364,26 @@ const contractFieldClass = computed(() => {
|
||||
}
|
||||
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(() => {
|
||||
if (isSubmitting.value || !isFormValid.value) {
|
||||
@@ -304,6 +411,9 @@ const loadContracts = async () => {
|
||||
|
||||
onMounted(async () => {
|
||||
await Promise.all([loadEmployees(), loadSites(), loadContracts()])
|
||||
if (form.contractStartDate === '') {
|
||||
form.contractStartDate = new Date().toISOString().slice(0, 10)
|
||||
}
|
||||
})
|
||||
|
||||
watch(sites, (nextSites) => {
|
||||
@@ -324,7 +434,12 @@ const handleSubmit = async () => {
|
||||
validationTouched.firstName = true
|
||||
validationTouched.lastName = true
|
||||
validationTouched.siteId = true
|
||||
validationTouched.contractId = true
|
||||
if (!editingEmployee.value) {
|
||||
validationTouched.contractId = true
|
||||
validationTouched.contractNature = true
|
||||
validationTouched.contractStartDate = true
|
||||
validationTouched.contractEndDate = true
|
||||
}
|
||||
if (!isFormValid.value) return
|
||||
|
||||
isSubmitting.value = true
|
||||
@@ -334,14 +449,17 @@ const handleSubmit = async () => {
|
||||
firstName: form.firstName,
|
||||
lastName: form.lastName,
|
||||
siteId: form.siteId === '' ? null : Number(form.siteId),
|
||||
contractId: Number(form.contractId)
|
||||
contractId: editingEmployee.value.contract?.id ?? Number(form.contractId)
|
||||
})
|
||||
} else {
|
||||
await createEmployee({
|
||||
firstName: form.firstName,
|
||||
lastName: form.lastName,
|
||||
siteId: form.siteId === '' ? null : Number(form.siteId),
|
||||
contractId: Number(form.contractId)
|
||||
contractId: Number(form.contractId),
|
||||
contractNature: form.contractNature,
|
||||
contractStartDate: form.contractStartDate,
|
||||
contractEndDate: requiresContractEndDate.value ? form.contractEndDate : null
|
||||
})
|
||||
}
|
||||
|
||||
@@ -349,6 +467,9 @@ const handleSubmit = async () => {
|
||||
form.lastName = ''
|
||||
form.siteId = ''
|
||||
form.contractId = ''
|
||||
form.contractNature = 'CDI'
|
||||
form.contractStartDate = new Date().toISOString().slice(0, 10)
|
||||
form.contractEndDate = ''
|
||||
editingEmployee.value = null
|
||||
isDrawerOpen.value = false
|
||||
await loadEmployees()
|
||||
@@ -363,6 +484,15 @@ watch(isDrawerOpen, (isOpen) => {
|
||||
validationTouched.lastName = false
|
||||
validationTouched.siteId = false
|
||||
validationTouched.contractId = false
|
||||
validationTouched.contractNature = false
|
||||
validationTouched.contractStartDate = false
|
||||
validationTouched.contractEndDate = false
|
||||
}
|
||||
})
|
||||
|
||||
watch(requiresContractEndDate, (required) => {
|
||||
if (!required) {
|
||||
form.contractEndDate = ''
|
||||
}
|
||||
})
|
||||
|
||||
@@ -371,7 +501,18 @@ const openEdit = (employee: Employee) => {
|
||||
form.firstName = employee.firstName
|
||||
form.lastName = employee.lastName
|
||||
form.siteId = employee.site?.id ?? ''
|
||||
form.contractId = employee.contract?.id ?? ''
|
||||
isDrawerOpen.value = true
|
||||
}
|
||||
|
||||
const openCreate = () => {
|
||||
editingEmployee.value = null
|
||||
form.firstName = ''
|
||||
form.lastName = ''
|
||||
form.siteId = ''
|
||||
form.contractId = ''
|
||||
form.contractNature = 'CDI'
|
||||
form.contractStartDate = new Date().toISOString().slice(0, 10)
|
||||
form.contractEndDate = ''
|
||||
isDrawerOpen.value = true
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
:on-toggle-validation-bulk="toggleValidationBulk"
|
||||
:get-row-metrics="getRowMetrics"
|
||||
:get-row-absence-label="getRowAbsenceLabel"
|
||||
:get-row-absence-style="getRowAbsenceStyle"
|
||||
:get-presence-day-value="getPresenceDayValue"
|
||||
:on-absence-click="openAbsenceDrawer"
|
||||
:format-minutes="formatMinutes"
|
||||
@@ -163,6 +164,7 @@ const {
|
||||
toggleValidationBulk,
|
||||
getRowMetrics,
|
||||
getRowAbsenceLabel,
|
||||
getRowAbsenceStyle,
|
||||
getPresenceDayValue,
|
||||
openAbsenceDrawer,
|
||||
submitAbsence,
|
||||
|
||||
@@ -7,5 +7,8 @@ export type Employee = {
|
||||
lastName: string
|
||||
site: Site
|
||||
contract?: Contract | null
|
||||
currentContractNature?: 'CDI' | 'CDD' | 'INTERIM'
|
||||
currentContractStartDate?: string | null
|
||||
currentContractEndDate?: string | null
|
||||
displayOrder?: number
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ export type WorkHourDayContextRow = {
|
||||
employeeId: number
|
||||
hasContractAtDate: boolean
|
||||
absenceLabel?: string | null
|
||||
absenceColor?: string | null
|
||||
absenceHalf?: 'AM' | 'PM' | null
|
||||
absentMorning: boolean
|
||||
absentAfternoon: boolean
|
||||
|
||||
@@ -26,13 +26,19 @@ export const createEmployee = async (payload: {
|
||||
lastName: string
|
||||
siteId?: number | null
|
||||
contractId: number
|
||||
contractNature?: 'CDI' | 'CDD' | 'INTERIM'
|
||||
contractStartDate?: string
|
||||
contractEndDate?: string | null
|
||||
}) => {
|
||||
const api = useApi()
|
||||
return api.post<Employee>('/employees', {
|
||||
firstName: payload.firstName,
|
||||
lastName: payload.lastName,
|
||||
site: payload.siteId ? `/api/sites/${payload.siteId}` : null,
|
||||
contract: `/api/contracts/${payload.contractId}`
|
||||
contract: `/api/contracts/${payload.contractId}`,
|
||||
contractNature: payload.contractNature,
|
||||
contractStartDate: payload.contractStartDate,
|
||||
contractEndDate: payload.contractEndDate ?? null
|
||||
}, {
|
||||
toastSuccessKey: 'success.employee.create',
|
||||
toastErrorKey: 'errors.employee.create'
|
||||
@@ -46,6 +52,9 @@ export const updateEmployee = async (
|
||||
lastName: string
|
||||
siteId?: number | null
|
||||
contractId: number
|
||||
contractNature?: 'CDI' | 'CDD' | 'INTERIM'
|
||||
contractStartDate?: string
|
||||
contractEndDate?: string | null
|
||||
displayOrder?: number
|
||||
}
|
||||
) => {
|
||||
@@ -55,6 +64,9 @@ export const updateEmployee = async (
|
||||
lastName: payload.lastName,
|
||||
site: payload.siteId ? `/api/sites/${payload.siteId}` : null,
|
||||
contract: `/api/contracts/${payload.contractId}`,
|
||||
contractNature: payload.contractNature,
|
||||
contractStartDate: payload.contractStartDate,
|
||||
contractEndDate: payload.contractEndDate ?? null,
|
||||
displayOrder: payload.displayOrder
|
||||
}, {
|
||||
toastSuccessKey: 'success.employee.update',
|
||||
|
||||
Reference in New Issue
Block a user