99 lines
2.7 KiB
Vue
99 lines
2.7 KiB
Vue
<script setup lang="ts">
|
|
import type { PropType} from "vue";
|
|
import type {ContextMenuType} from "@models/misc/contextMenu"
|
|
import type {calendarShowEvent, ShowEventActionTrigger} from "@models/misc/calendarShowEvent.ts";
|
|
import {calendarShowEventMenu} from "@models/misc/calendarShowEvent";
|
|
import { ref } from 'vue';
|
|
import ContextMenu from '@partials/ContextMenu.vue';
|
|
import { formatTime } from "@/helpers/DateFormatter.ts";
|
|
|
|
const emit = defineEmits([
|
|
'contextMenuEditInstance',
|
|
'contextMenuEditShow',
|
|
'contextMenuDeleteInstance',
|
|
'contextMenuDeleteShow'
|
|
]);
|
|
|
|
// Data
|
|
const calendar = ref(null);
|
|
const currentCalendarDate = ref(null);
|
|
const selectedShowInstance = ref(null);
|
|
const contextMenu = ref<ContextMenuType>({
|
|
visible: false,
|
|
position: {
|
|
top: 0,
|
|
left: 0,
|
|
},
|
|
menu: calendarShowEventMenu
|
|
});
|
|
|
|
// Props
|
|
const props = defineProps({
|
|
editMode: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
shows: {
|
|
type: Array as PropType<calendarShowEvent[]>,
|
|
default: false,
|
|
}
|
|
});
|
|
|
|
// Funcs
|
|
const openContextMenu = (showInstance: Record<string, unknown>, browserEvent: MouseEvent) => {
|
|
if (!props.editMode) return;
|
|
|
|
selectedShowInstance.value = showInstance;
|
|
contextMenu.value.visible = true;
|
|
contextMenu.value.position.top = browserEvent.y;
|
|
contextMenu.value.position.left = browserEvent.x + 5;
|
|
};
|
|
|
|
const hideContextMenu = () => {
|
|
contextMenu.value.visible = false;
|
|
};
|
|
|
|
const contextMenuAction = (action: ShowEventActionTrigger, item: Object) => {
|
|
if (!selectedShowInstance.value) return;
|
|
emit(action, selectedShowInstance.value.showInstanceIndex);
|
|
contextMenu.value.visible = false;
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<v-calendar
|
|
ref="calendar"
|
|
v-model="currentCalendarDate"
|
|
:events="props.shows"
|
|
:event-margin-bottom="3"
|
|
@contextmenu:event="openContextMenu"
|
|
>
|
|
<template v-slot:event="{ event }">
|
|
<div
|
|
class="v-event mx-1 event-content"
|
|
:style="{ backgroundColor: event.color as string }"
|
|
@click="(e) => openContextMenu(event, e)"
|
|
@click.self="hideContextMenu"
|
|
>
|
|
<span>{{ event.title }}</span>
|
|
<br/>
|
|
<span>{{ formatTime(event.start) as string }} - {{ formatTime(event.end) as string }}</span>
|
|
</div>
|
|
</template>
|
|
</v-calendar>
|
|
|
|
<ContextMenu v-if="contextMenu.visible" @contextMenuAction="contextMenuAction" :event="selectedShowInstance"
|
|
:menu="contextMenu.menu" :top="contextMenu.position.top" :left="contextMenu.position.left"/>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.event-content {
|
|
position: relative;
|
|
white-space: normal;
|
|
line-height: 1.2;
|
|
padding: 4px 8px;
|
|
background-color: #7492b9;
|
|
border-radius: 8px;
|
|
color: white;
|
|
}
|
|
</style>
|