@nyaruka/temba-components 0.139.0 → 0.141.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (385) hide show
  1. package/.github/workflows/cla.yml +1 -1
  2. package/.github/workflows/copilot-setup-steps.yml +6 -1
  3. package/.lintstagedrc.js +10 -0
  4. package/CHANGELOG.md +32 -0
  5. package/demo/data/flows/sample-flow.json +24 -0
  6. package/dist/locales/es.js +5 -5
  7. package/dist/locales/es.js.map +1 -1
  8. package/dist/locales/fr.js +5 -5
  9. package/dist/locales/fr.js.map +1 -1
  10. package/dist/locales/locale-codes.js +11 -2
  11. package/dist/locales/locale-codes.js.map +1 -1
  12. package/dist/locales/pt.js +5 -5
  13. package/dist/locales/pt.js.map +1 -1
  14. package/dist/temba-components.js +702 -338
  15. package/dist/temba-components.js.map +1 -1
  16. package/out-tsc/src/display/Chat.js +10 -7
  17. package/out-tsc/src/display/Chat.js.map +1 -1
  18. package/out-tsc/src/display/Dropdown.js +3 -1
  19. package/out-tsc/src/display/Dropdown.js.map +1 -1
  20. package/out-tsc/src/display/FloatingTab.js +4 -4
  21. package/out-tsc/src/display/FloatingTab.js.map +1 -1
  22. package/out-tsc/src/display/Thumbnail.js +163 -5
  23. package/out-tsc/src/display/Thumbnail.js.map +1 -1
  24. package/out-tsc/src/flow/CanvasNode.js +65 -23
  25. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  26. package/out-tsc/src/flow/Editor.js +369 -49
  27. package/out-tsc/src/flow/Editor.js.map +1 -1
  28. package/out-tsc/src/flow/NodeEditor.js +118 -10
  29. package/out-tsc/src/flow/NodeEditor.js.map +1 -1
  30. package/out-tsc/src/flow/Plumber.js +61 -14
  31. package/out-tsc/src/flow/Plumber.js.map +1 -1
  32. package/out-tsc/src/flow/StickyNote.js +13 -4
  33. package/out-tsc/src/flow/StickyNote.js.map +1 -1
  34. package/out-tsc/src/flow/actions/add_contact_groups.js +4 -1
  35. package/out-tsc/src/flow/actions/add_contact_groups.js.map +1 -1
  36. package/out-tsc/src/flow/actions/add_input_labels.js +4 -1
  37. package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -1
  38. package/out-tsc/src/flow/actions/audio-player.js +112 -0
  39. package/out-tsc/src/flow/actions/audio-player.js.map +1 -0
  40. package/out-tsc/src/flow/actions/enter_flow.js +43 -0
  41. package/out-tsc/src/flow/actions/enter_flow.js.map +1 -0
  42. package/out-tsc/src/flow/actions/play_audio.js +57 -4
  43. package/out-tsc/src/flow/actions/play_audio.js.map +1 -1
  44. package/out-tsc/src/flow/actions/remove_contact_groups.js +6 -1
  45. package/out-tsc/src/flow/actions/remove_contact_groups.js.map +1 -1
  46. package/out-tsc/src/flow/actions/say_msg.js +86 -3
  47. package/out-tsc/src/flow/actions/say_msg.js.map +1 -1
  48. package/out-tsc/src/flow/actions/send_broadcast.js +6 -2
  49. package/out-tsc/src/flow/actions/send_broadcast.js.map +1 -1
  50. package/out-tsc/src/flow/actions/set_contact_channel.js +13 -0
  51. package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -1
  52. package/out-tsc/src/flow/actions/set_contact_status.js +7 -5
  53. package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -1
  54. package/out-tsc/src/flow/actions/start_session.js +10 -3
  55. package/out-tsc/src/flow/actions/start_session.js.map +1 -1
  56. package/out-tsc/src/flow/config.js +11 -3
  57. package/out-tsc/src/flow/config.js.map +1 -1
  58. package/out-tsc/src/flow/nodes/shared-rules.js +1 -1
  59. package/out-tsc/src/flow/nodes/shared-rules.js.map +1 -1
  60. package/out-tsc/src/flow/nodes/split_by_contact_field.js +18 -5
  61. package/out-tsc/src/flow/nodes/split_by_contact_field.js.map +1 -1
  62. package/out-tsc/src/flow/nodes/split_by_expression.js +1 -1
  63. package/out-tsc/src/flow/nodes/split_by_expression.js.map +1 -1
  64. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +0 -1
  65. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -1
  66. package/out-tsc/src/flow/nodes/split_by_random.js +0 -1
  67. package/out-tsc/src/flow/nodes/split_by_random.js.map +1 -1
  68. package/out-tsc/src/flow/nodes/split_by_run_result.js +10 -4
  69. package/out-tsc/src/flow/nodes/split_by_run_result.js.map +1 -1
  70. package/out-tsc/src/flow/nodes/terminal.js +7 -0
  71. package/out-tsc/src/flow/nodes/terminal.js.map +1 -0
  72. package/out-tsc/src/flow/nodes/wait_for_audio.js +77 -0
  73. package/out-tsc/src/flow/nodes/wait_for_audio.js.map +1 -0
  74. package/out-tsc/src/flow/nodes/wait_for_dial.js +151 -0
  75. package/out-tsc/src/flow/nodes/wait_for_dial.js.map +1 -0
  76. package/out-tsc/src/flow/nodes/wait_for_digits.js +61 -1
  77. package/out-tsc/src/flow/nodes/wait_for_digits.js.map +1 -1
  78. package/out-tsc/src/flow/nodes/wait_for_menu.js +173 -2
  79. package/out-tsc/src/flow/nodes/wait_for_menu.js.map +1 -1
  80. package/out-tsc/src/flow/nodes/wait_for_response.js +1 -1
  81. package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
  82. package/out-tsc/src/flow/operators.js +21 -5
  83. package/out-tsc/src/flow/operators.js.map +1 -1
  84. package/out-tsc/src/flow/types.js.map +1 -1
  85. package/out-tsc/src/flow/utils.js +79 -3
  86. package/out-tsc/src/flow/utils.js.map +1 -1
  87. package/out-tsc/src/form/ArrayEditor.js +4 -2
  88. package/out-tsc/src/form/ArrayEditor.js.map +1 -1
  89. package/out-tsc/src/form/FieldRenderer.js +56 -0
  90. package/out-tsc/src/form/FieldRenderer.js.map +1 -1
  91. package/out-tsc/src/interfaces.js +1 -0
  92. package/out-tsc/src/interfaces.js.map +1 -1
  93. package/out-tsc/src/layout/Dialog.js +51 -7
  94. package/out-tsc/src/layout/Dialog.js.map +1 -1
  95. package/out-tsc/src/layout/Modax.js +20 -2
  96. package/out-tsc/src/layout/Modax.js.map +1 -1
  97. package/out-tsc/src/list/ContentMenu.js +14 -1
  98. package/out-tsc/src/list/ContentMenu.js.map +1 -1
  99. package/out-tsc/src/locales/es.js +5 -5
  100. package/out-tsc/src/locales/es.js.map +1 -1
  101. package/out-tsc/src/locales/fr.js +5 -5
  102. package/out-tsc/src/locales/fr.js.map +1 -1
  103. package/out-tsc/src/locales/locale-codes.js +11 -2
  104. package/out-tsc/src/locales/locale-codes.js.map +1 -1
  105. package/out-tsc/src/locales/pt.js +5 -5
  106. package/out-tsc/src/locales/pt.js.map +1 -1
  107. package/out-tsc/src/simulator/Simulator.js +21 -4
  108. package/out-tsc/src/simulator/Simulator.js.map +1 -1
  109. package/out-tsc/src/store/AppState.js +102 -3
  110. package/out-tsc/src/store/AppState.js.map +1 -1
  111. package/out-tsc/test/actions/add_contact_groups.test.js +35 -0
  112. package/out-tsc/test/actions/add_contact_groups.test.js.map +1 -1
  113. package/out-tsc/test/actions/add_input_labels.test.js +53 -0
  114. package/out-tsc/test/actions/add_input_labels.test.js.map +1 -0
  115. package/out-tsc/test/actions/enter_flow.test.js +71 -0
  116. package/out-tsc/test/actions/enter_flow.test.js.map +1 -0
  117. package/out-tsc/test/actions/play_audio.test.js +118 -0
  118. package/out-tsc/test/actions/play_audio.test.js.map +1 -0
  119. package/out-tsc/test/actions/remove_contact_groups.test.js +24 -0
  120. package/out-tsc/test/actions/remove_contact_groups.test.js.map +1 -1
  121. package/out-tsc/test/actions/say_msg.test.js +158 -0
  122. package/out-tsc/test/actions/say_msg.test.js.map +1 -0
  123. package/out-tsc/test/actions/send_broadcast.test.js +41 -0
  124. package/out-tsc/test/actions/send_broadcast.test.js.map +1 -1
  125. package/out-tsc/test/actions/set_contact_channel.test.js +67 -0
  126. package/out-tsc/test/actions/set_contact_channel.test.js.map +1 -0
  127. package/out-tsc/test/actions/set_contact_field.test.js +52 -0
  128. package/out-tsc/test/actions/set_contact_field.test.js.map +1 -0
  129. package/out-tsc/test/actions/set_contact_language.test.js +39 -0
  130. package/out-tsc/test/actions/set_contact_language.test.js.map +1 -0
  131. package/out-tsc/test/actions/set_contact_name.test.js +28 -0
  132. package/out-tsc/test/actions/set_contact_name.test.js.map +1 -0
  133. package/out-tsc/test/actions/set_contact_status.test.js +44 -0
  134. package/out-tsc/test/actions/set_contact_status.test.js.map +1 -0
  135. package/out-tsc/test/actions/set_run_result.test.js +47 -0
  136. package/out-tsc/test/actions/set_run_result.test.js.map +1 -0
  137. package/out-tsc/test/actions/start_session.test.js +76 -0
  138. package/out-tsc/test/actions/start_session.test.js.map +1 -1
  139. package/out-tsc/test/nodes/split_by_contact_field.test.js +50 -0
  140. package/out-tsc/test/nodes/split_by_contact_field.test.js.map +1 -1
  141. package/out-tsc/test/nodes/split_by_run_result.test.js +82 -0
  142. package/out-tsc/test/nodes/split_by_run_result.test.js.map +1 -1
  143. package/out-tsc/test/nodes/split_by_ticket.test.js +139 -0
  144. package/out-tsc/test/nodes/split_by_ticket.test.js.map +1 -0
  145. package/out-tsc/test/nodes/split_by_webhook.test.js +111 -0
  146. package/out-tsc/test/nodes/split_by_webhook.test.js.map +1 -0
  147. package/out-tsc/test/nodes/wait_for_audio.test.js +156 -0
  148. package/out-tsc/test/nodes/wait_for_audio.test.js.map +1 -0
  149. package/out-tsc/test/nodes/wait_for_dial.test.js +336 -0
  150. package/out-tsc/test/nodes/wait_for_dial.test.js.map +1 -0
  151. package/out-tsc/test/nodes/wait_for_digits.test.js +198 -84
  152. package/out-tsc/test/nodes/wait_for_digits.test.js.map +1 -1
  153. package/out-tsc/test/nodes/wait_for_menu.test.js +340 -0
  154. package/out-tsc/test/nodes/wait_for_menu.test.js.map +1 -0
  155. package/out-tsc/test/temba-flow-collision.test.js +261 -6
  156. package/out-tsc/test/temba-flow-collision.test.js.map +1 -1
  157. package/out-tsc/test/temba-flow-editor.test.js +187 -0
  158. package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
  159. package/out-tsc/test/temba-flow-plumber.test.js +19 -0
  160. package/out-tsc/test/temba-flow-plumber.test.js.map +1 -1
  161. package/out-tsc/test/temba-node-type-selector.test.js +6 -6
  162. package/out-tsc/test/temba-node-type-selector.test.js.map +1 -1
  163. package/out-tsc/test/temba-select.test.js +4 -1
  164. package/out-tsc/test/temba-select.test.js.map +1 -1
  165. package/out-tsc/test/utils.test.js +4 -2
  166. package/out-tsc/test/utils.test.js.map +1 -1
  167. package/package.json +3 -9
  168. package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
  169. package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
  170. package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
  171. package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
  172. package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
  173. package/screenshots/truth/actions/add_contact_urn/render/expression-facebook.png +0 -0
  174. package/screenshots/truth/actions/add_contact_urn/render/expression-phone.png +0 -0
  175. package/screenshots/truth/actions/add_contact_urn/render/facebook-id.png +0 -0
  176. package/screenshots/truth/actions/add_contact_urn/render/instagram-handle.png +0 -0
  177. package/screenshots/truth/actions/add_contact_urn/render/line-id.png +0 -0
  178. package/screenshots/truth/actions/add_contact_urn/render/phone-number.png +0 -0
  179. package/screenshots/truth/actions/add_contact_urn/render/telegram-id.png +0 -0
  180. package/screenshots/truth/actions/add_contact_urn/render/viber-id.png +0 -0
  181. package/screenshots/truth/actions/add_contact_urn/render/wechat-id.png +0 -0
  182. package/screenshots/truth/actions/add_contact_urn/render/whatsapp.png +0 -0
  183. package/screenshots/truth/actions/add_input_labels/editor/multiple-labels.png +0 -0
  184. package/screenshots/truth/actions/add_input_labels/editor/single-label.png +0 -0
  185. package/screenshots/truth/actions/add_input_labels/render/multiple-labels.png +0 -0
  186. package/screenshots/truth/actions/add_input_labels/render/single-label.png +0 -0
  187. package/screenshots/truth/actions/enter_flow/editor/basic-flow.png +0 -0
  188. package/screenshots/truth/actions/enter_flow/editor/long-flow-name.png +0 -0
  189. package/screenshots/truth/actions/enter_flow/render/basic-flow.png +0 -0
  190. package/screenshots/truth/actions/enter_flow/render/long-flow-name.png +0 -0
  191. package/screenshots/truth/actions/play_audio/editor/expression-url.png +0 -0
  192. package/screenshots/truth/actions/play_audio/editor/static-url.png +0 -0
  193. package/screenshots/truth/actions/play_audio/render/expression-url.png +0 -0
  194. package/screenshots/truth/actions/play_audio/render/static-url.png +0 -0
  195. package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
  196. package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
  197. package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
  198. package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
  199. package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
  200. package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
  201. package/screenshots/truth/actions/say_msg/editor/multiline-text.png +0 -0
  202. package/screenshots/truth/actions/say_msg/editor/simple-text.png +0 -0
  203. package/screenshots/truth/actions/say_msg/editor/text-with-audio-url.png +0 -0
  204. package/screenshots/truth/actions/say_msg/render/multiline-text.png +0 -0
  205. package/screenshots/truth/actions/say_msg/render/simple-text.png +0 -0
  206. package/screenshots/truth/actions/say_msg/render/text-with-audio-url.png +0 -0
  207. package/screenshots/truth/actions/send_broadcast/render/contacts-only.png +0 -0
  208. package/screenshots/truth/actions/send_broadcast/render/groups-and-contacts.png +0 -0
  209. package/screenshots/truth/actions/send_broadcast/render/groups-only.png +0 -0
  210. package/screenshots/truth/actions/send_broadcast/render/many-groups.png +0 -0
  211. package/screenshots/truth/actions/send_broadcast/render/multiline-text.png +0 -0
  212. package/screenshots/truth/actions/send_email/render/complex-business-email.png +0 -0
  213. package/screenshots/truth/actions/send_email/render/empty-body.png +0 -0
  214. package/screenshots/truth/actions/send_email/render/empty-subject.png +0 -0
  215. package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
  216. package/screenshots/truth/actions/send_email/render/multiline-body.png +0 -0
  217. package/screenshots/truth/actions/send_email/render/multiple-recipients.png +0 -0
  218. package/screenshots/truth/actions/send_email/render/simple-email.png +0 -0
  219. package/screenshots/truth/actions/send_email/render/with-expressions.png +0 -0
  220. package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
  221. package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
  222. package/screenshots/truth/actions/send_msg/render/simple-text.png +0 -0
  223. package/screenshots/truth/actions/send_msg/render/text-with-linebreaks.png +0 -0
  224. package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
  225. package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
  226. package/screenshots/truth/actions/send_msg/render/text-without-quick-replies.png +0 -0
  227. package/screenshots/truth/actions/set_contact_channel/editor/sms-channel.png +0 -0
  228. package/screenshots/truth/actions/set_contact_channel/editor/whatsapp-channel.png +0 -0
  229. package/screenshots/truth/actions/set_contact_channel/render/sms-channel.png +0 -0
  230. package/screenshots/truth/actions/set_contact_channel/render/whatsapp-channel.png +0 -0
  231. package/screenshots/truth/actions/set_contact_field/editor/clear-value.png +0 -0
  232. package/screenshots/truth/actions/set_contact_field/editor/set-value.png +0 -0
  233. package/screenshots/truth/actions/set_contact_field/render/clear-value.png +0 -0
  234. package/screenshots/truth/actions/set_contact_field/render/set-value.png +0 -0
  235. package/screenshots/truth/actions/set_contact_language/editor/english.png +0 -0
  236. package/screenshots/truth/actions/set_contact_language/editor/french.png +0 -0
  237. package/screenshots/truth/actions/set_contact_language/render/english.png +0 -0
  238. package/screenshots/truth/actions/set_contact_language/render/french.png +0 -0
  239. package/screenshots/truth/actions/set_contact_name/editor/expression-name.png +0 -0
  240. package/screenshots/truth/actions/set_contact_name/editor/static-name.png +0 -0
  241. package/screenshots/truth/actions/set_contact_name/render/expression-name.png +0 -0
  242. package/screenshots/truth/actions/set_contact_name/render/static-name.png +0 -0
  243. package/screenshots/truth/actions/set_contact_status/editor/active.png +0 -0
  244. package/screenshots/truth/actions/set_contact_status/editor/archived.png +0 -0
  245. package/screenshots/truth/actions/set_contact_status/editor/blocked.png +0 -0
  246. package/screenshots/truth/actions/set_contact_status/render/active.png +0 -0
  247. package/screenshots/truth/actions/set_contact_status/render/archived.png +0 -0
  248. package/screenshots/truth/actions/set_contact_status/render/blocked.png +0 -0
  249. package/screenshots/truth/actions/set_run_result/editor/expression-value.png +0 -0
  250. package/screenshots/truth/actions/set_run_result/editor/with-category.png +0 -0
  251. package/screenshots/truth/actions/set_run_result/render/expression-value.png +0 -0
  252. package/screenshots/truth/actions/set_run_result/render/with-category.png +0 -0
  253. package/screenshots/truth/actions/start_session/render/contact-query.png +0 -0
  254. package/screenshots/truth/actions/start_session/render/contacts-only.png +0 -0
  255. package/screenshots/truth/actions/start_session/render/create-contact.png +0 -0
  256. package/screenshots/truth/actions/start_session/render/groups-and-contacts.png +0 -0
  257. package/screenshots/truth/actions/start_session/render/groups-only.png +0 -0
  258. package/screenshots/truth/actions/start_session/render/many-recipients.png +0 -0
  259. package/screenshots/truth/editor/router.png +0 -0
  260. package/screenshots/truth/editor/wait.png +0 -0
  261. package/screenshots/truth/nodes/split_by_llm/render/information-extraction.png +0 -0
  262. package/screenshots/truth/nodes/split_by_llm/render/sentiment-analysis.png +0 -0
  263. package/screenshots/truth/nodes/split_by_llm/render/summarization.png +0 -0
  264. package/screenshots/truth/nodes/split_by_llm/render/translation-task.png +0 -0
  265. package/screenshots/truth/nodes/split_by_llm_categorize/editor/basic-categorization.png +0 -0
  266. package/screenshots/truth/nodes/split_by_llm_categorize/editor/custom-input-and-result-name.png +0 -0
  267. package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
  268. package/screenshots/truth/nodes/split_by_llm_categorize/editor/many-categories.png +0 -0
  269. package/screenshots/truth/nodes/split_by_llm_categorize/editor/minimal-categories.png +0 -0
  270. package/screenshots/truth/nodes/split_by_llm_categorize/render/basic-categorization.png +0 -0
  271. package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
  272. package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
  273. package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
  274. package/screenshots/truth/nodes/split_by_llm_categorize/render/minimal-categories.png +0 -0
  275. package/screenshots/truth/nodes/split_by_random/editor/ab-test-multiple-variants.png +0 -0
  276. package/screenshots/truth/nodes/split_by_random/editor/sampling-split.png +0 -0
  277. package/screenshots/truth/nodes/split_by_random/editor/three-way-split.png +0 -0
  278. package/screenshots/truth/nodes/split_by_random/editor/two-bucket-split.png +0 -0
  279. package/screenshots/truth/nodes/split_by_random/render/ab-test-multiple-variants.png +0 -0
  280. package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
  281. package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
  282. package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.png +0 -0
  283. package/screenshots/truth/nodes/wait_for_audio/editor/basic-audio-wait.png +0 -0
  284. package/screenshots/truth/nodes/wait_for_audio/render/basic-audio-wait.png +0 -0
  285. package/screenshots/truth/nodes/wait_for_dial/editor/basic-dial.png +0 -0
  286. package/screenshots/truth/nodes/wait_for_dial/editor/dial-with-limits.png +0 -0
  287. package/screenshots/truth/nodes/wait_for_dial/render/basic-dial.png +0 -0
  288. package/screenshots/truth/nodes/wait_for_dial/render/dial-with-limits.png +0 -0
  289. package/screenshots/truth/nodes/wait_for_digits/editor/basic-digits-wait.png +0 -0
  290. package/screenshots/truth/nodes/wait_for_digits/editor/digits-with-rules.png +0 -0
  291. package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
  292. package/screenshots/truth/nodes/wait_for_digits/render/digits-with-rules.png +0 -0
  293. package/screenshots/truth/nodes/wait_for_menu/editor/menu-with-digits.png +0 -0
  294. package/screenshots/truth/nodes/wait_for_menu/render/menu-with-digits.png +0 -0
  295. package/screenshots/truth/nodes/wait_for_response/editor/basic-wait.png +0 -0
  296. package/screenshots/truth/nodes/wait_for_response/editor/custom-result-name.png +0 -0
  297. package/screenshots/truth/nodes/wait_for_response/editor/no-timeout.png +0 -0
  298. package/screenshots/truth/nodes/wait_for_response/editor/short-timeout.png +0 -0
  299. package/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
  300. package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
  301. package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
  302. package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
  303. package/src/display/Chat.ts +13 -7
  304. package/src/display/Dropdown.ts +3 -1
  305. package/src/display/FloatingTab.ts +4 -4
  306. package/src/display/Thumbnail.ts +162 -2
  307. package/src/flow/CanvasNode.ts +70 -24
  308. package/src/flow/Editor.ts +440 -99
  309. package/src/flow/NodeEditor.ts +137 -9
  310. package/src/flow/Plumber.ts +89 -14
  311. package/src/flow/StickyNote.ts +14 -4
  312. package/src/flow/actions/add_contact_groups.ts +4 -1
  313. package/src/flow/actions/add_input_labels.ts +4 -1
  314. package/src/flow/actions/audio-player.ts +127 -0
  315. package/src/flow/actions/enter_flow.ts +44 -0
  316. package/src/flow/actions/play_audio.ts +64 -5
  317. package/src/flow/actions/remove_contact_groups.ts +6 -1
  318. package/src/flow/actions/say_msg.ts +94 -4
  319. package/src/flow/actions/send_broadcast.ts +6 -2
  320. package/src/flow/actions/set_contact_channel.ts +13 -1
  321. package/src/flow/actions/set_contact_status.ts +7 -5
  322. package/src/flow/actions/start_session.ts +10 -3
  323. package/src/flow/config.ts +11 -3
  324. package/src/flow/nodes/shared-rules.ts +1 -1
  325. package/src/flow/nodes/split_by_contact_field.ts +16 -5
  326. package/src/flow/nodes/split_by_expression.ts +1 -1
  327. package/src/flow/nodes/split_by_llm_categorize.ts +0 -1
  328. package/src/flow/nodes/split_by_random.ts +0 -1
  329. package/src/flow/nodes/split_by_run_result.ts +10 -4
  330. package/src/flow/nodes/terminal.ts +9 -0
  331. package/src/flow/nodes/wait_for_audio.ts +88 -0
  332. package/src/flow/nodes/wait_for_dial.ts +176 -0
  333. package/src/flow/nodes/wait_for_digits.ts +87 -2
  334. package/src/flow/nodes/wait_for_menu.ts +209 -3
  335. package/src/flow/nodes/wait_for_response.ts +1 -1
  336. package/src/flow/operators.ts +23 -5
  337. package/src/flow/types.ts +23 -1
  338. package/src/flow/utils.ts +82 -3
  339. package/src/form/ArrayEditor.ts +4 -2
  340. package/src/form/FieldRenderer.ts +71 -1
  341. package/src/interfaces.ts +2 -1
  342. package/src/layout/Dialog.ts +52 -7
  343. package/src/layout/Modax.ts +19 -2
  344. package/src/list/ContentMenu.ts +15 -1
  345. package/src/locales/es.ts +18 -13
  346. package/src/locales/fr.ts +18 -13
  347. package/src/locales/locale-codes.ts +11 -2
  348. package/src/locales/pt.ts +18 -13
  349. package/src/simulator/Simulator.ts +25 -4
  350. package/src/store/AppState.ts +120 -1
  351. package/src/store/flow-definition.d.ts +2 -0
  352. package/test/actions/add_contact_groups.test.ts +38 -0
  353. package/test/actions/add_input_labels.test.ts +67 -0
  354. package/test/actions/enter_flow.test.ts +88 -0
  355. package/test/actions/play_audio.test.ts +155 -0
  356. package/test/actions/remove_contact_groups.test.ts +29 -0
  357. package/test/actions/say_msg.test.ts +196 -0
  358. package/test/actions/send_broadcast.test.ts +44 -0
  359. package/test/actions/set_contact_channel.test.ts +88 -0
  360. package/test/actions/set_contact_field.test.ts +68 -0
  361. package/test/actions/set_contact_language.test.ts +55 -0
  362. package/test/actions/set_contact_name.test.ts +39 -0
  363. package/test/actions/set_contact_status.test.ts +64 -0
  364. package/test/actions/set_run_result.test.ts +61 -0
  365. package/test/actions/start_session.test.ts +82 -0
  366. package/test/nodes/split_by_contact_field.test.ts +59 -0
  367. package/test/nodes/split_by_run_result.test.ts +100 -0
  368. package/test/nodes/split_by_ticket.test.ts +157 -0
  369. package/test/nodes/split_by_webhook.test.ts +131 -0
  370. package/test/nodes/wait_for_audio.test.ts +182 -0
  371. package/test/nodes/wait_for_dial.test.ts +382 -0
  372. package/test/nodes/wait_for_digits.test.ts +233 -109
  373. package/test/nodes/wait_for_menu.test.ts +383 -0
  374. package/test/temba-flow-collision.test.ts +286 -6
  375. package/test/temba-flow-editor.test.ts +240 -0
  376. package/test/temba-flow-plumber.test.ts +62 -0
  377. package/test/temba-node-type-selector.test.ts +6 -6
  378. package/test/temba-select.test.ts +6 -1
  379. package/test/utils.test.ts +4 -2
  380. package/screenshots/truth/nodes/wait_for_digits/editor/phone-number-collection.png +0 -0
  381. package/screenshots/truth/nodes/wait_for_digits/editor/single-digit-with-timeout.png +0 -0
  382. package/screenshots/truth/nodes/wait_for_digits/editor/verification-code.png +0 -0
  383. package/screenshots/truth/nodes/wait_for_digits/render/phone-number-collection.png +0 -0
  384. package/screenshots/truth/nodes/wait_for_digits/render/single-digit-with-timeout.png +0 -0
  385. package/screenshots/truth/nodes/wait_for_digits/render/verification-code.png +0 -0
@@ -8,7 +8,7 @@ export const EXIT_STUB = 30;
8
8
  * Routes with right-angle segments, stubs at each end, and rounded corners.
9
9
  * Supports entering the target from top, left, or right faces.
10
10
  */
11
- export function calculateFlowchartPath(sourceX, sourceY, targetX, targetY, stubStart = 20, stubEnd = 10, cornerRadius = 5, targetFace = 'top') {
11
+ export function calculateFlowchartPath(sourceX, sourceY, targetX, targetY, stubStart = 20, stubEnd = 10, cornerRadius = 5, targetFace = 'top', jogYOffset = 0) {
12
12
  const r = cornerRadius;
13
13
  if (targetFace === 'top') {
14
14
  // Target is below (or we treat it as such): exit down, horizontal jog, enter from top
@@ -24,7 +24,8 @@ export function calculateFlowchartPath(sourceX, sourceY, targetX, targetY, stubS
24
24
  // jogY is the horizontal level — must be above entryY so the
25
25
  // final approach into the node is always downward (no backtracking).
26
26
  const dirX = targetX > sourceX ? 1 : -1;
27
- const jogY = Math.max(sourceY + r, Math.min(exitY, entryY - r));
27
+ const baseJogY = Math.max(sourceY + r, Math.min(exitY, entryY - r));
28
+ const jogY = Math.max(sourceY + r, Math.min(baseJogY + jogYOffset, entryY - r - 3));
28
29
  // Corner 1: vertical→horizontal at jogY
29
30
  const r1 = Math.min(r, jogY - sourceY);
30
31
  if (r1 >= 1) {
@@ -230,11 +231,17 @@ export class Plumber {
230
231
  }
231
232
  });
232
233
  this.pendingConnections = [];
233
- // Repaint all connections that share a target with newly created ones
234
- // so anchor distribution is correct after the full batch is processed
234
+ // Repaint all connections that share a target or source with newly
235
+ // created ones so anchor distribution and jogY offsets are correct
235
236
  if (createdTargets.size > 0) {
236
- this.connections.forEach((conn, exitId) => {
237
+ const createdScopes = new Set();
238
+ this.connections.forEach((conn) => {
237
239
  if (createdTargets.has(conn.toId)) {
240
+ createdScopes.add(conn.scope);
241
+ }
242
+ });
243
+ this.connections.forEach((conn, exitId) => {
244
+ if (createdTargets.has(conn.toId) || createdScopes.has(conn.scope)) {
238
245
  this.updateConnectionSVG(exitId);
239
246
  }
240
247
  });
@@ -267,7 +274,7 @@ export class Plumber {
267
274
  }
268
275
  return 'right';
269
276
  }
270
- getConnectionEndpoints(fromId, toId) {
277
+ getConnectionEndpoints(fromId, toId, scope) {
271
278
  const fromEl = document.getElementById(fromId);
272
279
  const toEl = document.getElementById(toId);
273
280
  if (!fromEl || !toEl)
@@ -350,7 +357,47 @@ export class Plumber {
350
357
  ? targetTop + targetH / 2
351
358
  : targetTop + margin + (span * (index + 0.5)) / count;
352
359
  }
353
- return { sourceX, sourceY, targetX, targetY, targetFace };
360
+ // Compute jogYOffset: stagger horizontal segments for sibling exits
361
+ // from the same source node so paths don't overlap
362
+ let jogYOffset = 0;
363
+ if (targetFace === 'top' && scope) {
364
+ const SIBLING_SPACING = 8;
365
+ const MAX_SPREAD = 50;
366
+ const siblings = [];
367
+ this.connections.forEach((conn) => {
368
+ if (conn.scope === scope && conn.toId !== toId) {
369
+ const connFromEl = document.getElementById(conn.fromId);
370
+ const connToEl = document.getElementById(conn.toId);
371
+ if (connFromEl && connToEl) {
372
+ const connFromRect = connFromEl.getBoundingClientRect();
373
+ const connToRect = connToEl.getBoundingClientRect();
374
+ const connSourceX = connFromRect.left + connFromRect.width / 2 - canvasRect.left;
375
+ const connSourceY = connFromRect.bottom - canvasRect.top;
376
+ const connFace = this.determineTargetFace(connSourceX, connSourceY, connToRect, canvasRect);
377
+ if (connFace === 'top') {
378
+ const connTargetLeft = connToRect.left - canvasRect.left;
379
+ const connTargetW = connToRect.width;
380
+ siblings.push({
381
+ fromId: conn.fromId,
382
+ targetX: connTargetLeft + connTargetW / 2
383
+ });
384
+ }
385
+ }
386
+ }
387
+ });
388
+ if (siblings.length > 0) {
389
+ siblings.push({ fromId, targetX });
390
+ siblings.sort((a, b) => a.targetX - b.targetX);
391
+ const idx = siblings.findIndex((s) => s.fromId === fromId);
392
+ const sibCount = siblings.length;
393
+ const rawSpread = (sibCount - 1) * SIBLING_SPACING;
394
+ const spacing = rawSpread > MAX_SPREAD
395
+ ? MAX_SPREAD / (sibCount - 1)
396
+ : SIBLING_SPACING;
397
+ jogYOffset = (idx - (sibCount - 1) / 2) * spacing;
398
+ }
399
+ }
400
+ return { sourceX, sourceY, targetX, targetY, targetFace, jogYOffset };
354
401
  }
355
402
  // --- SVG creation and management ---
356
403
  createSVGElement() {
@@ -384,7 +431,7 @@ export class Plumber {
384
431
  arrowEl.addEventListener('mouseleave', removeHover);
385
432
  return { svgEl, pathEl, arrowEl };
386
433
  }
387
- updateSVGPath(pathEl, arrowEl, sourceX, sourceY, targetX, targetY, targetFace = 'top') {
434
+ updateSVGPath(pathEl, arrowEl, sourceX, sourceY, targetX, targetY, targetFace = 'top', jogYOffset = 0) {
388
435
  const aw = ARROW_HALF_WIDTH;
389
436
  const al = ARROW_LENGTH;
390
437
  const stubBehindArrow = 8;
@@ -402,7 +449,7 @@ export class Plumber {
402
449
  pathTargetX = targetX + al;
403
450
  }
404
451
  const effectiveStub = stubBehindArrow;
405
- const d = calculateFlowchartPath(sourceX, sourceY, pathTargetX, pathTargetY, EXIT_STUB, effectiveStub, 5, targetFace);
452
+ const d = calculateFlowchartPath(sourceX, sourceY, pathTargetX, pathTargetY, EXIT_STUB, effectiveStub, 5, targetFace, jogYOffset);
406
453
  pathEl.setAttribute('d', d);
407
454
  // Arrow tip at node edge, base extends outward
408
455
  if (targetFace === 'top') {
@@ -416,11 +463,11 @@ export class Plumber {
416
463
  }
417
464
  }
418
465
  createConnectionSVG(exitId, scope, toId) {
419
- const endpoints = this.getConnectionEndpoints(exitId, toId);
466
+ const endpoints = this.getConnectionEndpoints(exitId, toId, scope);
420
467
  if (!endpoints)
421
468
  return false;
422
469
  const { svgEl, pathEl, arrowEl } = this.createSVGElement();
423
- this.updateSVGPath(pathEl, arrowEl, endpoints.sourceX, endpoints.sourceY, endpoints.targetX, endpoints.targetY, endpoints.targetFace);
470
+ this.updateSVGPath(pathEl, arrowEl, endpoints.sourceX, endpoints.sourceY, endpoints.targetX, endpoints.targetY, endpoints.targetFace, endpoints.jogYOffset);
424
471
  this.canvas.appendChild(svgEl);
425
472
  this.connections.set(exitId, {
426
473
  scope,
@@ -477,10 +524,10 @@ export class Plumber {
477
524
  const conn = this.connections.get(exitId);
478
525
  if (!conn)
479
526
  return;
480
- const endpoints = this.getConnectionEndpoints(conn.fromId, conn.toId);
527
+ const endpoints = this.getConnectionEndpoints(conn.fromId, conn.toId, conn.scope);
481
528
  if (!endpoints)
482
529
  return;
483
- this.updateSVGPath(conn.pathEl, conn.arrowEl, endpoints.sourceX, endpoints.sourceY, endpoints.targetX, endpoints.targetY, endpoints.targetFace);
530
+ this.updateSVGPath(conn.pathEl, conn.arrowEl, endpoints.sourceX, endpoints.sourceY, endpoints.targetX, endpoints.targetY, endpoints.targetFace, endpoints.jogYOffset);
484
531
  this.updateOverlayPosition(exitId);
485
532
  }
486
533
  removeConnectionSVG(exitId) {
@@ -658,7 +705,7 @@ export class Plumber {
658
705
  const conn = this.connections.get(exitId);
659
706
  if (!overlayEl || !conn)
660
707
  return;
661
- const endpoints = this.getConnectionEndpoints(conn.fromId, conn.toId);
708
+ const endpoints = this.getConnectionEndpoints(conn.fromId, conn.toId, conn.scope);
662
709
  if (!endpoints)
663
710
  return;
664
711
  overlayEl.style.position = 'absolute';
@@ -1 +1 @@
1
- {"version":3,"file":"Plumber.js","sourceRoot":"","sources":["../../../src/flow/Plumber.ts"],"names":[],"mappings":"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","sourcesContent":["export type TargetFace = 'top' | 'left' | 'right';\n\n// Shared arrow/drag constants used by both Plumber and Editor\nexport const ARROW_LENGTH = 13;\nexport const ARROW_HALF_WIDTH = 6.5;\nexport const CURSOR_GAP = 1;\nexport const EXIT_STUB = 30;\n\ninterface ConnectionEndpoints {\n sourceX: number;\n sourceY: number;\n targetX: number;\n targetY: number;\n targetFace: TargetFace;\n}\n\ninterface ConnectionInfo {\n scope: string; // nodeId\n fromId: string; // exitId\n toId: string; // target nodeId\n svgEl: SVGSVGElement;\n pathEl: SVGPathElement;\n arrowEl: SVGPolygonElement;\n}\n\ninterface DragState {\n sourceId: string;\n scope: string;\n originalTargetId: string | null;\n svgEl: SVGSVGElement;\n pathEl: SVGPathElement;\n arrowEl: SVGPolygonElement;\n onMove: (e: MouseEvent) => void;\n onUp: (e: MouseEvent) => void;\n}\n\n/**\n * Calculate a flowchart-style SVG path between two points.\n * Routes with right-angle segments, stubs at each end, and rounded corners.\n * Supports entering the target from top, left, or right faces.\n */\nexport function calculateFlowchartPath(\n sourceX: number,\n sourceY: number,\n targetX: number,\n targetY: number,\n stubStart = 20,\n stubEnd = 10,\n cornerRadius = 5,\n targetFace: TargetFace = 'top'\n): string {\n const r = cornerRadius;\n\n if (targetFace === 'top') {\n // Target is below (or we treat it as such): exit down, horizontal jog, enter from top\n const exitY = sourceY + stubStart;\n const entryY = targetY - stubEnd;\n\n let d = `M ${sourceX} ${sourceY}`;\n\n if (sourceX === targetX) {\n // Straight vertical — no turns needed\n d += ` L ${targetX} ${entryY}`;\n } else {\n // L-shape: exit curves horizontal, then straight down to target.\n // jogY is the horizontal level — must be above entryY so the\n // final approach into the node is always downward (no backtracking).\n const dirX = targetX > sourceX ? 1 : -1;\n const jogY = Math.max(sourceY + r, Math.min(exitY, entryY - r));\n\n // Corner 1: vertical→horizontal at jogY\n const r1 = Math.min(r, jogY - sourceY);\n if (r1 >= 1) {\n d += ` L ${sourceX} ${jogY - r1}`;\n d += ` Q ${sourceX} ${jogY}, ${sourceX + dirX * r1} ${jogY}`;\n } else {\n d += ` L ${sourceX} ${jogY}`;\n }\n\n // Corner 2: horizontal→vertical at targetX — leave minSeg of\n // straight line after the curve before reaching entryY\n const minSeg = 3;\n const r2 = Math.min(r, Math.max(0, entryY - jogY - minSeg));\n if (r2 >= 1) {\n d += ` L ${targetX - dirX * r2} ${jogY}`;\n d += ` Q ${targetX} ${jogY}, ${targetX} ${jogY + r2}`;\n } else {\n d += ` L ${targetX} ${jogY}`;\n }\n d += ` L ${targetX} ${entryY}`;\n }\n\n d += ` L ${targetX} ${targetY}`;\n return d;\n }\n\n if (targetFace === 'left' || targetFace === 'right') {\n // Route: exit down from source, horizontal jog, vertical to target Y, stub into side\n // When target is above source, skip the exit stub so the path turns horizontal\n // as quickly as possible (only the corner radius creates downward travel)\n const goingUp = targetY < sourceY;\n const exitY = sourceY + (goingUp ? 0 : stubStart);\n const sideDir = targetFace === 'left' ? -1 : 1;\n // Entry point is OUTSIDE the node boundary (stub behind arrowhead)\n const entryX = targetX + sideDir * stubEnd;\n\n const dirX = entryX > sourceX ? 1 : -1;\n\n // Minimum straight segment after each curve\n const minSeg = 3;\n\n // When the horizontal approach would double-back over the stub\n // (dirX matches sideDir), keep midY at the natural exit level so\n // the path jogs horizontally ABOVE the target and descends into\n // the stub — never dipping past the target and curving back up.\n // For non-backtrack, midY goes to targetY for a direct entry.\n const midY =\n dirX === sideDir ? exitY + r * 2 : Math.max(exitY + r * 2, targetY);\n\n let d = `M ${sourceX} ${sourceY} L ${sourceX} ${exitY}`;\n\n // Corner 1: vertical→horizontal at (sourceX, midY)\n if (midY - exitY > r) {\n d += ` L ${sourceX} ${midY - r}`;\n d += ` Q ${sourceX} ${midY}, ${sourceX + dirX * r} ${midY}`;\n }\n\n const vertGap = Math.abs(midY - targetY);\n\n if (vertGap < 1) {\n // midY ≈ targetY — horizontal to entryX, then stub into face\n d += ` L ${entryX} ${targetY}`;\n d += ` L ${targetX} ${targetY}`;\n } else {\n // Corners 2 and 3 — turnR is limited so that at least minSeg of\n // straight line remains between the two corners and after corner 3\n const turnDir = targetY < midY ? -1 : 1;\n const turnR = Math.min(\n r,\n Math.max(0, Math.floor((vertGap - minSeg) / 2)),\n Math.max(0, stubEnd - minSeg)\n );\n\n if (turnR >= 1) {\n // Corner 2: horizontal→vertical at (entryX, midY)\n d += ` L ${entryX - dirX * turnR} ${midY}`;\n d += ` Q ${entryX} ${midY}, ${entryX} ${midY + turnDir * turnR}`;\n // Vertical toward targetY\n d += ` L ${entryX} ${targetY - turnDir * turnR}`;\n // Corner 3: vertical→horizontal into side face\n d += ` Q ${entryX} ${targetY}, ${entryX - sideDir * turnR} ${targetY}`;\n } else {\n d += ` L ${entryX} ${midY}`;\n d += ` L ${entryX} ${targetY}`;\n }\n // Horizontal stub into target face\n d += ` L ${targetX} ${targetY}`;\n }\n\n return d;\n }\n\n return `M ${sourceX} ${sourceY} L ${targetX} ${targetY}`;\n}\n\nexport class Plumber {\n private connections: Map<string, ConnectionInfo> = new Map();\n private sources: Map<string, () => void> = new Map(); // exitId → cleanup fn\n private canvas: HTMLElement;\n private pendingConnections: {\n scope: string;\n fromId: string;\n toId: string;\n }[] = [];\n private connectionWait: number | null = null;\n private connectionListeners: Map<string, ((info: any) => void)[]> = new Map();\n private dragState: DragState | null = null;\n private editor: any;\n private retryCount = 0;\n private maxRetries = 3;\n\n // Activity overlay state\n private activityData: { segments: { [key: string]: number } } | null = null;\n private overlays: Map<string, HTMLElement> = new Map();\n private hoveredActivityKey: string | null = null;\n private recentContactsPopup: HTMLElement | null = null;\n private recentContactsCache: { [key: string]: any[] } = {};\n private pendingFetches: { [key: string]: AbortController } = {};\n private hideContactsTimeout: number | null = null;\n private showContactsTimeout: number | null = null;\n\n public connectionDragging = false;\n\n constructor(canvas: HTMLElement, editor: any) {\n this.canvas = canvas;\n this.editor = editor;\n }\n\n // --- Event system ---\n\n private notifyListeners(eventName: string, info: any) {\n const listeners = this.connectionListeners.get(eventName) || [];\n listeners.forEach((listener) => listener(info));\n }\n\n public on(eventName: string, callback: (info: any) => void) {\n if (!this.connectionListeners.has(eventName)) {\n this.connectionListeners.set(eventName, []);\n }\n this.connectionListeners.get(eventName).push(callback);\n }\n\n public off(eventName: string, callback: (info: any) => void) {\n if (!this.connectionListeners.has(eventName)) return;\n const listeners = this.connectionListeners.get(eventName);\n const index = listeners.indexOf(callback);\n if (index !== -1) {\n listeners.splice(index, 1);\n }\n }\n\n // --- Source/Target registration ---\n\n public makeSource(exitId: string) {\n const element = document.getElementById(exitId);\n if (!element) return;\n\n // Clean up any existing listener for this exit\n if (this.sources.has(exitId)) {\n this.sources.get(exitId)();\n }\n\n let pendingDrag: {\n startX: number;\n startY: number;\n onMove: (e: MouseEvent) => void;\n onUp: (e: MouseEvent) => void;\n } | null = null;\n\n const DRAG_THRESHOLD = 5;\n\n const onMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return;\n\n // Don't start drag from exit if it already has a connection —\n // existing connections are picked up from the arrowhead instead\n if (this.connections.has(exitId)) return;\n\n const startX = e.clientX;\n const startY = e.clientY;\n\n const nodeEl = element.closest('temba-flow-node');\n const scope = nodeEl?.getAttribute('uuid') || '';\n const originalTargetId: string | null = null;\n\n const onMove = (me: MouseEvent) => {\n const dx = me.clientX - startX;\n const dy = me.clientY - startY;\n if (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD) {\n // Exceeded threshold — start actual drag\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n pendingDrag = null;\n this.startDrag(exitId, scope, originalTargetId, me);\n }\n };\n\n const onUp = () => {\n // Mouse released without dragging — let click handler fire\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n pendingDrag = null;\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n pendingDrag = { startX, startY, onMove, onUp };\n };\n\n element.addEventListener('mousedown', onMouseDown);\n this.sources.set(exitId, () => {\n element.removeEventListener('mousedown', onMouseDown);\n if (pendingDrag) {\n document.removeEventListener('mousemove', pendingDrag.onMove);\n document.removeEventListener('mouseup', pendingDrag.onUp);\n pendingDrag = null;\n }\n });\n }\n\n public makeTarget(_nodeId: string) {\n // No-op: target detection happens via DOM hover during drag\n }\n\n // --- Connection creation ---\n\n public connectIds(scope: string, fromId: string, toId: string) {\n this.pendingConnections.push({ scope, fromId, toId });\n this.processPendingConnections();\n }\n\n public processPendingConnections() {\n if (this.connectionWait) {\n cancelAnimationFrame(this.connectionWait);\n this.connectionWait = null;\n }\n\n this.connectionWait = requestAnimationFrame(() => {\n const failed: { scope: string; fromId: string; toId: string }[] = [];\n const createdTargets = new Set<string>();\n\n this.pendingConnections.forEach((conn) => {\n const { scope, fromId, toId } = conn;\n // Remove existing connection from this exit if any\n this.removeConnectionSVG(fromId);\n if (!this.createConnectionSVG(fromId, scope, toId)) {\n failed.push(conn);\n } else {\n createdTargets.add(toId);\n }\n });\n this.pendingConnections = [];\n\n // Repaint all connections that share a target with newly created ones\n // so anchor distribution is correct after the full batch is processed\n if (createdTargets.size > 0) {\n this.connections.forEach((conn, exitId) => {\n if (createdTargets.has(conn.toId)) {\n this.updateConnectionSVG(exitId);\n }\n });\n }\n\n // Retry failed connections (elements may not be laid out yet)\n if (failed.length > 0 && this.retryCount < this.maxRetries) {\n this.retryCount++;\n this.pendingConnections = failed;\n this.processPendingConnections();\n } else {\n this.retryCount = 0;\n }\n });\n }\n\n // --- Anchor point distribution ---\n\n private determineTargetFace(\n sourceX: number,\n sourceY: number,\n targetRect: DOMRect,\n canvasRect: DOMRect\n ): TargetFace {\n const targetCenterX =\n targetRect.left + targetRect.width / 2 - canvasRect.left;\n const targetTop = targetRect.top - canvasRect.top;\n const verticalGap = targetTop - sourceY;\n\n // Top face requires enough vertical room for the exit stub, entry stub,\n // arrow, and curved corners. Below this threshold the path components\n // overlap and the connection backtracks, so use a side face instead.\n if (verticalGap > 30) {\n return 'top';\n }\n\n // Source is level with, below, or too close to target — connect to a side face\n if (sourceX < targetCenterX) {\n return 'left';\n }\n return 'right';\n }\n\n private getConnectionEndpoints(\n fromId: string,\n toId: string\n ): ConnectionEndpoints | null {\n const fromEl = document.getElementById(fromId);\n const toEl = document.getElementById(toId);\n if (!fromEl || !toEl) return null;\n\n const canvasRect = this.canvas.getBoundingClientRect();\n const fromRect = fromEl.getBoundingClientRect();\n const toRect = toEl.getBoundingClientRect();\n\n if (fromRect.width === 0 || toRect.width === 0) return null;\n\n const sourceX = fromRect.left + fromRect.width / 2 - canvasRect.left;\n const sourceY = fromRect.bottom - canvasRect.top;\n\n const targetFace = this.determineTargetFace(\n sourceX,\n sourceY,\n toRect,\n canvasRect\n );\n\n // Find all connections targeting the same node, grouped by face\n // Track source position for spatial sorting\n const faceConnections: Map<\n TargetFace,\n { fromId: string; sortPos: number }[]\n > = new Map();\n this.connections.forEach((conn) => {\n if (conn.toId === toId) {\n const connFromEl = document.getElementById(conn.fromId);\n if (connFromEl) {\n const connFromRect = connFromEl.getBoundingClientRect();\n const connSourceX =\n connFromRect.left + connFromRect.width / 2 - canvasRect.left;\n const connSourceY = connFromRect.bottom - canvasRect.top;\n const face = this.determineTargetFace(\n connSourceX,\n connSourceY,\n toRect,\n canvasRect\n );\n if (!faceConnections.has(face)) {\n faceConnections.set(face, []);\n }\n // Sort position: X for top face, Y for side faces\n const sortPos = face === 'top' ? connSourceX : connSourceY;\n faceConnections.get(face).push({ fromId: conn.fromId, sortPos });\n }\n }\n });\n\n // Add current connection to its face group if not already tracked\n if (!faceConnections.has(targetFace)) {\n faceConnections.set(targetFace, []);\n }\n const faceGroup = faceConnections.get(targetFace);\n if (!faceGroup.find((e) => e.fromId === fromId)) {\n const sortPos = targetFace === 'top' ? sourceX : sourceY;\n faceGroup.push({ fromId, sortPos });\n }\n\n // Sort by spatial position so connections don't cross\n faceGroup.sort((a, b) => a.sortPos - b.sortPos);\n const index = faceGroup.findIndex((e) => e.fromId === fromId);\n const count = faceGroup.length;\n\n // Calculate anchor point on the chosen face\n const targetLeft = toRect.left - canvasRect.left;\n const targetTop = toRect.top - canvasRect.top;\n const targetW = toRect.width;\n const targetH = toRect.height;\n\n let targetX: number;\n let targetY: number;\n\n if (targetFace === 'top') {\n // Distribute across top face (middle 60% of width)\n const margin = targetW * 0.2;\n const span = targetW * 0.6;\n targetX =\n count === 1\n ? targetLeft + targetW / 2\n : targetLeft + margin + (span * (index + 0.5)) / count;\n targetY = targetTop;\n } else if (targetFace === 'left') {\n targetX = targetLeft;\n // Distribute along left face (middle 60% of height)\n const margin = targetH * 0.2;\n const span = targetH * 0.6;\n targetY =\n count === 1\n ? targetTop + targetH / 2\n : targetTop + margin + (span * (index + 0.5)) / count;\n } else {\n // right\n targetX = targetLeft + targetW;\n const margin = targetH * 0.2;\n const span = targetH * 0.6;\n targetY =\n count === 1\n ? targetTop + targetH / 2\n : targetTop + margin + (span * (index + 0.5)) / count;\n }\n\n return { sourceX, sourceY, targetX, targetY, targetFace };\n }\n\n // --- SVG creation and management ---\n\n private createSVGElement(): {\n svgEl: SVGSVGElement;\n pathEl: SVGPathElement;\n arrowEl: SVGPolygonElement;\n } {\n const svgEl = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svgEl.classList.add('plumb-connector');\n svgEl.style.position = 'absolute';\n svgEl.style.left = '0';\n svgEl.style.top = '0';\n svgEl.style.width = '100%';\n svgEl.style.height = '100%';\n svgEl.style.pointerEvents = 'none';\n svgEl.style.overflow = 'visible';\n\n const pathEl = document.createElementNS(\n 'http://www.w3.org/2000/svg',\n 'path'\n );\n pathEl.setAttribute('fill', 'none');\n pathEl.setAttribute('stroke', 'var(--color-connectors)');\n pathEl.setAttribute('stroke-width', '3');\n pathEl.style.pointerEvents = 'stroke';\n\n const arrowEl = document.createElementNS(\n 'http://www.w3.org/2000/svg',\n 'polygon'\n );\n arrowEl.setAttribute('fill', 'var(--color-connectors)');\n arrowEl.classList.add('plumb-arrow');\n arrowEl.style.pointerEvents = 'fill';\n arrowEl.style.cursor = 'pointer';\n\n svgEl.appendChild(pathEl);\n svgEl.appendChild(arrowEl);\n\n // Hover support\n const addHover = () => svgEl.classList.add('hover');\n const removeHover = () => svgEl.classList.remove('hover');\n pathEl.addEventListener('mouseenter', addHover);\n pathEl.addEventListener('mouseleave', removeHover);\n arrowEl.addEventListener('mouseenter', addHover);\n arrowEl.addEventListener('mouseleave', removeHover);\n\n return { svgEl, pathEl, arrowEl };\n }\n\n private updateSVGPath(\n pathEl: SVGPathElement,\n arrowEl: SVGPolygonElement,\n sourceX: number,\n sourceY: number,\n targetX: number,\n targetY: number,\n targetFace: TargetFace = 'top'\n ) {\n const aw = ARROW_HALF_WIDTH;\n const al = ARROW_LENGTH;\n const stubBehindArrow = 8;\n\n // Path ends at arrow BASE (not tip) so the line never pokes through the front.\n // The arrow polygon covers from base to the node edge (tip).\n let pathTargetX = targetX;\n let pathTargetY = targetY;\n if (targetFace === 'top') {\n pathTargetY = targetY - al;\n } else if (targetFace === 'left') {\n pathTargetX = targetX - al;\n } else if (targetFace === 'right') {\n pathTargetX = targetX + al;\n }\n\n const effectiveStub = stubBehindArrow;\n const d = calculateFlowchartPath(\n sourceX,\n sourceY,\n pathTargetX,\n pathTargetY,\n EXIT_STUB,\n effectiveStub,\n 5,\n targetFace\n );\n pathEl.setAttribute('d', d);\n\n // Arrow tip at node edge, base extends outward\n if (targetFace === 'top') {\n arrowEl.setAttribute(\n 'points',\n `${targetX},${targetY} ${targetX - aw},${targetY - al} ${\n targetX + aw\n },${targetY - al}`\n );\n } else if (targetFace === 'left') {\n arrowEl.setAttribute(\n 'points',\n `${targetX},${targetY} ${targetX - al},${targetY - aw} ${\n targetX - al\n },${targetY + aw}`\n );\n } else {\n arrowEl.setAttribute(\n 'points',\n `${targetX},${targetY} ${targetX + al},${targetY - aw} ${\n targetX + al\n },${targetY + aw}`\n );\n }\n }\n\n private createConnectionSVG(\n exitId: string,\n scope: string,\n toId: string\n ): boolean {\n const endpoints = this.getConnectionEndpoints(exitId, toId);\n if (!endpoints) return false;\n\n const { svgEl, pathEl, arrowEl } = this.createSVGElement();\n this.updateSVGPath(\n pathEl,\n arrowEl,\n endpoints.sourceX,\n endpoints.sourceY,\n endpoints.targetX,\n endpoints.targetY,\n endpoints.targetFace\n );\n this.canvas.appendChild(svgEl);\n\n this.connections.set(exitId, {\n scope,\n fromId: exitId,\n toId,\n svgEl,\n pathEl,\n arrowEl\n });\n\n // Make arrowhead draggable for picking up existing connections\n const DRAG_THRESHOLD = 5;\n const onArrowMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return;\n e.stopPropagation();\n\n const startX = e.clientX;\n const startY = e.clientY;\n\n const onMove = (me: MouseEvent) => {\n const dx = me.clientX - startX;\n const dy = me.clientY - startY;\n if (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD) {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n this.startDrag(exitId, scope, toId, me);\n }\n };\n\n const onUp = () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n };\n arrowEl.addEventListener('mousedown', onArrowMouseDown);\n\n // Mark the exit element as connected\n const exitEl = document.getElementById(exitId);\n if (exitEl) {\n exitEl.classList.add('connected');\n }\n\n // Create activity overlay if activity data exists for this segment\n if (this.activityData) {\n const activityKey = `${exitId}:${toId}`;\n const count = this.activityData.segments[activityKey];\n if (count && count > 0) {\n const overlayEl = this.createOverlayElement(count, activityKey);\n this.canvas.appendChild(overlayEl);\n this.overlays.set(exitId, overlayEl);\n this.updateOverlayPosition(exitId);\n }\n }\n\n return true;\n }\n\n private updateConnectionSVG(exitId: string) {\n const conn = this.connections.get(exitId);\n if (!conn) return;\n\n const endpoints = this.getConnectionEndpoints(conn.fromId, conn.toId);\n if (!endpoints) return;\n\n this.updateSVGPath(\n conn.pathEl,\n conn.arrowEl,\n endpoints.sourceX,\n endpoints.sourceY,\n endpoints.targetX,\n endpoints.targetY,\n endpoints.targetFace\n );\n this.updateOverlayPosition(exitId);\n }\n\n private removeConnectionSVG(exitId: string) {\n const conn = this.connections.get(exitId);\n if (!conn) return;\n\n const overlay = this.overlays.get(exitId);\n if (overlay) {\n overlay.remove();\n this.overlays.delete(exitId);\n }\n\n conn.svgEl.remove();\n this.connections.delete(exitId);\n }\n\n // --- Repaint ---\n\n public repaintEverything() {\n this.connections.forEach((_conn, exitId) => {\n this.updateConnectionSVG(exitId);\n });\n }\n\n public revalidate(ids: string[]) {\n // Find all connections directly involving the given IDs\n const directExits: string[] = [];\n const affectedTargets = new Set<string>();\n\n this.connections.forEach((conn, exitId) => {\n if (\n ids.includes(conn.fromId) ||\n ids.includes(conn.toId) ||\n ids.includes(conn.scope)\n ) {\n directExits.push(exitId);\n affectedTargets.add(conn.toId);\n }\n });\n\n // Also repaint sibling connections that share a target\n // (so anchor distribution stays correct during drag)\n const allExitsToRepaint = new Set(directExits);\n this.connections.forEach((conn, exitId) => {\n if (affectedTargets.has(conn.toId)) {\n allExitsToRepaint.add(exitId);\n }\n });\n\n allExitsToRepaint.forEach((exitId) => {\n this.updateConnectionSVG(exitId);\n });\n }\n\n // --- Connection removal ---\n\n public forgetNode(nodeId: string) {\n // Remove all connections where this node is source or target\n const toRemove: string[] = [];\n this.connections.forEach((conn, exitId) => {\n if (conn.scope === nodeId || conn.toId === nodeId) {\n toRemove.push(exitId);\n }\n });\n toRemove.forEach((exitId) => this.removeConnectionSVG(exitId));\n\n // Remove source listeners for exits of this node\n const exitEls = document.getElementById(nodeId)?.querySelectorAll('.exit');\n if (exitEls) {\n exitEls.forEach((el) => {\n const id = el.id;\n if (this.sources.has(id)) {\n this.sources.get(id)();\n this.sources.delete(id);\n }\n });\n }\n }\n\n public removeNodeConnections(nodeId: string, exitIds?: string[]) {\n // Only remove outbound connections from this node's exits.\n // Inbound connections are managed by their source nodes and\n // will repaint correctly on the next revalidate.\n const exits =\n exitIds ||\n Array.from(\n document.getElementById(nodeId)?.querySelectorAll('.exit') || []\n ).map((el) => el.id);\n\n exits.forEach((exitId) => this.removeConnectionSVG(exitId));\n }\n\n public removeExitConnection(exitId: string): boolean {\n if (!this.connections.has(exitId)) return false;\n this.removeConnectionSVG(exitId);\n return true;\n }\n\n public removeAllEndpoints(nodeId: string) {\n // Remove source listeners for this node's exits\n const exitEls = document.getElementById(nodeId)?.querySelectorAll('.exit');\n if (exitEls) {\n exitEls.forEach((el) => {\n const id = el.id;\n if (this.sources.has(id)) {\n this.sources.get(id)();\n this.sources.delete(id);\n }\n });\n }\n }\n\n // --- Connection state ---\n\n public setConnectionRemovingState(\n exitId: string,\n isRemoving: boolean\n ): boolean {\n const conn = this.connections.get(exitId);\n if (!conn) return false;\n\n if (isRemoving) {\n conn.svgEl.classList.add('removing');\n } else {\n conn.svgEl.classList.remove('removing');\n }\n return true;\n }\n\n // --- Activity overlays ---\n\n public setActivityData(\n activityData: { segments: { [key: string]: number } } | null\n ) {\n this.activityData = activityData;\n this.clearRecentContactsCache();\n this.updateActivityOverlays();\n }\n\n private updateActivityOverlays() {\n if (!this.activityData) {\n this.overlays.forEach((el) => el.remove());\n this.overlays.clear();\n return;\n }\n\n const activeExitIds = new Set<string>();\n\n this.connections.forEach((conn, exitId) => {\n const activityKey = `${conn.fromId}:${conn.toId}`;\n const count = this.activityData.segments[activityKey];\n\n if (count && count > 0) {\n activeExitIds.add(exitId);\n let overlayEl = this.overlays.get(exitId);\n\n if (!overlayEl) {\n overlayEl = this.createOverlayElement(count, activityKey);\n this.canvas.appendChild(overlayEl);\n this.overlays.set(exitId, overlayEl);\n } else {\n overlayEl.textContent = count.toLocaleString();\n overlayEl.setAttribute('data-activity-key', activityKey);\n }\n\n this.updateOverlayPosition(exitId);\n }\n });\n\n // Remove overlays for connections that no longer have activity\n this.overlays.forEach((el, exitId) => {\n if (!activeExitIds.has(exitId)) {\n el.remove();\n this.overlays.delete(exitId);\n }\n });\n }\n\n private createOverlayElement(\n count: number,\n activityKey: string\n ): HTMLElement {\n const el = document.createElement('div');\n el.className = 'activity-overlay';\n el.textContent = count.toLocaleString();\n el.setAttribute('data-activity-key', activityKey);\n\n el.addEventListener('mouseenter', () => {\n const flowUuid = this.getFlowUuid();\n if (flowUuid) {\n this.fetchRecentContacts(activityKey, flowUuid);\n this.showContactsTimeout = window.setTimeout(() => {\n this.showRecentContacts(activityKey, flowUuid);\n }, 500);\n }\n });\n\n el.addEventListener('mouseleave', () => {\n if (this.showContactsTimeout) {\n clearTimeout(this.showContactsTimeout);\n this.showContactsTimeout = null;\n }\n this.hoveredActivityKey = null;\n this.hideRecentContacts();\n });\n\n return el;\n }\n\n private updateOverlayPosition(exitId: string) {\n const overlayEl = this.overlays.get(exitId);\n const conn = this.connections.get(exitId);\n if (!overlayEl || !conn) return;\n\n const endpoints = this.getConnectionEndpoints(conn.fromId, conn.toId);\n if (!endpoints) return;\n\n overlayEl.style.position = 'absolute';\n overlayEl.style.left = `${endpoints.sourceX}px`;\n overlayEl.style.top = `${endpoints.sourceY + EXIT_STUB / 2}px`;\n overlayEl.style.transform = 'translate(-50%, -50%)';\n }\n\n private getFlowUuid(): string | null {\n return this.editor?.definition?.uuid || null;\n }\n\n // --- Recent contacts ---\n\n private async fetchRecentContacts(activityKey: string, flowUuid: string) {\n if (\n this.recentContactsCache[activityKey] ||\n this.pendingFetches[activityKey]\n ) {\n return;\n }\n\n const controller = new AbortController();\n this.pendingFetches[activityKey] = controller;\n\n try {\n const [exitUuid, destinationUuid] = activityKey.split(':');\n const endpoint = `/flow/recent_contacts/${flowUuid}/${exitUuid}/${destinationUuid}/`;\n const response = await fetch(endpoint, { signal: controller.signal });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const data = await response.json();\n this.recentContactsCache[activityKey] = Array.isArray(data)\n ? data\n : data.results || [];\n } catch (error) {\n if ((error as Error).name !== 'AbortError') {\n console.error('Failed to fetch recent contacts:', error);\n }\n } finally {\n delete this.pendingFetches[activityKey];\n }\n }\n\n private async showRecentContacts(activityKey: string, flowUuid: string) {\n const overlayElement = this.findOverlayForActivityKey(activityKey);\n if (!overlayElement) return;\n\n if (this.hideContactsTimeout) {\n clearTimeout(this.hideContactsTimeout);\n this.hideContactsTimeout = null;\n }\n\n this.hoveredActivityKey = activityKey;\n\n if (!this.recentContactsPopup) {\n this.recentContactsPopup = document.createElement('div');\n this.recentContactsPopup.className = 'recent-contacts-popup';\n this.recentContactsPopup.style.position = 'absolute';\n this.recentContactsPopup.style.zIndex = '1015';\n this.recentContactsPopup.style.display = 'none';\n document.body.appendChild(this.recentContactsPopup);\n\n this.recentContactsPopup.onmouseenter = () => {\n if (this.hideContactsTimeout) {\n clearTimeout(this.hideContactsTimeout);\n this.hideContactsTimeout = null;\n }\n };\n this.recentContactsPopup.onmouseleave = () => {\n this.hoveredActivityKey = null;\n this.hideRecentContacts();\n };\n\n this.recentContactsPopup.onclick = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n if (target.classList.contains('contact-name')) {\n this.hideRecentContacts(false);\n const contactUuid = target.getAttribute('data-uuid');\n if (contactUuid) {\n this.editor.fireCustomEvent('temba-contact-clicked', {\n uuid: contactUuid\n });\n }\n }\n };\n }\n\n if (this.recentContactsCache[activityKey]) {\n this.renderRecentContactsPopup(this.recentContactsCache[activityKey]);\n this.positionPopup(overlayElement);\n } else {\n this.recentContactsPopup.innerHTML =\n '<div class=\"no-contacts-message\">Loading...</div>';\n this.positionPopup(overlayElement);\n await this.fetchRecentContacts(activityKey, flowUuid);\n if (this.hoveredActivityKey === activityKey) {\n this.renderRecentContactsPopup(\n this.recentContactsCache[activityKey] || []\n );\n this.positionPopup(overlayElement);\n }\n }\n }\n\n private findOverlayForActivityKey(activityKey: string): HTMLElement | null {\n for (const [, el] of this.overlays) {\n if (el.getAttribute('data-activity-key') === activityKey) {\n return el;\n }\n }\n return null;\n }\n\n private positionPopup(overlayElement: HTMLElement) {\n if (!this.recentContactsPopup) return;\n const rect = overlayElement.getBoundingClientRect();\n this.recentContactsPopup.style.left = `${rect.left + window.scrollX}px`;\n this.recentContactsPopup.style.top = `${\n rect.bottom + window.scrollY + 5\n }px`;\n this.recentContactsPopup.style.display = '';\n this.recentContactsPopup.classList.remove('show');\n void this.recentContactsPopup.offsetWidth;\n this.recentContactsPopup.classList.add('show');\n }\n\n private renderRecentContactsPopup(recentContacts: any[]) {\n if (!this.recentContactsPopup) return;\n\n if (recentContacts.length === 0) {\n this.recentContactsPopup.innerHTML =\n '<div class=\"no-contacts-message\">No Recent Contacts</div>';\n return;\n }\n\n let html = '<div class=\"popup-title\">Recent Contacts</div>';\n recentContacts.forEach((contact: any) => {\n html += '<div class=\"contact-row\">';\n html += `<div class=\"contact-name\" data-uuid=\"${contact.contact.uuid}\">${contact.contact.name}</div>`;\n if (contact.operand) {\n html += `<div class=\"contact-operand\">${contact.operand}</div>`;\n }\n if (contact.time) {\n const time = new Date(contact.time);\n const diffMs = Date.now() - time.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n let timeStr = '';\n if (diffMins < 1) timeStr = 'just now';\n else if (diffMins < 60) timeStr = `${diffMins}m ago`;\n else if (diffHours < 24) timeStr = `${diffHours}h ago`;\n else timeStr = `${diffDays}d ago`;\n html += `<div class=\"contact-time\">${timeStr}</div>`;\n }\n html += '</div>';\n });\n this.recentContactsPopup.innerHTML = html;\n }\n\n private hideRecentContacts(wait = true) {\n if (!wait) {\n if (this.recentContactsPopup) {\n this.recentContactsPopup.classList.remove('show');\n this.recentContactsPopup.style.display = 'none';\n this.hoveredActivityKey = null;\n }\n return;\n }\n\n this.hideContactsTimeout = window.setTimeout(() => {\n if (!this.hoveredActivityKey && this.recentContactsPopup) {\n this.recentContactsPopup.classList.remove('show');\n this.recentContactsPopup.style.display = 'none';\n this.hoveredActivityKey = null;\n }\n }, 200);\n }\n\n public clearRecentContactsCache() {\n this.recentContactsCache = {};\n Object.values(this.pendingFetches).forEach((controller) =>\n controller.abort()\n );\n this.pendingFetches = {};\n }\n\n // --- Drag-and-drop ---\n\n private startDrag(\n exitId: string,\n scope: string,\n originalTargetId: string | null,\n e: MouseEvent\n ) {\n // Remove existing connection SVG for this exit (the connection is being dragged away)\n this.removeConnectionSVG(exitId);\n\n const { svgEl, pathEl, arrowEl } = this.createSVGElement();\n svgEl.classList.add('dragging');\n // Ensure the drag SVG never intercepts mouse events (e.g. hover detection on nodes)\n pathEl.style.pointerEvents = 'none';\n arrowEl.style.pointerEvents = 'none';\n this.canvas.appendChild(svgEl);\n\n // Calculate source point\n const exitEl = document.getElementById(exitId);\n if (!exitEl) {\n svgEl.remove();\n return;\n }\n\n const canvasRect = this.canvas.getBoundingClientRect();\n const exitRect = exitEl.getBoundingClientRect();\n const sourceX = exitRect.left + exitRect.width / 2 - canvasRect.left;\n const sourceY = exitRect.bottom - canvasRect.top;\n\n const aw = ARROW_HALF_WIDTH;\n const al = ARROW_LENGTH;\n const stubBehindArrow = 8;\n\n // Update the drag path and arrow based on cursor position.\n // Arrow trails just before the cursor (between source and cursor).\n const cursorGap = CURSOR_GAP;\n const updateDragPath = (cx: number, cy: number) => {\n const goingUp = cy < sourceY;\n\n let routeFace: TargetFace = 'top';\n if (goingUp) {\n routeFace = cx < sourceX ? 'left' : 'right';\n }\n\n // Position the arrow so its top edge sits just before the cursor.\n // \"Top\" = smallest Y on screen, which is the base for a downward\n // arrow and the tip for an upward arrow.\n let arrowBaseY: number;\n if (goingUp) {\n // Arrow points up: tip just below cursor, base below that\n arrowBaseY = cy + cursorGap + al;\n } else {\n // Arrow points down: base just above cursor, tip below\n arrowBaseY = cy - cursorGap;\n }\n\n const d = calculateFlowchartPath(\n sourceX,\n sourceY,\n cx,\n arrowBaseY,\n EXIT_STUB,\n goingUp ? 0 : stubBehindArrow,\n 5,\n routeFace\n );\n pathEl.setAttribute('d', d);\n\n if (goingUp) {\n const tipY = cy + cursorGap;\n arrowEl.setAttribute(\n 'points',\n `${cx},${tipY} ${cx - aw},${arrowBaseY} ${cx + aw},${arrowBaseY}`\n );\n } else {\n const tipY = arrowBaseY + al;\n arrowEl.setAttribute(\n 'points',\n `${cx},${tipY} ${cx - aw},${arrowBaseY} ${cx + aw},${arrowBaseY}`\n );\n }\n };\n\n // Initial path to cursor\n const cursorX = e.clientX - canvasRect.left;\n const cursorY = e.clientY - canvasRect.top;\n updateDragPath(cursorX, cursorY);\n\n this.connectionDragging = true;\n\n const onMove = (me: MouseEvent) => {\n const cx = me.clientX - canvasRect.left;\n const cy = me.clientY - canvasRect.top;\n updateDragPath(cx, cy);\n };\n\n const onUp = (_me: MouseEvent) => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n\n // Remove the drag SVG\n svgEl.remove();\n this.connectionDragging = false;\n this.dragState = null;\n\n // Fire abort event so Editor can handle connection logic\n this.notifyListeners('connection:abort', {\n source: exitEl,\n sourceId: exitId,\n target: { id: originalTargetId },\n data: { nodeId: scope }\n });\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n\n this.dragState = {\n sourceId: exitId,\n scope,\n originalTargetId,\n svgEl,\n pathEl,\n arrowEl,\n onMove,\n onUp\n };\n\n // Fire drag event so Editor knows a drag has started\n this.notifyListeners('connection:drag', {\n sourceId: exitId,\n sourceX,\n sourceY,\n data: { nodeId: scope },\n target: { id: originalTargetId }\n });\n }\n\n // --- Reset ---\n\n public reset() {\n if (this.connectionWait) {\n cancelAnimationFrame(this.connectionWait);\n this.connectionWait = null;\n }\n this.pendingConnections = [];\n\n // Remove all connection SVGs\n this.connections.forEach((conn) => conn.svgEl.remove());\n this.connections.clear();\n\n // Remove all activity overlays\n this.overlays.forEach((el) => el.remove());\n this.overlays.clear();\n\n // Clean up recent contacts popup\n this.hideRecentContacts(false);\n if (this.recentContactsPopup) {\n this.recentContactsPopup.remove();\n this.recentContactsPopup = null;\n }\n this.recentContactsCache = {};\n Object.values(this.pendingFetches).forEach((c) => c.abort());\n this.pendingFetches = {};\n\n // Remove all source listeners\n this.sources.forEach((cleanup) => cleanup());\n this.sources.clear();\n\n // Clean up any active drag\n if (this.dragState) {\n document.removeEventListener('mousemove', this.dragState.onMove);\n document.removeEventListener('mouseup', this.dragState.onUp);\n this.dragState.svgEl.remove();\n this.dragState = null;\n this.connectionDragging = false;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"Plumber.js","sourceRoot":"","sources":["../../../src/flow/Plumber.ts"],"names":[],"mappings":"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","sourcesContent":["export type TargetFace = 'top' | 'left' | 'right';\n\n// Shared arrow/drag constants used by both Plumber and Editor\nexport const ARROW_LENGTH = 13;\nexport const ARROW_HALF_WIDTH = 6.5;\nexport const CURSOR_GAP = 1;\nexport const EXIT_STUB = 30;\n\ninterface ConnectionEndpoints {\n sourceX: number;\n sourceY: number;\n targetX: number;\n targetY: number;\n targetFace: TargetFace;\n jogYOffset: number;\n}\n\ninterface ConnectionInfo {\n scope: string; // nodeId\n fromId: string; // exitId\n toId: string; // target nodeId\n svgEl: SVGSVGElement;\n pathEl: SVGPathElement;\n arrowEl: SVGPolygonElement;\n}\n\ninterface DragState {\n sourceId: string;\n scope: string;\n originalTargetId: string | null;\n svgEl: SVGSVGElement;\n pathEl: SVGPathElement;\n arrowEl: SVGPolygonElement;\n onMove: (e: MouseEvent) => void;\n onUp: (e: MouseEvent) => void;\n}\n\n/**\n * Calculate a flowchart-style SVG path between two points.\n * Routes with right-angle segments, stubs at each end, and rounded corners.\n * Supports entering the target from top, left, or right faces.\n */\nexport function calculateFlowchartPath(\n sourceX: number,\n sourceY: number,\n targetX: number,\n targetY: number,\n stubStart = 20,\n stubEnd = 10,\n cornerRadius = 5,\n targetFace: TargetFace = 'top',\n jogYOffset = 0\n): string {\n const r = cornerRadius;\n\n if (targetFace === 'top') {\n // Target is below (or we treat it as such): exit down, horizontal jog, enter from top\n const exitY = sourceY + stubStart;\n const entryY = targetY - stubEnd;\n\n let d = `M ${sourceX} ${sourceY}`;\n\n if (sourceX === targetX) {\n // Straight vertical — no turns needed\n d += ` L ${targetX} ${entryY}`;\n } else {\n // L-shape: exit curves horizontal, then straight down to target.\n // jogY is the horizontal level — must be above entryY so the\n // final approach into the node is always downward (no backtracking).\n const dirX = targetX > sourceX ? 1 : -1;\n const baseJogY = Math.max(sourceY + r, Math.min(exitY, entryY - r));\n const jogY = Math.max(\n sourceY + r,\n Math.min(baseJogY + jogYOffset, entryY - r - 3)\n );\n\n // Corner 1: vertical→horizontal at jogY\n const r1 = Math.min(r, jogY - sourceY);\n if (r1 >= 1) {\n d += ` L ${sourceX} ${jogY - r1}`;\n d += ` Q ${sourceX} ${jogY}, ${sourceX + dirX * r1} ${jogY}`;\n } else {\n d += ` L ${sourceX} ${jogY}`;\n }\n\n // Corner 2: horizontal→vertical at targetX — leave minSeg of\n // straight line after the curve before reaching entryY\n const minSeg = 3;\n const r2 = Math.min(r, Math.max(0, entryY - jogY - minSeg));\n if (r2 >= 1) {\n d += ` L ${targetX - dirX * r2} ${jogY}`;\n d += ` Q ${targetX} ${jogY}, ${targetX} ${jogY + r2}`;\n } else {\n d += ` L ${targetX} ${jogY}`;\n }\n d += ` L ${targetX} ${entryY}`;\n }\n\n d += ` L ${targetX} ${targetY}`;\n return d;\n }\n\n if (targetFace === 'left' || targetFace === 'right') {\n // Route: exit down from source, horizontal jog, vertical to target Y, stub into side\n // When target is above source, skip the exit stub so the path turns horizontal\n // as quickly as possible (only the corner radius creates downward travel)\n const goingUp = targetY < sourceY;\n const exitY = sourceY + (goingUp ? 0 : stubStart);\n const sideDir = targetFace === 'left' ? -1 : 1;\n // Entry point is OUTSIDE the node boundary (stub behind arrowhead)\n const entryX = targetX + sideDir * stubEnd;\n\n const dirX = entryX > sourceX ? 1 : -1;\n\n // Minimum straight segment after each curve\n const minSeg = 3;\n\n // When the horizontal approach would double-back over the stub\n // (dirX matches sideDir), keep midY at the natural exit level so\n // the path jogs horizontally ABOVE the target and descends into\n // the stub — never dipping past the target and curving back up.\n // For non-backtrack, midY goes to targetY for a direct entry.\n const midY =\n dirX === sideDir ? exitY + r * 2 : Math.max(exitY + r * 2, targetY);\n\n let d = `M ${sourceX} ${sourceY} L ${sourceX} ${exitY}`;\n\n // Corner 1: vertical→horizontal at (sourceX, midY)\n if (midY - exitY > r) {\n d += ` L ${sourceX} ${midY - r}`;\n d += ` Q ${sourceX} ${midY}, ${sourceX + dirX * r} ${midY}`;\n }\n\n const vertGap = Math.abs(midY - targetY);\n\n if (vertGap < 1) {\n // midY ≈ targetY — horizontal to entryX, then stub into face\n d += ` L ${entryX} ${targetY}`;\n d += ` L ${targetX} ${targetY}`;\n } else {\n // Corners 2 and 3 — turnR is limited so that at least minSeg of\n // straight line remains between the two corners and after corner 3\n const turnDir = targetY < midY ? -1 : 1;\n const turnR = Math.min(\n r,\n Math.max(0, Math.floor((vertGap - minSeg) / 2)),\n Math.max(0, stubEnd - minSeg)\n );\n\n if (turnR >= 1) {\n // Corner 2: horizontal→vertical at (entryX, midY)\n d += ` L ${entryX - dirX * turnR} ${midY}`;\n d += ` Q ${entryX} ${midY}, ${entryX} ${midY + turnDir * turnR}`;\n // Vertical toward targetY\n d += ` L ${entryX} ${targetY - turnDir * turnR}`;\n // Corner 3: vertical→horizontal into side face\n d += ` Q ${entryX} ${targetY}, ${entryX - sideDir * turnR} ${targetY}`;\n } else {\n d += ` L ${entryX} ${midY}`;\n d += ` L ${entryX} ${targetY}`;\n }\n // Horizontal stub into target face\n d += ` L ${targetX} ${targetY}`;\n }\n\n return d;\n }\n\n return `M ${sourceX} ${sourceY} L ${targetX} ${targetY}`;\n}\n\nexport class Plumber {\n private connections: Map<string, ConnectionInfo> = new Map();\n private sources: Map<string, () => void> = new Map(); // exitId → cleanup fn\n private canvas: HTMLElement;\n private pendingConnections: {\n scope: string;\n fromId: string;\n toId: string;\n }[] = [];\n private connectionWait: number | null = null;\n private connectionListeners: Map<string, ((info: any) => void)[]> = new Map();\n private dragState: DragState | null = null;\n private editor: any;\n private retryCount = 0;\n private maxRetries = 3;\n\n // Activity overlay state\n private activityData: { segments: { [key: string]: number } } | null = null;\n private overlays: Map<string, HTMLElement> = new Map();\n private hoveredActivityKey: string | null = null;\n private recentContactsPopup: HTMLElement | null = null;\n private recentContactsCache: { [key: string]: any[] } = {};\n private pendingFetches: { [key: string]: AbortController } = {};\n private hideContactsTimeout: number | null = null;\n private showContactsTimeout: number | null = null;\n\n public connectionDragging = false;\n\n constructor(canvas: HTMLElement, editor: any) {\n this.canvas = canvas;\n this.editor = editor;\n }\n\n // --- Event system ---\n\n private notifyListeners(eventName: string, info: any) {\n const listeners = this.connectionListeners.get(eventName) || [];\n listeners.forEach((listener) => listener(info));\n }\n\n public on(eventName: string, callback: (info: any) => void) {\n if (!this.connectionListeners.has(eventName)) {\n this.connectionListeners.set(eventName, []);\n }\n this.connectionListeners.get(eventName).push(callback);\n }\n\n public off(eventName: string, callback: (info: any) => void) {\n if (!this.connectionListeners.has(eventName)) return;\n const listeners = this.connectionListeners.get(eventName);\n const index = listeners.indexOf(callback);\n if (index !== -1) {\n listeners.splice(index, 1);\n }\n }\n\n // --- Source/Target registration ---\n\n public makeSource(exitId: string) {\n const element = document.getElementById(exitId);\n if (!element) return;\n\n // Clean up any existing listener for this exit\n if (this.sources.has(exitId)) {\n this.sources.get(exitId)();\n }\n\n let pendingDrag: {\n startX: number;\n startY: number;\n onMove: (e: MouseEvent) => void;\n onUp: (e: MouseEvent) => void;\n } | null = null;\n\n const DRAG_THRESHOLD = 5;\n\n const onMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return;\n\n // Don't start drag from exit if it already has a connection —\n // existing connections are picked up from the arrowhead instead\n if (this.connections.has(exitId)) return;\n\n const startX = e.clientX;\n const startY = e.clientY;\n\n const nodeEl = element.closest('temba-flow-node');\n const scope = nodeEl?.getAttribute('uuid') || '';\n const originalTargetId: string | null = null;\n\n const onMove = (me: MouseEvent) => {\n const dx = me.clientX - startX;\n const dy = me.clientY - startY;\n if (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD) {\n // Exceeded threshold — start actual drag\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n pendingDrag = null;\n this.startDrag(exitId, scope, originalTargetId, me);\n }\n };\n\n const onUp = () => {\n // Mouse released without dragging — let click handler fire\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n pendingDrag = null;\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n pendingDrag = { startX, startY, onMove, onUp };\n };\n\n element.addEventListener('mousedown', onMouseDown);\n this.sources.set(exitId, () => {\n element.removeEventListener('mousedown', onMouseDown);\n if (pendingDrag) {\n document.removeEventListener('mousemove', pendingDrag.onMove);\n document.removeEventListener('mouseup', pendingDrag.onUp);\n pendingDrag = null;\n }\n });\n }\n\n public makeTarget(_nodeId: string) {\n // No-op: target detection happens via DOM hover during drag\n }\n\n // --- Connection creation ---\n\n public connectIds(scope: string, fromId: string, toId: string) {\n this.pendingConnections.push({ scope, fromId, toId });\n this.processPendingConnections();\n }\n\n public processPendingConnections() {\n if (this.connectionWait) {\n cancelAnimationFrame(this.connectionWait);\n this.connectionWait = null;\n }\n\n this.connectionWait = requestAnimationFrame(() => {\n const failed: { scope: string; fromId: string; toId: string }[] = [];\n const createdTargets = new Set<string>();\n\n this.pendingConnections.forEach((conn) => {\n const { scope, fromId, toId } = conn;\n // Remove existing connection from this exit if any\n this.removeConnectionSVG(fromId);\n if (!this.createConnectionSVG(fromId, scope, toId)) {\n failed.push(conn);\n } else {\n createdTargets.add(toId);\n }\n });\n this.pendingConnections = [];\n\n // Repaint all connections that share a target or source with newly\n // created ones so anchor distribution and jogY offsets are correct\n if (createdTargets.size > 0) {\n const createdScopes = new Set<string>();\n this.connections.forEach((conn) => {\n if (createdTargets.has(conn.toId)) {\n createdScopes.add(conn.scope);\n }\n });\n this.connections.forEach((conn, exitId) => {\n if (createdTargets.has(conn.toId) || createdScopes.has(conn.scope)) {\n this.updateConnectionSVG(exitId);\n }\n });\n }\n\n // Retry failed connections (elements may not be laid out yet)\n if (failed.length > 0 && this.retryCount < this.maxRetries) {\n this.retryCount++;\n this.pendingConnections = failed;\n this.processPendingConnections();\n } else {\n this.retryCount = 0;\n }\n });\n }\n\n // --- Anchor point distribution ---\n\n private determineTargetFace(\n sourceX: number,\n sourceY: number,\n targetRect: DOMRect,\n canvasRect: DOMRect\n ): TargetFace {\n const targetCenterX =\n targetRect.left + targetRect.width / 2 - canvasRect.left;\n const targetTop = targetRect.top - canvasRect.top;\n const verticalGap = targetTop - sourceY;\n\n // Top face requires enough vertical room for the exit stub, entry stub,\n // arrow, and curved corners. Below this threshold the path components\n // overlap and the connection backtracks, so use a side face instead.\n if (verticalGap > 30) {\n return 'top';\n }\n\n // Source is level with, below, or too close to target — connect to a side face\n if (sourceX < targetCenterX) {\n return 'left';\n }\n return 'right';\n }\n\n private getConnectionEndpoints(\n fromId: string,\n toId: string,\n scope?: string\n ): ConnectionEndpoints | null {\n const fromEl = document.getElementById(fromId);\n const toEl = document.getElementById(toId);\n if (!fromEl || !toEl) return null;\n\n const canvasRect = this.canvas.getBoundingClientRect();\n const fromRect = fromEl.getBoundingClientRect();\n const toRect = toEl.getBoundingClientRect();\n\n if (fromRect.width === 0 || toRect.width === 0) return null;\n\n const sourceX = fromRect.left + fromRect.width / 2 - canvasRect.left;\n const sourceY = fromRect.bottom - canvasRect.top;\n\n const targetFace = this.determineTargetFace(\n sourceX,\n sourceY,\n toRect,\n canvasRect\n );\n\n // Find all connections targeting the same node, grouped by face\n // Track source position for spatial sorting\n const faceConnections: Map<\n TargetFace,\n { fromId: string; sortPos: number }[]\n > = new Map();\n this.connections.forEach((conn) => {\n if (conn.toId === toId) {\n const connFromEl = document.getElementById(conn.fromId);\n if (connFromEl) {\n const connFromRect = connFromEl.getBoundingClientRect();\n const connSourceX =\n connFromRect.left + connFromRect.width / 2 - canvasRect.left;\n const connSourceY = connFromRect.bottom - canvasRect.top;\n const face = this.determineTargetFace(\n connSourceX,\n connSourceY,\n toRect,\n canvasRect\n );\n if (!faceConnections.has(face)) {\n faceConnections.set(face, []);\n }\n // Sort position: X for top face, Y for side faces\n const sortPos = face === 'top' ? connSourceX : connSourceY;\n faceConnections.get(face).push({ fromId: conn.fromId, sortPos });\n }\n }\n });\n\n // Add current connection to its face group if not already tracked\n if (!faceConnections.has(targetFace)) {\n faceConnections.set(targetFace, []);\n }\n const faceGroup = faceConnections.get(targetFace);\n if (!faceGroup.find((e) => e.fromId === fromId)) {\n const sortPos = targetFace === 'top' ? sourceX : sourceY;\n faceGroup.push({ fromId, sortPos });\n }\n\n // Sort by spatial position so connections don't cross\n faceGroup.sort((a, b) => a.sortPos - b.sortPos);\n const index = faceGroup.findIndex((e) => e.fromId === fromId);\n const count = faceGroup.length;\n\n // Calculate anchor point on the chosen face\n const targetLeft = toRect.left - canvasRect.left;\n const targetTop = toRect.top - canvasRect.top;\n const targetW = toRect.width;\n const targetH = toRect.height;\n\n let targetX: number;\n let targetY: number;\n\n if (targetFace === 'top') {\n // Distribute across top face (middle 60% of width)\n const margin = targetW * 0.2;\n const span = targetW * 0.6;\n targetX =\n count === 1\n ? targetLeft + targetW / 2\n : targetLeft + margin + (span * (index + 0.5)) / count;\n targetY = targetTop;\n } else if (targetFace === 'left') {\n targetX = targetLeft;\n // Distribute along left face (middle 60% of height)\n const margin = targetH * 0.2;\n const span = targetH * 0.6;\n targetY =\n count === 1\n ? targetTop + targetH / 2\n : targetTop + margin + (span * (index + 0.5)) / count;\n } else {\n // right\n targetX = targetLeft + targetW;\n const margin = targetH * 0.2;\n const span = targetH * 0.6;\n targetY =\n count === 1\n ? targetTop + targetH / 2\n : targetTop + margin + (span * (index + 0.5)) / count;\n }\n\n // Compute jogYOffset: stagger horizontal segments for sibling exits\n // from the same source node so paths don't overlap\n let jogYOffset = 0;\n if (targetFace === 'top' && scope) {\n const SIBLING_SPACING = 8;\n const MAX_SPREAD = 50;\n\n const siblings: { fromId: string; targetX: number }[] = [];\n this.connections.forEach((conn) => {\n if (conn.scope === scope && conn.toId !== toId) {\n const connFromEl = document.getElementById(conn.fromId);\n const connToEl = document.getElementById(conn.toId);\n if (connFromEl && connToEl) {\n const connFromRect = connFromEl.getBoundingClientRect();\n const connToRect = connToEl.getBoundingClientRect();\n const connSourceX =\n connFromRect.left + connFromRect.width / 2 - canvasRect.left;\n const connSourceY = connFromRect.bottom - canvasRect.top;\n const connFace = this.determineTargetFace(\n connSourceX,\n connSourceY,\n connToRect,\n canvasRect\n );\n if (connFace === 'top') {\n const connTargetLeft = connToRect.left - canvasRect.left;\n const connTargetW = connToRect.width;\n siblings.push({\n fromId: conn.fromId,\n targetX: connTargetLeft + connTargetW / 2\n });\n }\n }\n }\n });\n\n if (siblings.length > 0) {\n siblings.push({ fromId, targetX });\n siblings.sort((a, b) => a.targetX - b.targetX);\n const idx = siblings.findIndex((s) => s.fromId === fromId);\n const sibCount = siblings.length;\n const rawSpread = (sibCount - 1) * SIBLING_SPACING;\n const spacing =\n rawSpread > MAX_SPREAD\n ? MAX_SPREAD / (sibCount - 1)\n : SIBLING_SPACING;\n jogYOffset = (idx - (sibCount - 1) / 2) * spacing;\n }\n }\n\n return { sourceX, sourceY, targetX, targetY, targetFace, jogYOffset };\n }\n\n // --- SVG creation and management ---\n\n private createSVGElement(): {\n svgEl: SVGSVGElement;\n pathEl: SVGPathElement;\n arrowEl: SVGPolygonElement;\n } {\n const svgEl = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svgEl.classList.add('plumb-connector');\n svgEl.style.position = 'absolute';\n svgEl.style.left = '0';\n svgEl.style.top = '0';\n svgEl.style.width = '100%';\n svgEl.style.height = '100%';\n svgEl.style.pointerEvents = 'none';\n svgEl.style.overflow = 'visible';\n\n const pathEl = document.createElementNS(\n 'http://www.w3.org/2000/svg',\n 'path'\n );\n pathEl.setAttribute('fill', 'none');\n pathEl.setAttribute('stroke', 'var(--color-connectors)');\n pathEl.setAttribute('stroke-width', '3');\n pathEl.style.pointerEvents = 'stroke';\n\n const arrowEl = document.createElementNS(\n 'http://www.w3.org/2000/svg',\n 'polygon'\n );\n arrowEl.setAttribute('fill', 'var(--color-connectors)');\n arrowEl.classList.add('plumb-arrow');\n arrowEl.style.pointerEvents = 'fill';\n arrowEl.style.cursor = 'pointer';\n\n svgEl.appendChild(pathEl);\n svgEl.appendChild(arrowEl);\n\n // Hover support\n const addHover = () => svgEl.classList.add('hover');\n const removeHover = () => svgEl.classList.remove('hover');\n pathEl.addEventListener('mouseenter', addHover);\n pathEl.addEventListener('mouseleave', removeHover);\n arrowEl.addEventListener('mouseenter', addHover);\n arrowEl.addEventListener('mouseleave', removeHover);\n\n return { svgEl, pathEl, arrowEl };\n }\n\n private updateSVGPath(\n pathEl: SVGPathElement,\n arrowEl: SVGPolygonElement,\n sourceX: number,\n sourceY: number,\n targetX: number,\n targetY: number,\n targetFace: TargetFace = 'top',\n jogYOffset = 0\n ) {\n const aw = ARROW_HALF_WIDTH;\n const al = ARROW_LENGTH;\n const stubBehindArrow = 8;\n\n // Path ends at arrow BASE (not tip) so the line never pokes through the front.\n // The arrow polygon covers from base to the node edge (tip).\n let pathTargetX = targetX;\n let pathTargetY = targetY;\n if (targetFace === 'top') {\n pathTargetY = targetY - al;\n } else if (targetFace === 'left') {\n pathTargetX = targetX - al;\n } else if (targetFace === 'right') {\n pathTargetX = targetX + al;\n }\n\n const effectiveStub = stubBehindArrow;\n const d = calculateFlowchartPath(\n sourceX,\n sourceY,\n pathTargetX,\n pathTargetY,\n EXIT_STUB,\n effectiveStub,\n 5,\n targetFace,\n jogYOffset\n );\n pathEl.setAttribute('d', d);\n\n // Arrow tip at node edge, base extends outward\n if (targetFace === 'top') {\n arrowEl.setAttribute(\n 'points',\n `${targetX},${targetY} ${targetX - aw},${targetY - al} ${\n targetX + aw\n },${targetY - al}`\n );\n } else if (targetFace === 'left') {\n arrowEl.setAttribute(\n 'points',\n `${targetX},${targetY} ${targetX - al},${targetY - aw} ${\n targetX - al\n },${targetY + aw}`\n );\n } else {\n arrowEl.setAttribute(\n 'points',\n `${targetX},${targetY} ${targetX + al},${targetY - aw} ${\n targetX + al\n },${targetY + aw}`\n );\n }\n }\n\n private createConnectionSVG(\n exitId: string,\n scope: string,\n toId: string\n ): boolean {\n const endpoints = this.getConnectionEndpoints(exitId, toId, scope);\n if (!endpoints) return false;\n\n const { svgEl, pathEl, arrowEl } = this.createSVGElement();\n this.updateSVGPath(\n pathEl,\n arrowEl,\n endpoints.sourceX,\n endpoints.sourceY,\n endpoints.targetX,\n endpoints.targetY,\n endpoints.targetFace,\n endpoints.jogYOffset\n );\n this.canvas.appendChild(svgEl);\n\n this.connections.set(exitId, {\n scope,\n fromId: exitId,\n toId,\n svgEl,\n pathEl,\n arrowEl\n });\n\n // Make arrowhead draggable for picking up existing connections\n const DRAG_THRESHOLD = 5;\n const onArrowMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return;\n e.stopPropagation();\n\n const startX = e.clientX;\n const startY = e.clientY;\n\n const onMove = (me: MouseEvent) => {\n const dx = me.clientX - startX;\n const dy = me.clientY - startY;\n if (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD) {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n this.startDrag(exitId, scope, toId, me);\n }\n };\n\n const onUp = () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n };\n arrowEl.addEventListener('mousedown', onArrowMouseDown);\n\n // Mark the exit element as connected\n const exitEl = document.getElementById(exitId);\n if (exitEl) {\n exitEl.classList.add('connected');\n }\n\n // Create activity overlay if activity data exists for this segment\n if (this.activityData) {\n const activityKey = `${exitId}:${toId}`;\n const count = this.activityData.segments[activityKey];\n if (count && count > 0) {\n const overlayEl = this.createOverlayElement(count, activityKey);\n this.canvas.appendChild(overlayEl);\n this.overlays.set(exitId, overlayEl);\n this.updateOverlayPosition(exitId);\n }\n }\n\n return true;\n }\n\n private updateConnectionSVG(exitId: string) {\n const conn = this.connections.get(exitId);\n if (!conn) return;\n\n const endpoints = this.getConnectionEndpoints(\n conn.fromId,\n conn.toId,\n conn.scope\n );\n if (!endpoints) return;\n\n this.updateSVGPath(\n conn.pathEl,\n conn.arrowEl,\n endpoints.sourceX,\n endpoints.sourceY,\n endpoints.targetX,\n endpoints.targetY,\n endpoints.targetFace,\n endpoints.jogYOffset\n );\n this.updateOverlayPosition(exitId);\n }\n\n private removeConnectionSVG(exitId: string) {\n const conn = this.connections.get(exitId);\n if (!conn) return;\n\n const overlay = this.overlays.get(exitId);\n if (overlay) {\n overlay.remove();\n this.overlays.delete(exitId);\n }\n\n conn.svgEl.remove();\n this.connections.delete(exitId);\n }\n\n // --- Repaint ---\n\n public repaintEverything() {\n this.connections.forEach((_conn, exitId) => {\n this.updateConnectionSVG(exitId);\n });\n }\n\n public revalidate(ids: string[]) {\n // Find all connections directly involving the given IDs\n const directExits: string[] = [];\n const affectedTargets = new Set<string>();\n\n this.connections.forEach((conn, exitId) => {\n if (\n ids.includes(conn.fromId) ||\n ids.includes(conn.toId) ||\n ids.includes(conn.scope)\n ) {\n directExits.push(exitId);\n affectedTargets.add(conn.toId);\n }\n });\n\n // Also repaint sibling connections that share a target\n // (so anchor distribution stays correct during drag)\n const allExitsToRepaint = new Set(directExits);\n this.connections.forEach((conn, exitId) => {\n if (affectedTargets.has(conn.toId)) {\n allExitsToRepaint.add(exitId);\n }\n });\n\n allExitsToRepaint.forEach((exitId) => {\n this.updateConnectionSVG(exitId);\n });\n }\n\n // --- Connection removal ---\n\n public forgetNode(nodeId: string) {\n // Remove all connections where this node is source or target\n const toRemove: string[] = [];\n this.connections.forEach((conn, exitId) => {\n if (conn.scope === nodeId || conn.toId === nodeId) {\n toRemove.push(exitId);\n }\n });\n toRemove.forEach((exitId) => this.removeConnectionSVG(exitId));\n\n // Remove source listeners for exits of this node\n const exitEls = document.getElementById(nodeId)?.querySelectorAll('.exit');\n if (exitEls) {\n exitEls.forEach((el) => {\n const id = el.id;\n if (this.sources.has(id)) {\n this.sources.get(id)();\n this.sources.delete(id);\n }\n });\n }\n }\n\n public removeNodeConnections(nodeId: string, exitIds?: string[]) {\n // Only remove outbound connections from this node's exits.\n // Inbound connections are managed by their source nodes and\n // will repaint correctly on the next revalidate.\n const exits =\n exitIds ||\n Array.from(\n document.getElementById(nodeId)?.querySelectorAll('.exit') || []\n ).map((el) => el.id);\n\n exits.forEach((exitId) => this.removeConnectionSVG(exitId));\n }\n\n public removeExitConnection(exitId: string): boolean {\n if (!this.connections.has(exitId)) return false;\n this.removeConnectionSVG(exitId);\n return true;\n }\n\n public removeAllEndpoints(nodeId: string) {\n // Remove source listeners for this node's exits\n const exitEls = document.getElementById(nodeId)?.querySelectorAll('.exit');\n if (exitEls) {\n exitEls.forEach((el) => {\n const id = el.id;\n if (this.sources.has(id)) {\n this.sources.get(id)();\n this.sources.delete(id);\n }\n });\n }\n }\n\n // --- Connection state ---\n\n public setConnectionRemovingState(\n exitId: string,\n isRemoving: boolean\n ): boolean {\n const conn = this.connections.get(exitId);\n if (!conn) return false;\n\n if (isRemoving) {\n conn.svgEl.classList.add('removing');\n } else {\n conn.svgEl.classList.remove('removing');\n }\n return true;\n }\n\n // --- Activity overlays ---\n\n public setActivityData(\n activityData: { segments: { [key: string]: number } } | null\n ) {\n this.activityData = activityData;\n this.clearRecentContactsCache();\n this.updateActivityOverlays();\n }\n\n private updateActivityOverlays() {\n if (!this.activityData) {\n this.overlays.forEach((el) => el.remove());\n this.overlays.clear();\n return;\n }\n\n const activeExitIds = new Set<string>();\n\n this.connections.forEach((conn, exitId) => {\n const activityKey = `${conn.fromId}:${conn.toId}`;\n const count = this.activityData.segments[activityKey];\n\n if (count && count > 0) {\n activeExitIds.add(exitId);\n let overlayEl = this.overlays.get(exitId);\n\n if (!overlayEl) {\n overlayEl = this.createOverlayElement(count, activityKey);\n this.canvas.appendChild(overlayEl);\n this.overlays.set(exitId, overlayEl);\n } else {\n overlayEl.textContent = count.toLocaleString();\n overlayEl.setAttribute('data-activity-key', activityKey);\n }\n\n this.updateOverlayPosition(exitId);\n }\n });\n\n // Remove overlays for connections that no longer have activity\n this.overlays.forEach((el, exitId) => {\n if (!activeExitIds.has(exitId)) {\n el.remove();\n this.overlays.delete(exitId);\n }\n });\n }\n\n private createOverlayElement(\n count: number,\n activityKey: string\n ): HTMLElement {\n const el = document.createElement('div');\n el.className = 'activity-overlay';\n el.textContent = count.toLocaleString();\n el.setAttribute('data-activity-key', activityKey);\n\n el.addEventListener('mouseenter', () => {\n const flowUuid = this.getFlowUuid();\n if (flowUuid) {\n this.fetchRecentContacts(activityKey, flowUuid);\n this.showContactsTimeout = window.setTimeout(() => {\n this.showRecentContacts(activityKey, flowUuid);\n }, 500);\n }\n });\n\n el.addEventListener('mouseleave', () => {\n if (this.showContactsTimeout) {\n clearTimeout(this.showContactsTimeout);\n this.showContactsTimeout = null;\n }\n this.hoveredActivityKey = null;\n this.hideRecentContacts();\n });\n\n return el;\n }\n\n private updateOverlayPosition(exitId: string) {\n const overlayEl = this.overlays.get(exitId);\n const conn = this.connections.get(exitId);\n if (!overlayEl || !conn) return;\n\n const endpoints = this.getConnectionEndpoints(\n conn.fromId,\n conn.toId,\n conn.scope\n );\n if (!endpoints) return;\n\n overlayEl.style.position = 'absolute';\n overlayEl.style.left = `${endpoints.sourceX}px`;\n overlayEl.style.top = `${endpoints.sourceY + EXIT_STUB / 2}px`;\n overlayEl.style.transform = 'translate(-50%, -50%)';\n }\n\n private getFlowUuid(): string | null {\n return this.editor?.definition?.uuid || null;\n }\n\n // --- Recent contacts ---\n\n private async fetchRecentContacts(activityKey: string, flowUuid: string) {\n if (\n this.recentContactsCache[activityKey] ||\n this.pendingFetches[activityKey]\n ) {\n return;\n }\n\n const controller = new AbortController();\n this.pendingFetches[activityKey] = controller;\n\n try {\n const [exitUuid, destinationUuid] = activityKey.split(':');\n const endpoint = `/flow/recent_contacts/${flowUuid}/${exitUuid}/${destinationUuid}/`;\n const response = await fetch(endpoint, { signal: controller.signal });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const data = await response.json();\n this.recentContactsCache[activityKey] = Array.isArray(data)\n ? data\n : data.results || [];\n } catch (error) {\n if ((error as Error).name !== 'AbortError') {\n console.error('Failed to fetch recent contacts:', error);\n }\n } finally {\n delete this.pendingFetches[activityKey];\n }\n }\n\n private async showRecentContacts(activityKey: string, flowUuid: string) {\n const overlayElement = this.findOverlayForActivityKey(activityKey);\n if (!overlayElement) return;\n\n if (this.hideContactsTimeout) {\n clearTimeout(this.hideContactsTimeout);\n this.hideContactsTimeout = null;\n }\n\n this.hoveredActivityKey = activityKey;\n\n if (!this.recentContactsPopup) {\n this.recentContactsPopup = document.createElement('div');\n this.recentContactsPopup.className = 'recent-contacts-popup';\n this.recentContactsPopup.style.position = 'absolute';\n this.recentContactsPopup.style.zIndex = '1015';\n this.recentContactsPopup.style.display = 'none';\n document.body.appendChild(this.recentContactsPopup);\n\n this.recentContactsPopup.onmouseenter = () => {\n if (this.hideContactsTimeout) {\n clearTimeout(this.hideContactsTimeout);\n this.hideContactsTimeout = null;\n }\n };\n this.recentContactsPopup.onmouseleave = () => {\n this.hoveredActivityKey = null;\n this.hideRecentContacts();\n };\n\n this.recentContactsPopup.onclick = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n if (target.classList.contains('contact-name')) {\n this.hideRecentContacts(false);\n const contactUuid = target.getAttribute('data-uuid');\n if (contactUuid) {\n this.editor.fireCustomEvent('temba-contact-clicked', {\n uuid: contactUuid\n });\n }\n }\n };\n }\n\n if (this.recentContactsCache[activityKey]) {\n this.renderRecentContactsPopup(this.recentContactsCache[activityKey]);\n this.positionPopup(overlayElement);\n } else {\n this.recentContactsPopup.innerHTML =\n '<div class=\"no-contacts-message\">Loading...</div>';\n this.positionPopup(overlayElement);\n await this.fetchRecentContacts(activityKey, flowUuid);\n if (this.hoveredActivityKey === activityKey) {\n this.renderRecentContactsPopup(\n this.recentContactsCache[activityKey] || []\n );\n this.positionPopup(overlayElement);\n }\n }\n }\n\n private findOverlayForActivityKey(activityKey: string): HTMLElement | null {\n for (const [, el] of this.overlays) {\n if (el.getAttribute('data-activity-key') === activityKey) {\n return el;\n }\n }\n return null;\n }\n\n private positionPopup(overlayElement: HTMLElement) {\n if (!this.recentContactsPopup) return;\n const rect = overlayElement.getBoundingClientRect();\n this.recentContactsPopup.style.left = `${rect.left + window.scrollX}px`;\n this.recentContactsPopup.style.top = `${\n rect.bottom + window.scrollY + 5\n }px`;\n this.recentContactsPopup.style.display = '';\n this.recentContactsPopup.classList.remove('show');\n void this.recentContactsPopup.offsetWidth;\n this.recentContactsPopup.classList.add('show');\n }\n\n private renderRecentContactsPopup(recentContacts: any[]) {\n if (!this.recentContactsPopup) return;\n\n if (recentContacts.length === 0) {\n this.recentContactsPopup.innerHTML =\n '<div class=\"no-contacts-message\">No Recent Contacts</div>';\n return;\n }\n\n let html = '<div class=\"popup-title\">Recent Contacts</div>';\n recentContacts.forEach((contact: any) => {\n html += '<div class=\"contact-row\">';\n html += `<div class=\"contact-name\" data-uuid=\"${contact.contact.uuid}\">${contact.contact.name}</div>`;\n if (contact.operand) {\n html += `<div class=\"contact-operand\">${contact.operand}</div>`;\n }\n if (contact.time) {\n const time = new Date(contact.time);\n const diffMs = Date.now() - time.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n let timeStr = '';\n if (diffMins < 1) timeStr = 'just now';\n else if (diffMins < 60) timeStr = `${diffMins}m ago`;\n else if (diffHours < 24) timeStr = `${diffHours}h ago`;\n else timeStr = `${diffDays}d ago`;\n html += `<div class=\"contact-time\">${timeStr}</div>`;\n }\n html += '</div>';\n });\n this.recentContactsPopup.innerHTML = html;\n }\n\n private hideRecentContacts(wait = true) {\n if (!wait) {\n if (this.recentContactsPopup) {\n this.recentContactsPopup.classList.remove('show');\n this.recentContactsPopup.style.display = 'none';\n this.hoveredActivityKey = null;\n }\n return;\n }\n\n this.hideContactsTimeout = window.setTimeout(() => {\n if (!this.hoveredActivityKey && this.recentContactsPopup) {\n this.recentContactsPopup.classList.remove('show');\n this.recentContactsPopup.style.display = 'none';\n this.hoveredActivityKey = null;\n }\n }, 200);\n }\n\n public clearRecentContactsCache() {\n this.recentContactsCache = {};\n Object.values(this.pendingFetches).forEach((controller) =>\n controller.abort()\n );\n this.pendingFetches = {};\n }\n\n // --- Drag-and-drop ---\n\n private startDrag(\n exitId: string,\n scope: string,\n originalTargetId: string | null,\n e: MouseEvent\n ) {\n // Remove existing connection SVG for this exit (the connection is being dragged away)\n this.removeConnectionSVG(exitId);\n\n const { svgEl, pathEl, arrowEl } = this.createSVGElement();\n svgEl.classList.add('dragging');\n // Ensure the drag SVG never intercepts mouse events (e.g. hover detection on nodes)\n pathEl.style.pointerEvents = 'none';\n arrowEl.style.pointerEvents = 'none';\n this.canvas.appendChild(svgEl);\n\n // Calculate source point\n const exitEl = document.getElementById(exitId);\n if (!exitEl) {\n svgEl.remove();\n return;\n }\n\n const canvasRect = this.canvas.getBoundingClientRect();\n const exitRect = exitEl.getBoundingClientRect();\n const sourceX = exitRect.left + exitRect.width / 2 - canvasRect.left;\n const sourceY = exitRect.bottom - canvasRect.top;\n\n const aw = ARROW_HALF_WIDTH;\n const al = ARROW_LENGTH;\n const stubBehindArrow = 8;\n\n // Update the drag path and arrow based on cursor position.\n // Arrow trails just before the cursor (between source and cursor).\n const cursorGap = CURSOR_GAP;\n const updateDragPath = (cx: number, cy: number) => {\n const goingUp = cy < sourceY;\n\n let routeFace: TargetFace = 'top';\n if (goingUp) {\n routeFace = cx < sourceX ? 'left' : 'right';\n }\n\n // Position the arrow so its top edge sits just before the cursor.\n // \"Top\" = smallest Y on screen, which is the base for a downward\n // arrow and the tip for an upward arrow.\n let arrowBaseY: number;\n if (goingUp) {\n // Arrow points up: tip just below cursor, base below that\n arrowBaseY = cy + cursorGap + al;\n } else {\n // Arrow points down: base just above cursor, tip below\n arrowBaseY = cy - cursorGap;\n }\n\n const d = calculateFlowchartPath(\n sourceX,\n sourceY,\n cx,\n arrowBaseY,\n EXIT_STUB,\n goingUp ? 0 : stubBehindArrow,\n 5,\n routeFace\n );\n pathEl.setAttribute('d', d);\n\n if (goingUp) {\n const tipY = cy + cursorGap;\n arrowEl.setAttribute(\n 'points',\n `${cx},${tipY} ${cx - aw},${arrowBaseY} ${cx + aw},${arrowBaseY}`\n );\n } else {\n const tipY = arrowBaseY + al;\n arrowEl.setAttribute(\n 'points',\n `${cx},${tipY} ${cx - aw},${arrowBaseY} ${cx + aw},${arrowBaseY}`\n );\n }\n };\n\n // Initial path to cursor\n const cursorX = e.clientX - canvasRect.left;\n const cursorY = e.clientY - canvasRect.top;\n updateDragPath(cursorX, cursorY);\n\n this.connectionDragging = true;\n\n const onMove = (me: MouseEvent) => {\n const cx = me.clientX - canvasRect.left;\n const cy = me.clientY - canvasRect.top;\n updateDragPath(cx, cy);\n };\n\n const onUp = (_me: MouseEvent) => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n\n // Remove the drag SVG\n svgEl.remove();\n this.connectionDragging = false;\n this.dragState = null;\n\n // Fire abort event so Editor can handle connection logic\n this.notifyListeners('connection:abort', {\n source: exitEl,\n sourceId: exitId,\n target: { id: originalTargetId },\n data: { nodeId: scope }\n });\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n\n this.dragState = {\n sourceId: exitId,\n scope,\n originalTargetId,\n svgEl,\n pathEl,\n arrowEl,\n onMove,\n onUp\n };\n\n // Fire drag event so Editor knows a drag has started\n this.notifyListeners('connection:drag', {\n sourceId: exitId,\n sourceX,\n sourceY,\n data: { nodeId: scope },\n target: { id: originalTargetId }\n });\n }\n\n // --- Reset ---\n\n public reset() {\n if (this.connectionWait) {\n cancelAnimationFrame(this.connectionWait);\n this.connectionWait = null;\n }\n this.pendingConnections = [];\n\n // Remove all connection SVGs\n this.connections.forEach((conn) => conn.svgEl.remove());\n this.connections.clear();\n\n // Remove all activity overlays\n this.overlays.forEach((el) => el.remove());\n this.overlays.clear();\n\n // Clean up recent contacts popup\n this.hideRecentContacts(false);\n if (this.recentContactsPopup) {\n this.recentContactsPopup.remove();\n this.recentContactsPopup = null;\n }\n this.recentContactsCache = {};\n Object.values(this.pendingFetches).forEach((c) => c.abort());\n this.pendingFetches = {};\n\n // Remove all source listeners\n this.sources.forEach((cleanup) => cleanup());\n this.sources.clear();\n\n // Clean up any active drag\n if (this.dragState) {\n document.removeEventListener('mousemove', this.dragState.onMove);\n document.removeEventListener('mouseup', this.dragState.onUp);\n this.dragState.svgEl.remove();\n this.dragState = null;\n this.connectionDragging = false;\n }\n }\n}\n"]}
@@ -281,7 +281,7 @@ export class StickyNote extends RapidElement {
281
281
  }
282
282
  handleBodyBlur(event) {
283
283
  const target = event.target;
284
- const newBody = target.textContent || '';
284
+ const newBody = target.innerText || '';
285
285
  if (this.data && newBody !== this.data.body) {
286
286
  getStore()
287
287
  .getState()
@@ -301,7 +301,16 @@ export class StickyNote extends RapidElement {
301
301
  // Otherwise, stop propagation to enable editing
302
302
  event.stopPropagation();
303
303
  }
304
- handleKeyDown(event) {
304
+ handleTitleKeyDown(event) {
305
+ if (event.key === 'Enter') {
306
+ event.preventDefault();
307
+ event.target.blur();
308
+ }
309
+ if (event.key === 'Escape') {
310
+ event.target.blur();
311
+ }
312
+ }
313
+ handleBodyKeyDown(event) {
305
314
  if (event.key === 'Enter' && !event.shiftKey) {
306
315
  event.preventDefault();
307
316
  event.target.blur();
@@ -348,7 +357,7 @@ export class StickyNote extends RapidElement {
348
357
  class="sticky-title"
349
358
  contenteditable="${!this.isTranslating}"
350
359
  @blur="${this.handleTitleBlur}"
351
- @keydown="${this.handleKeyDown}"
360
+ @keydown="${this.handleTitleKeyDown}"
352
361
  @mousedown="${this.handleContentMouseDown}"
353
362
  .textContent="${this.data.title}"
354
363
  ></div>
@@ -358,7 +367,7 @@ export class StickyNote extends RapidElement {
358
367
  class="sticky-body"
359
368
  contenteditable="${!this.isTranslating}"
360
369
  @blur="${this.handleBodyBlur}"
361
- @keydown="${this.handleKeyDown}"
370
+ @keydown="${this.handleBodyKeyDown}"
362
371
  @mousedown="${this.handleContentMouseDown}"
363
372
  .textContent="${this.data.body}"
364
373
  ></div>