From 0a9d4f8a10304041722214eaa7702a2330036136 Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Tue, 23 Oct 2018 23:36:07 +0100 Subject: [PATCH] Calendar: implement basic recurrence support. At the moment it only shows recurrence in the calendar. You can't edit specific instances, only the whole series (the first event). You can't event edit the rrule at the moment. It's view only (mostly). While this is not much, this is already a major boost to the usability of etesync web. Fixes #15. --- src/components/Calendar.tsx | 28 +++++++++++++++++++++++++++- src/components/EventEdit.tsx | 9 +++++++++ src/pim-types.ts | 4 +++- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/components/Calendar.tsx b/src/components/Calendar.tsx index b9d4704..8e8e280 100644 --- a/src/components/Calendar.tsx +++ b/src/components/Calendar.tsx @@ -3,6 +3,7 @@ import BigCalendar, { View } from 'react-big-calendar'; import 'react-big-calendar/lib/css/react-big-calendar.css'; import * as moment from 'moment'; import 'moment/locale/en-gb'; +import * as ICAL from 'ical.js'; import { EventType } from '../pim-types'; @@ -11,6 +12,9 @@ import './Calendar.css'; moment.locale('en-gb'); const calendarLocalizer = BigCalendar.momentLocalizer(moment); +const MAX_RECURRENCE_DATE = ICAL.Time.now(); +MAX_RECURRENCE_DATE.adjust(800, 0, 0, 0); + function eventPropGetter(event: EventType) { return { style: { @@ -60,12 +64,34 @@ class Calendar extends React.PureComponent { } render() { + const entries = [] as Array; + this.props.entries.forEach((event) => { + entries.push(event); + + if (event.isRecurring()) { + const recur = event.iterator(); + + let next = recur.next(); // Skip the first one + while ((next = recur.next())) { + if (next.compare(MAX_RECURRENCE_DATE) > 0) { + break; + } + + const shift = next.subtractDateTz(event.startDate); + const ev = event.clone(); + ev.startDate.addDuration(shift); + ev.endDate.addDuration(shift); + entries.push(ev); + } + } + }); + return (

{this.props.item ? 'Edit Event' : 'New Event'}

+ {recurring && ( +
+ IMPORTANT: + This is a recurring event, for now, only editing the whole series + (by editing the first instance) is supported. +
+ )} {this.state.error && (
ERROR! {this.state.error}
)} diff --git a/src/pim-types.ts b/src/pim-types.ts index bac872a..775a612 100644 --- a/src/pim-types.ts +++ b/src/pim-types.ts @@ -43,7 +43,9 @@ export class EventType extends ICAL.Event implements PimType { } clone() { - return new EventType(new ICAL.Component(this.component.toJSON())); + const ret = new EventType(new ICAL.Component(this.component.toJSON())); + ret.color = this.color; + return ret; } }