vaadin-fullcalendar icon indicating copy to clipboard operation
vaadin-fullcalendar copied to clipboard

Recurring event does not extend infinitely

Open JaakkoHintsala opened this issue 1 year ago • 9 comments

I created a test view for recurring events as such:

@Route(value = "ctest") public class CalendarTest extends VerticalLayout {

private static final long serialVersionUID = 7733363567261805869L;

public CalendarTest() {
	var provider = new InMemoryEntryProvider<Entry>(makeTestEntries());
	FullCalendar calendar = makeCalendar(provider);
	this.setSizeFull();
	add(calendar);
}

private List<Entry> makeTestEntries() {
	var entry1 = new Entry(UUID.randomUUID().toString());
	entry1.setGroupId(UUID.randomUUID().toString());
	entry1.setRecurringStartDate(LocalDate.of(2024, 2, 20));
	entry1.setRecurringStartTime(LocalTime.of(12, 0));
	entry1.setRecurringStartTime(LocalTime.of(13, 0));
	return Arrays.asList(entry1);
}

private FullCalendar makeCalendar(InMemoryEntryProvider<Entry> provider2) {

	var ret = FullCalendarBuilder.create().build();
	ret.setSizeFull();
	ret.setFirstDay(DayOfWeek.MONDAY);
	ret.addThemeVariants(FullCalendarVariant.LUMO);
	ret.setTimeslotsSelectable(true);
	ret.setEntryProvider(provider2);
	ret.setOption(Option.SELECT_OVERLAP, false);
	ret.setOption(Option.ALL_DAY_SLOT, false);
	ret.changeView(CalendarViewImpl.TIME_GRID_WEEK);

	// https://www.oracle.com/java/technologies/javase/jdk11-suported-locales.html
	ret.setLocale(Locale.forLanguageTag("fi-FI"));

	return ret;
}

}

When I open this view the recurrence seems to be working fine kuva

but if I drag the event one day backwards the recurrence seems to stop kuva

flow Fullcalendar version: 6.2.1

JaakkoHintsala avatar Feb 20 '24 14:02 JaakkoHintsala

This bug is also in vanilla FullCalendar. I made an issue about this in their repo. https://github.com/fullcalendar/fullcalendar/issues/7603

JaakkoHintsala avatar Feb 20 '24 14:02 JaakkoHintsala

From your code I would assume, that this is a pure FC lib issue and nothing that I can change. I'd say a workaround is to set a dummy date somewhere in the future, e.g. in the year 9999, which then always can be checked against at to see if it is an entry with an infinite date.,

stefanuebe avatar Feb 21 '24 06:02 stefanuebe

Small update: I got it working correctly, when calling this code inside the entry dropped event listener

if (entry.isRecurring()) {
    event.applyChangesOnEntry();
    entry.setRecurringStartDate(entry.getStartAsLocalDate()); // apply changes on entry does not update the recurring date
   
    getCalendar().getEntryProvider().refreshItem(entry);
}

stefanuebe avatar Feb 21 '24 09:02 stefanuebe

But the above example is just very rudimentary and does not take into account, that one of "middle" entries might be moved. In Google Calendar for instance, when moving some recurring event, it does not automatically affect all other auto generated items but allow to customize the recurrence somehow.

Therefore there might be some more complex logic necessary, like

  • delete the current recurring definition
  • create a new recurring definition up to the latest unedited entry before the current moved event
  • create a new entry without any recurrence at the dropped point
  • create a new recurring entry starting after the dropped entry with the first unedited entry
  • keep the connection between all these entries alive so that modifying one of them still may affect all others

This of course has to be reflected somehow in your backing model.

stefanuebe avatar Feb 21 '24 09:02 stefanuebe

  • delete the current recurring definition

  • create a new recurring definition up to the latest unedited entry before the current moved event

  • create a new entry without any recurrence at the dropped point

  • create a new recurring entry starting after the dropped entry with the first unedited entry

  • keep the connection between all these entries alive so that modifying one of them still may affect all others

That's pretty much the functionality I need for my use case. Although I think it might be less convoluted to have dragging move the entire recurring event by default and splicing the recurring event as you described would require more input from the user.

JaakkoHintsala avatar Feb 21 '24 23:02 JaakkoHintsala

@stefanuebe This might be a bit off-topic, but do you have any ideas on how to find out from which part of the recurring event the user started dragging? It seems the only data there is, is the original entry and where the dragging stopped.

JaakkoHintsala avatar Feb 22 '24 11:02 JaakkoHintsala

I made a feature request for that https://github.com/fullcalendar/fullcalendar/issues/7607

JaakkoHintsala avatar Feb 22 '24 13:02 JaakkoHintsala

It is indeed the original entry, as for the model there is just one entry.

On the client side, the event info (the listener parameter) also contains the "oldEvent", which contains the source time. This can be added to the event listener information for the server side.

As a workaround however, you also get the delta of the drop so based on the delta plus the drop time you can calculate the original date.

stefanuebe avatar Feb 23 '24 05:02 stefanuebe

As a workaround however, you also get the delta of the drop so based on the delta plus the drop time you can calculate the original date.

Ah, I see, thanks for the clarification.

I was doing some testing on recurring event dnd and when I dropped an event, the start and end values were simply set to be the drop location value, no matter where the drag started. So I thought Delta would be the difference between those values.

JaakkoHintsala avatar Feb 23 '24 08:02 JaakkoHintsala