From 066e6bc8472dc1cbfd1c224cd6fbbfa6a5621356 Mon Sep 17 00:00:00 2001 From: David Nguyen Date: Thu, 12 Feb 2026 16:32:26 +1100 Subject: [PATCH] fix: envelope editor flush race condition (#2482) ## Description Fixes a race condition in the envelope editor when opening "Send Document" immediately after moving/resizing a selected field Replication 1. Move or resize a field (do not blur the selector/quickbar that appears when a field is selected) 2. Directly click the "Send Document" dialog 3. Error appears Note: Step 2 needs to happen relatively fast after step 1 since this is a race against the flush debouncer --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../envelope-editor-fields-page-renderer.tsx | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page-renderer.tsx b/apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page-renderer.tsx index b30026f16..2582d46e9 100644 --- a/apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page-renderer.tsx +++ b/apps/remix/app/components/general/envelope-editor/envelope-editor-fields-page-renderer.tsx @@ -434,15 +434,31 @@ export default function EnvelopeEditorFieldsPageRenderer() { renderFieldOnLayer(field); }); + // Reconcile selection state with live field nodes after flush/sync updates. + const liveSelectedFieldGroups = selectedKonvaFieldGroups.filter((fieldGroup) => { + if (!fieldGroup.getStage() || !fieldGroup.getParent()) { + return false; + } + + return localPageFields.some((field) => field.formId === fieldGroup.id()); + }); + + if (liveSelectedFieldGroups.length !== selectedKonvaFieldGroups.length) { + setSelectedFields(liveSelectedFieldGroups); + } + // Rerender the transformer interactiveTransformer.current?.forceUpdate(); pageLayer.current.batchDraw(); - }, [localPageFields]); + }, [localPageFields, selectedKonvaFieldGroups]); const setSelectedFields = (nodes: Konva.Node[]) => { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - const fieldGroups = nodes.filter((node) => node.hasName('field-group')) as Konva.Group[]; + const fieldGroups = nodes.filter( + (node) => + node.hasName('field-group') && Boolean(node.getStage()) && Boolean(node.getParent()), + ) as Konva.Group[]; interactiveTransformer.current?.nodes(fieldGroups); setSelectedKonvaFieldGroups(fieldGroups); @@ -674,6 +690,10 @@ const FieldActionButtons = ({ selectedFieldFormId.includes(field.formId), ); + if (fields.length === 0) { + return null; + } + const recipient = envelope.recipients.find( (recipient) => recipient.id === fields[0].recipientId, ); @@ -689,7 +709,7 @@ const FieldActionButtons = ({ } return null; - }, [editorFields.localFields]); + }, [editorFields.localFields, envelope.recipients, selectedFieldFormId]); return (