diff --git a/frontend/components/task/TaskCard.vue b/frontend/components/task/TaskCard.vue index 2147d59..528cf2e 100644 --- a/frontend/components/task/TaskCard.vue +++ b/frontend/components/task/TaskCard.vue @@ -9,7 +9,12 @@
- {{ task.project.code }}{{ task.number }} + {{ task.project.code }}{{ task.number }} +
-
+
{{ tag.label }} + + +{{ hiddenTagCount }} +
{{ duration }}
@@ -111,6 +117,17 @@ const sizeLevel = computed(() => { return 0 }) +const showTags = computed(() => (props.totalColumns ?? 1) <= 2) + +const maxVisibleTags = computed(() => { + const total = props.totalColumns ?? 1 + if (total >= 2) return 1 + return 2 +}) + +const visibleTags = computed(() => props.entry.tags.slice(0, maxVisibleTags.value)) +const hiddenTagCount = computed(() => Math.max(0, props.entry.tags.length - maxVisibleTags.value)) + const hasProject = computed(() => !!props.entry.project) const blockStyle = computed(() => { diff --git a/frontend/components/time-tracking/TimeEntryDrawer.vue b/frontend/components/time-tracking/TimeEntryDrawer.vue index 418fc7f..9f84763 100644 --- a/frontend/components/time-tracking/TimeEntryDrawer.vue +++ b/frontend/components/time-tracking/TimeEntryDrawer.vue @@ -105,12 +105,22 @@ > Supprimer - +
+ + +
@@ -231,6 +241,26 @@ watch([() => props.modelValue, () => props.entry] as const, ([open, entry]) => { } }) +async function onDuplicate() { + if (!form.date || !form.startTime || !form.endTime) return + + const { create } = useTimeEntryService() + + const payload: Record = { + title: form.title || null, + description: form.description || null, + startedAt: toISO(form.date, form.startTime), + stoppedAt: form.endTime ? toISO(form.date, form.endTime) : null, + user: `/api/users/${form.userId}`, + project: form.projectId ? `/api/projects/${form.projectId}` : null, + tags: form.tagIds.map(id => `/api/task_tags/${id}`), + } + + await create(payload as TimeEntryWrite) + emit('saved') + isOpen.value = false +} + async function onDelete() { if (!props.entry) return const { remove } = useTimeEntryService() diff --git a/frontend/components/time-tracking/TimeEntryList.vue b/frontend/components/time-tracking/TimeEntryList.vue index f74eee0..b561af0 100644 --- a/frontend/components/time-tracking/TimeEntryList.vue +++ b/frontend/components/time-tracking/TimeEntryList.vue @@ -7,7 +7,7 @@
@@ -18,14 +18,14 @@
-
- - {{ entry.title || $t('common.untitled') }} - +
+ {{ entry.title || $t('common.untitled') }} +
+
{{ tag.label }} diff --git a/frontend/components/time-tracking/TimeTrackingCalendar.vue b/frontend/components/time-tracking/TimeTrackingCalendar.vue index 0de926a..d23a81e 100644 --- a/frontend/components/time-tracking/TimeTrackingCalendar.vue +++ b/frontend/components/time-tracking/TimeTrackingCalendar.vue @@ -201,14 +201,11 @@ function getScrollParent(): HTMLElement | null { // Scroll to current hour on mount onMounted(() => { nextTick(() => { - if (!calendarEl.value) return - const scrollParent = getScrollParent() - if (!scrollParent) return + if (!gridBodyEl.value) return const now = new Date() const currentMinutes = now.getHours() * 60 + now.getMinutes() - const calendarTop = calendarEl.value.offsetTop - const scrollTarget = calendarTop + (currentMinutes / 60) * hourHeight - scrollParent.clientHeight / 3 - scrollParent.scrollTop = Math.max(0, scrollTarget) + const scrollTarget = (currentMinutes / 60) * hourHeight - gridBodyEl.value.clientHeight / 3 + gridBodyEl.value.scrollTop = Math.max(0, scrollTarget) }) }) diff --git a/frontend/components/ui/DateFilter.vue b/frontend/components/ui/DateFilter.vue index cd69acb..842b0d9 100644 --- a/frontend/components/ui/DateFilter.vue +++ b/frontend/components/ui/DateFilter.vue @@ -1,5 +1,5 @@