Files
Lesstime/frontend/components/TimeEntryContextMenu.vue
matthieu 74116506db feat(time-tracking) : add calendar page, timer sidebar, and all UI components
- SidebarTimer widget with play/stop button
- TimeEntryBlock with drag-to-move and resize
- TimeEntryDrawer for create/edit entries
- TimeEntryContextMenu for copy/paste/delete
- TimeTrackingCalendar grid with week/day view
- Time tracking page with filters and navigation
- Sidebar link and timer integration in layout
- TaskCard play button connected to timer store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 22:22:48 +01:00

90 lines
2.3 KiB
Vue

<template>
<Teleport to="body">
<div
v-if="visible"
ref="menuEl"
class="fixed z-50 min-w-36 rounded-md border border-neutral-200 bg-white py-1 shadow-lg"
:style="{ top: `${y}px`, left: `${x}px` }"
>
<button
v-if="entry"
class="flex w-full items-center gap-2 px-4 py-2 text-sm text-neutral-700 hover:bg-neutral-100"
@click="onCopy"
>
<Icon name="mdi:content-copy" size="16" />
Copier
</button>
<button
v-if="canPaste"
class="flex w-full items-center gap-2 px-4 py-2 text-sm text-neutral-700 hover:bg-neutral-100"
@click="onPaste"
>
<Icon name="mdi:content-paste" size="16" />
Coller
</button>
<button
v-if="entry"
class="flex w-full items-center gap-2 px-4 py-2 text-sm text-red-600 hover:bg-red-50"
@click="onDelete"
>
<Icon name="mdi:delete-outline" size="16" />
Supprimer
</button>
</div>
</Teleport>
</template>
<script setup lang="ts">
import type { TimeEntry } from '~/services/dto/time-entry'
const props = defineProps<{
visible: boolean
x: number
y: number
entry?: TimeEntry | null
canPaste: boolean
}>()
const emit = defineEmits<{
(e: 'close'): void
(e: 'copy', entry: TimeEntry): void
(e: 'paste'): void
(e: 'delete', entry: TimeEntry): void
}>()
const menuEl = ref<HTMLElement | null>(null)
function onCopy() {
if (props.entry) emit('copy', props.entry)
emit('close')
}
function onPaste() {
emit('paste')
emit('close')
}
function onDelete() {
if (props.entry) emit('delete', props.entry)
emit('close')
}
function onClickOutside(event: MouseEvent) {
if (menuEl.value && !menuEl.value.contains(event.target as Node)) {
emit('close')
}
}
watch(() => props.visible, (v) => {
if (v) {
setTimeout(() => document.addEventListener('click', onClickOutside), 0)
} else {
document.removeEventListener('click', onClickOutside)
}
})
onUnmounted(() => {
document.removeEventListener('click', onClickOutside)
})
</script>