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

This commit is contained in:
2026-02-26 17:15:13 +01:00
parent 9261cb5b1a
commit 4d90f2cb42
24 changed files with 853 additions and 114 deletions

View File

@@ -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
}
}
)

View File

@@ -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