feat(absences) : avancement module absences + suppression du portail client
Deux lots regroupés sur la branche feat/absence-management. Suppression complète du portail client : - retire ROLE_CLIENT (security.yaml) ; User::getRoles() ajoute toujours ROLE_USER - supprime l'entité ClientTicket (+ repo, states, relations), User.client et User.allowedProjects, NotificationService, ProjectAllowedExtension, le bloc ROLE_CLIENT de MailAccessChecker - front : pages /portal, layout portal, composants client-ticket/, AdminClientTicketTab, services/dto/i18n/docs associés - fixtures : retire les users client-liot / client-acme - migration Version20260522110000 (drop client_ticket, user_allowed_projects, colonnes liées ; task_document.task_id -> NOT NULL) - tests : retire les cas obsolètes testant le blocage des clients sur le mail Module gestion des absences (WIP) : - entités / migrations (Version20260521160000, Version20260522090000) - pages absences.vue / team-absences.vue, composants frontend/components/absence/ - services front, AccrueLeaveCommand, PublicHolidayController Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
v-for="day in days"
|
||||
:key="'header-' + day.dateStr"
|
||||
class="flex-1 border-r border-neutral-100 py-2 text-center"
|
||||
:class="{ 'bg-orange-50': day.holiday }"
|
||||
>
|
||||
<div class="text-lg font-bold" :class="isToday(day.date) ? 'text-orange-500' : 'text-neutral-900'">
|
||||
{{ day.dayNum }}
|
||||
@@ -16,6 +17,14 @@
|
||||
<div class="text-xs" :class="isToday(day.date) ? 'text-orange-500' : 'text-neutral-500'">
|
||||
{{ day.label }}
|
||||
</div>
|
||||
<div
|
||||
v-if="day.holiday"
|
||||
class="flex items-center justify-center gap-0.5 truncate px-1 text-[10px] font-medium text-amber-600"
|
||||
:title="day.holiday"
|
||||
>
|
||||
<Icon name="mdi:star-four-points-outline" size="10" class="flex-shrink-0" />
|
||||
<span class="truncate">{{ day.holiday }}</span>
|
||||
</div>
|
||||
<div class="text-[10px] text-neutral-400">{{ day.totalFormatted }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -40,6 +49,7 @@
|
||||
:key="day.dateStr"
|
||||
:ref="(el) => { dayColumnEls[dayIndex] = el as HTMLElement }"
|
||||
class="relative flex-1 border-r border-neutral-100"
|
||||
:class="{ 'bg-orange-50': day.holiday }"
|
||||
@click="onClickGrid($event, day)"
|
||||
@contextmenu.prevent="onContextMenuGrid($event, day)"
|
||||
>
|
||||
@@ -141,8 +151,10 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { TimeEntry } from '~/services/dto/time-entry'
|
||||
import { useAbsenceService } from '~/services/absences'
|
||||
|
||||
const { t } = useI18n()
|
||||
const absenceService = useAbsenceService()
|
||||
|
||||
const props = defineProps<{
|
||||
entries: TimeEntry[]
|
||||
@@ -209,6 +221,23 @@ onMounted(() => {
|
||||
})
|
||||
})
|
||||
|
||||
// --- Public holidays (computed server-side, shared with the absence calendar) ---
|
||||
const holidays = ref<Record<string, string>>({})
|
||||
|
||||
async function loadHolidays() {
|
||||
const count = props.viewMode === 'week' ? 7 : 1
|
||||
const start = new Date(props.startDate)
|
||||
const end = new Date(start)
|
||||
end.setDate(end.getDate() + count - 1)
|
||||
try {
|
||||
holidays.value = await absenceService.getPublicHolidays(toDateStr(start), toDateStr(end))
|
||||
} catch {
|
||||
holidays.value = {}
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => [props.startDate, props.viewMode], loadHolidays, { immediate: true })
|
||||
|
||||
// --- Days computation ---
|
||||
const days = computed(() => {
|
||||
const count = props.viewMode === 'week' ? 7 : 1
|
||||
@@ -231,6 +260,7 @@ const days = computed(() => {
|
||||
dateStr,
|
||||
dayNum: d.getDate(),
|
||||
label: dayLabels[d.getDay()],
|
||||
holiday: holidays.value[dateStr] ?? null,
|
||||
totalFormatted: `${String(totalH).padStart(2, '0')}:${String(totalM).padStart(2, '0')}:${String(totalS).padStart(2, '0')}`,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user