feat : date filter, project drawer, and misc frontend improvements

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-15 20:25:26 +01:00
parent 046ee396d3
commit f09ef67117
10 changed files with 852 additions and 9 deletions

View File

@@ -3,13 +3,22 @@
<div class="sticky top-8 z-20 bg-white pb-4 sm:top-12">
<div class="flex items-center justify-between gap-3">
<h1 class="text-xl font-bold text-primary-500 sm:text-2xl">{{ project?.name ?? '' }}</h1>
<button
class="shrink-0 rounded-md bg-primary-500 px-3 py-2 text-xs font-semibold text-white hover:bg-secondary-500 sm:px-4 sm:text-sm"
@click="openTaskCreate"
>
<span class="hidden sm:inline">+ Ajouter un ticket</span>
<span class="sm:hidden">+ Ticket</span>
</button>
<div class="flex items-center gap-2">
<button
class="shrink-0 rounded-md bg-primary-500 px-3 py-2 text-xs font-semibold text-white hover:bg-secondary-500 sm:px-4 sm:text-sm"
@click="openTaskCreate"
>
<span class="hidden sm:inline">+ Ajouter un ticket</span>
<span class="sm:hidden">+ Ticket</span>
</button>
<button
class="flex shrink-0 items-center rounded-md bg-neutral-200 px-3 py-2 text-neutral-600 hover:bg-neutral-300 sm:px-4"
title="Paramètres du projet"
@click="projectDrawerOpen = true"
>
<Icon name="heroicons:cog-6-tooth" class="size-4 sm:size-5" />
</button>
</div>
</div>
<div class="mt-4 flex flex-wrap gap-3">
@@ -120,6 +129,13 @@
@saved="onSaved"
/>
<ProjectDrawer
v-model="projectDrawerOpen"
:project="project"
:clients="clients"
@saved="onProjectSaved"
/>
</div>
</template>
@@ -132,7 +148,9 @@ import type { TaskPriority } from '~/services/dto/task-priority'
import type { TaskTag } from '~/services/dto/task-tag'
import type { TaskGroup } from '~/services/dto/task-group'
import type { UserData } from '~/services/dto/user-data'
import type { Client } from '~/services/dto/client'
import { useProjectService } from '~/services/projects'
import { useClientService } from '~/services/clients'
import { useTaskService } from '~/services/tasks'
import { useTaskStatusService } from '~/services/task-statuses'
import { useTaskEffortService } from '~/services/task-efforts'
@@ -147,6 +165,7 @@ const projectId = computed(() => Number(route.params.id))
useHead({ title: 'Projet' })
const projectService = useProjectService()
const clientService = useClientService()
const taskService = useTaskService()
const statusService = useTaskStatusService()
const effortService = useTaskEffortService()
@@ -163,6 +182,7 @@ const priorities = ref<TaskPriority[]>([])
const tags = ref<TaskTag[]>([])
const groups = ref<TaskGroup[]>([])
const users = ref<UserData[]>([])
const clients = ref<Client[]>([])
const isLoading = ref(true)
const selectedGroupId = ref<number | null>(null)
@@ -172,6 +192,7 @@ const selectedStatusId = ref<number | null>(null)
const dragOverStatusId = ref<number | null>(null)
const dragCounter = ref(0)
const taskDrawerOpen = ref(false)
const projectDrawerOpen = ref(false)
const selectedTask = ref<Task | null>(null)
const groupFilterOptions = computed(() =>
@@ -218,7 +239,7 @@ const backlogTasks = computed(() =>
async function loadData() {
isLoading.value = true
try {
const [p, t, s, e, pr, ty, g, u] = await Promise.all([
const [p, t, s, e, pr, ty, g, u, c] = await Promise.all([
projectService.getById(projectId.value),
taskService.getByProject(projectId.value),
statusService.getAll(),
@@ -227,6 +248,7 @@ async function loadData() {
tagService.getAll(),
groupService.getByProject(projectId.value),
userService.getAll(),
clientService.getAll(),
])
project.value = p
tasks.value = t
@@ -236,6 +258,7 @@ async function loadData() {
tags.value = ty
groups.value = g
users.value = u
clients.value = c
} finally {
isLoading.value = false
}
@@ -290,6 +313,10 @@ async function onSaved() {
await loadData()
}
async function onProjectSaved() {
await loadData()
}
onMounted(() => {
loadData()
})

View File

@@ -70,6 +70,8 @@
text-value="text-sm"
/>
</div>
<DateFilter v-model="selectedDateFilter" />
</div>
</div>
@@ -136,6 +138,7 @@ const startDate = ref(getMonday(new Date()))
const selectedUserId = ref<number | null>(authStore.user?.id ?? null)
const selectedTagId = ref<number | null>(null)
const selectedProjectId = ref<number | null>(null)
const selectedDateFilter = ref<Date | [Date, Date] | null>(null)
const entries = ref<TimeEntry[]>([])
const users = ref<UserData[]>([])
@@ -189,6 +192,28 @@ const filteredEntries = computed(() => {
if (selectedTagId.value) {
result = result.filter((e) => e.tags.some((t) => t.id === selectedTagId.value))
}
if (selectedDateFilter.value) {
if (Array.isArray(selectedDateFilter.value)) {
const [start, end] = selectedDateFilter.value
const startDay = new Date(start)
startDay.setHours(0, 0, 0, 0)
const endDay = new Date(end)
endDay.setHours(23, 59, 59, 999)
result = result.filter((e) => {
const entryDate = new Date(e.startedAt)
return entryDate >= startDay && entryDate <= endDay
})
} else {
const day = new Date(selectedDateFilter.value)
day.setHours(0, 0, 0, 0)
const nextDay = new Date(day)
nextDay.setDate(nextDay.getDate() + 1)
result = result.filter((e) => {
const entryDate = new Date(e.startedAt)
return entryDate >= day && entryDate < nextDay
})
}
}
return result
})