fix: keep the edits when the recurring event question is cancelled

This commit is contained in:
Linus Rath
2026-10-15 03:37:58 +02:00
parent de1b955bfd
commit 72b4f4abac
3 changed files with 42 additions and 1 deletions
+16
View File
@@ -13,6 +13,7 @@ import {
timePattern,
layoutOverlappingEvents,
CALENDAR_COLOR_PALETTE,
reopenedEdit,
} from '../calendar-utils';
import type { CalendarEvent } from '../../api/types';
import { useSettingsStore } from '../../stores/settings-store';
@@ -278,3 +279,18 @@ describe('layoutOverlappingEvents', () => {
expect(layoutOverlappingEvents(events, day)).toHaveLength(0);
});
});
describe('reopenedEdit', () => {
it('puts the unsaved edits over the event and drops cleared fields', () => {
const event = {
id: 'e1', title: 'Team sync', start: '2026-10-19T10:00:00', duration: 'PT30M',
locations: { l: { '@type': 'Location', name: 'Room 2' } },
} as unknown as CalendarEvent;
const reopened = reopenedEdit(event, { title: 'Team sync (moved)', start: '2026-10-19T11:00:00', locations: null });
expect(reopened.id).toBe('e1');
expect(reopened.title).toBe('Team sync (moved)');
expect(reopened.start).toBe('2026-10-19T11:00:00');
expect(reopened.duration).toBe('PT30M');
expect('locations' in reopened).toBe(false);
});
});
+14
View File
@@ -604,3 +604,17 @@ export function getPrimaryCalendarId(
): string | undefined {
return Object.keys(event.calendarIds || {})[0];
}
/**
* The event as the editor last had it: the stored event with the unsaved
* edits on top, a field cleared in the editor (sent as `null`) removed. Used
* to reopen the editor when the recurrence-scope question is cancelled.
*/
export function reopenedEdit(event: CalendarEvent, updates: Partial<CalendarEvent>): CalendarEvent {
const merged: Record<string, unknown> = { ...event };
for (const [key, value] of Object.entries(updates)) {
if (value === null) delete merged[key];
else if (value !== undefined) merged[key] = value;
}
return merged as unknown as CalendarEvent;
}
+12 -1
View File
@@ -86,6 +86,7 @@ import {
getTaskDueDate,
pickUnusedCalendarColor,
sharedCalendarColorKey,
reopenedEdit,
} from '../lib/calendar-utils';
import { buildReplyTo } from '../lib/calendar-invitation';
import {
@@ -825,6 +826,16 @@ export default function CalendarScreen() {
[modalEvent, createEvent, updateEvent],
);
// Cancelling "which occurrences?" after editing a recurring event goes back
// to the editor with the edits still in it; they used to be thrown away.
const cancelScope = React.useCallback(() => {
const pending = pendingAction;
setPendingAction(null);
if (pending?.kind !== 'edit') return;
setModalEvent(reopenedEdit(pending.event, pending.updates));
setModalVisible(true);
}, [pendingAction]);
const handleDeleteFromModal = React.useCallback(
async (event: CalendarEvent) => {
setModalVisible(false);
@@ -1232,7 +1243,7 @@ export default function CalendarScreen() {
visible={!!pendingAction}
actionType={pendingAction?.kind ?? 'edit'}
onSelect={handleScopeSelect}
onClose={() => setPendingAction(null)}
onClose={cancelScope}
/>
<CalendarSidebarDrawer