Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 267cea76da | |||
| 6938616064 |
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
parameters:
|
parameters:
|
||||||
app.version: '0.4.38'
|
app.version: '0.4.39'
|
||||||
|
|||||||
@@ -105,8 +105,7 @@
|
|||||||
|
|
||||||
<div class="h-full flex-1 flex flex-col min-h-0 min-w-0">
|
<div class="h-full flex-1 flex flex-col min-h-0 min-w-0">
|
||||||
<AppTopNav :user="auth.user" />
|
<AppTopNav :user="auth.user" />
|
||||||
<main class="flex flex-1 flex-col overflow-y-auto overflow-x-hidden bg-white px-4 pb-24 sm:px-8 lg:px-16">
|
<main class="flex flex-1 flex-col overflow-y-auto overflow-x-hidden bg-white px-4 pb-24 sm:px-6 lg:px-12 xl:px-11">
|
||||||
<div aria-hidden="true" class="pointer-events-none sticky top-0 z-30 h-8 flex-shrink-0 bg-white sm:h-12" />
|
|
||||||
<slot/>
|
<slot/>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<template>
|
||||||
|
<!-- Entête de page standard : source unique du style des titres.
|
||||||
|
Toujours sticky en haut du <main> scrollable : reste visible au scroll.
|
||||||
|
Fond blanc + pt-[38px]/pb-[30px] (au lieu de marges) pour que le contenu
|
||||||
|
défilant soit masqué sous l'entête (espaces haut ET bas compris) et que
|
||||||
|
l'entête soit collée sous l'AppTopNav sans trou.
|
||||||
|
Slots :
|
||||||
|
- défaut : texte du titre
|
||||||
|
- #actions : boutons à droite du titre
|
||||||
|
- #subheader : barre de filtres / onglets rendue SOUS le titre, dans le
|
||||||
|
même bloc sticky (reste donc collée avec le titre). La
|
||||||
|
marge titre -> sous-entête est portée par le contenu passé
|
||||||
|
(ex. mt-4) pour laisser chaque page régler son cas. -->
|
||||||
|
<div class="sticky top-0 z-20 bg-white pt-[38px] pb-[30px]">
|
||||||
|
<div class="flex items-center justify-between gap-4">
|
||||||
|
<h1 class="text-[30px] font-semibold text-primary-500">
|
||||||
|
<slot/>
|
||||||
|
</h1>
|
||||||
|
<div v-if="$slots.actions" class="shrink-0">
|
||||||
|
<slot name="actions"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<slot name="subheader"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -1,15 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col gap-6">
|
<div>
|
||||||
<div class="flex items-center justify-between">
|
<PageHeader>
|
||||||
<h1 class="text-2xl font-bold text-neutral-900">{{ $t('absences.title') }}</h1>
|
{{ $t('absences.title') }}
|
||||||
<MalioButton
|
<template #actions>
|
||||||
:label="$t('absences.newRequest')"
|
<MalioButton
|
||||||
icon-name="mdi:plus"
|
:label="$t('absences.newRequest')"
|
||||||
icon-position="left"
|
icon-name="mdi:plus"
|
||||||
@click="requestDrawerOpen = true"
|
icon-position="left"
|
||||||
/>
|
@click="requestDrawerOpen = true"
|
||||||
</div>
|
/>
|
||||||
|
</template>
|
||||||
|
</PageHeader>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-6">
|
||||||
<AbsenceBalanceCards :balances="balances" />
|
<AbsenceBalanceCards :balances="balances" />
|
||||||
|
|
||||||
<!-- Filters -->
|
<!-- Filters -->
|
||||||
@@ -65,6 +68,7 @@
|
|||||||
:can-cancel="selected?.status === 'pending'"
|
:can-cancel="selected?.status === 'pending'"
|
||||||
@cancelled="reload"
|
@cancelled="reload"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col gap-6">
|
<div>
|
||||||
<h1 class="text-2xl font-bold text-neutral-900">
|
<PageHeader>
|
||||||
{{ $t("absences.teamTitle") }}
|
{{ $t("absences.teamTitle") }}
|
||||||
</h1>
|
</PageHeader>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-6">
|
||||||
<!-- KPIs -->
|
<!-- KPIs -->
|
||||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-3">
|
<div class="grid grid-cols-1 gap-4 sm:grid-cols-3">
|
||||||
<div class="rounded-lg border border-neutral-200 bg-white p-4">
|
<div class="rounded-lg border border-neutral-200 bg-white p-4">
|
||||||
@@ -189,6 +190,7 @@
|
|||||||
:user="selectedEmployee"
|
:user="selectedEmployee"
|
||||||
@saved="loadEmployees"
|
@saved="loadEmployees"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<NuxtLayout name="default">
|
<NuxtLayout name="default">
|
||||||
<div class="mx-auto max-w-lg px-4 py-10">
|
<div class="mx-auto max-w-lg px-4 py-10">
|
||||||
<h1 class="mb-8 text-2xl font-bold text-neutral-900">{{ $t('profile.title') }}</h1>
|
<PageHeader>{{ $t('profile.title') }}</PageHeader>
|
||||||
|
|
||||||
<div class="flex flex-col items-center gap-6 rounded-xl border border-neutral-200 bg-white p-8 shadow-sm">
|
<div class="flex flex-col items-center gap-6 rounded-xl border border-neutral-200 bg-white p-8 shadow-sm">
|
||||||
<!-- Current avatar -->
|
<!-- Current avatar -->
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col gap-6">
|
<div>
|
||||||
<div class="flex items-center gap-3 pt-4">
|
<PageHeader>
|
||||||
<MalioButtonIcon icon="mdi:arrow-left" :aria-label="$t('common.back')" @click="goBack" />
|
<span class="inline-flex items-center gap-3">
|
||||||
<h1 class="text-2xl font-bold text-neutral-900">{{ client?.name ?? '…' }}</h1>
|
<MalioButtonIcon icon="mdi:arrow-left" :aria-label="$t('common.back')" @click="goBack" />
|
||||||
</div>
|
{{ client?.name ?? '…' }}
|
||||||
|
</span>
|
||||||
|
</PageHeader>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-6">
|
||||||
<p v-if="loading">{{ $t('common.loading') }}</p>
|
<p v-if="loading">{{ $t('common.loading') }}</p>
|
||||||
<template v-else-if="client">
|
<template v-else-if="client">
|
||||||
<MalioTabList v-model="activeTab" :tabs="tabs">
|
<MalioTabList v-model="activeTab" :tabs="tabs">
|
||||||
@@ -111,6 +114,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</MalioTabList>
|
</MalioTabList>
|
||||||
</template>
|
</template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col gap-6">
|
<div>
|
||||||
<h1 class="text-2xl font-bold text-neutral-900">
|
<PageHeader>
|
||||||
{{ $t('directory.title') }}
|
{{ $t('directory.title') }}
|
||||||
</h1>
|
</PageHeader>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-6">
|
||||||
<MalioTabList v-model="activeTab" :tabs="tabs">
|
<MalioTabList v-model="activeTab" :tabs="tabs">
|
||||||
<!-- Clients -->
|
<!-- Clients -->
|
||||||
<template #clients>
|
<template #clients>
|
||||||
@@ -171,6 +172,7 @@
|
|||||||
:message="deleteModalMessage"
|
:message="deleteModalMessage"
|
||||||
@confirm="confirmDelete"
|
@confirm="confirmDelete"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col gap-6">
|
<div>
|
||||||
<div class="flex items-center gap-3 pt-4">
|
<PageHeader>
|
||||||
<MalioButtonIcon icon="mdi:arrow-left" :aria-label="$t('common.back')" @click="goBack" />
|
<span class="inline-flex items-center gap-3">
|
||||||
<h1 class="text-2xl font-bold text-neutral-900">{{ prestataire?.name ?? '…' }}</h1>
|
<MalioButtonIcon icon="mdi:arrow-left" :aria-label="$t('common.back')" @click="goBack" />
|
||||||
</div>
|
{{ prestataire?.name ?? '…' }}
|
||||||
|
</span>
|
||||||
|
</PageHeader>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-6">
|
||||||
<p v-if="loading">{{ $t('common.loading') }}</p>
|
<p v-if="loading">{{ $t('common.loading') }}</p>
|
||||||
<template v-else-if="prestataire">
|
<template v-else-if="prestataire">
|
||||||
<MalioTabList v-model="activeTab" :tabs="tabs">
|
<MalioTabList v-model="activeTab" :tabs="tabs">
|
||||||
@@ -111,6 +114,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</MalioTabList>
|
</MalioTabList>
|
||||||
</template>
|
</template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col gap-6">
|
<div>
|
||||||
<div class="flex items-center gap-3 pt-4">
|
<PageHeader>
|
||||||
<MalioButtonIcon icon="mdi:arrow-left" :aria-label="$t('common.back')" @click="goBack" />
|
<span class="inline-flex items-center gap-3">
|
||||||
<h1 class="text-2xl font-bold text-neutral-900">{{ prospect?.company ?? '…' }}</h1>
|
<MalioButtonIcon icon="mdi:arrow-left" :aria-label="$t('common.back')" @click="goBack" />
|
||||||
</div>
|
{{ prospect?.company ?? '…' }}
|
||||||
|
</span>
|
||||||
|
</PageHeader>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-6">
|
||||||
<p v-if="loading">{{ $t('common.loading') }}</p>
|
<p v-if="loading">{{ $t('common.loading') }}</p>
|
||||||
<template v-else-if="prospect">
|
<template v-else-if="prospect">
|
||||||
<MalioTabList v-model="activeTab" :tabs="tabs">
|
<MalioTabList v-model="activeTab" :tabs="tabs">
|
||||||
@@ -126,6 +129,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</MalioTabList>
|
</MalioTabList>
|
||||||
</template>
|
</template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -95,11 +95,13 @@ function handleTaskLinked(_taskId: number): void {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex h-full flex-col overflow-hidden">
|
<div class="flex h-full flex-col overflow-hidden">
|
||||||
<div class="flex flex-shrink-0 items-center justify-between border-b border-neutral-200 bg-white px-4 py-3">
|
<div class="flex-shrink-0">
|
||||||
<h1 class="text-lg font-semibold text-neutral-900">
|
<PageHeader>
|
||||||
{{ t('mail.title') }}
|
{{ t('mail.title') }}
|
||||||
</h1>
|
<template #actions>
|
||||||
<MailRefreshButton />
|
<MailRefreshButton />
|
||||||
|
</template>
|
||||||
|
</PageHeader>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-1 overflow-hidden">
|
<div class="flex flex-1 overflow-hidden">
|
||||||
|
|||||||
@@ -355,9 +355,9 @@ onMounted(async () => {
|
|||||||
<template>
|
<template>
|
||||||
<div class="min-w-0">
|
<div class="min-w-0">
|
||||||
<!-- Header + Filters -->
|
<!-- Header + Filters -->
|
||||||
<div class="sticky top-8 z-20 bg-white pb-4 sm:top-12">
|
<PageHeader>
|
||||||
<div class="flex items-center justify-between gap-3">
|
{{ $t('myTasks.title') }}
|
||||||
<h1 class="text-xl font-bold text-primary-500 sm:text-2xl">{{ $t('myTasks.title') }}</h1>
|
<template #actions>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<MalioButton
|
<MalioButton
|
||||||
icon-name="mdi:plus"
|
icon-name="mdi:plus"
|
||||||
@@ -378,78 +378,79 @@ onMounted(async () => {
|
|||||||
<Icon name="mdi:format-list-bulleted" size="20" />
|
<Icon name="mdi:format-list-bulleted" size="20" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
|
<template #subheader>
|
||||||
<div class="mt-4 flex flex-wrap gap-3">
|
<div class="mt-4 flex flex-wrap gap-3">
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedProjectId"
|
v-model="selectedProjectId"
|
||||||
:options="projectOptions"
|
:options="projectOptions"
|
||||||
label="Projet"
|
label="Projet"
|
||||||
:empty-option-label="$t('myTasks.allProjects')"
|
:empty-option-label="$t('myTasks.allProjects')"
|
||||||
group-class="!w-40"
|
group-class="!w-40"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedGroupId"
|
v-model="selectedGroupId"
|
||||||
:options="groupOptions"
|
:options="groupOptions"
|
||||||
label="Groupe"
|
label="Groupe"
|
||||||
:empty-option-label="$t('myTasks.allGroups')"
|
:empty-option-label="$t('myTasks.allGroups')"
|
||||||
group-class="!w-40"
|
group-class="!w-40"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedTagId"
|
v-model="selectedTagId"
|
||||||
:options="tagOptions"
|
:options="tagOptions"
|
||||||
label="Type"
|
label="Type"
|
||||||
:empty-option-label="$t('myTasks.allTypes')"
|
:empty-option-label="$t('myTasks.allTypes')"
|
||||||
group-class="!w-40"
|
group-class="!w-40"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedPriorityId"
|
v-model="selectedPriorityId"
|
||||||
:options="priorityOptions"
|
:options="priorityOptions"
|
||||||
label="Priorité"
|
label="Priorité"
|
||||||
:empty-option-label="$t('myTasks.allPriorities')"
|
:empty-option-label="$t('myTasks.allPriorities')"
|
||||||
group-class="!w-40"
|
group-class="!w-40"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedEffortId"
|
v-model="selectedEffortId"
|
||||||
:options="effortOptions"
|
:options="effortOptions"
|
||||||
label="Effort"
|
label="Effort"
|
||||||
:empty-option-label="$t('myTasks.allEfforts')"
|
:empty-option-label="$t('myTasks.allEfforts')"
|
||||||
group-class="!w-40"
|
group-class="!w-40"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedAssigneeId"
|
v-model="selectedAssigneeId"
|
||||||
:options="assigneeOptions"
|
:options="assigneeOptions"
|
||||||
label="Assigné"
|
label="Assigné"
|
||||||
:empty-option-label="$t('myTasks.allAssignees')"
|
:empty-option-label="$t('myTasks.allAssignees')"
|
||||||
group-class="!w-40"
|
group-class="!w-40"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="sortById"
|
v-model="sortById"
|
||||||
:options="sortOptions"
|
:options="sortOptions"
|
||||||
:label="$t('myTasks.sortBy')"
|
:label="$t('myTasks.sortBy')"
|
||||||
:empty-option-label="$t('myTasks.sortDefault')"
|
:empty-option-label="$t('myTasks.sortDefault')"
|
||||||
group-class="!w-40"
|
group-class="!w-40"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
|
</PageHeader>
|
||||||
|
|
||||||
<!-- Kanban View — grouped by canonical category -->
|
<!-- Kanban View — grouped by canonical category -->
|
||||||
<div v-if="viewMode === 'kanban'">
|
<div v-if="viewMode === 'kanban'">
|
||||||
<div class="mt-6 flex h-[calc(100vh-260px)] gap-3 overflow-x-auto pb-4">
|
<div class="flex h-[calc(100vh-260px)] gap-3 overflow-x-auto pb-4">
|
||||||
<div
|
<div
|
||||||
v-for="cat in CATEGORIES"
|
v-for="cat in CATEGORIES"
|
||||||
:key="cat"
|
:key="cat"
|
||||||
@@ -509,7 +510,7 @@ onMounted(async () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- List View -->
|
<!-- List View -->
|
||||||
<div v-if="viewMode === 'list'" class="mt-6 flex flex-col gap-2.5 rounded-[10px] bg-tertiary-500 p-2.5">
|
<div v-if="viewMode === 'list'" class="flex flex-col gap-2.5 rounded-[10px] bg-tertiary-500 p-2.5">
|
||||||
<TaskBulkActions
|
<TaskBulkActions
|
||||||
:selected-count="selectedTaskIds.size"
|
:selected-count="selectedTaskIds.size"
|
||||||
:total-count="tasks.length"
|
:total-count="tasks.length"
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="sticky top-8 z-20 bg-white pb-4 sm:top-12">
|
<PageHeader>
|
||||||
<div class="flex items-center justify-between">
|
{{ project?.name ?? '' }} — {{ $t('archive.title') }}
|
||||||
<h1 class="text-xl font-bold text-primary-500 sm:text-2xl">{{ project?.name ?? '' }} — {{ $t('archive.title') }}</h1>
|
<template #subheader>
|
||||||
</div>
|
<div class="mt-4">
|
||||||
|
<MalioSelect
|
||||||
<div class="mt-4">
|
v-model="selectedGroupId"
|
||||||
<MalioSelect
|
:options="groupFilterOptions"
|
||||||
v-model="selectedGroupId"
|
label="Groupe"
|
||||||
:options="groupFilterOptions"
|
empty-option-label="Tous les groupes"
|
||||||
label="Groupe"
|
group-class="w-64"
|
||||||
empty-option-label="Tous les groupes"
|
/>
|
||||||
group-class="w-64"
|
</div>
|
||||||
/>
|
</template>
|
||||||
</div>
|
</PageHeader>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p v-if="filteredTasks.length === 0" class="text-sm text-neutral-400">
|
<p v-if="filteredTasks.length === 0" class="text-sm text-neutral-400">
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="sticky top-8 z-20 bg-white pb-4 sm:top-12">
|
<PageHeader>{{ project?.name ?? '' }} — Groupes</PageHeader>
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<h1 class="text-xl font-bold text-primary-500 sm:text-2xl">{{ project?.name ?? '' }} — Groupes</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<ProjectGroupTab :project-id="projectId" />
|
<ProjectGroupTab :project-id="projectId" />
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="min-w-0">
|
<div class="min-w-0">
|
||||||
<div class="sticky top-8 z-20 bg-white pb-4 sm:top-12">
|
<PageHeader>
|
||||||
<div class="flex items-center justify-between gap-3">
|
{{ project?.name ?? '' }}
|
||||||
<h1 class="text-xl font-bold text-primary-500 sm:text-2xl">{{ project?.name ?? '' }}</h1>
|
<template #actions>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<MalioButton
|
<MalioButton
|
||||||
icon-name="mdi:plus"
|
icon-name="mdi:plus"
|
||||||
@@ -30,66 +30,67 @@
|
|||||||
@click="projectDrawerOpen = true"
|
@click="projectDrawerOpen = true"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
|
<template #subheader>
|
||||||
<div class="mt-4 flex flex-wrap gap-3">
|
<div class="mt-4 flex flex-wrap gap-3">
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedGroupId"
|
v-model="selectedGroupId"
|
||||||
:options="groupFilterOptions"
|
:options="groupFilterOptions"
|
||||||
label="Groupe"
|
label="Groupe"
|
||||||
empty-option-label="Tous les groupes"
|
empty-option-label="Tous les groupes"
|
||||||
group-class="!w-40"
|
group-class="!w-40"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedTagId"
|
v-model="selectedTagId"
|
||||||
:options="tagFilterOptions"
|
:options="tagFilterOptions"
|
||||||
label="Tags"
|
label="Tags"
|
||||||
empty-option-label="Tous les tags"
|
empty-option-label="Tous les tags"
|
||||||
group-class="!w-40"
|
group-class="!w-40"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedAssigneeId"
|
v-model="selectedAssigneeId"
|
||||||
:options="userFilterOptions"
|
:options="userFilterOptions"
|
||||||
label="User"
|
label="User"
|
||||||
empty-option-label="Tous les users"
|
empty-option-label="Tous les users"
|
||||||
group-class="!w-40"
|
group-class="!w-40"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-if="viewMode === 'list'"
|
v-if="viewMode === 'list'"
|
||||||
v-model="selectedStatusId"
|
v-model="selectedStatusId"
|
||||||
:options="statusFilterOptions"
|
:options="statusFilterOptions"
|
||||||
label="Status"
|
label="Status"
|
||||||
empty-option-label="Tous les status"
|
empty-option-label="Tous les status"
|
||||||
group-class="!w-40"
|
group-class="!w-40"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedPriorityId"
|
v-model="selectedPriorityId"
|
||||||
:options="priorityFilterOptions"
|
:options="priorityFilterOptions"
|
||||||
label="Priorité"
|
label="Priorité"
|
||||||
empty-option-label="Toutes"
|
empty-option-label="Toutes"
|
||||||
group-class="!w-40"
|
group-class="!w-40"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedEffortId"
|
v-model="selectedEffortId"
|
||||||
:options="effortFilterOptions"
|
:options="effortFilterOptions"
|
||||||
label="Effort"
|
label="Effort"
|
||||||
empty-option-label="Tous"
|
empty-option-label="Tous"
|
||||||
group-class="!w-40"
|
group-class="!w-40"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
|
</PageHeader>
|
||||||
|
|
||||||
<!-- Kanban -->
|
<!-- Kanban -->
|
||||||
<div v-if="viewMode === 'kanban'" class="mt-6 flex h-[calc(100vh-200px)] gap-3 overflow-x-auto pb-4">
|
<div v-if="viewMode === 'kanban'" class="mt-6 flex h-[calc(100vh-200px)] gap-3 overflow-x-auto pb-4">
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="sticky top-8 z-20 bg-white pb-4 sm:top-12">
|
<PageHeader>
|
||||||
<div class="flex flex-wrap items-center justify-between gap-3">
|
{{ $t('projects.title') }}
|
||||||
<h1 class="text-xl font-bold text-primary-500 sm:text-2xl">{{ $t('projects.title') }}</h1>
|
<template #actions>
|
||||||
<div class="flex items-center gap-2 sm:gap-3">
|
<div class="flex items-center gap-2 sm:gap-3">
|
||||||
<MalioButton
|
<MalioButton
|
||||||
variant="tertiary"
|
variant="tertiary"
|
||||||
@@ -23,8 +23,8 @@
|
|||||||
<span class="sm:hidden">{{ $t('projects.addProjectShort') }}</span>
|
<span class="sm:hidden">{{ $t('projects.addProjectShort') }}</span>
|
||||||
</MalioButton>
|
</MalioButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</PageHeader>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -1,60 +1,59 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="sticky top-8 z-20 bg-white pb-4 sm:top-12">
|
<PageHeader>
|
||||||
<h1 class="text-xl font-bold text-primary-500 sm:text-2xl">
|
{{ $t('reporting.title') }}
|
||||||
{{ $t('reporting.title') }}
|
<template #subheader>
|
||||||
</h1>
|
<!-- Filters -->
|
||||||
|
<div class="mt-4 flex flex-wrap items-end gap-3">
|
||||||
<!-- Filters -->
|
<MalioSelect
|
||||||
<div class="mt-4 flex flex-wrap items-end gap-3">
|
v-model="selectedPeriod"
|
||||||
<MalioSelect
|
:options="periodOptions"
|
||||||
v-model="selectedPeriod"
|
:label="$t('reporting.filters.period')"
|
||||||
:options="periodOptions"
|
group-class="!w-48"
|
||||||
:label="$t('reporting.filters.period')"
|
text-field="text-sm"
|
||||||
group-class="!w-48"
|
text-value="text-sm"
|
||||||
text-field="text-sm"
|
/>
|
||||||
text-value="text-sm"
|
<div class="w-40">
|
||||||
/>
|
<label class="mb-1 block text-sm font-medium text-neutral-700">
|
||||||
<div class="w-40">
|
{{ $t('reporting.filters.from') }}
|
||||||
<label class="mb-1 block text-sm font-medium text-neutral-700">
|
</label>
|
||||||
{{ $t('reporting.filters.from') }}
|
<MalioDate
|
||||||
</label>
|
v-model="customFrom"
|
||||||
<MalioDate
|
:disabled="selectedPeriod !== 'custom'"
|
||||||
v-model="customFrom"
|
group-class="w-full"
|
||||||
:disabled="selectedPeriod !== 'custom'"
|
/>
|
||||||
group-class="w-full"
|
</div>
|
||||||
|
<div class="w-40">
|
||||||
|
<label class="mb-1 block text-sm font-medium text-neutral-700">
|
||||||
|
{{ $t('reporting.filters.to') }}
|
||||||
|
</label>
|
||||||
|
<MalioDate
|
||||||
|
v-model="customTo"
|
||||||
|
:disabled="selectedPeriod !== 'custom'"
|
||||||
|
group-class="w-full"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<MalioSelect
|
||||||
|
v-model="selectedProjectId"
|
||||||
|
:options="projectOptions"
|
||||||
|
:label="$t('reporting.filters.project')"
|
||||||
|
:empty-option-label="$t('reporting.filters.allProjects')"
|
||||||
|
group-class="!w-44"
|
||||||
|
text-field="text-sm"
|
||||||
|
text-value="text-sm"
|
||||||
|
/>
|
||||||
|
<MalioSelect
|
||||||
|
v-model="selectedUserId"
|
||||||
|
:options="userOptions"
|
||||||
|
:label="$t('reporting.filters.user')"
|
||||||
|
:empty-option-label="$t('reporting.filters.allUsers')"
|
||||||
|
group-class="!w-44"
|
||||||
|
text-field="text-sm"
|
||||||
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-40">
|
</template>
|
||||||
<label class="mb-1 block text-sm font-medium text-neutral-700">
|
</PageHeader>
|
||||||
{{ $t('reporting.filters.to') }}
|
|
||||||
</label>
|
|
||||||
<MalioDate
|
|
||||||
v-model="customTo"
|
|
||||||
:disabled="selectedPeriod !== 'custom'"
|
|
||||||
group-class="w-full"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<MalioSelect
|
|
||||||
v-model="selectedProjectId"
|
|
||||||
:options="projectOptions"
|
|
||||||
:label="$t('reporting.filters.project')"
|
|
||||||
:empty-option-label="$t('reporting.filters.allProjects')"
|
|
||||||
group-class="!w-44"
|
|
||||||
text-field="text-sm"
|
|
||||||
text-value="text-sm"
|
|
||||||
/>
|
|
||||||
<MalioSelect
|
|
||||||
v-model="selectedUserId"
|
|
||||||
:options="userOptions"
|
|
||||||
:label="$t('reporting.filters.user')"
|
|
||||||
:empty-option-label="$t('reporting.filters.allUsers')"
|
|
||||||
group-class="!w-44"
|
|
||||||
text-field="text-sm"
|
|
||||||
text-value="text-sm"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Loading -->
|
<!-- Loading -->
|
||||||
<div v-if="isLoading" class="mt-12 flex items-center justify-center">
|
<div v-if="isLoading" class="mt-12 flex items-center justify-center">
|
||||||
|
|||||||
@@ -1,101 +1,104 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex min-h-0 flex-1 flex-col">
|
<div class="flex min-h-0 flex-1 flex-col">
|
||||||
<div ref="pageHeaderEl" class="sticky top-8 z-20 flex-shrink-0 bg-white pb-4 sm:top-12">
|
<div ref="pageHeaderEl" class="flex-shrink-0">
|
||||||
<div class="flex items-center justify-between gap-3">
|
<PageHeader>
|
||||||
<h1 class="text-xl font-bold text-primary-500 sm:text-2xl">Suivi des temps</h1>
|
Suivi des temps
|
||||||
<MalioButton
|
<template #actions>
|
||||||
icon-name="mdi:plus"
|
<MalioButton
|
||||||
icon-position="left"
|
icon-name="mdi:plus"
|
||||||
button-class="shrink-0"
|
icon-position="left"
|
||||||
@click="openCreateDrawer()"
|
button-class="shrink-0"
|
||||||
>
|
@click="openCreateDrawer()"
|
||||||
<span class="hidden sm:inline">Ajouter une Activité</span>
|
|
||||||
<span class="sm:hidden">Activité</span>
|
|
||||||
</MalioButton>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="relative z-30 mt-4 flex flex-wrap items-center gap-3 sm:gap-4">
|
|
||||||
<div class="flex shrink-0 items-center gap-1 h-8">
|
|
||||||
<MalioButtonIcon
|
|
||||||
icon="mdi:chevron-left"
|
|
||||||
aria-label="Précédent"
|
|
||||||
variant="ghost"
|
|
||||||
@click="navigatePrev"
|
|
||||||
/>
|
|
||||||
<DateFilter v-model="selectedDateFilter" :picker-mode="viewMode === 'day' ? 'day' : 'week'" />
|
|
||||||
<h2 class="shrink-0 whitespace-nowrap text-lg font-bold leading-8 text-orange-500">
|
|
||||||
{{ currentMonthLabel }}
|
|
||||||
</h2>
|
|
||||||
<MalioButtonIcon
|
|
||||||
icon="mdi:chevron-right"
|
|
||||||
aria-label="Suivant"
|
|
||||||
variant="ghost"
|
|
||||||
@click="navigateNext"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex items-center rounded-full bg-neutral-100 p-1">
|
|
||||||
<button
|
|
||||||
v-for="mode in (['week', 'day', 'list'] as const)"
|
|
||||||
:key="mode"
|
|
||||||
class="rounded-full px-4 py-1.5 text-sm font-semibold transition-all"
|
|
||||||
:class="viewMode === mode
|
|
||||||
? 'bg-primary-500 text-white shadow-sm'
|
|
||||||
: 'text-neutral-500 hover:text-neutral-700'"
|
|
||||||
@click="viewMode = mode"
|
|
||||||
>
|
>
|
||||||
{{ mode === 'week' ? 'Semaine' : mode === 'day' ? 'Jour' : 'Liste' }}
|
<span class="hidden sm:inline">Ajouter une Activité</span>
|
||||||
</button>
|
<span class="sm:hidden">Activité</span>
|
||||||
</div>
|
</MalioButton>
|
||||||
|
</template>
|
||||||
|
<template #subheader>
|
||||||
|
<div class="relative z-30 mt-4 flex flex-wrap items-center gap-3 sm:gap-4">
|
||||||
|
<div class="flex shrink-0 items-center gap-1 h-8">
|
||||||
|
<MalioButtonIcon
|
||||||
|
icon="mdi:chevron-left"
|
||||||
|
aria-label="Précédent"
|
||||||
|
variant="ghost"
|
||||||
|
@click="navigatePrev"
|
||||||
|
/>
|
||||||
|
<DateFilter v-model="selectedDateFilter" :picker-mode="viewMode === 'day' ? 'day' : 'week'" />
|
||||||
|
<h2 class="shrink-0 whitespace-nowrap text-lg font-bold leading-8 text-orange-500">
|
||||||
|
{{ currentMonthLabel }}
|
||||||
|
</h2>
|
||||||
|
<MalioButtonIcon
|
||||||
|
icon="mdi:chevron-right"
|
||||||
|
aria-label="Suivant"
|
||||||
|
variant="ghost"
|
||||||
|
@click="navigateNext"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="[&>div]:!mt-0">
|
<div class="flex items-center rounded-full bg-neutral-100 p-1">
|
||||||
<MalioSelect
|
<button
|
||||||
v-model="selectedUserId"
|
v-for="mode in (['week', 'day', 'list'] as const)"
|
||||||
:options="userOptions"
|
:key="mode"
|
||||||
group-class="!w-36 sm:!w-44"
|
class="rounded-full px-4 py-1.5 text-sm font-semibold transition-all"
|
||||||
text-field="text-sm"
|
:class="viewMode === mode
|
||||||
text-value="text-sm"
|
? 'bg-primary-500 text-white shadow-sm'
|
||||||
label="User"
|
: 'text-neutral-500 hover:text-neutral-700'"
|
||||||
empty-option-label="Tous"
|
@click="viewMode = mode"
|
||||||
/>
|
>
|
||||||
</div>
|
{{ mode === 'week' ? 'Semaine' : mode === 'day' ? 'Jour' : 'Liste' }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="[&>div]:!mt-0">
|
<div class="[&>div]:!mt-0">
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedProjectId"
|
v-model="selectedUserId"
|
||||||
:options="projectOptions"
|
:options="userOptions"
|
||||||
empty-option-label="Tous"
|
group-class="!w-36 sm:!w-44"
|
||||||
label="Projet"
|
text-field="text-sm"
|
||||||
group-class="!w-36 sm:!w-44"
|
text-value="text-sm"
|
||||||
text-field="text-sm"
|
label="User"
|
||||||
text-value="text-sm"
|
empty-option-label="Tous"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="[&>div]:!mt-0">
|
<div class="[&>div]:!mt-0">
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedTagId"
|
v-model="selectedProjectId"
|
||||||
:options="tagOptions"
|
:options="projectOptions"
|
||||||
empty-option-label="Tous"
|
empty-option-label="Tous"
|
||||||
label="Tag"
|
label="Projet"
|
||||||
group-class="!w-36 sm:!w-44"
|
group-class="!w-36 sm:!w-44"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MalioButton
|
<div class="[&>div]:!mt-0">
|
||||||
:label="$t('timeEntries.export')"
|
<MalioSelect
|
||||||
variant="secondary"
|
v-model="selectedTagId"
|
||||||
icon-name="mdi:download"
|
:options="tagOptions"
|
||||||
icon-position="left"
|
empty-option-label="Tous"
|
||||||
button-class="w-auto px-4"
|
label="Tag"
|
||||||
@click="exportDrawerOpen = true"
|
group-class="!w-36 sm:!w-44"
|
||||||
/>
|
text-field="text-sm"
|
||||||
</div>
|
text-value="text-sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<MalioButton
|
||||||
|
:label="$t('timeEntries.export')"
|
||||||
|
variant="secondary"
|
||||||
|
icon-name="mdi:download"
|
||||||
|
icon-position="left"
|
||||||
|
button-class="w-auto px-4"
|
||||||
|
@click="exportDrawerOpen = true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</PageHeader>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="relative z-0 mt-4 -mb-24 min-h-0 flex-1">
|
<div class="relative z-0 -mb-24 min-h-0 flex-1">
|
||||||
<TimeEntryList
|
<TimeEntryList
|
||||||
v-if="viewMode === 'list'"
|
v-if="viewMode === 'list'"
|
||||||
:entries="filteredEntries"
|
:entries="filteredEntries"
|
||||||
|
|||||||
Generated
+4
-4
@@ -7,7 +7,7 @@
|
|||||||
"name": "nuxt-app",
|
"name": "nuxt-app",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@malio/layer-ui": "^1.7.5",
|
"@malio/layer-ui": "^1.7.16",
|
||||||
"@nuxt/icon": "^2.2.1",
|
"@nuxt/icon": "^2.2.1",
|
||||||
"@nuxtjs/i18n": "^10.2.3",
|
"@nuxtjs/i18n": "^10.2.3",
|
||||||
"@nuxtjs/tailwindcss": "^6.14.0",
|
"@nuxtjs/tailwindcss": "^6.14.0",
|
||||||
@@ -2220,9 +2220,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@malio/layer-ui": {
|
"node_modules/@malio/layer-ui": {
|
||||||
"version": "1.7.5",
|
"version": "1.7.16",
|
||||||
"resolved": "https://gitea.malio.fr/api/packages/MALIO-DEV/npm/%40malio%2Flayer-ui/-/1.7.5/layer-ui-1.7.5.tgz",
|
"resolved": "https://gitea.malio.fr/api/packages/MALIO-DEV/npm/%40malio%2Flayer-ui/-/1.7.16/layer-ui-1.7.16.tgz",
|
||||||
"integrity": "sha512-xryrAYgVgX3eurEWXT/d0p4r/MBYNBB3mBnvV6xVcFhzxW+HfOra8hsVHLvrCtd+m5E1t7PDRzjw1FObkV6fdQ==",
|
"integrity": "sha512-24scQzhfnwLJr+JTlusiiazkjEK8pqwPp5NZGLdFbP32f+J9RpwoJf/U0ztwIJssXEeYvJB4cdLDYow7dZJv6Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxt/icon": "^2.2.1",
|
"@nuxt/icon": "^2.2.1",
|
||||||
"@nuxtjs/tailwindcss": "^6.14.0",
|
"@nuxtjs/tailwindcss": "^6.14.0",
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"build:dist": "nuxt generate && rm -rf dist && cp -R .output/public dist"
|
"build:dist": "nuxt generate && rm -rf dist && cp -R .output/public dist"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@malio/layer-ui": "^1.7.5",
|
"@malio/layer-ui": "^1.7.16",
|
||||||
"@nuxt/icon": "^2.2.1",
|
"@nuxt/icon": "^2.2.1",
|
||||||
"@nuxtjs/i18n": "^10.2.3",
|
"@nuxtjs/i18n": "^10.2.3",
|
||||||
"@nuxtjs/tailwindcss": "^6.14.0",
|
"@nuxtjs/tailwindcss": "^6.14.0",
|
||||||
|
|||||||
+20
-19
@@ -1,24 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="sticky top-8 z-20 bg-white pb-4 sm:top-12">
|
<PageHeader>
|
||||||
<h1 class="text-xl font-bold text-primary-500 sm:text-2xl">Administration</h1>
|
Administration
|
||||||
|
<template #subheader>
|
||||||
<div class="mt-6 border-b border-neutral-200 overflow-x-auto">
|
<div class="mt-6 border-b border-neutral-200 overflow-x-auto">
|
||||||
<nav class="flex gap-4 sm:gap-6">
|
<nav class="flex gap-4 sm:gap-6">
|
||||||
<button
|
<button
|
||||||
v-for="tab in visibleTabs"
|
v-for="tab in visibleTabs"
|
||||||
:key="tab.key"
|
:key="tab.key"
|
||||||
class="whitespace-nowrap px-1 pb-3 text-sm font-semibold transition"
|
class="whitespace-nowrap px-1 pb-3 text-sm font-semibold transition"
|
||||||
:class="activeTab === tab.key
|
:class="activeTab === tab.key
|
||||||
? 'border-b-2 border-primary-500 text-primary-500'
|
? 'border-b-2 border-primary-500 text-primary-500'
|
||||||
: 'text-neutral-500 hover:text-neutral-700'"
|
: 'text-neutral-500 hover:text-neutral-700'"
|
||||||
@click="activeTab = tab.key"
|
@click="activeTab = tab.key"
|
||||||
>
|
>
|
||||||
{{ tab.label }}
|
{{ tab.label }}
|
||||||
</button>
|
</button>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
|
</PageHeader>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<AdminWorkflowTab v-if="activeTab === 'workflows'" />
|
<AdminWorkflowTab v-if="activeTab === 'workflows'" />
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-xl font-bold text-primary-500 sm:text-2xl">{{ $t('sharedFiles.title') }}</h1>
|
<PageHeader>{{ $t('sharedFiles.title') }}</PageHeader>
|
||||||
|
|
||||||
<!-- Fil d'Ariane -->
|
<!-- Fil d'Ariane -->
|
||||||
<nav class="mt-4 flex flex-wrap items-center gap-1 text-sm text-neutral-500">
|
<nav class="flex flex-wrap items-center gap-1 text-sm text-neutral-500">
|
||||||
<button class="hover:text-primary-500" @click="openPath('')">{{ $t('sharedFiles.root') }}</button>
|
<button class="hover:text-primary-500" @click="openPath('')">{{ $t('sharedFiles.root') }}</button>
|
||||||
<template v-for="crumb in breadcrumb" :key="crumb.path">
|
<template v-for="crumb in breadcrumb" :key="crumb.path">
|
||||||
<span>/</span>
|
<span>/</span>
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!-- Filtre local + rechargement -->
|
<!-- Filtre local + rechargement -->
|
||||||
<div class="mt-4 flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<div class="max-w-sm flex-1">
|
<div class="max-w-sm flex-1">
|
||||||
<MalioInputText
|
<MalioInputText
|
||||||
v-model="filter"
|
v-model="filter"
|
||||||
|
|||||||
+35
-34
@@ -506,39 +506,40 @@ const lineOptions = {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="sticky top-8 z-20 bg-white pb-4 sm:top-12">
|
<PageHeader>
|
||||||
<h1 class="text-xl font-bold text-primary-500 sm:text-2xl">{{ $t('dashboard.title') }}</h1>
|
{{ $t('dashboard.title') }}
|
||||||
|
<template #subheader>
|
||||||
<!-- Filters -->
|
<!-- Filters -->
|
||||||
<div class="mt-4 flex flex-wrap gap-3">
|
<div class="mt-4 flex flex-wrap gap-3">
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedPeriod"
|
v-model="selectedPeriod"
|
||||||
:options="periodOptions"
|
:options="periodOptions"
|
||||||
:label="$t('dashboard.filters.period')"
|
:label="$t('dashboard.filters.period')"
|
||||||
group-class="!w-48"
|
group-class="!w-48"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedProjectId"
|
v-model="selectedProjectId"
|
||||||
:options="projectOptions"
|
:options="projectOptions"
|
||||||
:label="$t('dashboard.filters.project')"
|
:label="$t('dashboard.filters.project')"
|
||||||
:empty-option-label="$t('dashboard.filters.allProjects')"
|
:empty-option-label="$t('dashboard.filters.allProjects')"
|
||||||
group-class="!w-40"
|
group-class="!w-40"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-model="selectedUserId"
|
v-model="selectedUserId"
|
||||||
:options="userOptions"
|
:options="userOptions"
|
||||||
:label="$t('dashboard.filters.user')"
|
:label="$t('dashboard.filters.user')"
|
||||||
:empty-option-label="$t('dashboard.filters.allUsers')"
|
:empty-option-label="$t('dashboard.filters.allUsers')"
|
||||||
group-class="!w-40"
|
group-class="!w-40"
|
||||||
text-field="text-sm"
|
text-field="text-sm"
|
||||||
text-value="text-sm"
|
text-value="text-sm"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
|
</PageHeader>
|
||||||
|
|
||||||
<!-- Loading -->
|
<!-- Loading -->
|
||||||
<div v-if="isLoading" class="mt-12 flex items-center justify-center">
|
<div v-if="isLoading" class="mt-12 flex items-center justify-center">
|
||||||
@@ -547,7 +548,7 @@ const lineOptions = {
|
|||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<!-- KPI Cards -->
|
<!-- KPI Cards -->
|
||||||
<div class="mt-6 grid grid-cols-2 gap-4 lg:grid-cols-4">
|
<div class="grid grid-cols-2 gap-4 lg:grid-cols-4">
|
||||||
<div class="rounded-xl border border-neutral-100 bg-neutral-50 p-5">
|
<div class="rounded-xl border border-neutral-100 bg-neutral-50 p-5">
|
||||||
<p class="text-xs font-medium uppercase tracking-wider text-neutral-400">
|
<p class="text-xs font-medium uppercase tracking-wider text-neutral-400">
|
||||||
{{ $t('dashboard.stats.hoursPeriod') }}
|
{{ $t('dashboard.stats.hoursPeriod') }}
|
||||||
|
|||||||
Reference in New Issue
Block a user