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:
@@ -1,7 +1,10 @@
|
||||
<template>
|
||||
<AppDrawer v-model="drawerOpen" title="Nouvelle absence">
|
||||
<MalioDrawer v-model="drawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Nouvelle absence</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="handleSubmit">
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
:model-value="absenceForm.employeeId === '' ? null : absenceForm.employeeId"
|
||||
:options="employeeOptions"
|
||||
label="Employé *"
|
||||
@@ -12,7 +15,7 @@
|
||||
@update:model-value="onEmployeeChange"
|
||||
/>
|
||||
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
:model-value="absenceForm.typeId === '' ? null : absenceForm.typeId"
|
||||
:options="typeOptions"
|
||||
label="Type d'absence *"
|
||||
@@ -24,16 +27,16 @@
|
||||
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="start-date">Début</label>
|
||||
<div class="mt-2 grid grid-cols-2 gap-2">
|
||||
<input
|
||||
id="start-date"
|
||||
<label class="text-md font-semibold text-neutral-700">Début</label>
|
||||
<div class="mt-2 space-y-2">
|
||||
<MalioDate
|
||||
v-model="absenceForm.startDate"
|
||||
type="date"
|
||||
:class="[dateInputBaseClass, absenceForm.startDate ? 'border-black' : 'border-m-muted']"
|
||||
:clearable="false"
|
||||
:reserve-message-space="false"
|
||||
:disabled="props.lockDates"
|
||||
group-class="w-full"
|
||||
/>
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
:model-value="absenceForm.startHalf"
|
||||
:options="halfDayOptions"
|
||||
min-width=""
|
||||
@@ -42,16 +45,16 @@
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="end-date">Fin</label>
|
||||
<div class="mt-2 grid grid-cols-2 gap-2">
|
||||
<input
|
||||
id="end-date"
|
||||
<label class="text-md font-semibold text-neutral-700">Fin</label>
|
||||
<div class="mt-2 space-y-2">
|
||||
<MalioDate
|
||||
v-model="absenceForm.endDate"
|
||||
type="date"
|
||||
:class="[dateInputBaseClass, absenceForm.endDate ? 'border-black' : 'border-m-muted']"
|
||||
:clearable="false"
|
||||
:reserve-message-space="false"
|
||||
:disabled="props.lockDates"
|
||||
group-class="w-full"
|
||||
/>
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
:model-value="absenceForm.endHalf"
|
||||
:options="halfDayOptions"
|
||||
min-width=""
|
||||
@@ -72,31 +75,30 @@
|
||||
</div>
|
||||
|
||||
<div v-if="editingAbsence" class="grid grid-cols-2 gap-3 pt-2">
|
||||
<button
|
||||
type="button"
|
||||
class="flex items-center justify-center rounded-md bg-red-500 px-4 py-2 text-md font-semibold text-white hover:bg-red-600"
|
||||
<MalioButton
|
||||
label="Supprimer"
|
||||
variant="danger"
|
||||
button-class="w-full"
|
||||
@click="handleDelete"
|
||||
>
|
||||
Supprimer
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="flex items-center justify-center rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500"
|
||||
:class="submitButtonClass"
|
||||
>
|
||||
Modifier
|
||||
</button>
|
||||
/>
|
||||
<MalioButton
|
||||
label="Modifier"
|
||||
variant="primary"
|
||||
button-class="w-full"
|
||||
:disabled="props.isSubmitting || !isFormValid"
|
||||
@click="handleSubmit"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="flex justify-center pt-2">
|
||||
<MalioButton
|
||||
type="submit"
|
||||
label="Valider"
|
||||
button-class="w-[200px]"
|
||||
:disabled="props.isSubmitting || !isFormValid"
|
||||
@click="handleSubmit"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</AppDrawer>
|
||||
</MalioDrawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -106,7 +108,6 @@ import type { AbsenceType } from '~/services/dto/absence-type'
|
||||
import type { Absence } from '~/services/dto/absence'
|
||||
import type { HalfDay } from '~/services/dto/half-day'
|
||||
import { HALF_DAYS } from '~/services/dto/half-day'
|
||||
import AppDrawer from '~/components/AppDrawer.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
@@ -159,13 +160,6 @@ const showTypeError = computed(
|
||||
() => validationTouched.type && !isTypeValid.value
|
||||
)
|
||||
|
||||
const submitButtonClass = computed(() => {
|
||||
if (props.isSubmitting || !isFormValid.value) {
|
||||
return 'opacity-50 cursor-not-allowed'
|
||||
}
|
||||
return ''
|
||||
})
|
||||
|
||||
const employeeOptions = computed(() =>
|
||||
props.employees.map((e) => ({ label: `${e.firstName} ${e.lastName}`, value: e.id }))
|
||||
)
|
||||
@@ -174,9 +168,6 @@ const typeOptions = computed(() =>
|
||||
)
|
||||
const halfDayOptions = HALF_DAYS.map((h) => ({ label: h.label, value: h.value }))
|
||||
|
||||
const dateInputBaseClass =
|
||||
'h-10 w-full rounded-md border px-3 text-md text-black outline-none focus:border-2 focus:border-m-primary'
|
||||
|
||||
const onEmployeeChange = (value: string | number | null) => {
|
||||
absenceForm.value.employeeId = value === null ? '' : Number(value)
|
||||
}
|
||||
|
||||
@@ -1,36 +1,28 @@
|
||||
<template>
|
||||
<AppDrawer v-model="drawerOpen" title="Imprimer les absences">
|
||||
<MalioDrawer v-model="drawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Imprimer les absences</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="handleSubmit">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="print-from">
|
||||
Date de début <span class="text-red-600">*</span>
|
||||
</label>
|
||||
<input
|
||||
id="print-from"
|
||||
v-model="printForm.from"
|
||||
type="date"
|
||||
:class="fromFieldClass"
|
||||
/>
|
||||
<p v-if="showFromError" class="mt-1 text-sm text-red-600">
|
||||
La date de début est obligatoire.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="print-to">
|
||||
Date de fin <span class="text-red-600">*</span>
|
||||
</label>
|
||||
<input
|
||||
id="print-to"
|
||||
v-model="printForm.to"
|
||||
type="date"
|
||||
:class="toFieldClass"
|
||||
/>
|
||||
<p v-if="showToError" class="mt-1 text-sm text-red-600">
|
||||
La date de fin est obligatoire.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<MalioDate
|
||||
v-model="printForm.from"
|
||||
label="Date de début"
|
||||
required
|
||||
:clearable="false"
|
||||
:reserve-message-space="false"
|
||||
:error="showFromError ? 'La date de début est obligatoire.' : ''"
|
||||
group-class="w-full"
|
||||
/>
|
||||
|
||||
<MalioDate
|
||||
v-model="printForm.to"
|
||||
label="Date de fin"
|
||||
required
|
||||
:clearable="false"
|
||||
:reserve-message-space="false"
|
||||
:error="showToError ? 'La date de fin est obligatoire.' : ''"
|
||||
group-class="w-full"
|
||||
/>
|
||||
|
||||
<div class="space-y-2">
|
||||
<p class="text-md font-semibold text-neutral-700">
|
||||
@@ -97,21 +89,19 @@
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center pt-2">
|
||||
<button
|
||||
type="submit"
|
||||
class="flex w-[200px] items-center justify-center gap-2 rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500"
|
||||
:class="submitButtonClass"
|
||||
>
|
||||
Imprimer
|
||||
</button>
|
||||
<MalioButton
|
||||
label="Imprimer"
|
||||
variant="primary"
|
||||
:button-class="submitButtonClass"
|
||||
@click="handleSubmit"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</AppDrawer>
|
||||
</MalioDrawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, reactive, toRef, watch } from 'vue'
|
||||
import AppDrawer from '~/components/AppDrawer.vue'
|
||||
|
||||
type SiteOption = {
|
||||
id: number
|
||||
@@ -190,21 +180,6 @@ const showSitesError = computed(() => validationTouched.sites && !isSitesValid.v
|
||||
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'
|
||||
const fromFieldClass = computed(() => {
|
||||
if (showFromError.value) {
|
||||
return `${baseInputClass} border-red-500`
|
||||
}
|
||||
return `${baseInputClass} border-neutral-300`
|
||||
})
|
||||
const toFieldClass = computed(() => {
|
||||
if (showToError.value) {
|
||||
return `${baseInputClass} border-red-500`
|
||||
}
|
||||
return `${baseInputClass} border-neutral-300`
|
||||
})
|
||||
|
||||
const submitButtonClass = computed(() => {
|
||||
if (!isFormValid.value) {
|
||||
return 'opacity-50 cursor-not-allowed'
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
<template>
|
||||
<div v-if="modelValue" class="fixed inset-0 z-[60]">
|
||||
<Transition name="drawer-backdrop">
|
||||
<div class="absolute inset-0 bg-black/40" @click="close" />
|
||||
</Transition>
|
||||
<Transition name="drawer-panel">
|
||||
<div class="absolute right-0 top-0 h-full w-full max-w-md bg-white shadow-xl flex flex-col">
|
||||
<div class="shrink-0 flex items-center justify-between px-[20px] pt-8 pb-8">
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">
|
||||
{{ title }}
|
||||
</h2>
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-md p-1 text-primary-500 hover:text-secondary-500"
|
||||
@click="close"
|
||||
>
|
||||
<Icon name="mdi:close" size="24"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="min-h-0 flex-1 overflow-y-auto px-[20px] pb-4 pt-1">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{ modelValue: boolean; title?: string }>()
|
||||
const emit = defineEmits<{ (e: 'update:modelValue', value: boolean): void }>()
|
||||
|
||||
const close = () => emit('update:modelValue', false)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.drawer-backdrop-enter-active,
|
||||
.drawer-backdrop-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.drawer-backdrop-enter-from,
|
||||
.drawer-backdrop-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.drawer-panel-enter-active,
|
||||
.drawer-panel-leave-active {
|
||||
transition: transform 0.2s ease, opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.drawer-panel-enter-from,
|
||||
.drawer-panel-leave-to {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<AppDrawer v-model="drawerOpen" title="Export heures (tous les employés)">
|
||||
<MalioDrawer v-model="drawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Export heures (tous les employés)</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="handleSubmit">
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="bulk-yearly-hours-year">
|
||||
@@ -29,26 +32,19 @@
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center pt-2">
|
||||
<button
|
||||
type="submit"
|
||||
class="flex w-[200px] items-center justify-center gap-2 rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
<MalioButton
|
||||
:label="isLoading ? 'Génération en cours...' : 'Imprimer'"
|
||||
button-class="w-[200px]"
|
||||
:disabled="isLoading || selectedMonth === ''"
|
||||
>
|
||||
<template v-if="isLoading">
|
||||
Génération en cours...
|
||||
</template>
|
||||
<template v-else>
|
||||
Imprimer
|
||||
</template>
|
||||
</button>
|
||||
@click="handleSubmit"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</AppDrawer>
|
||||
</MalioDrawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import AppDrawer from '~/components/AppDrawer.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<AppDrawer v-model="drawerOpen" title="Export heures">
|
||||
<MalioDrawer v-model="drawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Export heures</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="handleSubmit">
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="yearly-hours-year">
|
||||
@@ -29,20 +32,18 @@
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center pt-2">
|
||||
<button
|
||||
type="submit"
|
||||
class="flex w-[200px] items-center justify-center gap-2 rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500"
|
||||
>
|
||||
Imprimer
|
||||
</button>
|
||||
<MalioButton
|
||||
label="Imprimer"
|
||||
button-class="w-[200px]"
|
||||
@click="handleSubmit"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</AppDrawer>
|
||||
</MalioDrawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import AppDrawer from '~/components/AppDrawer.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<AppDrawer v-model="drawerOpen" title="Récapitulatif Salaire">
|
||||
<MalioDrawer v-model="drawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Récapitulatif Salaire</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="handleSubmit">
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="salary-recap-month">
|
||||
@@ -17,21 +20,18 @@
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center pt-2">
|
||||
<button
|
||||
type="submit"
|
||||
class="flex w-[200px] items-center justify-center gap-2 rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500"
|
||||
:class="submitButtonClass"
|
||||
>
|
||||
Imprimer
|
||||
</button>
|
||||
<MalioButton
|
||||
label="Imprimer"
|
||||
button-class="w-[200px]"
|
||||
@click="handleSubmit"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</AppDrawer>
|
||||
</MalioDrawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import AppDrawer from '~/components/AppDrawer.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
@@ -63,13 +63,6 @@ const monthFieldClass = computed(() => {
|
||||
return `${baseInputClass} border-neutral-300`
|
||||
})
|
||||
|
||||
const submitButtonClass = computed(() => {
|
||||
if (!isMonthValid.value) {
|
||||
return 'opacity-50 cursor-not-allowed'
|
||||
}
|
||||
return ''
|
||||
})
|
||||
|
||||
const handleSubmit = () => {
|
||||
validationTouched.value = true
|
||||
if (!isMonthValid.value) return
|
||||
|
||||
@@ -33,7 +33,10 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<AppDrawer v-model="isDrawerOpen" :title="isEditing ? 'Modification prime' : 'Nouvelle prime'">
|
||||
<MalioDrawer v-model="isDrawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">{{ isEditing ? 'Modification prime' : 'Nouvelle prime' }}</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="onSubmit">
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="bonus-month">
|
||||
@@ -75,38 +78,38 @@
|
||||
</div>
|
||||
|
||||
<div v-if="isEditing" class="grid grid-cols-2 gap-3 pt-2">
|
||||
<button
|
||||
type="button"
|
||||
class="flex items-center justify-center rounded-md bg-red-500 px-4 py-2 text-md font-semibold text-white hover:bg-red-600"
|
||||
<MalioButton
|
||||
label="Supprimer"
|
||||
variant="danger"
|
||||
button-class="w-full"
|
||||
@click="onDelete"
|
||||
>
|
||||
Supprimer
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="flex items-center justify-center rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
/>
|
||||
<MalioButton
|
||||
label="Modifier"
|
||||
variant="primary"
|
||||
button-class="w-full"
|
||||
:disabled="!isFormValid"
|
||||
>
|
||||
Modifier
|
||||
</button>
|
||||
@click="onSubmit"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="flex justify-center pt-2">
|
||||
<button
|
||||
type="submit"
|
||||
class="flex w-[200px] items-center justify-center gap-2 rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
<MalioButton
|
||||
label="Ajouter"
|
||||
icon-name="mdi:plus"
|
||||
icon-position="left"
|
||||
variant="primary"
|
||||
button-class="w-[200px]"
|
||||
:disabled="!isFormValid"
|
||||
>
|
||||
+ Ajouter
|
||||
</button>
|
||||
@click="onSubmit"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</AppDrawer>
|
||||
</MalioDrawer>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Bonus } from '~/services/dto/bonus'
|
||||
import AppDrawer from '~/components/AppDrawer.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
bonuses: Bonus[]
|
||||
|
||||
@@ -43,7 +43,10 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<AppDrawer :model-value="isContractDrawerOpen" title="Modifier le contrat" @update:model-value="onUpdateContractDrawerOpen">
|
||||
<MalioDrawer :model-value="isContractDrawerOpen" @update:model-value="onUpdateContractDrawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Modifier le contrat</h2>
|
||||
</template>
|
||||
<div class="mb-4 flex border-b border-neutral-200">
|
||||
<button
|
||||
type="button"
|
||||
@@ -141,13 +144,12 @@
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center pt-2">
|
||||
<button
|
||||
type="submit"
|
||||
class="flex w-[200px] items-center justify-center gap-2 rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
<MalioButton
|
||||
label="Modifier"
|
||||
button-class="w-[200px]"
|
||||
:disabled="isContractSubmitting || !isContractEndDateValid"
|
||||
>
|
||||
Modifier
|
||||
</button>
|
||||
@click="onSubmitCloseContract"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -188,27 +190,29 @@
|
||||
class="mt-2 w-full rounded-md border border-neutral-300 bg-white px-3 py-2 text-base text-neutral-900 focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-secondary-500/20"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="w-full rounded-md bg-primary-500 px-4 py-2 text-base font-semibold text-white transition hover:bg-secondary-500 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
<MalioButton
|
||||
:label="form.id ? 'Modifier' : 'Ajouter'"
|
||||
button-class="w-full"
|
||||
:disabled="!form.startDate || isSuspensionSubmitting"
|
||||
@click="onSubmitSuspension(index)"
|
||||
>
|
||||
{{ form.id ? 'Modifier' : 'Ajouter' }}
|
||||
</button>
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="w-full rounded-md border-2 border-dashed border-primary-500/50 px-4 py-3 text-base font-semibold text-primary-500/50 transition hover:border-primary-500 hover:text-primary-500"
|
||||
<MalioButton
|
||||
label="Ajouter une suspension"
|
||||
icon-name="mdi:plus"
|
||||
icon-position="left"
|
||||
variant="tertiary"
|
||||
button-class="w-full"
|
||||
@click="onAddSuspensionForm"
|
||||
>
|
||||
+ Ajouter une suspension
|
||||
</button>
|
||||
/>
|
||||
</div>
|
||||
</AppDrawer>
|
||||
</MalioDrawer>
|
||||
|
||||
<AppDrawer :model-value="isCreateContractDrawerOpen" title="Ajouter un contrat" @update:model-value="onUpdateCreateContractDrawerOpen">
|
||||
<MalioDrawer :model-value="isCreateContractDrawerOpen" @update:model-value="onUpdateCreateContractDrawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Ajouter un contrat</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="onSubmitCreateContract">
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="create-contract-nature">
|
||||
@@ -282,16 +286,17 @@
|
||||
/>
|
||||
|
||||
<div class="sticky bottom-0 -mx-[20px] bg-white px-[20px] py-3 flex justify-center">
|
||||
<button
|
||||
type="submit"
|
||||
class="flex w-[200px] items-center justify-center gap-2 rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
<MalioButton
|
||||
label="Ajouter"
|
||||
icon-name="mdi:plus"
|
||||
icon-position="left"
|
||||
button-class="w-[200px]"
|
||||
:disabled="isCreateContractSubmitting || !isCreateContractFormValid"
|
||||
>
|
||||
+ Ajouter
|
||||
</button>
|
||||
@click="onSubmitCreateContract"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</AppDrawer>
|
||||
</MalioDrawer>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -47,7 +47,10 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<AppDrawer v-model="isDrawerOpen" title="Formation">
|
||||
<MalioDrawer v-model="isDrawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Formation</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="onSubmit">
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="formation-start-date">
|
||||
@@ -107,39 +110,39 @@
|
||||
</div>
|
||||
|
||||
<div v-if="isEditing" class="grid grid-cols-2 gap-3 pt-2">
|
||||
<button
|
||||
type="button"
|
||||
class="flex items-center justify-center rounded-md bg-red-500 px-4 py-2 text-md font-semibold text-white hover:bg-red-600"
|
||||
<MalioButton
|
||||
label="Supprimer"
|
||||
variant="danger"
|
||||
button-class="w-full"
|
||||
@click="onDelete"
|
||||
>
|
||||
Supprimer
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="flex items-center justify-center rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
/>
|
||||
<MalioButton
|
||||
label="Modifier"
|
||||
variant="primary"
|
||||
button-class="w-full"
|
||||
:disabled="!isFormValid"
|
||||
>
|
||||
Modifier
|
||||
</button>
|
||||
@click="onSubmit"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="flex justify-center pt-2">
|
||||
<button
|
||||
type="submit"
|
||||
class="flex w-[200px] items-center justify-center gap-2 rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
<MalioButton
|
||||
label="Ajouter"
|
||||
icon-name="mdi:plus"
|
||||
icon-position="left"
|
||||
variant="primary"
|
||||
button-class="w-[200px]"
|
||||
:disabled="!isFormValid"
|
||||
>
|
||||
+ Ajouter
|
||||
</button>
|
||||
@click="onSubmit"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</AppDrawer>
|
||||
</MalioDrawer>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type {Formation} from '~/services/dto/formation'
|
||||
import {getFormationJustificatifUrl} from '~/services/formations'
|
||||
import AppDrawer from '~/components/AppDrawer.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
formations: Formation[]
|
||||
|
||||
@@ -111,7 +111,10 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<AppDrawer v-model="isFractionedDrawerOpen" title="Jours fractionnés">
|
||||
<MalioDrawer v-model="isFractionedDrawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Jours fractionnés</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="handleSubmitFractioned">
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="fractioned-days">
|
||||
@@ -127,24 +130,25 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end gap-3 pt-2">
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-lg border border-neutral-200 px-4 py-2 text-md font-semibold text-neutral-700 hover:bg-neutral-100"
|
||||
<div class="grid grid-cols-2 gap-3 pt-2">
|
||||
<MalioButton
|
||||
label="Annuler"
|
||||
variant="tertiary"
|
||||
button-class="w-full"
|
||||
@click="isFractionedDrawerOpen = false"
|
||||
>
|
||||
Annuler
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="rounded-lg bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500"
|
||||
>
|
||||
Enregistrer
|
||||
</button>
|
||||
/>
|
||||
<MalioButton
|
||||
label="Enregistrer"
|
||||
button-class="w-full"
|
||||
@click="handleSubmitFractioned"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</AppDrawer>
|
||||
<AppDrawer v-model="isPaidLeaveDrawerOpen" title="Congés N-1 payés">
|
||||
</MalioDrawer>
|
||||
<MalioDrawer v-model="isPaidLeaveDrawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Congés N-1 payés</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="handleSubmitPaidLeave">
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="paid-leave-days">
|
||||
@@ -160,23 +164,21 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end gap-3 pt-2">
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-lg border border-neutral-200 px-4 py-2 text-md font-semibold text-neutral-700 hover:bg-neutral-100"
|
||||
<div class="grid grid-cols-2 gap-3 pt-2">
|
||||
<MalioButton
|
||||
label="Annuler"
|
||||
variant="tertiary"
|
||||
button-class="w-full"
|
||||
@click="isPaidLeaveDrawerOpen = false"
|
||||
>
|
||||
Annuler
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="rounded-lg bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500"
|
||||
>
|
||||
Enregistrer
|
||||
</button>
|
||||
/>
|
||||
<MalioButton
|
||||
label="Enregistrer"
|
||||
button-class="w-full"
|
||||
@click="handleSubmitPaidLeave"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</AppDrawer>
|
||||
</MalioDrawer>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -184,7 +186,6 @@
|
||||
import type {Absence} from '~/services/dto/absence'
|
||||
import type {EmployeeLeaveSummary} from '~/services/dto/employee-leave-summary'
|
||||
import {normalizeDate, toYmd} from '~/utils/date'
|
||||
import AppDrawer from '~/components/AppDrawer.vue'
|
||||
|
||||
type DayLeaveState = {
|
||||
am: boolean
|
||||
|
||||
@@ -64,7 +64,10 @@
|
||||
</div>
|
||||
|
||||
|
||||
<AppDrawer v-model="isDrawerOpen" title="Frais">
|
||||
<MalioDrawer v-model="isDrawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Frais</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="onSubmit">
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="mileage-month">
|
||||
@@ -157,39 +160,39 @@
|
||||
</div>
|
||||
|
||||
<div v-if="isEditing" class="grid grid-cols-2 gap-3 pt-2">
|
||||
<button
|
||||
type="button"
|
||||
class="flex items-center justify-center rounded-md bg-red-500 px-4 py-2 text-md font-semibold text-white hover:bg-red-600"
|
||||
<MalioButton
|
||||
label="Supprimer"
|
||||
variant="danger"
|
||||
button-class="w-full"
|
||||
@click="onDelete"
|
||||
>
|
||||
Supprimer
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="flex items-center justify-center rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
/>
|
||||
<MalioButton
|
||||
label="Modifier"
|
||||
variant="primary"
|
||||
button-class="w-full"
|
||||
:disabled="!isFormValid"
|
||||
>
|
||||
Modifier
|
||||
</button>
|
||||
@click="onSubmit"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="flex justify-center pt-2">
|
||||
<button
|
||||
type="submit"
|
||||
class="flex w-[200px] items-center justify-center gap-2 rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
<MalioButton
|
||||
label="Ajouter"
|
||||
icon-name="mdi:plus"
|
||||
icon-position="left"
|
||||
variant="primary"
|
||||
button-class="w-[200px]"
|
||||
:disabled="!isFormValid"
|
||||
>
|
||||
+ Ajouter
|
||||
</button>
|
||||
@click="onSubmit"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</AppDrawer>
|
||||
</MalioDrawer>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type {MileageAllowance} from '~/services/dto/mileage-allowance'
|
||||
import {getKmReceiptUrl, getAmountReceiptUrl} from '~/services/mileage-allowances'
|
||||
import AppDrawer from '~/components/AppDrawer.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
allowances: MileageAllowance[]
|
||||
|
||||
@@ -31,7 +31,10 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<AppDrawer v-model="isDrawerOpen" :title="isEditing ? 'Modification observation' : 'Nouvelle observation'">
|
||||
<MalioDrawer v-model="isDrawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">{{ isEditing ? 'Modification observation' : 'Nouvelle observation' }}</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="onSubmit">
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="observation-month">
|
||||
@@ -59,38 +62,38 @@
|
||||
</div>
|
||||
|
||||
<div v-if="isEditing" class="grid grid-cols-2 gap-3 pt-2">
|
||||
<button
|
||||
type="button"
|
||||
class="flex items-center justify-center rounded-md bg-red-500 px-4 py-2 text-md font-semibold text-white hover:bg-red-600"
|
||||
<MalioButton
|
||||
label="Supprimer"
|
||||
variant="danger"
|
||||
button-class="w-full"
|
||||
@click="onDelete"
|
||||
>
|
||||
Supprimer
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="flex items-center justify-center rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
/>
|
||||
<MalioButton
|
||||
label="Modifier"
|
||||
variant="primary"
|
||||
button-class="w-full"
|
||||
:disabled="!isFormValid"
|
||||
>
|
||||
Modifier
|
||||
</button>
|
||||
@click="onSubmit"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="flex justify-center pt-2">
|
||||
<button
|
||||
type="submit"
|
||||
class="flex w-[200px] items-center justify-center gap-2 rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
<MalioButton
|
||||
label="Ajouter"
|
||||
icon-name="mdi:plus"
|
||||
icon-position="left"
|
||||
variant="primary"
|
||||
button-class="w-[200px]"
|
||||
:disabled="!isFormValid"
|
||||
>
|
||||
+ Ajouter
|
||||
</button>
|
||||
@click="onSubmit"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</AppDrawer>
|
||||
</MalioDrawer>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Observation } from '~/services/dto/observation'
|
||||
import AppDrawer from '~/components/AppDrawer.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
observations: Observation[]
|
||||
|
||||
@@ -203,7 +203,10 @@
|
||||
</div>
|
||||
|
||||
<!-- Payment Drawer -->
|
||||
<AppDrawer v-model="isPaymentDrawerOpen" title="Payer des RTT">
|
||||
<MalioDrawer v-model="isPaymentDrawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Payer des RTT</h2>
|
||||
</template>
|
||||
<form @submit.prevent="onSubmitPayment">
|
||||
<div class="mb-4">
|
||||
<label class="block text-sm font-medium text-neutral-700">Mois</label>
|
||||
@@ -254,30 +257,27 @@
|
||||
class="mt-2 w-full rounded-md border border-neutral-300 px-3 py-2 text-base text-neutral-900 focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-secondary-500/20"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex justify-end gap-3">
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-md border border-neutral-300 px-4 py-2 text-sm font-medium text-neutral-700 hover:bg-neutral-50"
|
||||
<div class="grid grid-cols-2 gap-3 pt-2">
|
||||
<MalioButton
|
||||
label="Annuler"
|
||||
variant="tertiary"
|
||||
button-class="w-full"
|
||||
@click="isPaymentDrawerOpen = false"
|
||||
>
|
||||
Annuler
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="rounded-md bg-primary-500 px-4 py-2 text-sm font-medium text-white hover:bg-primary-600"
|
||||
>
|
||||
Enregistrer
|
||||
</button>
|
||||
/>
|
||||
<MalioButton
|
||||
label="Enregistrer"
|
||||
button-class="w-full"
|
||||
@click="onSubmitPayment"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</AppDrawer>
|
||||
</MalioDrawer>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { EmployeeRttSummary, EmployeeRttWeekSummary } from '~/services/dto/employee-rtt-summary'
|
||||
import type { ContractPhase } from '~/services/dto/contract-phase'
|
||||
import AppDrawer from '~/components/AppDrawer.vue'
|
||||
|
||||
type RttYearOption = {
|
||||
value: number
|
||||
|
||||
@@ -1,49 +1,43 @@
|
||||
<template>
|
||||
<AppDrawer v-model="drawerOpen" title="Export des heures">
|
||||
<MalioDrawer v-model="drawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Export des heures</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="handleSubmit">
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700" for="hours-export-date">
|
||||
Date <span class="text-red-600">*</span>
|
||||
</label>
|
||||
<input
|
||||
id="hours-export-date"
|
||||
v-model="selectedDate"
|
||||
type="date"
|
||||
class="mt-2 w-full rounded-md border border-black px-3 py-2 text-md text-neutral-900"
|
||||
>
|
||||
</div>
|
||||
<MalioDate
|
||||
v-model="selectedDate"
|
||||
label="Date"
|
||||
required
|
||||
:clearable="false"
|
||||
:reserve-message-space="false"
|
||||
group-class="w-full"
|
||||
/>
|
||||
|
||||
<div>
|
||||
<label class="text-md font-semibold text-neutral-700">
|
||||
Sites <span class="text-red-600">*</span>
|
||||
</label>
|
||||
<MalioSelectCheckbox
|
||||
v-model="selectedSites"
|
||||
:options="siteOptions"
|
||||
groupClass="w-full mt-2"
|
||||
label="Sites"
|
||||
display-select-all
|
||||
display-tag
|
||||
/>
|
||||
</div>
|
||||
<MalioSelectCheckbox
|
||||
v-model="selectedSites"
|
||||
:options="siteOptions"
|
||||
label="Sites"
|
||||
required
|
||||
:reserve-message-space="false"
|
||||
groupClass="w-full"
|
||||
display-select-all
|
||||
display-tag
|
||||
/>
|
||||
|
||||
<div class="flex justify-center pt-2">
|
||||
<button
|
||||
type="submit"
|
||||
class="flex w-[200px] items-center justify-center gap-2 rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
<MalioButton
|
||||
:label="isLoading ? 'Génération en cours...' : 'Exporter'"
|
||||
button-class="w-[200px]"
|
||||
:disabled="isLoading || !selectedDate || selectedSites.length === 0"
|
||||
>
|
||||
<template v-if="isLoading">Génération en cours...</template>
|
||||
<template v-else>Exporter</template>
|
||||
</button>
|
||||
@click="handleSubmit"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</AppDrawer>
|
||||
</MalioDrawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import AppDrawer from '~/components/AppDrawer.vue'
|
||||
import type { Site } from '~/services/dto/site'
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<!-- Desktop: filters row -->
|
||||
<div class="hidden lg:flex lg:items-center lg:gap-4">
|
||||
<div v-if="sites.length > 0 && isAdmin" class="relative z-50 w-80">
|
||||
<MalioSelectCheckbox
|
||||
<MalioSelectCheckbox :reserve-message-space="false"
|
||||
v-model="selectedSiteIds"
|
||||
:options="siteOptions"
|
||||
groupClass="w-80"
|
||||
@@ -11,8 +11,8 @@
|
||||
display-select-all
|
||||
/>
|
||||
</div>
|
||||
<div v-if="isAdmin" class="w-80">
|
||||
<MalioInputText
|
||||
<div v-if="isAdmin" class="w-96">
|
||||
<MalioInputText :reserve-message-space="false"
|
||||
v-model="employeeFilter"
|
||||
label="Recherche d'un employé"
|
||||
icon-name="mdi:magnify"
|
||||
@@ -23,7 +23,7 @@
|
||||
<!-- Mobile: search + filter button -->
|
||||
<div v-if="isAdmin" class="flex items-center gap-2 lg:hidden">
|
||||
<div class="flex-1 min-w-0">
|
||||
<MalioInputText
|
||||
<MalioInputText :reserve-message-space="false"
|
||||
v-model="employeeFilter"
|
||||
label="Recherche d'un employé"
|
||||
icon-name="mdi:magnify"
|
||||
@@ -39,12 +39,15 @@
|
||||
</div>
|
||||
|
||||
<!-- Mobile filters drawer -->
|
||||
<AppDrawer v-model="filtersDrawerOpen" title="Filtres">
|
||||
<MalioDrawer v-model="filtersDrawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Filtres</h2>
|
||||
</template>
|
||||
<div class="space-y-6">
|
||||
<div v-if="sites.length > 0 && isAdmin">
|
||||
<label class="text-md font-semibold text-neutral-700">Sites</label>
|
||||
<div class="mt-2">
|
||||
<MalioSelectCheckbox
|
||||
<MalioSelectCheckbox :reserve-message-space="false"
|
||||
v-model="selectedSiteIds"
|
||||
:options="siteOptions"
|
||||
groupClass="w-80"
|
||||
@@ -77,11 +80,11 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AppDrawer>
|
||||
</MalioDrawer>
|
||||
|
||||
<!-- Date navigation -->
|
||||
<div class="flex flex-col gap-3 lg:flex-row lg:justify-between lg:items-center lg:gap-4">
|
||||
<div class="flex flex-col gap-3 lg:flex-row lg:flex-wrap lg:gap-4">
|
||||
<div class="flex flex-col gap-3 lg:flex-row lg:flex-wrap lg:items-center lg:gap-4">
|
||||
<div
|
||||
v-if="viewMode === 'day'"
|
||||
class="inline-flex h-10 w-full overflow-hidden rounded-md border border-primary-500 bg-white lg:w-[320px]"
|
||||
@@ -142,10 +145,33 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Vue Jour (opt-in) : calendrier Malio avec jours validés en vert (markedDates). -->
|
||||
<MalioDate
|
||||
v-if="viewMode === 'day' && showValidationCalendar"
|
||||
:model-value="selectedDate"
|
||||
:clearable="false"
|
||||
:reserve-message-space="false"
|
||||
:marked-dates="markedDates"
|
||||
group-class="w-full lg:w-96"
|
||||
label="Date"
|
||||
@update:model-value="onDatePicked"
|
||||
@month-change="(payload) => emit('month-change', payload)"
|
||||
/>
|
||||
<!-- Vue Semaine : sélecteur de semaine Malio. -->
|
||||
<MalioDateWeek
|
||||
v-else-if="viewMode === 'week'"
|
||||
:model-value="pickerValue"
|
||||
:clearable="false"
|
||||
:reserve-message-space="false"
|
||||
group-class="w-full lg:w-96"
|
||||
label="Semaine"
|
||||
@update:model-value="onWeekPicked"
|
||||
/>
|
||||
<PeriodStepperPicker
|
||||
v-else
|
||||
width-class="w-full lg:w-[320px]"
|
||||
:label="formattedSelectedDate"
|
||||
:picker-type="viewMode === 'week' ? 'week' : 'date'"
|
||||
picker-type="date"
|
||||
:picker-value="pickerValue"
|
||||
prev-aria-label="Période précédente"
|
||||
next-aria-label="Période suivante"
|
||||
@@ -195,7 +221,6 @@
|
||||
import type { Site } from '~/services/dto/site'
|
||||
import type { AbsenceType } from '~/services/dto/absence-type'
|
||||
import PeriodStepperPicker from '~/components/PeriodStepperPicker.vue'
|
||||
import AppDrawer from '~/components/AppDrawer.vue'
|
||||
import { weekInputValueToYmd, ymdToWeekInputValue } from '~/utils/date'
|
||||
|
||||
const selectedDate = defineModel<string>('selectedDate', { required: true })
|
||||
@@ -208,6 +233,10 @@ const props = defineProps<{
|
||||
sites: Site[]
|
||||
absenceTypes: AbsenceType[]
|
||||
formattedSelectedDate: string
|
||||
// Calendrier des jours validés (vert) : opt-in, réservé à l'écran Heures.
|
||||
// L'écran Heures Conducteurs ne le passe pas → garde le PeriodStepperPicker.
|
||||
showValidationCalendar?: boolean
|
||||
markedDates?: Record<string, 'success' | 'danger'>
|
||||
shortcutButtonClass: (target: 'yesterday' | 'today' | 'tomorrow') => string
|
||||
weekShortcutButtonClass: (target: 'previousWeek' | 'thisWeek' | 'nextWeek') => string
|
||||
getWeekShortcutLabel: (target: 'previousWeek' | 'thisWeek' | 'nextWeek') => string
|
||||
@@ -223,6 +252,7 @@ const emit = defineEmits<{
|
||||
(e: 'set-this-week'): void
|
||||
(e: 'set-next-week'): void
|
||||
(e: 'shift-date', value: number): void
|
||||
(e: 'month-change', value: { month: number; year: number }): void
|
||||
}>()
|
||||
|
||||
const filtersDrawerOpen = ref(false)
|
||||
@@ -252,4 +282,20 @@ const onPickerValue = (value: string) => {
|
||||
|
||||
selectedDate.value = value
|
||||
}
|
||||
|
||||
// Sélection d'un jour dans le calendrier MalioDate (vue Jour). `clearable=false`
|
||||
// → pas de null en pratique, mais on garde la garde par sécurité.
|
||||
const onDatePicked = (value: string | null) => {
|
||||
if (!value) return
|
||||
selectedDate.value = value
|
||||
}
|
||||
|
||||
// Sélection d'une semaine dans MalioDateWeek (vue Semaine) : v-model au format ISO
|
||||
// week (YYYY-Www) → on repositionne selectedDate sur le lundi de cette semaine.
|
||||
const onWeekPicked = (value: string | null) => {
|
||||
if (!value) return
|
||||
const ymd = weekInputValueToYmd(value)
|
||||
if (!ymd) return
|
||||
selectedDate.value = ymd
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
<template>
|
||||
<MalioDrawer v-model="drawerOpen" title="Commentaire">
|
||||
<MalioDrawer v-model="drawerOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">Commentaire</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="onSave">
|
||||
<div v-if="employeeLabel" class="text-md font-semibold text-neutral-700">{{ employeeLabel }}</div>
|
||||
<div class="text-md font-semibold text-neutral-700">{{ formatWeekRange }}</div>
|
||||
<MalioInputTextArea
|
||||
<MalioInputTextArea :reserve-message-space="false"
|
||||
v-model="content"
|
||||
label="Commentaire"
|
||||
:size="8"
|
||||
@@ -11,17 +14,18 @@
|
||||
:show-counter="true"
|
||||
resize="vertical"
|
||||
/>
|
||||
<div class="sticky bottom-0 -mx-[20px] bg-white px-[20px] py-3 flex justify-between gap-3">
|
||||
<div class="sticky bottom-0 -mx-[20px] bg-white px-[20px] py-3 flex gap-3">
|
||||
<MalioButton
|
||||
v-if="commentId"
|
||||
label="Supprimer"
|
||||
variant="danger"
|
||||
button-class="flex-1"
|
||||
:disabled="isSubmitting"
|
||||
@click="onDelete"
|
||||
/>
|
||||
<MalioButton
|
||||
label="Enregistrer"
|
||||
button-class="ml-auto"
|
||||
button-class="flex-1"
|
||||
:disabled="isSubmitting || !canSubmit"
|
||||
@click="onSave"
|
||||
/>
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
bulkUpdateWorkHourValidation,
|
||||
bulkUpsertWorkHours,
|
||||
getWorkHourDayContext,
|
||||
getWorkHourValidationStatus,
|
||||
getWeeklyWorkHourSummary,
|
||||
listWorkHoursByDate,
|
||||
updateWorkHourSiteValidation,
|
||||
@@ -28,7 +29,8 @@ import {
|
||||
getWeekStartDate,
|
||||
getTodayYmd,
|
||||
parseYmd,
|
||||
shiftYmd
|
||||
shiftYmd,
|
||||
toYmd
|
||||
} from '~/utils/date'
|
||||
import { sortEmployeesBySiteAndOrder } from '~/utils/employee'
|
||||
|
||||
@@ -68,6 +70,9 @@ export const useDriverHoursPage = () => {
|
||||
const isSubmitting = ref(false)
|
||||
const validatingRowIds = ref<number[]>([])
|
||||
const siteValidatingRowIds = ref<number[]>([])
|
||||
// Jours entièrement validés (conducteurs) par mois civil, pour le calendrier de
|
||||
// la vue Jour. Clé 'YYYY-MM' → dates Y-m-d. Chargé à la volée sur @month-change.
|
||||
const validatedDaysByMonth = ref<Record<string, string[]>>({})
|
||||
|
||||
const dayGridCols = computed(() => {
|
||||
const metricCol = '0.4fr'
|
||||
@@ -519,10 +524,11 @@ export const useDriverHoursPage = () => {
|
||||
const refreshAfterAbsenceChange = async () => {
|
||||
if (isAdmin.value) {
|
||||
await Promise.all([loadWeeklySummary(), loadDayContext(), loadAbsences()])
|
||||
return
|
||||
} else {
|
||||
weeklySummary.value = null
|
||||
await Promise.all([loadDayContext(), loadAbsences()])
|
||||
}
|
||||
weeklySummary.value = null
|
||||
await Promise.all([loadDayContext(), loadAbsences()])
|
||||
await reloadValidationMonth(selectedDate.value)
|
||||
}
|
||||
|
||||
const submitAbsence = async () => {
|
||||
@@ -626,6 +632,7 @@ export const useDriverHoursPage = () => {
|
||||
try {
|
||||
await updateWorkHourValidation(updatedRow.workHourId, checked, { toast: options.toast })
|
||||
updatedRow.isValid = checked
|
||||
await reloadValidationMonth(selectedDate.value)
|
||||
} finally {
|
||||
validatingRowIds.value = validatingRowIds.value.filter((id) => id !== employeeId)
|
||||
}
|
||||
@@ -708,6 +715,7 @@ export const useDriverHoursPage = () => {
|
||||
}, { toast: false })
|
||||
|
||||
await loadWorkHours()
|
||||
await reloadValidationMonth(selectedDate.value)
|
||||
|
||||
if (result.updated === 0) {
|
||||
toast.error({ title: 'Erreur', message: 'Aucune ligne mise à jour.' })
|
||||
@@ -825,6 +833,45 @@ export const useDriverHoursPage = () => {
|
||||
dayContext.value = await getWorkHourDayContext(selectedDate.value)
|
||||
}
|
||||
|
||||
// --- Calendrier vue Jour : jours validés en vert (scope conducteurs) ---------
|
||||
const monthKey = (year: number, monthIndex: number) => `${year}-${String(monthIndex + 1).padStart(2, '0')}`
|
||||
|
||||
const markedDates = computed<Record<string, 'success'>>(() => {
|
||||
const map: Record<string, 'success'> = {}
|
||||
for (const days of Object.values(validatedDaysByMonth.value)) {
|
||||
for (const day of days) map[day] = 'success'
|
||||
}
|
||||
return map
|
||||
})
|
||||
|
||||
// Plage = grille visible complète (lundi avant le 1er → dimanche après le dernier).
|
||||
// driver:true → l'endpoint ne considère que les conducteurs.
|
||||
const loadValidationMonth = async (monthIndex: number, year: number, options: { force?: boolean } = {}) => {
|
||||
const key = monthKey(year, monthIndex)
|
||||
if (!options.force && validatedDaysByMonth.value[key]) return
|
||||
|
||||
const gridStart = getWeekStartDate(new Date(year, monthIndex, 1))
|
||||
const gridEnd = getWeekStartDate(new Date(year, monthIndex + 1, 0))
|
||||
gridEnd.setDate(gridEnd.getDate() + 6)
|
||||
|
||||
const from = toYmd(gridStart.getFullYear(), gridStart.getMonth(), gridStart.getDate())
|
||||
const to = toYmd(gridEnd.getFullYear(), gridEnd.getMonth(), gridEnd.getDate())
|
||||
const days = await getWorkHourValidationStatus(from, to, { driver: true })
|
||||
validatedDaysByMonth.value = { ...validatedDaysByMonth.value, [key]: days }
|
||||
}
|
||||
|
||||
const onCalendarMonthChange = (payload: { month: number; year: number }) => {
|
||||
void loadValidationMonth(payload.month, payload.year)
|
||||
}
|
||||
|
||||
const reloadValidationMonth = async (dateYmd: string) => {
|
||||
const parsed = parseYmd(dateYmd)
|
||||
if (!parsed) return
|
||||
const key = monthKey(parsed.getFullYear(), parsed.getMonth())
|
||||
if (!validatedDaysByMonth.value[key]) return
|
||||
await loadValidationMonth(parsed.getMonth(), parsed.getFullYear(), { force: true })
|
||||
}
|
||||
|
||||
const refreshByDate = async () => {
|
||||
if (isAdmin.value) {
|
||||
await Promise.all([loadWorkHours(), loadWeeklySummary(), loadDayContext(), loadAbsences()])
|
||||
@@ -921,6 +968,7 @@ export const useDriverHoursPage = () => {
|
||||
})
|
||||
|
||||
await refreshByDate()
|
||||
await reloadValidationMonth(selectedDate.value)
|
||||
} finally {
|
||||
isSubmitting.value = false
|
||||
}
|
||||
@@ -1003,6 +1051,8 @@ export const useDriverHoursPage = () => {
|
||||
closeAbsenceDrawer,
|
||||
formatMinutes,
|
||||
handleSave,
|
||||
markedDates,
|
||||
onCalendarMonthChange,
|
||||
isWeekCommentDrawerOpen,
|
||||
weekCommentContext,
|
||||
openWeekCommentDrawer,
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
bulkUpdateWorkHourValidation,
|
||||
bulkUpsertWorkHours,
|
||||
getWorkHourDayContext,
|
||||
getWorkHourValidationStatus,
|
||||
getWeeklyWorkHourSummary,
|
||||
listWorkHoursByDate,
|
||||
updateWorkHourSiteValidation,
|
||||
@@ -30,7 +31,8 @@ import {
|
||||
getWeekStartDate,
|
||||
getTodayYmd,
|
||||
parseYmd,
|
||||
shiftYmd
|
||||
shiftYmd,
|
||||
toYmd
|
||||
} from '~/utils/date'
|
||||
import { sortEmployeesBySiteAndOrder } from '~/utils/employee'
|
||||
|
||||
@@ -70,6 +72,10 @@ export const useHoursPage = () => {
|
||||
const isSubmitting = ref(false)
|
||||
const validatingRowIds = ref<number[]>([])
|
||||
const siteValidatingRowIds = ref<number[]>([])
|
||||
// Jours entièrement validés (admin) par mois civil affiché dans le calendrier
|
||||
// de la vue Jour. Clé = 'YYYY-MM', valeur = liste de dates Y-m-d. Chargé à la
|
||||
// volée sur @month-change (jamais préchargé sur plusieurs années).
|
||||
const validatedDaysByMonth = ref<Record<string, string[]>>({})
|
||||
|
||||
const dayGridCols = computed(() => {
|
||||
const metricCol = '0.4fr'
|
||||
@@ -686,11 +692,11 @@ export const useHoursPage = () => {
|
||||
const refreshAfterAbsenceChange = async () => {
|
||||
if (isAdmin.value) {
|
||||
await Promise.all([loadWeeklySummary(), loadDayContext(), loadAbsences()])
|
||||
return
|
||||
} else {
|
||||
weeklySummary.value = null
|
||||
await Promise.all([loadDayContext(), loadAbsences()])
|
||||
}
|
||||
|
||||
weeklySummary.value = null
|
||||
await Promise.all([loadDayContext(), loadAbsences()])
|
||||
await reloadValidationMonth(selectedDate.value)
|
||||
}
|
||||
|
||||
const submitAbsence = async () => {
|
||||
@@ -787,6 +793,7 @@ export const useHoursPage = () => {
|
||||
try {
|
||||
await updateWorkHourValidation(updatedRow.workHourId, checked, { toast: options.toast })
|
||||
updatedRow.isValid = checked
|
||||
await reloadValidationMonth(selectedDate.value)
|
||||
} finally {
|
||||
validatingRowIds.value = validatingRowIds.value.filter((id) => id !== employeeId)
|
||||
}
|
||||
@@ -891,6 +898,7 @@ export const useHoursPage = () => {
|
||||
}, { toast: false })
|
||||
|
||||
await loadWorkHours()
|
||||
await reloadValidationMonth(selectedDate.value)
|
||||
|
||||
if (result.updated === 0) {
|
||||
toast.error({
|
||||
@@ -1031,6 +1039,50 @@ export const useHoursPage = () => {
|
||||
dayContext.value = await getWorkHourDayContext(selectedDate.value)
|
||||
}
|
||||
|
||||
// --- Calendrier vue Jour : jours validés en vert ---------------------------
|
||||
const monthKey = (year: number, monthIndex: number) => `${year}-${String(monthIndex + 1).padStart(2, '0')}`
|
||||
|
||||
// Fusionne tous les mois chargés en une seule map ISO → 'success' pour MalioDate.
|
||||
const markedDates = computed<Record<string, 'success'>>(() => {
|
||||
const map: Record<string, 'success'> = {}
|
||||
for (const days of Object.values(validatedDaysByMonth.value)) {
|
||||
for (const day of days) map[day] = 'success'
|
||||
}
|
||||
return map
|
||||
})
|
||||
|
||||
// Charge le statut du mois affiché. La plage couvre toute la grille visible
|
||||
// (lundi avant le 1er → dimanche après le dernier jour) pour colorer aussi les
|
||||
// jours débordants des mois adjacents.
|
||||
const loadValidationMonth = async (monthIndex: number, year: number, options: { force?: boolean } = {}) => {
|
||||
const key = monthKey(year, monthIndex)
|
||||
if (!options.force && validatedDaysByMonth.value[key]) return
|
||||
|
||||
const gridStart = getWeekStartDate(new Date(year, monthIndex, 1))
|
||||
const gridEnd = getWeekStartDate(new Date(year, monthIndex + 1, 0))
|
||||
gridEnd.setDate(gridEnd.getDate() + 6)
|
||||
|
||||
const from = toYmd(gridStart.getFullYear(), gridStart.getMonth(), gridStart.getDate())
|
||||
const to = toYmd(gridEnd.getFullYear(), gridEnd.getMonth(), gridEnd.getDate())
|
||||
const days = await getWorkHourValidationStatus(from, to)
|
||||
validatedDaysByMonth.value = { ...validatedDaysByMonth.value, [key]: days }
|
||||
}
|
||||
|
||||
const onCalendarMonthChange = (payload: { month: number; year: number }) => {
|
||||
void loadValidationMonth(payload.month, payload.year)
|
||||
}
|
||||
|
||||
// Après une modification qui touche la validation d'un jour (validation,
|
||||
// sauvegarde d'heures, absence), recharge le mois concerné s'il est déjà en
|
||||
// cache → le calendrier se recolore. Sinon no-op (le prochain affichage fetch).
|
||||
const reloadValidationMonth = async (dateYmd: string) => {
|
||||
const parsed = parseYmd(dateYmd)
|
||||
if (!parsed) return
|
||||
const key = monthKey(parsed.getFullYear(), parsed.getMonth())
|
||||
if (!validatedDaysByMonth.value[key]) return
|
||||
await loadValidationMonth(parsed.getMonth(), parsed.getFullYear(), { force: true })
|
||||
}
|
||||
|
||||
const refreshByDate = async () => {
|
||||
if (isAdmin.value) {
|
||||
await Promise.all([loadWorkHours(), loadWeeklySummary(), loadDayContext(), loadAbsences()])
|
||||
@@ -1131,6 +1183,7 @@ export const useHoursPage = () => {
|
||||
})
|
||||
|
||||
await refreshByDate()
|
||||
await reloadValidationMonth(selectedDate.value)
|
||||
} finally {
|
||||
isSubmitting.value = false
|
||||
}
|
||||
@@ -1221,6 +1274,8 @@ export const useHoursPage = () => {
|
||||
closeAbsenceDrawer,
|
||||
formatMinutes,
|
||||
handleSave,
|
||||
markedDates,
|
||||
onCalendarMonthChange,
|
||||
isWeekCommentDrawerOpen,
|
||||
weekCommentContext,
|
||||
openWeekCommentDrawer,
|
||||
|
||||
@@ -159,6 +159,17 @@ export const documentationSections: DocSection[] = [
|
||||
{ type: 'note', content: 'Toute vraie modification effectuée par un administrateur remet automatiquement les deux validations à zéro.' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'calendrier-jours-valides',
|
||||
title: 'Calendrier des jours validés (vue Jour)',
|
||||
requiredLevel: 'site_manager',
|
||||
blocks: [
|
||||
{ type: 'paragraph', content: 'En vue Jour, le sélecteur de date est un calendrier qui colore en vert les jours entièrement validés. Vous repérez ainsi d\'un coup d\'œil les jours où il reste de la validation à faire.' },
|
||||
{ type: 'list', content: 'Vert : le jour porte au moins une ligne et toutes sont validées par un administrateur.\nNeutre (sans couleur) : il reste au moins une ligne à valider, ou aucune ligne n\'a encore été saisie ce jour-là.' },
|
||||
{ type: 'paragraph', content: 'Le vert reflète tout votre périmètre (vos sites), indépendamment du filtre Sites de l\'écran. Les conducteurs ne sont pas pris en compte (écran Heures Conducteurs). Cliquez sur un jour pour vous y rendre.' },
|
||||
{ type: 'note', content: 'La couleur se met à jour automatiquement quand vous validez des lignes, enregistrez des heures ou modifiez une absence. La validation de site (chef de site) ne change pas la couleur : seule la validation RH/admin compte.' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
Generated
+833
-5
@@ -7,7 +7,7 @@
|
||||
"name": "frontend",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@malio/layer-ui": "^1.4.6",
|
||||
"@malio/layer-ui": "^1.7.11",
|
||||
"@nuxt/icon": "^2.2.1",
|
||||
"@nuxtjs/i18n": "^10.2.1",
|
||||
"@pinia/nuxt": "^0.11.3",
|
||||
@@ -1196,6 +1196,31 @@
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/core": {
|
||||
"version": "1.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
|
||||
"integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/utils": "^0.2.11"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/dom": {
|
||||
"version": "1.7.6",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz",
|
||||
"integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/core": "^1.7.5",
|
||||
"@floating-ui/utils": "^0.2.11"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/utils": {
|
||||
"version": "0.2.11",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz",
|
||||
"integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@humanfs/core": {
|
||||
"version": "0.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
|
||||
@@ -2222,14 +2247,22 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@malio/layer-ui": {
|
||||
"version": "1.4.6",
|
||||
"resolved": "https://gitea.malio.fr/api/packages/MALIO-DEV/npm/%40malio%2Flayer-ui/-/1.4.6/layer-ui-1.4.6.tgz",
|
||||
"integrity": "sha512-stHqUAJ8E6a62Ka7QXlE177GhkIsjtmYNa/tNk1TVpbJ099okfLLivrlofEl7CCAqDeMaIepnW4q0vxJT+EFEA==",
|
||||
"version": "1.7.11",
|
||||
"resolved": "https://gitea.malio.fr/api/packages/MALIO-DEV/npm/%40malio%2Flayer-ui/-/1.7.11/layer-ui-1.7.11.tgz",
|
||||
"integrity": "sha512-uTISSe0L2T0TcpJShdK8VOEr0GpYzyDFDkLNFRa5APbpnfb8GPchx0xlFA1pgEF7DbnYB/zxYTWZCrGOhmaWOQ==",
|
||||
"dependencies": {
|
||||
"@nuxt/icon": "^2.2.1",
|
||||
"@nuxtjs/tailwindcss": "^6.14.0",
|
||||
"@tiptap/extension-color": "^3.22.5",
|
||||
"@tiptap/extension-highlight": "^3.22.5",
|
||||
"@tiptap/extension-placeholder": "^3.22.5",
|
||||
"@tiptap/extension-text-style": "^3.22.5",
|
||||
"@tiptap/pm": "^3.22.5",
|
||||
"@tiptap/starter-kit": "^3.22.5",
|
||||
"@tiptap/vue-3": "^3.22.5",
|
||||
"maska": "^3.2.0",
|
||||
"tailwind-merge": "^3.3.1"
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"tiptap-markdown": "^0.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"nuxt": "^4.0.0"
|
||||
@@ -5323,6 +5356,480 @@
|
||||
"integrity": "sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA==",
|
||||
"license": "CC0-1.0"
|
||||
},
|
||||
"node_modules/@tiptap/core": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.26.1.tgz",
|
||||
"integrity": "sha512-TX9PyPqBoix0qDLjtok/bddtdSy54QhzLVha405C07V+WySOpH3s/pWYkywehZQY0SQtcrcY4MNSCeQjCbA28A==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/pm": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-blockquote": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.26.1.tgz",
|
||||
"integrity": "sha512-WaKjKmUaadgvZDDBk9JOn/oidlOFr6booqJIWHGL5S0aUUTKHS19oGfKQq/l9Z1y1niaRePk0Y4fy/jxCnfKPA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-bold": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.26.1.tgz",
|
||||
"integrity": "sha512-VIlF2sAiV6K009pcIDotfY8mvsPaq90dxeG9Q0ZIqfMD958TUCqjHw4MGYZf0/FgP12xksBfmcR7W312xgUf9Q==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-bubble-menu": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.26.1.tgz",
|
||||
"integrity": "sha512-Y3R9wFKP/U9M04JG+0PM/yW3OV+MSbUp6YBKQWZmUu8x6y7TbcNvDsaJ6QEFZt5aRMS6qH1ksYPTOz47JdjcfA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1",
|
||||
"@tiptap/pm": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-bullet-list": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-3.26.1.tgz",
|
||||
"integrity": "sha512-JB6bEJJHxXNAXEXTIAN3/j70p1ARHdeMfhzshGZswWKUWtDibTCrspIp7p1VNeiuVtJ/HB6PpFkGi7yWtQ3RTg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extension-list": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-code": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.26.1.tgz",
|
||||
"integrity": "sha512-t9/VR5k3rGPyhcGau9YvVgaAQ+nP9R9WzS996bQQ7GIrMOTSXb0FWwoQFBiYl83V6VA16Tlj/oScC7SFlA8lvA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-code-block": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-3.26.1.tgz",
|
||||
"integrity": "sha512-NY7SYqcrqDVYTSWyaNGdSfCims6pOHoRQ2Rh4DEFb/rb8gLVkqbLZhcHzQCVfinlPqgV3xWF6cYMORwmnlBkXQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1",
|
||||
"@tiptap/pm": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-color": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-color/-/extension-color-3.26.1.tgz",
|
||||
"integrity": "sha512-f8yy+CBRDqMeaIaQ0UHDbGUqjfGka5O16ja47shatXm49lqLcL06js9tGoiZFVzp9/lcKOLSXjuzxNf0OZ9SbA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extension-text-style": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-document": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.26.1.tgz",
|
||||
"integrity": "sha512-6W2vZjvi0Mv+4xEtwMDGhWwo7FotWR6eKfmntmduvehWevFpMxOKcTtyotjLigfZv738y50YWmvbaPuAPJG3BA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-dropcursor": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-3.26.1.tgz",
|
||||
"integrity": "sha512-eVq3BvFIa3YD+pBIlj1i72vYEixlegGVKHnSYiVF2ovkQOSAH9sca7pkq6WgV1sMTCyWCU8e+WznTqtydvHUWA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extensions": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-floating-menu": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.26.1.tgz",
|
||||
"integrity": "sha512-xn0g4m/q2bjG+hULPwp6Aqb/6wpzUtc65jOhgJsG/S3Ey3kLJGUvZBuhozwNFu8FcugxM1fMUpNhkJkodCCGFw==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@floating-ui/dom": "^1.0.0",
|
||||
"@tiptap/core": "3.26.1",
|
||||
"@tiptap/pm": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-gapcursor": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.26.1.tgz",
|
||||
"integrity": "sha512-BWW1yMQQA4TbEU0LLK+4cd9ebLTuZG5KjHwFMBRD/bGiRW9V1gTWFsCqThBbczcANoQiZK9pn5/4Ad/rGM3HUg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extensions": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-hard-break": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-3.26.1.tgz",
|
||||
"integrity": "sha512-gzNb1e/fK6HN+ko1axsrasjK7F1q0Bnm0G4ZY/0eq7pV7s1wZuwoCiGbvUx/9LCFKRV6+94FTqlb0A3NbYN36g==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-heading": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.26.1.tgz",
|
||||
"integrity": "sha512-eRlv9XxzUL8FobKAiF1WjP35CT2QpbcxxeyYFF7BmGEONvKI7r5g7JGwyGli4Cvclh70h8w6JuoXSmGUVEU65A==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-highlight": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-highlight/-/extension-highlight-3.26.1.tgz",
|
||||
"integrity": "sha512-qgx4Eetqkogh3OyomZO0yIMQGHhjatCDAtELkC7NQxnmPsp2c9i6ck/hh7mP5We5ccBwUoYRuNGC9lkflCx75g==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-horizontal-rule": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.26.1.tgz",
|
||||
"integrity": "sha512-l9lPZYeSmY90y/2GkQcKaICFD5Atr8sx2SzJGkQzpNC9tRxZXyAHnfJE3OjBkspuGzjWIN0DimxBj4ibz58sKw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1",
|
||||
"@tiptap/pm": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-italic": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.26.1.tgz",
|
||||
"integrity": "sha512-cLKYvOLToWEkJkAPspgIZ/PYDzAxacLm1VWcAq1tO1QDQCDe2Kw+y/zsGlyYEq/aKsAgpp4JNopBwAXRXxt2/A==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-link": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.26.1.tgz",
|
||||
"integrity": "sha512-aLLGLgikuhLFHRbjfUC6D4gRg+NUty4uhW7YkyVl8AxxPME47dPbCOX4H6uLCjEZcn3WnfNuCTr6HCTl0KEmGA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"linkifyjs": "^4.3.3"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1",
|
||||
"@tiptap/pm": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-list": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.26.1.tgz",
|
||||
"integrity": "sha512-06nOjnyXpzMO8Ys5k3IbYsDsKib1mv2OtaxBYX1/1uvRyOKwUX5tqDLb/qigic0LIANNL73lkNC8Z8XPeG4Tkg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1",
|
||||
"@tiptap/pm": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-list-item": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-3.26.1.tgz",
|
||||
"integrity": "sha512-5gLXJUiP763NA6i4HgrtcwUDXPP8820hsaBQyF1Y1VsXNi02uW9FVLe3RZK8jF0NZUNh9CqD0gogYJCbKOUU8A==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extension-list": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-list-keymap": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-list-keymap/-/extension-list-keymap-3.26.1.tgz",
|
||||
"integrity": "sha512-EReSayePO6SIxtRbxx+7KfBQreWHvoZmMb3O/RemfT8W6J0hCG5N/Rh8Z12+YZOnCDRXJ4RzFpAikYka3E54jQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extension-list": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-ordered-list": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-3.26.1.tgz",
|
||||
"integrity": "sha512-LeFPeFwb7ylkQVuuaHj+niu7WhWHpjDOi1GKZJE/ohOa2lgt7P221HMqhUzPiDlXOExN72oWTNmXUlT0ymCTkw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extension-list": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-paragraph": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.26.1.tgz",
|
||||
"integrity": "sha512-OkBeYUNM3eTzjm3z6IcC3NHryOX8g3eGNI86P/B+tFoFQSRuzLsKZU50ARCfIiLLg812NjcqujeJ1eX3BKDZrw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-placeholder": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-3.26.1.tgz",
|
||||
"integrity": "sha512-oJCEVmaaUY1Jn5v8KbRMdgYLFH9aptLkir+M0ZMnl+8TTmvMdLK2H02X9ofZQwAb12qreQgb890hB3PFen7TDg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extensions": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-strike": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.26.1.tgz",
|
||||
"integrity": "sha512-7hmQ2mBsA+75GRrJIKYxb+10H23mblEQSGGsv9Ptl7JLaGmj+8sv2HGQGSUT9QBiBVprxaYTqyWFXQC9akfLWg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-text": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.26.1.tgz",
|
||||
"integrity": "sha512-Gocui5WvcCCJJIX17gdOVCSdYi5H4fDwaR0qkMAUZPq5kJCdrfl+vNpt8BTt53Bk+/QumiUW21fhQ184w7RoeQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-text-style": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-3.26.1.tgz",
|
||||
"integrity": "sha512-V8t7qOyLH7IBR2HjjJVZ9rUHTnuFToJx07L9PN9PpgQLhz9q8Jah4gAwmjLBXDRG2YaXImGK0RwKKCU/yHhwOg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-underline": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.26.1.tgz",
|
||||
"integrity": "sha512-HUHtQ+DRWDM0opW7Nk3YQwrLzw876hMU7cr1X/ZTG+8Bp+AKHihlwU+bqrPgG5St0mqASyUEhHQ/vK5PlnUYOQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extensions": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.26.1.tgz",
|
||||
"integrity": "sha512-PmRaoe6bebTgz/ZQrjmzwZMST1d9js9ZTiKnUXeXl3Fm+V5U/c3TbbKDfqmL63qPQdjtShDMHi9tYuv+c77OFQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.26.1",
|
||||
"@tiptap/pm": "3.26.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/pm": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.26.1.tgz",
|
||||
"integrity": "sha512-48cJQRbvr9Ux0+IgM1BR5vOLU5hkC+n+uerdQy2JjrIRKpYE/huU8fQFm6PoRppoKYfilklzb29elsQ+n2TA+g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-changeset": "^2.3.0",
|
||||
"prosemirror-commands": "^1.6.2",
|
||||
"prosemirror-dropcursor": "^1.8.1",
|
||||
"prosemirror-gapcursor": "^1.3.2",
|
||||
"prosemirror-history": "^1.4.1",
|
||||
"prosemirror-inputrules": "^1.4.0",
|
||||
"prosemirror-keymap": "^1.2.3",
|
||||
"prosemirror-model": "^1.25.7",
|
||||
"prosemirror-schema-list": "^1.5.0",
|
||||
"prosemirror-state": "^1.4.4",
|
||||
"prosemirror-tables": "^1.8.0",
|
||||
"prosemirror-transform": "^1.12.0",
|
||||
"prosemirror-view": "^1.41.8"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/starter-kit": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-3.26.1.tgz",
|
||||
"integrity": "sha512-A0zsvwGU9exLND34F8e8KqUXFSfs835tNN+VC+ZT3yNeaO/WXnlh/Cgal1F6pHHbcxy7RV2CRwJU5S3cWLPxrA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tiptap/core": "^3.26.1",
|
||||
"@tiptap/extension-blockquote": "^3.26.1",
|
||||
"@tiptap/extension-bold": "^3.26.1",
|
||||
"@tiptap/extension-bullet-list": "^3.26.1",
|
||||
"@tiptap/extension-code": "^3.26.1",
|
||||
"@tiptap/extension-code-block": "^3.26.1",
|
||||
"@tiptap/extension-document": "^3.26.1",
|
||||
"@tiptap/extension-dropcursor": "^3.26.1",
|
||||
"@tiptap/extension-gapcursor": "^3.26.1",
|
||||
"@tiptap/extension-hard-break": "^3.26.1",
|
||||
"@tiptap/extension-heading": "^3.26.1",
|
||||
"@tiptap/extension-horizontal-rule": "^3.26.1",
|
||||
"@tiptap/extension-italic": "^3.26.1",
|
||||
"@tiptap/extension-link": "^3.26.1",
|
||||
"@tiptap/extension-list": "^3.26.1",
|
||||
"@tiptap/extension-list-item": "^3.26.1",
|
||||
"@tiptap/extension-list-keymap": "^3.26.1",
|
||||
"@tiptap/extension-ordered-list": "^3.26.1",
|
||||
"@tiptap/extension-paragraph": "^3.26.1",
|
||||
"@tiptap/extension-strike": "^3.26.1",
|
||||
"@tiptap/extension-text": "^3.26.1",
|
||||
"@tiptap/extension-underline": "^3.26.1",
|
||||
"@tiptap/extensions": "^3.26.1",
|
||||
"@tiptap/pm": "^3.26.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/vue-3": {
|
||||
"version": "3.26.1",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/vue-3/-/vue-3-3.26.1.tgz",
|
||||
"integrity": "sha512-ihhAYUeOpAQqtY7NcgBFQoIrB5zaB4rYr81dqsfqoqjbnUv5cfDWLIeMQKuXoisqk312IVpvz6Ut+y9fCyIvhQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@tiptap/extension-bubble-menu": "^3.26.1",
|
||||
"@tiptap/extension-floating-menu": "^3.26.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@floating-ui/dom": "^1.0.0",
|
||||
"@tiptap/core": "3.26.1",
|
||||
"@tiptap/pm": "3.26.1",
|
||||
"vue": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tybys/wasm-util": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
|
||||
@@ -5346,6 +5853,28 @@
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@types/linkify-it": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz",
|
||||
"integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/markdown-it": {
|
||||
"version": "13.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-13.0.9.tgz",
|
||||
"integrity": "sha512-1XPwR0+MgXLWfTn9gCsZ55AHOKW1WN+P9vr0PaQh5aerR9LLQXUbjfEAFhjmEmyoYFWAyuN2Mqkn40MZ4ukjBw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/linkify-it": "^3",
|
||||
"@types/mdurl": "^1"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/mdurl": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz",
|
||||
"integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/parse-path": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/parse-path/-/parse-path-7.0.3.tgz",
|
||||
@@ -9466,6 +9995,31 @@
|
||||
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/linkify-it": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.1.tgz",
|
||||
"integrity": "sha512-wVoTjP4Q6R0NW5hiZkVJaFZPWgtXfoGF+6LucL3/FtiNjmcHhYjEr5f1Kqjirc1nBW07J/ZuRFumqr2oqccEWg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/puzrin"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/markdown-it"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"uc.micro": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/linkifyjs": {
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.3.3.tgz",
|
||||
"integrity": "sha512-P8aEP5U/D1/IlTY2OeYsErdwh9bGuLE30NcXtKEjgdHcahveQoQwM2yZNsioQHsWFz0P7KKudisbrzCgR0sDHg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/listhen": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/listhen/-/listhen-1.9.0.tgz",
|
||||
@@ -9640,6 +10194,51 @@
|
||||
"source-map-js": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it": {
|
||||
"version": "14.2.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.2.0.tgz",
|
||||
"integrity": "sha512-1TGiQiJVRQ3NPmZH6sx5Cfnmg6GQm9jvC1ch4TK511NjSJvjzKLzn5pPfZRNZkRPZP0HqCioSndqH8v2nRaWVQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/puzrin"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/markdown-it"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1",
|
||||
"entities": "^4.4.0",
|
||||
"linkify-it": "^5.0.1",
|
||||
"mdurl": "^2.0.0",
|
||||
"punycode.js": "^2.3.1",
|
||||
"uc.micro": "^2.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"markdown-it": "bin/markdown-it.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it-task-lists": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz",
|
||||
"integrity": "sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/markdown-it/node_modules/entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/maska": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/maska/-/maska-3.2.0.tgz",
|
||||
@@ -9661,6 +10260,12 @@
|
||||
"integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==",
|
||||
"license": "CC0-1.0"
|
||||
},
|
||||
"node_modules/mdurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
@@ -10444,6 +11049,12 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/orderedmap": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz",
|
||||
"integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/oxc-minify": {
|
||||
"version": "0.110.0",
|
||||
"resolved": "https://registry.npmjs.org/oxc-minify/-/oxc-minify-0.110.0.tgz",
|
||||
@@ -11527,6 +12138,178 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-changeset": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.4.1.tgz",
|
||||
"integrity": "sha512-96WBLhOaYhJ+kPhLg3uW359Tz6I/MfcrQfL4EGv4SrcqKEMC1gmoGrXHecPE8eOwTVCJ4IwgfzM8fFad25wNfw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-transform": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-commands": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz",
|
||||
"integrity": "sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.10.2"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-dropcursor": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz",
|
||||
"integrity": "sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.1.0",
|
||||
"prosemirror-view": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-gapcursor": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.4.1.tgz",
|
||||
"integrity": "sha512-pMdYaEnjNMSwl11yjEGtgTmLkR08m/Vl+Jj443167p9eB3HVQKhYCc4gmHVDsLPODfZfjr/MmirsdyZziXbQKw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-keymap": "^1.0.0",
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-view": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-history": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.5.0.tgz",
|
||||
"integrity": "sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.2.2",
|
||||
"prosemirror-transform": "^1.0.0",
|
||||
"prosemirror-view": "^1.31.0",
|
||||
"rope-sequence": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-inputrules": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.1.tgz",
|
||||
"integrity": "sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-keymap": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz",
|
||||
"integrity": "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"w3c-keyname": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-markdown": {
|
||||
"version": "1.13.4",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.4.tgz",
|
||||
"integrity": "sha512-D98dm4cQ3Hs6EmjK500TdAOew4Z03EV71ajEFiWra3Upr7diytJsjF4mPV2dW+eK5uNectiRj0xFxYI9NLXDbw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/markdown-it": "^14.0.0",
|
||||
"markdown-it": "^14.0.0",
|
||||
"prosemirror-model": "^1.25.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-markdown/node_modules/@types/linkify-it": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/prosemirror-markdown/node_modules/@types/markdown-it": {
|
||||
"version": "14.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
|
||||
"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/linkify-it": "^5",
|
||||
"@types/mdurl": "^2"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-markdown/node_modules/@types/mdurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/prosemirror-model": {
|
||||
"version": "1.25.9",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.9.tgz",
|
||||
"integrity": "sha512-pRTklkDDMMRopyoAcrr9wV/8g/RYgrLHBuJAb5hlEuYZRdm5yqmPjWId83fpBwPpSFqEdja0H7Dfd7z1X/npcA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"orderedmap": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-schema-list": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz",
|
||||
"integrity": "sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-state": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz",
|
||||
"integrity": "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-transform": "^1.0.0",
|
||||
"prosemirror-view": "^1.27.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-tables": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.8.5.tgz",
|
||||
"integrity": "sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-keymap": "^1.2.3",
|
||||
"prosemirror-model": "^1.25.4",
|
||||
"prosemirror-state": "^1.4.4",
|
||||
"prosemirror-transform": "^1.10.5",
|
||||
"prosemirror-view": "^1.41.4"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-transform": {
|
||||
"version": "1.12.0",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.12.0.tgz",
|
||||
"integrity": "sha512-GxboyN4AMIsoHNtz5uf2r2Ru551i5hWeCMD6E2Ib4Eogqoub0NflniaBPVQ4MrGE5yZ8JV9tUHg9qcZTTrcN4w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-view": {
|
||||
"version": "1.41.9",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.9.tgz",
|
||||
"integrity": "sha512-clTunTX+eaLbr87L1V1QPheRlEQJyTlL3gXe9x3jQIk3rL0RVWxviDGz8tFaydwIVm+hKhYCyr+R/zBtWr9s6A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.25.8",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/protocols": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.2.tgz",
|
||||
@@ -11543,6 +12326,15 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/punycode.js": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
|
||||
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/quansync": {
|
||||
"version": "0.2.11",
|
||||
"resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
|
||||
@@ -11948,6 +12740,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/rope-sequence": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz",
|
||||
"integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/rou3": {
|
||||
"version": "0.7.12",
|
||||
"resolved": "https://registry.npmjs.org/rou3/-/rou3-0.7.12.tgz",
|
||||
@@ -12918,6 +13716,24 @@
|
||||
"url": "https://github.com/sponsors/SuperchupuDev"
|
||||
}
|
||||
},
|
||||
"node_modules/tiptap-markdown": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/tiptap-markdown/-/tiptap-markdown-0.9.0.tgz",
|
||||
"integrity": "sha512-dKLQ9iiuGNgrlGVjrNauF/UBzWu4LYOx5pkD0jNkmQt/GOwfCJsBuzZTsf1jZ204ANHOm572mZ9PYvGh1S7tpQ==",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"example"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/markdown-it": "^13.0.7",
|
||||
"markdown-it": "^14.1.0",
|
||||
"markdown-it-task-lists": "^2.1.1",
|
||||
"prosemirror-markdown": "^1.11.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
@@ -13077,6 +13893,12 @@
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/uc.micro": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
|
||||
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ufo": {
|
||||
"version": "1.6.3",
|
||||
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz",
|
||||
@@ -13950,6 +14772,12 @@
|
||||
"vue": "^3.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/w3c-keyname": {
|
||||
"version": "2.2.8",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
||||
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
"build:dist": "nuxt generate && rm -rf dist && cp -R .output/public dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@malio/layer-ui": "^1.7.11",
|
||||
"@nuxt/icon": "^2.2.1",
|
||||
"@nuxtjs/i18n": "^10.2.1",
|
||||
"@malio/layer-ui": "^1.4.6",
|
||||
"@pinia/nuxt": "^0.11.3",
|
||||
"nuxt": "^4.3.0",
|
||||
"nuxt-toast": "^1.4.0",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="flex items-center justify-between pb-6">
|
||||
<h1 class="text-4xl font-bold text-primary-500">Types de statut</h1>
|
||||
<MalioButton
|
||||
label="Ajouter un type"
|
||||
label="Ajouter"
|
||||
icon-name="mdi:plus"
|
||||
icon-position="left"
|
||||
@click="openCreate"
|
||||
@@ -55,16 +55,19 @@
|
||||
</div>
|
||||
</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.code"
|
||||
label="Code *"
|
||||
group-class="mt-2"
|
||||
:max-length="10"
|
||||
:error="showCodeError ? 'Le code est obligatoire.' : ''"
|
||||
/>
|
||||
<MalioInputText
|
||||
<MalioInputText :reserve-message-space="false"
|
||||
v-model="form.label"
|
||||
label="Libellé *"
|
||||
group-class="mt-2"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</div>
|
||||
<div class="flex flex-col gap-3 py-6">
|
||||
<div class="flex items-center justify-between gap-4">
|
||||
<MalioSelectCheckbox
|
||||
<MalioSelectCheckbox :reserve-message-space="false"
|
||||
v-model="selectedSiteIds"
|
||||
:options="siteOptions"
|
||||
label="Sites"
|
||||
@@ -14,7 +14,7 @@
|
||||
/>
|
||||
<div class="flex gap-4">
|
||||
<MalioButton
|
||||
label="Ajouter une absence"
|
||||
label="Ajouter"
|
||||
icon-name="mdi:plus"
|
||||
icon-position="left"
|
||||
@click="openCreateFromToday"
|
||||
@@ -31,7 +31,7 @@
|
||||
<div class="flex justify-between">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="w-80">
|
||||
<MalioInputText
|
||||
<MalioInputText :reserve-message-space="false"
|
||||
v-model="employeeFilter"
|
||||
label="Recherche d'un employé"
|
||||
icon-name="mdi:magnify"
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
:sites="sites"
|
||||
:absence-types="absenceTypes"
|
||||
:formatted-selected-date="formattedSelectedDate"
|
||||
:show-validation-calendar="true"
|
||||
:marked-dates="markedDates"
|
||||
:shortcut-button-class="shortcutButtonClass"
|
||||
:week-shortcut-button-class="weekShortcutButtonClass"
|
||||
:get-week-shortcut-label="getWeekShortcutLabel"
|
||||
@@ -23,6 +25,7 @@
|
||||
@set-this-week="setThisWeek"
|
||||
@set-next-week="setNextWeek"
|
||||
@shift-date="shiftDate"
|
||||
@month-change="onCalendarMonthChange"
|
||||
/>
|
||||
|
||||
<div v-if="isLoading" class="rounded-lg border border-neutral-200 bg-white p-6 text-md text-neutral-600">
|
||||
@@ -193,6 +196,8 @@ const {
|
||||
isSelectedDateHoliday,
|
||||
selectedHolidayLabel,
|
||||
handleSave,
|
||||
markedDates,
|
||||
onCalendarMonthChange,
|
||||
isWeekCommentDrawerOpen,
|
||||
weekCommentContext,
|
||||
openWeekCommentDrawer,
|
||||
|
||||
@@ -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 }))
|
||||
)
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
:sites="sites"
|
||||
:absence-types="absenceTypes"
|
||||
:formatted-selected-date="formattedSelectedDate"
|
||||
:show-validation-calendar="true"
|
||||
:marked-dates="markedDates"
|
||||
:shortcut-button-class="shortcutButtonClass"
|
||||
:week-shortcut-button-class="weekShortcutButtonClass"
|
||||
:get-week-shortcut-label="getWeekShortcutLabel"
|
||||
@@ -39,6 +41,7 @@
|
||||
@set-this-week="setThisWeek"
|
||||
@set-next-week="setNextWeek"
|
||||
@shift-date="shiftDate"
|
||||
@month-change="onCalendarMonthChange"
|
||||
/>
|
||||
|
||||
<div v-if="isLoading" class="rounded-lg border border-neutral-200 bg-white p-6 text-md text-neutral-600">
|
||||
@@ -225,6 +228,8 @@ const {
|
||||
closeAbsenceDrawer,
|
||||
formatMinutes,
|
||||
handleSave,
|
||||
markedDates,
|
||||
onCalendarMonthChange,
|
||||
isWeekCommentDrawerOpen,
|
||||
weekCommentContext,
|
||||
openWeekCommentDrawer,
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
class="mt-8 space-y-6 rounded-lg border border-neutral-200 bg-white p-6 shadow-sm"
|
||||
@submit.prevent="handleSubmit"
|
||||
>
|
||||
<MalioInputText
|
||||
<MalioInputText :reserve-message-space="false"
|
||||
v-model="username"
|
||||
label="Nom d'utilisateur"
|
||||
autocomplete="username"
|
||||
group-class="mt-2"
|
||||
/>
|
||||
|
||||
<MalioInputPassword
|
||||
<MalioInputPassword :reserve-message-space="false"
|
||||
v-model="password"
|
||||
label="Mot de passe"
|
||||
autocomplete="current-password"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="flex items-center justify-between pb-6">
|
||||
<h1 class="text-4xl font-bold text-primary-500">Sites</h1>
|
||||
<MalioButton
|
||||
label="Ajouter un site"
|
||||
label="Ajouter"
|
||||
icon-name="mdi:plus"
|
||||
icon-position="left"
|
||||
@click="openCreate"
|
||||
@@ -51,9 +51,12 @@
|
||||
</div>
|
||||
</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.name"
|
||||
label="Nom *"
|
||||
group-class="mt-2"
|
||||
|
||||
@@ -94,10 +94,12 @@
|
||||
|
||||
<MalioDrawer
|
||||
v-model="isDrawerOpen"
|
||||
:title="editingUser ? 'Modifier un utilisateur' : 'Ajouter un utilisateur'"
|
||||
>
|
||||
<template #header>
|
||||
<h2 class="text-[32px] font-semibold text-primary-500">{{ editingUser ? 'Modifier un utilisateur' : 'Ajouter un utilisateur' }}</h2>
|
||||
</template>
|
||||
<form class="space-y-4" @submit.prevent="handleSubmit">
|
||||
<MalioInputText
|
||||
<MalioInputText :reserve-message-space="false"
|
||||
v-model="form.username"
|
||||
:label="editingUser ? `Nom d'utilisateur` : `Nom d'utilisateur *`"
|
||||
group-class="mt-2"
|
||||
@@ -105,7 +107,7 @@
|
||||
/>
|
||||
|
||||
<div>
|
||||
<MalioInputPassword
|
||||
<MalioInputPassword :reserve-message-space="false"
|
||||
v-model="form.password"
|
||||
:label="editingUser ? 'Mot de passe' : 'Mot de passe *'"
|
||||
:hint="editingUser ? 'Laisse vide pour ne pas changer le mot de passe.' : ''"
|
||||
@@ -153,7 +155,7 @@
|
||||
</div>
|
||||
|
||||
<div v-if="form.accessMode === 'self'">
|
||||
<MalioSelect
|
||||
<MalioSelect :reserve-message-space="false"
|
||||
:model-value="form.employeeId === '' ? null : form.employeeId"
|
||||
:options="employeeOptions"
|
||||
label="Employé lié"
|
||||
@@ -172,7 +174,7 @@
|
||||
:key="site.id"
|
||||
class="flex h-10 items-center rounded-md border border-neutral-200 px-3"
|
||||
>
|
||||
<MalioCheckbox
|
||||
<MalioCheckbox :reserve-message-space="false"
|
||||
:model-value="form.siteIds.includes(site.id)"
|
||||
:label="site.name"
|
||||
group-class="flex items-center"
|
||||
@@ -186,7 +188,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<MalioCheckbox
|
||||
<MalioCheckbox :reserve-message-space="false"
|
||||
v-model="form.isLocked"
|
||||
label="Verrouiller le compte"
|
||||
hint="Un compte verrouillé ne peut plus se connecter."
|
||||
@@ -194,7 +196,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<MalioCheckbox
|
||||
<MalioCheckbox :reserve-message-space="false"
|
||||
v-model="form.hasLeaveRecapAccess"
|
||||
label="Accès à l'écran Récap. congés"
|
||||
hint="Affiche l'onglet dans la sidebar et donne accès au tableau récap."
|
||||
|
||||
@@ -138,3 +138,23 @@ export const getWorkHourDayContext = async (workDate: string) => {
|
||||
{ toast: false }
|
||||
)
|
||||
}
|
||||
|
||||
// Jours entièrement validés (admin) sur une plage, pour colorer le calendrier de
|
||||
// la vue Jour. `validatedDays` = liste de dates Y-m-d (cf. doc/hours-validated-days).
|
||||
// `driver` : true → écran Heures Conducteurs (seuls les conducteurs), false → écran Heures.
|
||||
export const getWorkHourValidationStatus = async (
|
||||
from: string,
|
||||
to: string,
|
||||
options?: { driver?: boolean }
|
||||
) => {
|
||||
const api = useApi()
|
||||
const query: Record<string, string> = { from, to }
|
||||
if (options?.driver) query.driver = '1'
|
||||
const data = await api.get<{ from: string; to: string; validatedDays: string[] }>(
|
||||
'/work-hours/validation-status',
|
||||
query,
|
||||
{ toast: false }
|
||||
)
|
||||
|
||||
return data?.validatedDays ?? []
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user