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.master
parent
048c591b95
commit
0a9d4f8a10
|
@ -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<EventType>;
|
||||
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 (
|
||||
<div style={{width: '100%', height: 'calc(100vh - 230px)', minHeight: 500}}>
|
||||
<BigCalendar
|
||||
defaultDate={new Date()}
|
||||
localizer={calendarLocalizer}
|
||||
events={this.props.entries}
|
||||
events={entries}
|
||||
selectable={true}
|
||||
onSelectEvent={this.props.onItemClick as any}
|
||||
onSelectSlot={this.slotClicked as any}
|
||||
|
|
|
@ -205,11 +205,20 @@ class EventEdit extends React.PureComponent {
|
|||
},
|
||||
};
|
||||
|
||||
const recurring = this.props.item && this.props.item.isRecurring;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<h2>
|
||||
{this.props.item ? 'Edit Event' : 'New Event'}
|
||||
</h2>
|
||||
{recurring && (
|
||||
<div>
|
||||
<span style={{ color: 'red' }}>IMPORTANT: </span>
|
||||
This is a recurring event, for now, only editing the whole series
|
||||
(by editing the first instance) is supported.
|
||||
</div>
|
||||
)}
|
||||
{this.state.error && (
|
||||
<div>ERROR! {this.state.error}</div>
|
||||
)}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue