diff --git a/frontend/src/components/CalendarWeek.vue b/frontend/src/components/CalendarWeek.vue index 9986ee12..e25600ce 100644 --- a/frontend/src/components/CalendarWeek.vue +++ b/frontend/src/components/CalendarWeek.vue @@ -30,13 +30,19 @@ @mouseleave="popup = {...initialEventPopupData}" >
-
- {{ event.title }} +
+
+ {{ event.title }} +
@@ -53,63 +59,73 @@
+
+
-
- {{ event.title }} + > + {{ event.title }} +
-
-
-
+
{{ event.times }} +
+
{ // create position of event, smallest unit is one minute const timePosition = (start, duration) => ({ - offset: 60 * dj(start).format('H') + 1 * dj(start).format('m') - 60 * startHour.value + 1, + offset: (60 * dj(start).format('H') + 1 * dj(start).format('m') - 60 * startHour.value + 1) + 30, span: duration, times: `${dj(start).format(timeFormat())} - ${dj(start).add(duration, 'minutes').format(timeFormat())}`, }); -// handle events to show -const events = computed(() => { +const processEvents = ((allDays) => { const eventsOnDate = {}; - // add appointments - props.appointments?.forEach((event) => { - event.slots.forEach((slot) => { - const key = dj(slot.start).format('YYYY-MM-DD'); - const extendedEvent = { ...event, ...slot, ...timePosition(slot.start, slot.duration) }; - delete extendedEvent.slots; - if (key in eventsOnDate) { - eventsOnDate[key].push(extendedEvent); - } else { - eventsOnDate[key] = [extendedEvent]; - } + const offsets = {}; + + // add appointments, only for allDays === false + if (!allDays) { + props.appointments?.forEach((event) => { + event.slots.forEach((slot) => { + const key = dj(slot.start).format('YYYY-MM-DD'); + const innerKey = dj(slot.start).format('HH:mm'); + const extendedEvent = {...event, ...slot, ...timePosition(slot.start, slot.duration)}; + delete extendedEvent.slots; + offsets[extendedEvent.offset] = extendedEvent.offset; + + if (!(key in eventsOnDate)) { + eventsOnDate[key] = {}; + } + + if (innerKey in eventsOnDate[key] && eventsOnDate[key][innerKey]['items'].length < 4) { + eventsOnDate[key][innerKey]['items'].push(extendedEvent); + } else if (!(innerKey in eventsOnDate[key])) { + eventsOnDate[key][innerKey] = { + 'items': [extendedEvent], + 'order': 0, + 'offset': extendedEvent.offset, + }; + } + + }); }); - }); + } // add calendar events props.events?.forEach((event) => { + if (!allDays && event.all_day) { + return; + } else if (allDays && !event.all_day) { + return; + } const key = dj(event.start).format('YYYY-MM-DD'); + const innerKey = dj(event.start).format('HH:mm'); const extendedEvent = { ...event, ...timePosition(event.start, event.duration), remote: true }; - if (key in eventsOnDate) { - eventsOnDate[key].push(extendedEvent); - } else { - eventsOnDate[key] = [extendedEvent]; + offsets[extendedEvent.offset] = extendedEvent.offset; + + if (!(key in eventsOnDate)) { + eventsOnDate[key] = {}; + } + + if (innerKey in eventsOnDate[key] && eventsOnDate[key][innerKey]['items'].length < 4) { + eventsOnDate[key][innerKey]['items'].push(extendedEvent); + } else if (!(innerKey in eventsOnDate[key])) { + eventsOnDate[key][innerKey] = { + 'items': [extendedEvent], + 'order': 0, + 'offset': extendedEvent.offset, + }; } }); + + const orderedOffsets = Object.values(offsets).sort(); + + // Sort offset for order - it's ugly sorry. + // We don't store offsets by day, so you might see order: 4, and order: 7. Since it's sorted by value it should be fine. + Object.keys(eventsOnDate).map((eventDate) => { + Object.keys(eventsOnDate[eventDate]).map((eventTime) => { + eventsOnDate[eventDate][eventTime]['order'] = orderedOffsets.indexOf(eventsOnDate[eventDate][eventTime]['items'][0].offset); + }); + }); + return eventsOnDate; +}) + +// handle events to show + +// Events excluding all day events +const events = computed(() => { + const evts = processEvents(false); + console.log(">> DURING DAY ", evts); + + return evts; +}); +// Events excluding during day events +const allDayEvents = computed(() => { + const evts = processEvents(true); + console.log(">> ALL DAY ", evts); + return evts; }); -const eventsByDate = (d) => { - const key = dj(d).format('YYYY-MM-DD'); - if (key in events.value) { - return { - duringDay: events.value[key].filter((e) => !e.all_day), - allDay: events.value[key].filter((e) => e.all_day), - }; - } - return null; -}; // generate names for each day of week const days = computed(() => { diff --git a/frontend/src/utils.js b/frontend/src/utils.js index 67309259..993016b0 100644 --- a/frontend/src/utils.js +++ b/frontend/src/utils.js @@ -73,20 +73,25 @@ export const initialEventPopupData = { left: 'initial', }; // calculate properties of event popup for given element and show popup -export const showEventPopup = (el, event, position='right') => { +export const showEventPopup = (el, event, position = 'right') => { const obj = { ...initialEventPopupData }; obj.event = event; obj.display = 'block'; - obj.top = `${el.target.offsetTop + el.target.clientHeight / 2 - el.target.parentElement.scrollTop}px`; + + const bounds = el.target.getBoundingClientRect(); + const top = window.scrollY + bounds.top; + const left = window.scrollX + bounds.left; + + obj.top = `${top + bounds.height / 2 - el.target.parentElement.scrollTop}px`; if (!position || position === 'right') { - obj.left = `${el.target.offsetLeft + el.target.clientWidth + 4}px`; + obj.left = `${left + bounds.width + 4}px`; } if (position === 'left') { - obj.left = `${el.target.offsetLeft - 4}px`;; + obj.left = `${left - 4}px`; } if (position === 'top') { - obj.left = `${el.target.offsetLeft + el.target.clientWidth/2}px`; - obj.top = `${el.target.offsetTop - 50}px`; + obj.left = `${left + bounds.width/2}px`; + obj.top = `${top - 50}px`; } return obj; };