@@ -259,41 +259,44 @@ function TaskModalContent({
259259
260260 /**
261261 * Submits the draft and waits for it to persist. The `submitting` guard blocks
262- * a double-submit (Enter racing the click); on success the modal closes, on
263- * failure it stays open so the draft survives — the mutation hook surfaces the
264- * error via toast, so no message is duplicated here. `submitting` always resets
265- * in `finally`, so the button can never stick disabled if the modal is kept open.
262+ * a double-submit (Enter racing the click). The modal closes only when the save
263+ * resolves; a rejection leaves it open so the draft survives — the mutation hook
264+ * already surfaces the error via toast, so it is swallowed here rather than
265+ * duplicated. `submitting` is always cleared, so the button can never stick
266+ * disabled while the modal stays open.
266267 */
267268 const handleSubmit = async ( ) => {
268269 if ( ! promptText || isPastLaunch || submitting ) return
269270 setSubmitting ( true )
270- try {
271- await onSubmit ( {
271+ const persisted = await Promise . resolve (
272+ onSubmit ( {
272273 prompt : editor . getPlainValue ( ) . trim ( ) ,
273274 contexts : editor . contexts . length > 0 ? editor . contexts : undefined ,
274275 launchDate,
275276 launchTime,
276277 timezone,
277278 recurrence,
278279 } )
279- close ( )
280- } catch {
281- // Failure keeps the modal open; the mutation hook surfaces the error via toast.
282- } finally {
283- setSubmitting ( false )
284- }
280+ )
281+ . then ( ( ) => true )
282+ . catch ( ( ) => false )
283+ setSubmitting ( false )
284+ if ( persisted ) close ( )
285285 }
286286
287+ /**
288+ * Footer secondary actions. Delete is disabled while `submitting` because it
289+ * bypasses the dismiss guard — it closes the modal via `closeTask`, not the
290+ * guarded `onOpenChange` — so without the lock an in-flight edit and a delete
291+ * could run against the same task at once.
292+ */
287293 const secondaryActions : ChipModalFooterSlotAction [ ] = [
288294 ...( edit && onRequestDelete
289295 ? [
290296 {
291297 label : 'Delete' ,
292298 variant : 'destructive' as const ,
293299 onClick : onRequestDelete ,
294- // Locked during a save: Delete bypasses the dismiss guard (it closes the
295- // modal via closeTask, not onOpenChange), so without this an in-flight
296- // edit and a delete could run against the same task at once.
297300 disabled : submitting ,
298301 } ,
299302 ]
0 commit comments