Read the statement by Michael Teeuw here.
MMM-CalendarExt3
-
@Ragged4310 said in MMM-CalendarExt3:
I understand this request may be complex, and if a solution isn’t feasible,
its just code, if you can do it in your head, then code can do it…
-
@Ragged4310
Sure, that’s doable. There’s no reason why it shouldn’t be possible.This kind of work is
domain analysis
, which is basically my real-world job.However, it’s not exactly simple. By simple, I mean it’ll take more than the usual 10 minutes I’d spend diving into this hobby project that genuinely interests me.
And honestly, my rate is quite high. :D (Just kidding.)
Let’s clarify a few things first.
- CX3 is usually useful for viewing events from multiple calendars at once, so you’re probably using other types of calendars (e.g., personal meetings, family schedules) together. For this task, let’s assume that the target “customer reservation” events are in a separate, independent calendar. For convenience, I’ll call this calendar “Reservation” from now on.
- Given the nature of calendars, I assume that there won’t be any overlapping events in the Reservation calendar. Additionally, I’ll assume there are no full-day events or events that span midnight.
With these assumptions, I’ll give it a shot sometime tomorrow when I have some free time. I can’t make any promises, so please don’t get your hopes up too high.
-
See the green events
eventPayload
in CX3 config;/* CX3 config section in `config/config.js` */ eventPayload: (payload) => { const targetCalendar = "Reservation" const divideGap = 1000 * 60 * 60 * 1 const locale = 'en-US' const timeStyle = { timeStyle: 'short' } const condition = (ev) => { return (ev.calendarName === targetCalendar && ev.fullDayEvent === false) } const target = payload.filter(condition).sort((a, b) => a.endDate - b.endDate) const result = payload.filter(e => !condition(e)) const dateStr = (dateValue) => Intl.DateTimeFormat(locale, timeStyle).format(new Date(+dateValue)) const collapse = (template, ev) => { if (!template?.["title"]) template = { ...ev, collapseCount: 0, description: '', location: '' } template.collapseCount++ template.startDate = String(Math.min(+template.startDate, +ev.startDate)) template.endDate = String(Math.max(+template.endDate, +ev.endDate)) template.title = `${dateStr(template.startDate)} - ${dateStr(template.endDate)}` if (template.collapseCount > 1) template.title += ` <span class="count">${template.collapseCount}</span>` template.description += `<div class="collapsedEvent"> <p class="title">${ev.title}</p> <p class="period">${dateStr(ev.startDate)} - ${dateStr(ev.endDate)}</p>` if (ev.description) template.description += `<p class="description">${ev.description}</p>` if (ev.location) template.description += `<p class="location">${ev.location}</p>` template.description += '</div>' return template } const dateKey = (dateValue) => new Date(+dateValue).toLocaleDateString('en-CA') let collapsedEvent = {} for (const ev of target) { const currentKey = dateKey(ev.startDate) if (!collapsedEvent?.[ 'title' ]) { collapsedEvent = collapse(collapsedEvent, ev) continue } const collapsedKey = dateKey(collapsedEvent.startDate) if (collapsedKey !== currentKey || +ev.startDate - +collapsedEvent.endDate > divideGap) { result.push(collapsedEvent) collapsedEvent = collapse({}, ev) } else { collapsedEvent = collapse(collapsedEvent, ev) } } if (collapsedEvent?.[ 'title' ]) result.push(collapsedEvent) return result }
You can modify
targetCalendar
,divideGap
,locale
andetimeStyle
for your purpose.To beautify;
/* css/custom.css */ .CX3 .event.calendar_Reservation .headline .time { display: none; } #CX3_POPOVER .title .count, .CX3 .calendar_Reservation .title .count { font-weight: bold; color: gray; } #CX3_POPOVER .title .count::before, .CX3 .calendar_Reservation .title .count::before { content: "["; } #CX3_POPOVER .title .count::after, .CX3 .calendar_Reservation .title .count::after { content: "]"; } #CX3_POPOVER .description .collapsedEvent { line-height: 115%; border-bottom: 2px solid silver; p { margin-top: 0; margin-bottom: 0; } .title { font-weight: bold; } .period { text-align: right; } .description { font-style: italic; white-space: pre; padding-left: 20px; } .location { font-style: italic; text-align: right; } }
-
@MMRIZE said in MMM-CalendarExt3:
See the green events
eventPayload
in CX3 config;/* CX3 config section in `config/config.js` */ eventPayload: (payload) => { const targetCalendar = "Reservation" const divideGap = 1000 * 60 * 60 * 1 const locale = 'en-US' const timeStyle = { timeStyle: 'short' } const condition = (ev) => { return (ev.calendarName === targetCalendar && ev.fullDayEvent === false) } const target = payload.filter(condition).sort((a, b) => a.endDate - b.endDate) const result = payload.filter(e => !condition(e)) const dateStr = (dateValue) => Intl.DateTimeFormat(locale, timeStyle).format(new Date(+dateValue)) const collapse = (template, ev) => { if (!template?.["title"]) template = { ...ev, collapseCount: 0, description: '', location: '' } template.collapseCount++ template.startDate = String(Math.min(+template.startDate, +ev.startDate)) template.endDate = String(Math.max(+template.endDate, +ev.endDate)) template.title = `${dateStr(template.startDate)} - ${dateStr(template.endDate)}` if (template.collapseCount > 1) template.title += ` <span class="count">${template.collapseCount}</span>` template.description += `<div class="collapsedEvent"> <p class="title">${ev.title}</p> <p class="period">${dateStr(ev.startDate)} - ${dateStr(ev.endDate)}</p>` if (ev.description) template.description += `<p class="description">${ev.description}</p>` if (ev.location) template.description += `<p class="location">${ev.location}</p>` template.description += '</div>' return template } const dateKey = (dateValue) => new Date(+dateValue).toLocaleDateString('en-CA') let collapsedEvent = {} for (const ev of target) { const currentKey = dateKey(ev.startDate) if (!collapsedEvent?.[ 'title' ]) { collapsedEvent = collapse(collapsedEvent, ev) continue } const collapsedKey = dateKey(collapsedEvent.startDate) if (collapsedKey !== currentKey || +ev.startDate - +collapsedEvent.endDate > divideGap) { result.push(collapsedEvent) collapsedEvent = collapse({}, ev) } else { collapsedEvent = collapse(collapsedEvent, ev) } } if (collapsedEvent?.[ 'title' ]) result.push(collapsedEvent) return result }
You can modify
targetCalendar
,divideGap
,locale
andetimeStyle
for your purpose.To beautify;
/* css/custom.css */ .CX3 .event.calendar_Reservation .headline .time { display: none; } #CX3_POPOVER .title .count, .CX3 .calendar_Reservation .title .count { font-weight: bold; color: gray; } #CX3_POPOVER .title .count::before, .CX3 .calendar_Reservation .title .count::before { content: "["; } #CX3_POPOVER .title .count::after, .CX3 .calendar_Reservation .title .count::after { content: "]"; } #CX3_POPOVER .description .collapsedEvent { line-height: 115%; border-bottom: 2px solid silver; p { margin-top: 0; margin-bottom: 0; } .title { font-weight: bold; } .period { text-align: right; } .description { font-style: italic; white-space: pre; padding-left: 20px; } .location { font-style: italic; text-align: right; } }
I had to play around with it a bit to get it just right, but you nailed it!
My calendar is a lot less cluttered now. Thank you for all your help!
-
thanks for adding maxEventLines: { row: line, row: line, … } .
But I am having trouble getting it to work.
{ module: "MMM-CalendarExt3", position: "top_right", title: "", instanceId: '1', config: { mode: 'month', carouselId: "basicCalendar", locale: 'en-ZA', header: "", //headerTitleOptions: {month: 'long' , year:'numeric'}, eventTimeOptions: {timeStyle: 'short'}, useWeather: false, //maxEventLines: 1, firstDayOfWeek: 1, displayEndTime: false, useMarquee: true, displayCW: false, showMore: true, showEnd: false, weekIndex: 0, // From which week the view starts; -1 : last week, 0: this week 2: 2 weeks later, ... //weeksInView: 5, // How many weeks will be shown from `weekIndex` fontSize: "18px", eventHight: "20px", calendarSet: ['Pieter', 'US_holiday'], maxEventLines: { 4:6, 5:5, 6:4 , 7:3}, } },
I would expect this line maxEventLines: { 4:6, 5:5, 6:4 , 7:3}, to limit the number of rows based on the number of weeks so this month has 6 week rows so the entries in the cell should be limited to 4?
I even did a test case just to see if it would only make one line by doing this
maxEventLines: { 3:1, 4:1, 5:1, 6:1 , 7:1, 8:1}, and it did not work.What am I missing.
thanks for your help.
-
-
@MMRIZE thanks for all your help.
I will update later and let you know if it worked.
-
@MMRIZE the updated fixed my issue.
thanks.