mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-17 20:19:28 +00:00
163 lines
3.9 KiB
JavaScript
163 lines
3.9 KiB
JavaScript
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) {
|
|
DragAndDrop.setTransferData(evt.detail.originalEvent, evt.detail.item.orig);
|
|
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: `
|
|
<div
|
|
class="fhc-calendar-base-draganddrop"
|
|
@calendar-dragstart="onDragstart"
|
|
@calendar-dragend="onDragend"
|
|
v-cal-dnd:dropcage
|
|
@calendar-dragenter="onDragenter"
|
|
@calendar-dragleave="onDragleave"
|
|
@calendar-dragchange="onDragchange"
|
|
@drop="onDrop"
|
|
>
|
|
<slot />
|
|
</div>
|
|
`
|
|
}
|