mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-04 16:06:41 +00:00
fix: keep the edits when the recurring event question is cancelled
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
|||||||
timePattern,
|
timePattern,
|
||||||
layoutOverlappingEvents,
|
layoutOverlappingEvents,
|
||||||
CALENDAR_COLOR_PALETTE,
|
CALENDAR_COLOR_PALETTE,
|
||||||
|
reopenedEdit,
|
||||||
} from '../calendar-utils';
|
} from '../calendar-utils';
|
||||||
import type { CalendarEvent } from '../../api/types';
|
import type { CalendarEvent } from '../../api/types';
|
||||||
import { useSettingsStore } from '../../stores/settings-store';
|
import { useSettingsStore } from '../../stores/settings-store';
|
||||||
@@ -278,3 +279,18 @@ describe('layoutOverlappingEvents', () => {
|
|||||||
expect(layoutOverlappingEvents(events, day)).toHaveLength(0);
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -604,3 +604,17 @@ export function getPrimaryCalendarId(
|
|||||||
): string | undefined {
|
): string | undefined {
|
||||||
return Object.keys(event.calendarIds || {})[0];
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ import {
|
|||||||
getTaskDueDate,
|
getTaskDueDate,
|
||||||
pickUnusedCalendarColor,
|
pickUnusedCalendarColor,
|
||||||
sharedCalendarColorKey,
|
sharedCalendarColorKey,
|
||||||
|
reopenedEdit,
|
||||||
} from '../lib/calendar-utils';
|
} from '../lib/calendar-utils';
|
||||||
import { buildReplyTo } from '../lib/calendar-invitation';
|
import { buildReplyTo } from '../lib/calendar-invitation';
|
||||||
import {
|
import {
|
||||||
@@ -825,6 +826,16 @@ export default function CalendarScreen() {
|
|||||||
[modalEvent, createEvent, updateEvent],
|
[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(
|
const handleDeleteFromModal = React.useCallback(
|
||||||
async (event: CalendarEvent) => {
|
async (event: CalendarEvent) => {
|
||||||
setModalVisible(false);
|
setModalVisible(false);
|
||||||
@@ -1232,7 +1243,7 @@ export default function CalendarScreen() {
|
|||||||
visible={!!pendingAction}
|
visible={!!pendingAction}
|
||||||
actionType={pendingAction?.kind ?? 'edit'}
|
actionType={pendingAction?.kind ?? 'edit'}
|
||||||
onSelect={handleScopeSelect}
|
onSelect={handleScopeSelect}
|
||||||
onClose={() => setPendingAction(null)}
|
onClose={cancelScope}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<CalendarSidebarDrawer
|
<CalendarSidebarDrawer
|
||||||
|
|||||||
Reference in New Issue
Block a user