73 lines
1.9 KiB
Vue
73 lines
1.9 KiB
Vue
<script setup>
|
|
import { ref, onMounted, onBeforeUnmount } from 'vue'
|
|
import CalendarView from './components/CalendarView.vue'
|
|
import EventDialog from './components/EventDialog.vue'
|
|
import { useCalendarStore } from './stores/CalendarStore'
|
|
|
|
const eventDialog = ref(null)
|
|
const calendarStore = useCalendarStore()
|
|
|
|
// Initialize holidays when app starts
|
|
function isEditableElement(el) {
|
|
if (!el) return false
|
|
const tag = el.tagName
|
|
if (tag === 'INPUT' || tag === 'TEXTAREA') return true
|
|
if (el.isContentEditable) return true
|
|
return false
|
|
}
|
|
|
|
function handleGlobalKey(e) {
|
|
// Only consider Ctrl/Meta+Z combos
|
|
if (!(e.ctrlKey || e.metaKey)) return
|
|
if (e.key !== 'z' && e.key !== 'Z') return
|
|
// Don't interfere with native undo/redo inside editable fields
|
|
const target = e.target
|
|
if (isEditableElement(target)) return
|
|
// Decide undo vs redo (Shift = redo)
|
|
if (e.shiftKey) {
|
|
calendarStore.$history?.redo()
|
|
} else {
|
|
calendarStore.$history?.undo()
|
|
}
|
|
e.preventDefault()
|
|
}
|
|
|
|
onMounted(() => {
|
|
calendarStore.initializeHolidaysFromConfig()
|
|
document.addEventListener('keydown', handleGlobalKey, { passive: false })
|
|
})
|
|
|
|
onBeforeUnmount(() => {
|
|
document.removeEventListener('keydown', handleGlobalKey)
|
|
})
|
|
|
|
const handleCreateEvent = (eventData) => {
|
|
if (eventDialog.value) {
|
|
const selectionData = {
|
|
startDate: eventData.startDate,
|
|
dayCount: eventData.dayCount,
|
|
}
|
|
setTimeout(() => eventDialog.value.openCreateDialog(selectionData), 50)
|
|
}
|
|
}
|
|
|
|
const handleEditEvent = (eventClickPayload) => {
|
|
if (eventDialog.value) {
|
|
eventDialog.value.openEditDialog(eventClickPayload)
|
|
}
|
|
}
|
|
|
|
const handleClearSelection = () => {}
|
|
</script>
|
|
|
|
<template>
|
|
<CalendarView @create-event="handleCreateEvent" @edit-event="handleEditEvent" />
|
|
<EventDialog
|
|
ref="eventDialog"
|
|
:selection="{ startDate: null, dayCount: 0 }"
|
|
@clear-selection="handleClearSelection"
|
|
/>
|
|
</template>
|
|
|
|
<style scoped></style>
|