import DragAndDrop from '../../../helpers/DragAndDrop.js'; import CalDnd from '../../../directives/Calendar/DragAndDrop.js'; /** * TODO(chris): this needs serious rework! */ export default { name: "CalendarDragAndDrop", directives: { CalDnd }, provide() { return { events: Vue.computed(() => this.correctedEvents), backgrounds: Vue.computed(() => this.backgrounds), dropAllowed: Vue.computed(() => this.dragging && this.dropAllowed) }; }, inject: { mode: "mode", dropableEvents: "dropableEvents" }, props: { events: Array, backgrounds: Array }, emits: [ "drop" ], data() { return { dragging: false, allowed: false, draggedInternalEvent: null, draggedExternalEvent: null, targetTimestamp: 0, targetGridEnds: null, dropAllowed: false, shadowPreview: false // TODO(chris): IMPLEMENT! (use background instead of event as preview) }; }, computed: { correctedEvents() { if (this.dragging) { if (this.draggedInternalEvent) { const index = this.events.findIndex(e => e.id == this.draggedInternalEvent.id); if (this.previewEvent && !this.shadowPreview) return this.events.toSpliced(index, 1, this.previewEvent); else return this.events.toSpliced(index, 1); } if (this.previewEvent && !this.shadowPreview) return [...this.events, this.previewEvent]; } return this.events; }, correctedBackgrounds() { if (this.dragging) { if (this.shadowPreview) { // TODO(chris): how to get the length return [...this.backgrounds, { start: new Date(this.targetTimestamp), class: 'shadow-preview' }]; } } return this.backgrounds; }, previewEvent() { if (!this.dragging || !this.dropAllowed) return null; if (!this.targetTimestamp) return null; const event = this.draggedInternalEvent || this.draggedExternalEvent; if (!event) return null; // TODO(chris): calculate length correctly from orig let length = event.end - event.start; if (this.targetGridEnds) length = this.targetGridEnds.find(end => end >= this.targetTimestamp + length) - this.targetTimestamp; return { orig: event.orig, start: this.targetTimestamp, end: this.targetTimestamp + length }; } }, methods: { onDragstart(evt) { const data = DragAndDrop.convertToTransferData(evt.detail.item.orig); if (DragAndDrop.isValidDragObject(data)) { DragAndDrop.setTransferData(evt.detail.originalEvent, data); this.draggedInternalEvent = evt.detail.item; } }, onDragend() { this.draggedInternalEvent = null; this.dragging = false; }, onDragenter(evt) { this.dragging = true; if (!this.draggedInternalEvent) { const event = DragAndDrop.getValidTransferData(evt.detail.originalEvent); if (event) { this.draggedExternalEvent = { id: event.id, type: event.type, start: event.isostart ? luxon.DateTime.fromISO(event.isostart).setZone(this.timezone) : luxon.DateTime.local().setZone(this.timezone), end: event.isoend ? luxon.DateTime.fromISO(event.isoend).setZone(this.timezone) : luxon.DateTime.local().setZone(this.timezone), orig: event }; } else { this.draggedExternalEvent = null; } this.dropAllowed = this.dropableEvents(event, this.mode); } else { this.dropAllowed = this.dropableEvents(this.draggedInternalEvent, this.mode); } }, onDragleave() { this.dragging = false; }, onDragchange(evt) { this.targetTimestamp = evt.detail.timestamp; this.targetGridEnds = evt.detail.ends || null; }, onDrop(evt) { if (!this.dragging || !this.dropAllowed) return; this.$emit('drop', evt, this.previewEvent.start, this.previewEvent.end); this.dropAllowed = false; this.dragging = false; } }, template: `