From d2666b5970674d791db679b78a5010aec94e7b53 Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Fri, 19 Nov 2021 16:45:30 +0100 Subject: [PATCH] Replace CalDAV availability component with component lib Signed-off-by: Christoph Wurst --- apps/dav/src/service/CalendarService.js | 117 ++------------------ apps/dav/src/views/Availability.vue | 140 +++++------------------- package-lock.json | 28 ++++- package.json | 3 +- webpack.modules.js | 1 + 5 files changed, 65 insertions(+), 224 deletions(-) diff --git a/apps/dav/src/service/CalendarService.js b/apps/dav/src/service/CalendarService.js index 10d3e2524653b..2b416d6b670d1 100644 --- a/apps/dav/src/service/CalendarService.js +++ b/apps/dav/src/service/CalendarService.js @@ -19,11 +19,13 @@ * along with this program. If not, see . */ import { getClient } from '../dav/client' -import ICAL from 'ical.js' import logger from './logger' import { parseXML } from 'webdav/dist/node/tools/dav' -import { getZoneString } from 'icalzone' -import { v4 as uuidv4 } from 'uuid' + +import { + slotsToVavailability, + vavailabilityToSlots, +} from '@nextcloud/calendar-availability-vue' /** * @@ -67,44 +69,7 @@ export async function findScheduleInboxAvailability() { return undefined } - const parsedIcal = ICAL.parse(availability) - - const vcalendarComp = new ICAL.Component(parsedIcal) - const vavailabilityComp = vcalendarComp.getFirstSubcomponent('vavailability') - - let timezoneId - const timezoneComp = vcalendarComp.getFirstSubcomponent('vtimezone') - if (timezoneComp) { - timezoneId = timezoneComp.getFirstProperty('tzid').getFirstValue() - } - - const availableComps = vavailabilityComp.getAllSubcomponents('available') - // Combine all AVAILABLE blocks into a week of slots - const slots = getEmptySlots() - availableComps.forEach((availableComp) => { - const start = availableComp.getFirstProperty('dtstart').getFirstValue().toJSDate() - const end = availableComp.getFirstProperty('dtend').getFirstValue().toJSDate() - const rrule = availableComp.getFirstProperty('rrule') - - if (rrule.getFirstValue().freq !== 'WEEKLY') { - logger.warn('rrule not supported', { - rrule: rrule.toICALString(), - }) - return - } - - rrule.getFirstValue().getComponent('BYDAY').forEach(day => { - slots[day].push({ - start, - end, - }) - }) - }) - - return { - slots, - timezoneId, - } + return vavailabilityToSlots(availability) } /** @@ -117,74 +82,10 @@ export async function saveScheduleInboxAvailability(slots, timezoneId) { day: dayId, })))] - const vcalendarComp = new ICAL.Component('vcalendar') - vcalendarComp.addPropertyWithValue('prodid', 'Nextcloud DAV app') - - // Store time zone info - // If possible we use the info from a time zone database - const predefinedTimezoneIcal = getZoneString(timezoneId) - if (predefinedTimezoneIcal) { - const timezoneComp = new ICAL.Component(ICAL.parse(predefinedTimezoneIcal)) - vcalendarComp.addSubcomponent(timezoneComp) - } else { - // Fall back to a simple markup - const timezoneComp = new ICAL.Component('vtimezone') - timezoneComp.addPropertyWithValue('tzid', timezoneId) - vcalendarComp.addSubcomponent(timezoneComp) - } - - // Store availability info - const vavailabilityComp = new ICAL.Component('vavailability') - - // Deduplicate by start and end time - const deduplicated = all.reduce((acc, slot) => { - const key = [ - slot.start.getHours(), - slot.start.getMinutes(), - slot.end.getHours(), - slot.end.getMinutes(), - ].join('-') - - return { - ...acc, - [key]: [...(acc[key] ?? []), slot], - } - }, {}) - - // Create an AVAILABILITY component for every recurring slot - Object.keys(deduplicated).map(key => { - const slots = deduplicated[key] - const start = slots[0].start - const end = slots[0].end - // Combine days but make them also unique - const days = slots.map(slot => slot.day).filter((day, index, self) => self.indexOf(day) === index) - - const availableComp = new ICAL.Component('available') - - // Define DTSTART and DTEND - const startTimeProp = availableComp.addPropertyWithValue('dtstart', ICAL.Time.fromJSDate(start, false)) - startTimeProp.setParameter('tzid', timezoneId) - const endTimeProp = availableComp.addPropertyWithValue('dtend', ICAL.Time.fromJSDate(end, false)) - endTimeProp.setParameter('tzid', timezoneId) - - // Add mandatory UID - availableComp.addPropertyWithValue('uid', uuidv4()) - - // TODO: add optional summary - - // Define RRULE - availableComp.addPropertyWithValue('rrule', { - freq: 'WEEKLY', - byday: days, - }) - - return availableComp - }).map(vavailabilityComp.addSubcomponent.bind(vavailabilityComp)) + const vavailability = slotsToVavailability(all, timezoneId) - vcalendarComp.addSubcomponent(vavailabilityComp) logger.debug('New availability ical created', { - asObject: vcalendarComp, - asString: vcalendarComp.toString(), + vavailability, }) const client = getClient('calendars') @@ -194,7 +95,7 @@ export async function saveScheduleInboxAvailability(slots, timezoneId) { - ${vcalendarComp.toString()} + ${vavailability} `, diff --git a/apps/dav/src/views/Availability.vue b/apps/dav/src/views/Availability.vue index 6291581004274..bba35f35b1fe1 100644 --- a/apps/dav/src/views/Availability.vue +++ b/apps/dav/src/views/Availability.vue @@ -12,45 +12,19 @@ -
- -
+