fix(03): WR-01 preserve existing RRULE on edit instead of resetting to none
This commit is contained in:
@@ -138,7 +138,10 @@ export interface CreateEventPayload {
|
||||
allDay: boolean
|
||||
start: string // 'YYYY-MM-DD' for allDay; ISO 8601 for timed
|
||||
end: string // same format as start
|
||||
recurrence: RecurrencePreset
|
||||
// WR-01: optional. CREATE always sends it; EDIT omits it so the API/worker preserve
|
||||
// the event's existing RRULE (the occurrence contract does not expose recurrence, so
|
||||
// the form cannot echo it back without silently resetting it to 'none').
|
||||
recurrence?: RecurrencePreset
|
||||
location?: string
|
||||
description?: string
|
||||
calendarUrl?: string // omit to use the member's default writable calendar (D-01)
|
||||
|
||||
@@ -305,12 +305,19 @@ export function EventForm() {
|
||||
endTime,
|
||||
)
|
||||
|
||||
// WR-01: on EDIT, omit `recurrence` from the payload. The occurrence/expand contract
|
||||
// does not expose the event's existing recurrence (D-03), so the form cannot know it
|
||||
// and would otherwise send 'none' — silently stripping the RRULE and converting a
|
||||
// recurring series into a single event. Omitting the field signals "unchanged"; the
|
||||
// outbox worker then preserves the stored RRULE (see outboxWorker.ts WR-01). On
|
||||
// CREATE the user explicitly chose a recurrence, so it is always sent.
|
||||
const isEdit = eventFormMode === 'edit' && !!eventFormUid
|
||||
const payload: CreateEventPayload = {
|
||||
title: title.trim(),
|
||||
allDay,
|
||||
start: serializedStart,
|
||||
end: serializedEnd,
|
||||
recurrence,
|
||||
...(isEdit ? {} : { recurrence }),
|
||||
...(location.trim() ? { location: location.trim() } : {}),
|
||||
...(description.trim() ? { description: description.trim() } : {}),
|
||||
...(writableCalendars.length > 1 && calendarUrl ? { calendarUrl } : {}),
|
||||
@@ -702,7 +709,11 @@ export function EventForm() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Recurrence picker (D-11: whole-series only) */}
|
||||
{/* Recurrence picker (D-11: whole-series only).
|
||||
WR-01: disabled in edit mode — the occurrence contract does not expose the
|
||||
event's recurrence, so the form cannot show/change it without risking a
|
||||
silent reset. Editing recurrence is deferred until the contract exposes it;
|
||||
the existing RRULE is preserved server-side on edit. */}
|
||||
<div style={fieldStyle}>
|
||||
<label htmlFor="event-recurrence" style={labelStyle}>
|
||||
Repeat
|
||||
@@ -710,8 +721,14 @@ export function EventForm() {
|
||||
<select
|
||||
id="event-recurrence"
|
||||
value={recurrence}
|
||||
disabled={eventFormMode === 'edit'}
|
||||
onChange={(e) => setRecurrence(e.target.value as RecurrencePreset)}
|
||||
style={{ ...inputStyle, padding: '0 var(--space-3)', cursor: 'pointer' }}
|
||||
style={{
|
||||
...inputStyle,
|
||||
padding: '0 var(--space-3)',
|
||||
cursor: eventFormMode === 'edit' ? 'not-allowed' : 'pointer',
|
||||
opacity: eventFormMode === 'edit' ? 0.6 : 1,
|
||||
}}
|
||||
>
|
||||
<option value="none">None</option>
|
||||
<option value="daily">Daily</option>
|
||||
|
||||
Reference in New Issue
Block a user