import BaseDraganddrop from './Base/DragAndDrop.js'; import BaseHeader from './Base/Header.js'; import BaseSlider from './Base/Slider.js'; import BsModal from '../Bootstrap/Modal.js'; import CalClick from '../../directives/Calendar/Click.js'; export default { name: "CalendarBase", components: { BaseDraganddrop, BaseHeader, BaseSlider, BsModal }, directives: { CalClick }, provide() { return { locale: Vue.computed(() => this.locale), timezone: Vue.computed(() => this.timezone), timeGrid: Vue.computed(() => this.timeGrid), draggableEvents: Vue.computed(() => { if (!this.draggableEvents) return () => false; if (Array.isArray(this.draggableEvents)) return event => this.draggableEvents.includes(event.type); if (this.draggableEvents instanceof Function) return this.draggableEvents; return () => true; }), dropableEvents: Vue.computed(() => { if (!this.onDrop) return () => false; if (Array.isArray(this.dropableEvents)) return item => this.dropableEvents.includes(item.type); if (this.dropableEvents instanceof Function) return this.dropableEvents; return () => true; }), hasDragoverFunc: Vue.computed(() => this.onDragover), mode: Vue.computed(() => this.mode) }; }, props: { locale: { type: String, default: 'de' }, timezone: { type: String, required: true }, date: { type: [Date, String, Number, luxon.DateTime], default: props => luxon.DateTime.now().setZone(props.timezone).startOf('day') }, modes: { type: Object, required: true, default: {} // TODO(chris): verfication functions }, mode: String, modeOptions: Object, events: { type: Array, default: [] }, backgrounds: { type: Array, default: [] }, showBtns: Boolean, btnMonth: { type: Boolean, default: undefined }, btnWeek: { type: Boolean, default: undefined }, btnDay: { type: Boolean, default: undefined }, btnList: { type: Boolean, default: undefined }, timeGrid: Array, draggableEvents: [Boolean, Array, Function], dropableEvents: [Boolean, Array, Function], onDragover: Function, onDrop: Function }, emits: [ "click:next", "click:prev", "click:mode", "click:event", "click:day", "click:week", "update:date", "update:mode", "update:range", "drop" ], data() { return { internalView: null, internalDate: null, modalEvent: null }; }, computed: { convertedEvents() { return this.events.map(orig => ({ id: orig.type + orig[orig.type + '_id'], type: orig.type, start: luxon.DateTime.fromISO(orig.isostart).setZone(this.timezone), end: luxon.DateTime.fromISO(orig.isoend).setZone(this.timezone), orig })); }, convertedBackgrounds() { return this.backgrounds.map(bg => { const res = { ...bg }; if (res.start) { if (Number.isInteger(res.start)) res.start = luxon.DateTime.fromMillis(res.start, { zone: this.timezone, locale: this.locale }); else if (res.start instanceof Date) res.start = luxon.DateTime.fromJSDate(res.start, { zone: this.timezone, locale: this.locale }); else if (typeof res.start === 'string' || res.start instanceof String) res.start = luxon.DateTime.fromISO(res.start, { zone: this.timezone, locale: this.locale }); } if (res.end) { if (Number.isInteger(res.end)) res.end = luxon.DateTime.fromMillis(res.end, { zone: this.timezone, locale: this.locale }); else if (res.end instanceof Date) res.end = luxon.DateTime.fromJSDate(res.end, { zone: this.timezone, locale: this.locale }); else if (typeof res.end === 'string' || res.end instanceof String) res.end = luxon.DateTime.fromISO(res.end, { zone: this.timezone, locale: this.locale }); } return res; }); }, sDate() { if (this.date instanceof luxon.DateTime) return this.date; return luxon.DateTime.fromJSDate(new Date(this.date)).setZone(this.timezone); }, cDate: { get() { const date = this.internalDate ? this.internalDate : this.sDate; return date.setLocale(this.locale); }, set(value) { this.internalDate = value; this.$emit('update:date', value, this.cMode); } }, sMode() { // choose default mode let mode = this.mode; if (mode) mode = mode.toLowerCase(); if (!mode || !this.modes[mode]) mode = Object.keys(this.modes).find(Boolean); // start with first entry as active mode return mode || ''; }, cMode: { get() { return this.internalView ? this.internalView : this.sMode; }, set(value) { this.internalView = value; this.$emit('update:mode', value, this.cDate); } } }, watch: { sDate(n, o) { if (this.sDate.isValid && !this.sDate.hasSame(this.internalDate, 'day')) this.internalDate = this.sDate; }, sMode() { if (this.sMode) this.internalView = this.sMode; } }, methods: { clickPrev() { const evt = new Event('click:prev', {cancelable: true}); this.$emit('click:prev', evt); if (evt.defaultPrevented) return; // default: switch page this.$refs.mode.prevPage(); }, clickNext() { const evt = new Event('click:next', {cancelable: true}); this.$emit('click:next', evt); if (evt.defaultPrevented) return; // default: switch page this.$refs.mode.nextPage(); }, handleClickDefaults(evt) { // TODO(chris): implement switch (evt.detail.source) { case 'day': if (this.cMode != 'day' && this.modes['day']) { evt.stopPropagation(); this.cDate = evt.detail.value; this.cMode = 'day'; } break; case 'week': if (this.cMode != 'week' && this.modes['week']) { evt.stopPropagation(); this.cDate = luxon.DateTime.fromObject({ localWeekNumber: evt.detail.value.number, localWeekYear: evt.detail.value.year }, { zone: this.cDate.zoneName, locale: this.cDate.locale }); this.cMode = 'week'; } break; } }, onDropItem(evt, start, end) { this.$emit('drop', evt, start, end); }, showEventModal(eventObj) { this.modalEvent = eventObj; this.$refs.modal.show(); }, hideEventModal() { if (this.modalEvent) this.modalEvent.closeFn = undefined; this.$refs.modal.hide(); this.modalEvent = null; }, onModalHidden() { if (this.modalEvent.closeFn) this.modalEvent.closeFn(); } }, beforeUnmount() { this.hideEventModal(); }, template: /* html */`
` }