fix(scheduling): harden edit/reschedule after review
Address findings from 3 review agents on the edit/reschedule feature: - Race (correctness): handleEdit now marks the old message as cancelling while its cancel is in flight, so its Edit/Cancel buttons are disabled. Previously the old row stayed live during the fire-and-forget cancel, so a fast second edit could orphan a still-scheduled event and send twice. - Durability (correctness): on a failed cancel-old, re-insert the old message if auto-prune removed its row while the modal was open, so the still-live delayed event stays visible and retriable instead of failing silently. Also clear any stale cancel error when starting an edit. - a11y: per-row Edit/Cancel buttons now carry distinct aria-labels that include the message preview and send-time, so screen-reader users can tell which of several scheduled messages each button targets. - UX: modal gains a submitLabel prop; the edit flow shows "Reschedule" instead of "Schedule". Modal now focuses the message body on open. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -30,6 +30,8 @@ interface ScheduleMessageModalProps {
|
||||
initialSendAt?: number;
|
||||
/** Header title; defaults to "Schedule Message". */
|
||||
title?: string;
|
||||
/** Primary-button label; defaults to "Schedule" (e.g. "Reschedule" when editing). */
|
||||
submitLabel?: string;
|
||||
onScheduled: (delayId: string, sendAt: number, content: IContent) => void;
|
||||
onClose: () => void;
|
||||
}
|
||||
@@ -94,6 +96,7 @@ export function ScheduleMessageModal({
|
||||
initialBody,
|
||||
initialSendAt,
|
||||
title = 'Schedule Message',
|
||||
submitLabel = 'Schedule',
|
||||
onScheduled,
|
||||
onClose,
|
||||
}: ScheduleMessageModalProps) {
|
||||
@@ -179,7 +182,7 @@ export function ScheduleMessageModal({
|
||||
<OverlayCenter>
|
||||
<FocusTrap
|
||||
focusTrapOptions={{
|
||||
initialFocus: false,
|
||||
initialFocus: '#schedule-message-body',
|
||||
onDeactivate: onClose,
|
||||
clickOutsideDeactivates: true,
|
||||
escapeDeactivates: stopPropagation,
|
||||
@@ -341,7 +344,7 @@ export function ScheduleMessageModal({
|
||||
disabled={submitting || !preview}
|
||||
before={submitting ? <Spinner variant="Primary" size="100" /> : undefined}
|
||||
>
|
||||
<Text size="B400">Schedule</Text>
|
||||
<Text size="B400">{submitLabel}</Text>
|
||||
</Button>
|
||||
</Box>
|
||||
</Dialog>
|
||||
|
||||
Reference in New Issue
Block a user