@nyaruka/temba-components 0.129.10 → 0.130.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 (316) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/demo/components/flow/example.html +5 -1
  3. package/demo/data/flows/sample-flow.json +217 -113
  4. package/dist/temba-components.js +310 -356
  5. package/dist/temba-components.js.map +1 -1
  6. package/out-tsc/src/events.js.map +1 -1
  7. package/out-tsc/src/flow/CanvasNode.js +3 -35
  8. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  9. package/out-tsc/src/flow/Editor.js +9 -6
  10. package/out-tsc/src/flow/Editor.js.map +1 -1
  11. package/out-tsc/src/flow/NodeEditor.js +44 -11
  12. package/out-tsc/src/flow/NodeEditor.js.map +1 -1
  13. package/out-tsc/src/flow/actions/add_contact_groups.js +1 -1
  14. package/out-tsc/src/flow/actions/add_contact_groups.js.map +1 -1
  15. package/out-tsc/src/flow/actions/add_contact_urn.js +1 -1
  16. package/out-tsc/src/flow/actions/add_contact_urn.js.map +1 -1
  17. package/out-tsc/src/flow/actions/add_input_labels.js +1 -1
  18. package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -1
  19. package/out-tsc/src/flow/actions/remove_contact_groups.js +1 -1
  20. package/out-tsc/src/flow/actions/remove_contact_groups.js.map +1 -1
  21. package/out-tsc/src/flow/actions/send_email.js +9 -0
  22. package/out-tsc/src/flow/actions/send_email.js.map +1 -1
  23. package/out-tsc/src/flow/actions/send_msg.js +7 -8
  24. package/out-tsc/src/flow/actions/send_msg.js.map +1 -1
  25. package/out-tsc/src/flow/actions/set_contact_channel.js +25 -4
  26. package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -1
  27. package/out-tsc/src/flow/actions/set_contact_field.js +51 -1
  28. package/out-tsc/src/flow/actions/set_contact_field.js.map +1 -1
  29. package/out-tsc/src/flow/actions/set_contact_language.js +70 -2
  30. package/out-tsc/src/flow/actions/set_contact_language.js.map +1 -1
  31. package/out-tsc/src/flow/actions/set_contact_name.js +27 -2
  32. package/out-tsc/src/flow/actions/set_contact_name.js.map +1 -1
  33. package/out-tsc/src/flow/actions/set_contact_status.js +32 -2
  34. package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -1
  35. package/out-tsc/src/flow/actions/set_run_result.js +13 -11
  36. package/out-tsc/src/flow/actions/set_run_result.js.map +1 -1
  37. package/out-tsc/src/flow/actions/split_by_expression_example.js +4 -4
  38. package/out-tsc/src/flow/actions/split_by_expression_example.js.map +1 -1
  39. package/out-tsc/src/flow/config.js +2 -8
  40. package/out-tsc/src/flow/config.js.map +1 -1
  41. package/out-tsc/src/flow/forms/index.js +2 -0
  42. package/out-tsc/src/flow/forms/index.js.map +1 -0
  43. package/out-tsc/src/flow/nodes/split_by_llm.js +101 -0
  44. package/out-tsc/src/flow/nodes/split_by_llm.js.map +1 -0
  45. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +4 -89
  46. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -1
  47. package/out-tsc/src/flow/nodes/split_by_random.js +117 -0
  48. package/out-tsc/src/flow/nodes/split_by_random.js.map +1 -1
  49. package/out-tsc/src/flow/nodes/split_by_subflow.js +123 -3
  50. package/out-tsc/src/flow/nodes/split_by_subflow.js.map +1 -1
  51. package/out-tsc/src/flow/nodes/split_by_ticket.js +114 -13
  52. package/out-tsc/src/flow/nodes/split_by_ticket.js.map +1 -1
  53. package/out-tsc/src/flow/nodes/split_by_webhook.js +158 -12
  54. package/out-tsc/src/flow/nodes/split_by_webhook.js.map +1 -1
  55. package/out-tsc/src/flow/types.js.map +1 -1
  56. package/out-tsc/src/form/ArrayEditor.js +9 -25
  57. package/out-tsc/src/form/ArrayEditor.js.map +1 -1
  58. package/out-tsc/src/form/FieldRenderer.js +6 -64
  59. package/out-tsc/src/form/FieldRenderer.js.map +1 -1
  60. package/out-tsc/src/form/select/Select.js +29 -58
  61. package/out-tsc/src/form/select/Select.js.map +1 -1
  62. package/out-tsc/src/live/ContactChat.js +48 -66
  63. package/out-tsc/src/live/ContactChat.js.map +1 -1
  64. package/out-tsc/src/utils.js +118 -0
  65. package/out-tsc/src/utils.js.map +1 -1
  66. package/out-tsc/test/nodes/split_by_llm.test.js +174 -0
  67. package/out-tsc/test/nodes/split_by_llm.test.js.map +1 -0
  68. package/out-tsc/test/nodes/split_by_random.test.js +0 -6
  69. package/out-tsc/test/nodes/split_by_random.test.js.map +1 -1
  70. package/out-tsc/test/temba-field-renderer.test.js +6 -3
  71. package/out-tsc/test/temba-field-renderer.test.js.map +1 -1
  72. package/out-tsc/test/utils.test.js +18 -0
  73. package/out-tsc/test/utils.test.js.map +1 -1
  74. package/package.json +1 -1
  75. package/screenshots/truth/actions/add_contact_groups/editor/descriptive-group-names.png +0 -0
  76. package/screenshots/truth/actions/add_contact_groups/editor/long-group-names.png +0 -0
  77. package/screenshots/truth/actions/add_contact_groups/editor/many-groups.png +0 -0
  78. package/screenshots/truth/actions/add_contact_groups/editor/multiple-groups.png +0 -0
  79. package/screenshots/truth/actions/add_contact_groups/editor/single-group.png +0 -0
  80. package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
  81. package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
  82. package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
  83. package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
  84. package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
  85. package/screenshots/truth/actions/call_llm/editor/information-extraction.png +0 -0
  86. package/screenshots/truth/actions/call_llm/editor/sentiment-analysis.png +0 -0
  87. package/screenshots/truth/actions/call_llm/editor/summarization.png +0 -0
  88. package/screenshots/truth/actions/call_llm/editor/translation-task.png +0 -0
  89. package/screenshots/truth/actions/remove_contact_groups/editor/cleanup-groups.png +0 -0
  90. package/screenshots/truth/actions/remove_contact_groups/editor/long-descriptive-group-names.png +0 -0
  91. package/screenshots/truth/actions/remove_contact_groups/editor/many-groups.png +0 -0
  92. package/screenshots/truth/actions/remove_contact_groups/editor/multiple-groups.png +0 -0
  93. package/screenshots/truth/actions/remove_contact_groups/editor/remove-from-all-groups.png +0 -0
  94. package/screenshots/truth/actions/remove_contact_groups/editor/single-group.png +0 -0
  95. package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
  96. package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
  97. package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
  98. package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
  99. package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
  100. package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
  101. package/screenshots/truth/actions/send_email/editor/complex-business-email.png +0 -0
  102. package/screenshots/truth/actions/send_email/editor/empty-body.png +0 -0
  103. package/screenshots/truth/actions/send_email/editor/empty-subject.png +0 -0
  104. package/screenshots/truth/actions/send_email/editor/long-subject.png +0 -0
  105. package/screenshots/truth/actions/send_email/editor/multiline-body.png +0 -0
  106. package/screenshots/truth/actions/send_email/editor/multiple-recipients.png +0 -0
  107. package/screenshots/truth/actions/send_email/editor/simple-email.png +0 -0
  108. package/screenshots/truth/actions/send_email/editor/with-expressions.png +0 -0
  109. package/screenshots/truth/actions/send_msg/editor/long-quick-replies.png +0 -0
  110. package/screenshots/truth/actions/send_msg/editor/multiline-text-with-replies.png +0 -0
  111. package/screenshots/truth/actions/send_msg/editor/simple-text.png +0 -0
  112. package/screenshots/truth/actions/send_msg/editor/text-with-linebreaks.png +0 -0
  113. package/screenshots/truth/actions/send_msg/editor/text-with-many-quick-replies.png +0 -0
  114. package/screenshots/truth/actions/send_msg/editor/text-with-quick-replies.png +0 -0
  115. package/screenshots/truth/actions/send_msg/editor/text-without-quick-replies.png +0 -0
  116. package/screenshots/truth/checkbox/checkbox-label-background-hover.png +0 -0
  117. package/screenshots/truth/checkbox/checkbox-no-label-no-background-hover.png +0 -0
  118. package/screenshots/truth/checkbox/checkbox-whitespace-label-no-background-hover.png +0 -0
  119. package/screenshots/truth/checkbox/checkbox-with-help-text.png +0 -0
  120. package/screenshots/truth/checkbox/checked.png +0 -0
  121. package/screenshots/truth/checkbox/default.png +0 -0
  122. package/screenshots/truth/colorpicker/default.png +0 -0
  123. package/screenshots/truth/colorpicker/focused.png +0 -0
  124. package/screenshots/truth/colorpicker/initialized.png +0 -0
  125. package/screenshots/truth/colorpicker/selected.png +0 -0
  126. package/screenshots/truth/compose/attachments-tab.png +0 -0
  127. package/screenshots/truth/compose/attachments-with-files.png +0 -0
  128. package/screenshots/truth/compose/intial-text.png +0 -0
  129. package/screenshots/truth/compose/no-counter.png +0 -0
  130. package/screenshots/truth/compose/wraps-text-and-spaces.png +0 -0
  131. package/screenshots/truth/compose/wraps-text-and-url.png +0 -0
  132. package/screenshots/truth/compose/wraps-text-no-spaces.png +0 -0
  133. package/screenshots/truth/contacts/chat-failure.png +0 -0
  134. package/screenshots/truth/contacts/chat-for-active-contact.png +0 -0
  135. package/screenshots/truth/contacts/chat-sends-attachments-only.png +0 -0
  136. package/screenshots/truth/contacts/chat-sends-text-and-attachments.png +0 -0
  137. package/screenshots/truth/contacts/chat-sends-text-only.png +0 -0
  138. package/screenshots/truth/counter/summary.png +0 -0
  139. package/screenshots/truth/counter/text.png +0 -0
  140. package/screenshots/truth/counter/unicode-variables.png +0 -0
  141. package/screenshots/truth/counter/unicode.png +0 -0
  142. package/screenshots/truth/counter/variable.png +0 -0
  143. package/screenshots/truth/datepicker/date-truncated-time.png +0 -0
  144. package/screenshots/truth/datepicker/date.png +0 -0
  145. package/screenshots/truth/datepicker/initial-timezone.png +0 -0
  146. package/screenshots/truth/datepicker/range-picker-editing-start.png +0 -0
  147. package/screenshots/truth/datepicker/updated-keyboard-date.png +0 -0
  148. package/screenshots/truth/dialog/focused.png +0 -0
  149. package/screenshots/truth/dropdown/right-edge-collision.png +0 -0
  150. package/screenshots/truth/editor/router.png +0 -0
  151. package/screenshots/truth/editor/send_msg.png +0 -0
  152. package/screenshots/truth/editor/set_contact_language.png +0 -0
  153. package/screenshots/truth/editor/set_contact_name.png +0 -0
  154. package/screenshots/truth/editor/set_run_result.png +0 -0
  155. package/screenshots/truth/editor/wait.png +0 -0
  156. package/screenshots/truth/field-renderer/checkbox-checked.png +0 -0
  157. package/screenshots/truth/field-renderer/checkbox-unchecked.png +0 -0
  158. package/screenshots/truth/field-renderer/checkbox-with-errors.png +0 -0
  159. package/screenshots/truth/field-renderer/context-comparison.png +0 -0
  160. package/screenshots/truth/field-renderer/key-value-with-label.png +0 -0
  161. package/screenshots/truth/field-renderer/message-editor-with-label.png +0 -0
  162. package/screenshots/truth/field-renderer/select-multi.png +0 -0
  163. package/screenshots/truth/field-renderer/select-no-label.png +0 -0
  164. package/screenshots/truth/field-renderer/select-with-label.png +0 -0
  165. package/screenshots/truth/field-renderer/text-evaluated.png +0 -0
  166. package/screenshots/truth/field-renderer/text-no-label.png +0 -0
  167. package/screenshots/truth/field-renderer/text-with-errors.png +0 -0
  168. package/screenshots/truth/field-renderer/text-with-label.png +0 -0
  169. package/screenshots/truth/field-renderer/textarea-evaluated.png +0 -0
  170. package/screenshots/truth/field-renderer/textarea-with-label.png +0 -0
  171. package/screenshots/truth/integration/checkbox-markdown-errors.png +0 -0
  172. package/screenshots/truth/list/fields-dragging.png +0 -0
  173. package/screenshots/truth/list/fields-filtered.png +0 -0
  174. package/screenshots/truth/list/fields-hovered.png +0 -0
  175. package/screenshots/truth/list/fields.png +0 -0
  176. package/screenshots/truth/list/items-selected.png +0 -0
  177. package/screenshots/truth/list/items-updated.png +0 -0
  178. package/screenshots/truth/list/items.png +0 -0
  179. package/screenshots/truth/menu/menu-focused-with items.png +0 -0
  180. package/screenshots/truth/menu/menu-refresh-1.png +0 -0
  181. package/screenshots/truth/menu/menu-refresh-2.png +0 -0
  182. package/screenshots/truth/menu/menu-submenu.png +0 -0
  183. package/screenshots/truth/menu/menu-tasks-nextup.png +0 -0
  184. package/screenshots/truth/menu/menu-tasks.png +0 -0
  185. package/screenshots/truth/message-editor/autogrow-initial-content.png +0 -0
  186. package/screenshots/truth/message-editor/default.png +0 -0
  187. package/screenshots/truth/message-editor/drag-highlight.png +0 -0
  188. package/screenshots/truth/message-editor/filtered-attachments.png +0 -0
  189. package/screenshots/truth/message-editor/with-completion.png +0 -0
  190. package/screenshots/truth/message-editor/with-properties.png +0 -0
  191. package/screenshots/truth/modax/form.png +0 -0
  192. package/screenshots/truth/modax/simple.png +0 -0
  193. package/screenshots/truth/nodes/split_by_llm/editor/information-extraction.png +0 -0
  194. package/screenshots/truth/nodes/split_by_llm/editor/sentiment-analysis.png +0 -0
  195. package/screenshots/truth/nodes/split_by_llm/editor/summarization.png +0 -0
  196. package/screenshots/truth/nodes/split_by_llm/editor/translation-task.png +0 -0
  197. package/screenshots/truth/nodes/split_by_llm/render/information-extraction.png +0 -0
  198. package/screenshots/truth/nodes/split_by_llm/render/sentiment-analysis.png +0 -0
  199. package/screenshots/truth/nodes/split_by_llm/render/summarization.png +0 -0
  200. package/screenshots/truth/nodes/split_by_llm/render/translation-task.png +0 -0
  201. package/screenshots/truth/nodes/split_by_llm_categorize/editor/basic-categorization.png +0 -0
  202. package/screenshots/truth/nodes/split_by_llm_categorize/editor/custom-input-and-result-name.png +0 -0
  203. package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
  204. package/screenshots/truth/nodes/split_by_llm_categorize/editor/many-categories.png +0 -0
  205. package/screenshots/truth/nodes/split_by_llm_categorize/editor/minimal-categories.png +0 -0
  206. package/screenshots/truth/nodes/split_by_random/editor/ab-test-multiple-variants.png +0 -0
  207. package/screenshots/truth/nodes/split_by_random/editor/sampling-split.png +0 -0
  208. package/screenshots/truth/nodes/split_by_random/editor/three-way-split.png +0 -0
  209. package/screenshots/truth/nodes/split_by_random/editor/two-bucket-split.png +0 -0
  210. package/screenshots/truth/nodes/wait_for_digits/editor/basic-digits-wait.png +0 -0
  211. package/screenshots/truth/nodes/wait_for_digits/editor/phone-number-collection.png +0 -0
  212. package/screenshots/truth/nodes/wait_for_digits/editor/single-digit-with-timeout.png +0 -0
  213. package/screenshots/truth/nodes/wait_for_digits/editor/verification-code.png +0 -0
  214. package/screenshots/truth/nodes/wait_for_response/editor/basic-wait.png +0 -0
  215. package/screenshots/truth/nodes/wait_for_response/editor/custom-result-name.png +0 -0
  216. package/screenshots/truth/nodes/wait_for_response/editor/no-timeout.png +0 -0
  217. package/screenshots/truth/nodes/wait_for_response/editor/short-timeout.png +0 -0
  218. package/screenshots/truth/omnibox/selected.png +0 -0
  219. package/screenshots/truth/options/block.png +0 -0
  220. package/screenshots/truth/run-list/basic.png +0 -0
  221. package/screenshots/truth/select/disabled-multi-selection.png +0 -0
  222. package/screenshots/truth/select/disabled-selection.png +0 -0
  223. package/screenshots/truth/select/disabled.png +0 -0
  224. package/screenshots/truth/select/embedded.png +0 -0
  225. package/screenshots/truth/select/empty-options.png +0 -0
  226. package/screenshots/truth/select/expression-selected.png +0 -0
  227. package/screenshots/truth/select/expressions.png +0 -0
  228. package/screenshots/truth/select/functions.png +0 -0
  229. package/screenshots/truth/select/local-options.png +0 -0
  230. package/screenshots/truth/select/multi-with-endpoint.png +0 -0
  231. package/screenshots/truth/select/multiple-initial-values.png +0 -0
  232. package/screenshots/truth/select/remote-options.png +0 -0
  233. package/screenshots/truth/select/search-enabled.png +0 -0
  234. package/screenshots/truth/select/search-multi-no-matches.png +0 -0
  235. package/screenshots/truth/select/search-selected-focus.png +0 -0
  236. package/screenshots/truth/select/search-selected.png +0 -0
  237. package/screenshots/truth/select/search-with-selected.png +0 -0
  238. package/screenshots/truth/select/searching.png +0 -0
  239. package/screenshots/truth/select/selected-multi-maxitems-reached.png +0 -0
  240. package/screenshots/truth/select/selected-multi.png +0 -0
  241. package/screenshots/truth/select/selected-single.png +0 -0
  242. package/screenshots/truth/select/selection-clearable.png +0 -0
  243. package/screenshots/truth/select/static-initial-value.png +0 -0
  244. package/screenshots/truth/select/static-initial-via-selected.png +0 -0
  245. package/screenshots/truth/select/truncated-selection.png +0 -0
  246. package/screenshots/truth/select/with-placeholder.png +0 -0
  247. package/screenshots/truth/select/without-placeholder.png +0 -0
  248. package/screenshots/truth/slider/update-slider-on-circle-dragged.png +0 -0
  249. package/screenshots/truth/templates/default.png +0 -0
  250. package/screenshots/truth/templates/unapproved.png +0 -0
  251. package/screenshots/truth/textinput/autogrow-initial.png +0 -0
  252. package/screenshots/truth/textinput/input-disabled.png +0 -0
  253. package/screenshots/truth/textinput/input-focused.png +0 -0
  254. package/screenshots/truth/textinput/input-form.png +0 -0
  255. package/screenshots/truth/textinput/input-inserted.png +0 -0
  256. package/screenshots/truth/textinput/input-placeholder.png +0 -0
  257. package/screenshots/truth/textinput/input-updated.png +0 -0
  258. package/screenshots/truth/textinput/input.png +0 -0
  259. package/screenshots/truth/textinput/textarea-focused.png +0 -0
  260. package/screenshots/truth/textinput/textarea.png +0 -0
  261. package/src/events.ts +4 -2
  262. package/src/flow/CanvasNode.ts +2 -39
  263. package/src/flow/Editor.ts +6 -3
  264. package/src/flow/NodeEditor.ts +54 -13
  265. package/src/flow/actions/add_contact_groups.ts +1 -1
  266. package/src/flow/actions/add_contact_urn.ts +1 -1
  267. package/src/flow/actions/add_input_labels.ts +1 -1
  268. package/src/flow/actions/remove_contact_groups.ts +1 -1
  269. package/src/flow/actions/send_email.ts +11 -1
  270. package/src/flow/actions/send_msg.ts +20 -11
  271. package/src/flow/actions/set_contact_channel.ts +28 -5
  272. package/src/flow/actions/set_contact_field.ts +56 -2
  273. package/src/flow/actions/set_contact_language.ts +74 -3
  274. package/src/flow/actions/set_contact_name.ts +31 -3
  275. package/src/flow/actions/set_contact_status.ts +36 -3
  276. package/src/flow/actions/set_run_result.ts +13 -15
  277. package/src/flow/actions/split_by_expression_example.ts +4 -4
  278. package/src/flow/config.ts +2 -8
  279. package/src/flow/forms/index.ts +1 -0
  280. package/src/flow/nodes/split_by_llm.ts +119 -0
  281. package/src/flow/nodes/split_by_llm_categorize.ts +13 -116
  282. package/src/flow/nodes/split_by_random.ts +148 -0
  283. package/src/flow/nodes/split_by_subflow.ts +153 -3
  284. package/src/flow/nodes/split_by_ticket.ts +134 -12
  285. package/src/flow/nodes/split_by_webhook.ts +185 -12
  286. package/src/flow/types.ts +2 -1
  287. package/src/form/ArrayEditor.ts +6 -20
  288. package/src/form/FieldRenderer.ts +6 -65
  289. package/src/form/select/Select.ts +34 -66
  290. package/src/live/ContactChat.ts +56 -58
  291. package/src/store/flow-definition.d.ts +8 -2
  292. package/src/utils.ts +196 -0
  293. package/static/api/fields.json +93 -1208
  294. package/static/api/workspace.json +23 -0
  295. package/test/nodes/split_by_llm.test.ts +232 -0
  296. package/test/nodes/split_by_random.test.ts +0 -7
  297. package/test/temba-field-renderer.test.ts +26 -13
  298. package/test/utils.test.ts +20 -0
  299. package/test-assets/style.css +36 -234
  300. package/web-dev-server.config.mjs +28 -0
  301. package/web-test-runner.config.mjs +38 -1
  302. package/out-tsc/src/flow/actions/call_llm.js +0 -64
  303. package/out-tsc/src/flow/actions/call_llm.js.map +0 -1
  304. package/out-tsc/src/flow/actions/call_webhook.js +0 -131
  305. package/out-tsc/src/flow/actions/call_webhook.js.map +0 -1
  306. package/out-tsc/src/flow/actions/enter_flow.js +0 -14
  307. package/out-tsc/src/flow/actions/enter_flow.js.map +0 -1
  308. package/out-tsc/src/flow/actions/open_ticket.js +0 -73
  309. package/out-tsc/src/flow/actions/open_ticket.js.map +0 -1
  310. package/out-tsc/test/actions/call_llm.test.js +0 -103
  311. package/out-tsc/test/actions/call_llm.test.js.map +0 -1
  312. package/src/flow/actions/call_llm.ts +0 -66
  313. package/src/flow/actions/call_webhook.ts +0 -143
  314. package/src/flow/actions/enter_flow.ts +0 -15
  315. package/src/flow/actions/open_ticket.ts +0 -83
  316. package/test/actions/call_llm.test.ts +0 -137
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/events.ts"],"names":[],"mappings":"","sourcesContent":["import { Msg, ObjectReference, User } from './interfaces';\n\nexport interface EventGroup {\n type: string;\n events: ContactEvent[];\n open: boolean;\n}\n\nexport interface ContactEvent {\n uuid?: string;\n type: string;\n created_on: string;\n created_by?: User;\n}\n\nexport interface ChannelEvent extends ContactEvent {\n channel_event_type: string;\n duration: number;\n\n event: {\n type: string;\n channel: { uuid: string; name: string };\n duration?: number;\n optin?: {\n uuid: string;\n name: string;\n };\n };\n}\n\nexport interface ContactLanguageChangedEvent extends ContactEvent {\n language: string;\n step_uuid: string;\n session_uuid: string;\n}\n\nexport interface OptInEvent extends ContactEvent {\n optin: {\n uuid: string;\n name: string;\n };\n}\n\nexport interface CallEvent extends ContactEvent {\n call?: {\n uuid: string;\n urn: string;\n };\n}\n\nexport interface ChatStartedEvent extends ContactEvent {\n params?: object;\n}\n\nexport interface MsgEvent extends ContactEvent {\n msg: Msg;\n status: string;\n failed_reason?: string;\n failed_reason_display?: string;\n logs_url: string;\n recipient_count?: number;\n created_by?: User;\n optin?: ObjectReference;\n}\n\nexport interface RunEvent extends ContactEvent {\n flow: ObjectReference;\n status: string;\n}\n\nexport interface URNsChangedEvent extends ContactEvent {\n urns: string[];\n}\n\nexport interface TicketEvent extends ContactEvent {\n note?: string;\n assignee?: User;\n ticket: {\n uuid: string;\n topic?: ObjectReference;\n closed_on?: string;\n opened_on?: string;\n };\n topic?: ObjectReference;\n created_by?: User;\n}\n\nexport interface NameChangedEvent extends ContactEvent {\n name: string;\n}\n\nexport interface UpdateFieldEvent extends ContactEvent {\n field: { key: string; name: string };\n value: { text: string };\n}\n\nexport interface ContactGroupsEvent extends ContactEvent {\n groups_added: ObjectReference[];\n groups_removed: ObjectReference[];\n}\n\nexport interface AirtimeTransferredEvent extends ContactEvent {\n sender: string;\n recipient: string;\n currency: string;\n amount: string;\n}\n\nexport type CallStartedEvent = ContactEvent;\n\nexport interface ContactHistoryPage {\n has_older: boolean;\n recent_only: boolean;\n next_before: number;\n next_after: number;\n start_date: Date;\n events: ContactEvent[];\n}\n"]}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/events.ts"],"names":[],"mappings":"","sourcesContent":["import { Msg, ObjectReference, User } from './interfaces';\n\nexport interface EventGroup {\n type: string;\n events: ContactEvent[];\n open: boolean;\n}\n\nexport interface ContactEvent {\n uuid?: string;\n type: string;\n created_on: string;\n created_by?: User;\n}\n\nexport interface ChannelEvent extends ContactEvent {\n channel_event_type: string;\n duration: number;\n\n event: {\n type: string;\n channel: { uuid: string; name: string };\n duration?: number;\n optin?: {\n uuid: string;\n name: string;\n };\n };\n}\n\nexport interface ContactLanguageChangedEvent extends ContactEvent {\n language: string;\n}\n\nexport interface ContactStatusChangedEvent extends ContactEvent {\n status: string;\n}\n\nexport interface OptInEvent extends ContactEvent {\n optin: {\n uuid: string;\n name: string;\n };\n}\n\nexport interface CallEvent extends ContactEvent {\n call?: {\n uuid: string;\n urn: string;\n };\n}\n\nexport interface ChatStartedEvent extends ContactEvent {\n params?: object;\n}\n\nexport interface MsgEvent extends ContactEvent {\n msg: Msg;\n status: string;\n failed_reason?: string;\n failed_reason_display?: string;\n logs_url: string;\n recipient_count?: number;\n created_by?: User;\n optin?: ObjectReference;\n}\n\nexport interface RunEvent extends ContactEvent {\n flow: ObjectReference;\n status: string;\n}\n\nexport interface URNsChangedEvent extends ContactEvent {\n urns: string[];\n}\n\nexport interface TicketEvent extends ContactEvent {\n note?: string;\n assignee?: User;\n ticket: {\n uuid: string;\n topic?: ObjectReference;\n closed_on?: string;\n opened_on?: string;\n };\n topic?: ObjectReference;\n created_by?: User;\n}\n\nexport interface NameChangedEvent extends ContactEvent {\n name: string;\n}\n\nexport interface UpdateFieldEvent extends ContactEvent {\n field: { key: string; name: string };\n value: { text: string };\n}\n\nexport interface ContactGroupsEvent extends ContactEvent {\n groups_added: ObjectReference[];\n groups_removed: ObjectReference[];\n}\n\nexport interface AirtimeTransferredEvent extends ContactEvent {\n sender: string;\n recipient: string;\n currency: string;\n amount: string;\n}\n\nexport type CallStartedEvent = ContactEvent;\n\nexport interface ContactHistoryPage {\n has_older: boolean;\n recent_only: boolean;\n next_before: number;\n next_after: number;\n start_date: Date;\n events: ContactEvent[];\n}\n"]}
@@ -745,28 +745,7 @@ export class CanvasNode extends RapidElement {
745
745
  renderRouter(router, ui) {
746
746
  const nodeConfig = NODE_CONFIG[ui.type];
747
747
  if (nodeConfig) {
748
- // For tests that call renderRouter directly without setting this.node
749
- const hasActions = this.node ? this.node.actions.length > 0 : false;
750
- const isRemoving = this.node &&
751
- this.node.actions.length === 0 &&
752
- this.actionRemovingState.has(this.node.uuid);
753
748
  return html `<div class="router" style="position: relative;">
754
- ${!hasActions
755
- ? html ` <button
756
- class="remove-button"
757
- @click=${(e) => this.handleNodeRemoveClick(e)}
758
- title="Remove node"
759
- >
760
-
761
- </button>
762
- <div
763
- @mousedown=${(e) => this.handleNodeMouseDown(e)}
764
- @mouseup=${(e) => this.handleNodeMouseUp(e)}
765
- style="cursor: pointer;"
766
- >
767
- ${this.renderNodeTitle(nodeConfig, isRemoving)}
768
- </div>`
769
- : ''}
770
749
  ${router.result_name
771
750
  ? html `<div
772
751
  class="body"
@@ -826,7 +805,7 @@ export class CanvasNode extends RapidElement {
826
805
  : ''}"
827
806
  style="left:${this.ui.position.left}px;top:${this.ui.position.top}px"
828
807
  >
829
- ${nodeConfig && nodeConfig.render
808
+ ${nodeConfig && nodeConfig.type !== 'execute_actions'
830
809
  ? html `<div class="router" style="position: relative;">
831
810
  <button
832
811
  class="remove-button"
@@ -841,7 +820,7 @@ export class CanvasNode extends RapidElement {
841
820
  style="cursor: pointer;"
842
821
  >
843
822
  ${this.renderNodeTitle(nodeConfig, this.actionRemovingState.has(this.node.uuid))}
844
- ${nodeConfig.render(this.node)}
823
+ ${nodeConfig.render ? nodeConfig.render(this.node) : null}
845
824
  </div>
846
825
  </div>`
847
826
  : this.node.actions.length > 0
@@ -853,18 +832,7 @@ export class CanvasNode extends RapidElement {
853
832
  ${repeat(this.node.actions, (action) => action.uuid, (action, index) => this.renderAction(this.node, action, index))}
854
833
  </temba-sortable-list>`
855
834
  : html `${repeat(this.node.actions, (action) => action.uuid, (action, index) => this.renderAction(this.node, action, index))}`
856
- : !this.node.router && nodeConfig && nodeConfig.name
857
- ? html `<div class="router" style="position: relative;">
858
- <button
859
- class="remove-button"
860
- @click=${(e) => this.handleNodeRemoveClick(e)}
861
- title="Remove node"
862
- >
863
-
864
- </button>
865
- ${this.renderNodeTitle(nodeConfig, this.actionRemovingState.has(this.node.uuid))}
866
- </div>`
867
- : ''}
835
+ : ''}
868
836
  ${this.node.router
869
837
  ? html ` ${this.renderRouter(this.node.router, this.ui)}
870
838
  ${this.renderCategories(this.node)}`
@@ -1 +1 @@
1
- {"version":3,"file":"CanvasNode.js","sourceRoot":"","sources":["../../../src/flow/CanvasNode.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { ACTION_CONFIG, ActionConfig, NODE_CONFIG, NodeConfig } from './config';\nimport { Action, Exit, Node, NodeUI, Router } from '../store/flow-definition';\nimport { property } from 'lit/decorators.js';\nimport { RapidElement } from '../RapidElement';\nimport { getClasses } from '../utils';\nimport { Plumber } from './Plumber';\nimport { getStore } from '../store/Store';\nimport { CustomEventType } from '../interfaces';\n\nconst DRAG_THRESHOLD = 5;\n\nexport class CanvasNode extends RapidElement {\n createRenderRoot() {\n return this;\n }\n\n @property({ type: Object })\n private plumber: Plumber;\n\n @property({ type: Object })\n private node: Node;\n\n @property({ type: Object })\n private ui: NodeUI;\n\n // Track exits that are in \"removing\" state\n private exitRemovalTimeouts: Map<string, number> = new Map();\n\n // Set of exit UUIDs that are in the removing state\n private exitRemovingState: Set<string> = new Set();\n\n // Track actions that are in \"removing\" state\n private actionRemovalTimeouts: Map<string, number> = new Map();\n\n // Set of action UUIDs that are in the removing state\n private actionRemovingState: Set<string> = new Set();\n\n // Track action click state to distinguish from drag\n private actionClickStartPos: { x: number; y: number } | null = null;\n private pendingActionClick: { action: Action; event: MouseEvent } | null =\n null;\n\n // Track node click state to distinguish from drag\n private nodeClickStartPos: { x: number; y: number } | null = null;\n private pendingNodeClick: { event: MouseEvent } | null = null;\n\n static get styles() {\n return css`\n\n .node {\n background-color: #fff;\n box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\n min-width: 200px;\n border-radius: var(--curvature);\n \n color: #333;\n cursor: move;\n user-select: none;\n\n }\n\n /* Cap width for execute_actions nodes */\n .node.execute-actions {\n max-width: 200px;\n }\n\n .node:hover {\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);\n }\n\n .node.dragging {\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.4);\n transform: scale(1.02);\n z-index: 1000;\n }\n\n .action {\n position: relative;\n font-size: 13px;\n }\n\n .action .remove-button {\n position: absolute;\n top: 5px;\n right: 5px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--color-error, #dc3545);\n color: white;\n border: none;\n cursor: pointer;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n line-height: 1;\n z-index: 10;\n }\n\n .action:hover .remove-button,\n .router:hover .remove-button {\n display: flex;\n }\n\n .action.removing .title,\n .router .title.removing {\n background-color: var(--color-error, #dc3545) !important;\n }\n\n .action.removing .title .name,\n .router .title.removing .name {\n color: white;\n }\n\n .router .remove-button {\n position: absolute;\n top: 5px;\n right: 5px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--color-error, #dc3545);\n color: white;\n border: none;\n cursor: pointer;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n line-height: 1;\n z-index: 10;\n }\n\n .action.sortable {\n display: flex;\n align-items: stretch;\n }\n\n .action .action-content {\n flex-grow: 1;\n display: flex;\n flex-direction: column;\n min-width: 0; /* Allow flex item to shrink below its content size */\n overflow: hidden;\n }\n\n .action .body {\n padding: 0.75em;\n word-wrap: break-word;\n overflow-wrap: break-word;\n hyphens: auto;\n white-space: normal;\n overflow: hidden;\n }\n\n .node.execute-actions temba-sortable-list .action:last-child .body {\n padding-bottom: 1.5em;\n } \n\n .action .drag-handle {\n opacity: 0;\n transition: all 200ms ease-in-out;\n cursor: move;\n background: rgba(0, 0, 0, 0.02);\n max-width:0px;\n position: absolute;\n }\n\n .action:hover .drag-handle {\n opacity: 0.5;\n padding: 0.25em;\n max-width: 20px;\n }\n\n .action .drag-handle:hover {\n opacity: 1;\n \n }\n\n .action .title,\n .router .title {\n display: flex;\n color: #fff;\n padding: 5px 1px;\n text-align: center;\n font-size: 1em;\n font-weight: normal;\n\n }\n\n .title .name {\n flex-grow: 1;\n }\n\n .quick-replies {\n margin-top: 0.5em;\n }\n\n .quick-reply {\n background-color: #f0f0f0;\n border: 1px solid #e0e0e0;\n border-radius: calc(var(--curvature) * 1.5);\n padding: 0.2em 1em;\n display: inline-block;\n font-size: 0.8em;\n margin: 0.2em;\n }\n\n .categories {\n display: flex;\n flex-direction: row;\n\n }\n\n .category {\n margin:-1px -0.5px;\n border: 1px solid #f3f3f3;\n padding: 0.75em;\n flex-grow:1;\n text-align: center;\n display: flex;\n flex-direction: column;\n }\n\n .action-exits {\n padding-bottom: 0.6em;\n margin-top: -0.8em;\n }\n\n .category .title {\n font-weight: normal;\n font-size: 1em;\n max-width: 150px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .router .body {\n padding: 0.75em;\n }\n\n .result-name {\n font-weight: bold;\n display: inline-block;\n }\n \n .exit-wrapper {\n display: flex;\n justify-content: center;\n align-items: center;\n position: relative;\n margin-bottom: -1.2em;\n padding-top:0.2em;\n }\n\n .exit {\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background-color: tomato;\n position: relative;\n box-shadow: 0 2px 2px rgba(0, 0, 0, .1);\n cursor: pointer;\n pointer-events: none;\n }\n\n .exit.jtk-connected {\n background: var(--color-connectors, #e6e6e6);\n }\n\n .exit.connected {\n background-color: #fff;\n pointer-events: all;\n }\n\n .exit.connected:hover {\n background-color: var(--color-connectors, #e6e6e6);\n }\n \n .exit.removing, .exit.removing:hover {\n background-color: var(--color-error);\n pointer-events: all;\n }\n \n .exit.removing::before {\n content: '✕';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 8px;\n color: white;\n line-height: 1;\n }\n \n /* Connector in removing state */\n :host {\n --color-connector-removing: var(--color-error);\n }\n \n body svg.plumb-connector.removing path {\n stroke: var(--color-connector-removing, tomato) !important;\n stroke-width: 3px;\n }\n \n body .plumb-connector.removing .plumb-arrow {\n fill: var(--color-connector-removing, tomato) !important;\n stroke: var(--color-connector-removing, transparent) !important;\n }\n\n .category:first-child {\n border-bottom-left-radius: var(--curvature);\n }\n\n .category:last-child {\n border-bottom-right-radius: var(--curvature);\n }\n\n .router .title {\n border-top-left-radius: var(--curvature);\n border-top-right-radius: var(--curvature);\n }\n\n .action{\n overflow: hidden;\n }\n\n .action:first-child .title {\n border-top-left-radius: var(--curvature);\n border-top-right-radius: var(--curvature);\n }\n }`;\n }\n\n constructor() {\n super();\n this.handleActionOrderChanged = this.handleActionOrderChanged.bind(this);\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('node')) {\n // Only proceed if plumber is available (for tests that don't set it up)\n if (this.plumber) {\n this.plumber.removeNodeConnections(this.node.uuid);\n // make our initial connections\n for (const exit of this.node.exits) {\n if (!exit.destination_uuid) {\n // if we have no destination, then we are a source\n // so make our source endpoint\n this.plumber.makeSource(exit.uuid);\n } else {\n this.plumber.connectIds(\n this.node.uuid,\n exit.uuid,\n exit.destination_uuid\n );\n }\n }\n\n this.plumber.revalidate([this.node.uuid]);\n }\n\n const ele = this.parentElement;\n if (ele) {\n const rect = ele.getBoundingClientRect();\n\n getStore()\n ?.getState()\n .expandCanvas(\n this.ui.position.left + rect.width,\n this.ui.position.top + rect.height\n );\n }\n }\n }\n\n disconnectedCallback() {\n // Remove the event listener when the component is removed\n super.disconnectedCallback();\n\n // Clear any pending exit removal timeouts\n this.exitRemovalTimeouts.forEach((timeoutId) => {\n clearTimeout(timeoutId);\n });\n this.exitRemovalTimeouts.clear();\n\n // Clear any pending action removal timeouts\n this.actionRemovalTimeouts.forEach((timeoutId) => {\n clearTimeout(timeoutId);\n });\n this.actionRemovalTimeouts.clear();\n\n // Clear the removing state\n this.exitRemovingState.clear();\n this.actionRemovingState.clear();\n }\n\n private handleExitClick(event: MouseEvent, exit: Exit) {\n event.preventDefault();\n event.stopPropagation();\n\n const exitId = exit.uuid;\n\n // If exit is not connected, do nothing\n if (!exit.destination_uuid) return;\n\n // If the exit is already in removing state, perform the disconnect\n if (this.exitRemovingState.has(exitId)) {\n this.disconnectExit(exit);\n return;\n }\n\n // Start removal UI state\n this.exitRemovingState.add(exitId);\n this.requestUpdate();\n\n // Set the connection to removing state\n this.plumber.setConnectionRemovingState(exitId, true);\n\n // Clear any existing timeout for this exit\n if (this.exitRemovalTimeouts.has(exitId)) {\n clearTimeout(this.exitRemovalTimeouts.get(exitId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.exitRemovingState.delete(exitId);\n this.exitRemovalTimeouts.delete(exitId);\n\n // Reset the connection to normal state\n this.plumber.setConnectionRemovingState(exitId, false);\n\n this.requestUpdate();\n }, 1500);\n\n this.exitRemovalTimeouts.set(exitId, timeoutId);\n }\n\n private disconnectExit(exit: Exit) {\n const exitId = exit.uuid;\n\n // Clear the UI state\n this.exitRemovingState.delete(exitId);\n\n // Reset the connection to normal state (this will be redundant as we're about to remove it,\n // but it's safer to do this in case there's any timing issue)\n this.plumber.setConnectionRemovingState(exitId, false);\n\n // Clear any timeout\n if (this.exitRemovalTimeouts.has(exitId)) {\n clearTimeout(this.exitRemovalTimeouts.get(exitId));\n this.exitRemovalTimeouts.delete(exitId);\n }\n\n // Remove the JSPlumb connection\n this.plumber.removeExitConnection(exitId);\n\n // Update the flow definition\n const updatedExit = { ...exit, destination_uuid: null };\n const updatedExits = this.node.exits.map((e) =>\n e.uuid === exitId ? updatedExit : e\n );\n\n // Update the node\n const updatedNode = { ...this.node, exits: updatedExits };\n getStore()?.getState().updateNode(this.node.uuid, updatedNode);\n\n // Request update to reflect changes\n this.requestUpdate();\n }\n\n private handleActionRemoveClick(\n event: MouseEvent,\n action: Action,\n index: number\n ) {\n event.preventDefault();\n event.stopPropagation();\n\n const actionId = action.uuid;\n\n // If the action is already in removing state, perform the removal\n if (this.actionRemovingState.has(actionId)) {\n this.removeAction(action, index);\n return;\n }\n\n // Start removal UI state\n this.actionRemovingState.add(actionId);\n this.requestUpdate();\n\n // Clear any existing timeout for this action\n if (this.actionRemovalTimeouts.has(actionId)) {\n clearTimeout(this.actionRemovalTimeouts.get(actionId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.actionRemovingState.delete(actionId);\n this.actionRemovalTimeouts.delete(actionId);\n this.requestUpdate();\n }, 1000); // 1 second as per requirements\n\n this.actionRemovalTimeouts.set(actionId, timeoutId);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n private removeAction(action: Action, _index: number) {\n const actionId = action.uuid;\n\n // Clear the UI state\n this.actionRemovingState.delete(actionId);\n\n // Clear any timeout\n if (this.actionRemovalTimeouts.has(actionId)) {\n clearTimeout(this.actionRemovalTimeouts.get(actionId));\n this.actionRemovalTimeouts.delete(actionId);\n }\n\n // Remove the action from the node\n const updatedActions = this.node.actions.filter((a) => a.uuid !== actionId);\n\n // If no actions remain, remove the entire node\n if (updatedActions.length === 0) {\n this.fireCustomEvent(CustomEventType.NodeDeleted, {\n uuid: this.node.uuid\n });\n } else {\n // Update the node with remaining actions\n const updatedNode = { ...this.node, actions: updatedActions };\n getStore()?.getState().updateNode(this.node.uuid, updatedNode);\n\n // Request update to reflect changes\n this.requestUpdate();\n }\n }\n\n private handleNodeRemoveClick(event: MouseEvent) {\n event.preventDefault();\n event.stopPropagation();\n\n const nodeId = this.node.uuid;\n\n // If the node is already in removing state, perform the removal\n if (this.actionRemovingState.has(nodeId)) {\n this.removeNode();\n return;\n }\n\n // Start removal UI state\n this.actionRemovingState.add(nodeId);\n this.requestUpdate();\n\n // Clear any existing timeout for this node\n if (this.actionRemovalTimeouts.has(nodeId)) {\n clearTimeout(this.actionRemovalTimeouts.get(nodeId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.actionRemovingState.delete(nodeId);\n this.actionRemovalTimeouts.delete(nodeId);\n this.requestUpdate();\n }, 1000); // 1 second as per requirements\n\n this.actionRemovalTimeouts.set(nodeId, timeoutId);\n }\n\n private removeNode() {\n const nodeId = this.node.uuid;\n\n // Clear the UI state\n this.actionRemovingState.delete(nodeId);\n\n // Clear any timeout\n if (this.actionRemovalTimeouts.has(nodeId)) {\n clearTimeout(this.actionRemovalTimeouts.get(nodeId));\n this.actionRemovalTimeouts.delete(nodeId);\n }\n\n // Fire the node deleted event\n this.fireCustomEvent(CustomEventType.NodeDeleted, {\n uuid: this.node.uuid\n });\n }\n\n private handleActionOrderChanged(event: CustomEvent) {\n const [fromIdx, toIdx] = event.detail.swap;\n\n // swap our actions\n const newActions = [...this.node.actions];\n const movedAction = newActions.splice(fromIdx, 1)[0];\n newActions.splice(toIdx, 0, movedAction);\n\n // udate our internal reprensentation, this isn't strictly necessary\n // since the editor will update us from it's definition subscription\n // but it makes testing a lot easier\n this.node = { ...this.node, actions: newActions };\n\n getStore()\n ?.getState()\n .updateNode(this.node.uuid, { ...this.node, actions: newActions });\n }\n\n private handleActionMouseDown(event: MouseEvent, action: Action): void {\n // Don't handle clicks on the remove button or when action is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(action.uuid)\n ) {\n return;\n }\n\n // Store the starting position and action for later comparison\n // Don't prevent default - let the Editor's drag system work normally\n this.actionClickStartPos = { x: event.clientX, y: event.clientY };\n this.pendingActionClick = { action, event };\n }\n\n private handleActionMouseUp(event: MouseEvent, action: Action): void {\n // Don't handle if we don't have a pending click or if it's not the same action\n if (\n !this.pendingActionClick ||\n this.pendingActionClick.action.uuid !== action.uuid\n ) {\n this.actionClickStartPos = null;\n this.pendingActionClick = null;\n return;\n }\n\n // Don't handle clicks on the remove button or when action is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(action.uuid)\n ) {\n this.actionClickStartPos = null;\n this.pendingActionClick = null;\n return;\n }\n\n // Check if the mouse moved beyond the drag threshold\n if (this.actionClickStartPos) {\n const deltaX = event.clientX - this.actionClickStartPos.x;\n const deltaY = event.clientY - this.actionClickStartPos.y;\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n\n // Check if the Editor is currently in dragging mode\n const editor = this.closest('temba-flow-editor') as any;\n const editorWasDragging = editor?.dragging;\n\n // Only fire the action edit event if we haven't dragged beyond the threshold\n // AND either there's no Editor parent (test case) or the Editor didn't drag the node\n if (distance <= DRAG_THRESHOLD && (!editor || !editorWasDragging)) {\n // Fire event to request action editing\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action,\n nodeUuid: this.node.uuid\n });\n }\n }\n\n // Clean up\n this.actionClickStartPos = null;\n this.pendingActionClick = null;\n }\n\n private handleActionClick(event: MouseEvent, action: Action): void {\n // This method is kept for backward compatibility but should not be used\n // The new mousedown/mouseup approach handles click vs drag properly\n event.preventDefault();\n event.stopPropagation();\n\n // Don't handle clicks on the remove button or when action is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(action.uuid)\n ) {\n return;\n }\n\n // Fire event to request action editing\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action,\n nodeUuid: this.node.uuid\n });\n }\n\n private handleNodeEditClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n // Don't handle clicks on the remove button or when node is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(this.node.uuid)\n ) {\n return;\n }\n\n // Fire node edit requested event if the node has a router\n if (this.node.router) {\n // If router node has exactly one action, open the action editor directly\n if (this.node.actions && this.node.actions.length === 1) {\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action: this.node.actions[0],\n nodeUuid: this.node.uuid\n });\n } else {\n // Otherwise open the node editor as before\n this.fireCustomEvent(CustomEventType.NodeEditRequested, {\n node: this.node,\n nodeUI: this.ui\n });\n }\n }\n }\n\n private handleNodeMouseDown(event: MouseEvent): void {\n // Don't handle clicks on the remove button, exits, or when node is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n target.closest('.exit') ||\n target.closest('.exit-wrapper') ||\n this.actionRemovingState.has(this.node.uuid)\n ) {\n return;\n }\n\n // Store the starting position for later comparison\n // Don't prevent default - let the Editor's drag system work normally\n this.nodeClickStartPos = { x: event.clientX, y: event.clientY };\n this.pendingNodeClick = { event };\n }\n\n private handleNodeMouseUp(event: MouseEvent): void {\n // Don't handle if we don't have a pending click\n if (!this.pendingNodeClick) {\n this.nodeClickStartPos = null;\n this.pendingNodeClick = null;\n return;\n }\n\n // Don't handle clicks on the remove button, exits, or when node is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n target.closest('.exit') ||\n target.closest('.exit-wrapper') ||\n this.actionRemovingState.has(this.node.uuid)\n ) {\n this.nodeClickStartPos = null;\n this.pendingNodeClick = null;\n return;\n }\n\n // Check if the mouse moved beyond the drag threshold\n if (this.nodeClickStartPos) {\n const deltaX = event.clientX - this.nodeClickStartPos.x;\n const deltaY = event.clientY - this.nodeClickStartPos.y;\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n\n // Check if the Editor is currently in dragging mode\n const editor = this.closest('temba-flow-editor') as any;\n const editorWasDragging = editor?.dragging;\n\n // Only fire the node edit event if we haven't dragged beyond the threshold\n // AND either there's no Editor parent (test case) or the Editor didn't drag the node\n if (distance <= 5 && (!editor || !editorWasDragging)) {\n // Using literal 5 instead of DRAG_THRESHOLD since it's not imported\n // Fire event to request node editing if the node has a router\n if (this.node.router) {\n // If router node has exactly one action, open the action editor directly\n if (this.node.actions && this.node.actions.length === 1) {\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action: this.node.actions[0],\n nodeUuid: this.node.uuid\n });\n } else {\n // Otherwise open the node editor as before\n this.fireCustomEvent(CustomEventType.NodeEditRequested, {\n node: this.node,\n nodeUI: this.ui\n });\n }\n }\n }\n }\n\n // Clean up\n this.nodeClickStartPos = null;\n this.pendingNodeClick = null;\n }\n\n private renderTitle(config: ActionConfig, isRemoving: boolean = false) {\n return html`<div class=\"title\" style=\"background:${config.color}\">\n ${this.node?.actions?.length > 1\n ? html`<temba-icon class=\"drag-handle\" name=\"sort\"></temba-icon>`\n : null}\n\n <div class=\"name\">${isRemoving ? 'Remove?' : config.name}</div>\n </div>`;\n }\n\n private renderNodeTitle(config: NodeConfig, isRemoving: boolean = false) {\n return html`<div\n class=\"title ${isRemoving ? 'removing' : ''}\"\n style=\"background:${config.color}\"\n >\n <div class=\"name\">${isRemoving ? 'Remove?' : config.name}</div>\n </div>`;\n }\n\n private renderAction(node: Node, action: Action, index: number) {\n const config = ACTION_CONFIG[action.type];\n const isRemoving = this.actionRemovingState.has(action.uuid);\n\n if (config) {\n return html`<div\n class=\"action sortable ${action.type} ${isRemoving ? 'removing' : ''}\"\n id=\"action-${index}\"\n >\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) =>\n this.handleActionRemoveClick(e, action, index)}\n title=\"Remove action\"\n >\n ✕\n </button>\n <div\n class=\"action-content\"\n @mousedown=${(e: MouseEvent) => this.handleActionMouseDown(e, action)}\n @mouseup=${(e: MouseEvent) => this.handleActionMouseUp(e, action)}\n style=\"cursor: pointer;\"\n >\n ${this.renderTitle(config, isRemoving)}\n <div class=\"body\">\n ${config.render\n ? config.render(node, action)\n : html`<pre>${action.type}</pre>`}\n </div>\n </div>\n </div>`;\n }\n return html`<div\n class=\"action sortable ${isRemoving ? 'removing' : ''}\"\n id=\"action-${index}\"\n >\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) =>\n this.handleActionRemoveClick(e, action, index)}\n title=\"Remove action\"\n >\n ✕\n </button>\n ${action.type}\n </div>`;\n }\n\n private renderRouter(router: Router, ui: NodeUI) {\n const nodeConfig = NODE_CONFIG[ui.type];\n if (nodeConfig) {\n // For tests that call renderRouter directly without setting this.node\n const hasActions = this.node ? this.node.actions.length > 0 : false;\n const isRemoving =\n this.node &&\n this.node.actions.length === 0 &&\n this.actionRemovingState.has(this.node.uuid);\n\n return html`<div class=\"router\" style=\"position: relative;\">\n ${!hasActions\n ? html` <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) => this.handleNodeRemoveClick(e)}\n title=\"Remove node\"\n >\n ✕\n </button>\n <div\n @mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}\n @mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}\n style=\"cursor: pointer;\"\n >\n ${this.renderNodeTitle(nodeConfig, isRemoving)}\n </div>`\n : ''}\n ${router.result_name\n ? html`<div\n class=\"body\"\n @mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}\n @mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}\n style=\"cursor: pointer;\"\n >\n Save as\n <div class=\"result-name\">${router.result_name}</div>\n </div>`\n : null}\n </div>`;\n }\n }\n\n private renderCategories(node: Node) {\n if (!node.router || !node.router.categories) {\n return null;\n }\n\n return html`<div class=\"categories\">\n ${repeat(\n node.router.categories,\n (category) => category.uuid,\n (category) => {\n const exit = node.exits.find(\n (exit: Exit) => exit.uuid == category.exit_uuid\n );\n\n return html`<div\n class=\"category\"\n @mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}\n @mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}\n style=\"cursor: pointer;\"\n >\n <div class=\"title\">${category.name}</div>\n ${this.renderExit(exit)}\n </div>`;\n }\n )}\n </div>`;\n }\n\n private renderExit(exit: Exit): TemplateResult {\n return html`<div class=\"exit-wrapper\">\n <div\n id=\"${exit.uuid}\"\n class=${getClasses({\n exit: true,\n connected: !!exit.destination_uuid,\n removing: this.exitRemovingState.has(exit.uuid)\n })}\n @click=${(e: MouseEvent) => this.handleExitClick(e, exit)}\n ></div>\n </div>`;\n }\n\n public render() {\n if (!this.node || !this.ui) {\n return html`<div class=\"node\">Loading...</div>`;\n }\n\n const nodeConfig = NODE_CONFIG[this.ui.type];\n\n return html`\n <div\n id=\"${this.node.uuid}\"\n class=\"node ${this.ui.type === 'execute_actions'\n ? 'execute-actions'\n : ''}\"\n style=\"left:${this.ui.position.left}px;top:${this.ui.position.top}px\"\n >\n ${nodeConfig && nodeConfig.render\n ? html`<div class=\"router\" style=\"position: relative;\">\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) => this.handleNodeRemoveClick(e)}\n title=\"Remove node\"\n >\n ✕\n </button>\n <div\n @mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}\n @mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}\n style=\"cursor: pointer;\"\n >\n ${this.renderNodeTitle(\n nodeConfig,\n this.actionRemovingState.has(this.node.uuid)\n )}\n ${nodeConfig.render(this.node)}\n </div>\n </div>`\n : this.node.actions.length > 0\n ? this.ui.type === 'execute_actions'\n ? html`<temba-sortable-list\n dragHandle=\"drag-handle\"\n @temba-order-changed=\"${this.handleActionOrderChanged}\"\n >\n ${repeat(\n this.node.actions,\n (action) => action.uuid,\n (action, index) => this.renderAction(this.node, action, index)\n )}\n </temba-sortable-list>`\n : html`${repeat(\n this.node.actions,\n (action) => action.uuid,\n (action, index) => this.renderAction(this.node, action, index)\n )}`\n : !this.node.router && nodeConfig && nodeConfig.name\n ? html`<div class=\"router\" style=\"position: relative;\">\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) => this.handleNodeRemoveClick(e)}\n title=\"Remove node\"\n >\n ✕\n </button>\n ${this.renderNodeTitle(\n nodeConfig,\n this.actionRemovingState.has(this.node.uuid)\n )}\n </div>`\n : ''}\n ${this.node.router\n ? html` ${this.renderRouter(this.node.router, this.ui)}\n ${this.renderCategories(this.node)}`\n : html`<div class=\"action-exits\">\n ${repeat(\n this.node.exits,\n (exit) => exit.uuid,\n (exit) => this.renderExit(exit)\n )}\n </div>`}\n </div>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"CanvasNode.js","sourceRoot":"","sources":["../../../src/flow/CanvasNode.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { ACTION_CONFIG, ActionConfig, NODE_CONFIG, NodeConfig } from './config';\nimport { Action, Exit, Node, NodeUI, Router } from '../store/flow-definition';\nimport { property } from 'lit/decorators.js';\nimport { RapidElement } from '../RapidElement';\nimport { getClasses } from '../utils';\nimport { Plumber } from './Plumber';\nimport { getStore } from '../store/Store';\nimport { CustomEventType } from '../interfaces';\n\nconst DRAG_THRESHOLD = 5;\n\nexport class CanvasNode extends RapidElement {\n createRenderRoot() {\n return this;\n }\n\n @property({ type: Object })\n private plumber: Plumber;\n\n @property({ type: Object })\n private node: Node;\n\n @property({ type: Object })\n private ui: NodeUI;\n\n // Track exits that are in \"removing\" state\n private exitRemovalTimeouts: Map<string, number> = new Map();\n\n // Set of exit UUIDs that are in the removing state\n private exitRemovingState: Set<string> = new Set();\n\n // Track actions that are in \"removing\" state\n private actionRemovalTimeouts: Map<string, number> = new Map();\n\n // Set of action UUIDs that are in the removing state\n private actionRemovingState: Set<string> = new Set();\n\n // Track action click state to distinguish from drag\n private actionClickStartPos: { x: number; y: number } | null = null;\n private pendingActionClick: { action: Action; event: MouseEvent } | null =\n null;\n\n // Track node click state to distinguish from drag\n private nodeClickStartPos: { x: number; y: number } | null = null;\n private pendingNodeClick: { event: MouseEvent } | null = null;\n\n static get styles() {\n return css`\n\n .node {\n background-color: #fff;\n box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\n min-width: 200px;\n border-radius: var(--curvature);\n \n color: #333;\n cursor: move;\n user-select: none;\n\n }\n\n /* Cap width for execute_actions nodes */\n .node.execute-actions {\n max-width: 200px;\n }\n\n .node:hover {\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);\n }\n\n .node.dragging {\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.4);\n transform: scale(1.02);\n z-index: 1000;\n }\n\n .action {\n position: relative;\n font-size: 13px;\n }\n\n .action .remove-button {\n position: absolute;\n top: 5px;\n right: 5px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--color-error, #dc3545);\n color: white;\n border: none;\n cursor: pointer;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n line-height: 1;\n z-index: 10;\n }\n\n .action:hover .remove-button,\n .router:hover .remove-button {\n display: flex;\n }\n\n .action.removing .title,\n .router .title.removing {\n background-color: var(--color-error, #dc3545) !important;\n }\n\n .action.removing .title .name,\n .router .title.removing .name {\n color: white;\n }\n\n .router .remove-button {\n position: absolute;\n top: 5px;\n right: 5px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--color-error, #dc3545);\n color: white;\n border: none;\n cursor: pointer;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n line-height: 1;\n z-index: 10;\n }\n\n .action.sortable {\n display: flex;\n align-items: stretch;\n }\n\n .action .action-content {\n flex-grow: 1;\n display: flex;\n flex-direction: column;\n min-width: 0; /* Allow flex item to shrink below its content size */\n overflow: hidden;\n }\n\n .action .body {\n padding: 0.75em;\n word-wrap: break-word;\n overflow-wrap: break-word;\n hyphens: auto;\n white-space: normal;\n overflow: hidden;\n }\n\n .node.execute-actions temba-sortable-list .action:last-child .body {\n padding-bottom: 1.5em;\n } \n\n .action .drag-handle {\n opacity: 0;\n transition: all 200ms ease-in-out;\n cursor: move;\n background: rgba(0, 0, 0, 0.02);\n max-width:0px;\n position: absolute;\n }\n\n .action:hover .drag-handle {\n opacity: 0.5;\n padding: 0.25em;\n max-width: 20px;\n }\n\n .action .drag-handle:hover {\n opacity: 1;\n \n }\n\n .action .title,\n .router .title {\n display: flex;\n color: #fff;\n padding: 5px 1px;\n text-align: center;\n font-size: 1em;\n font-weight: normal;\n\n }\n\n .title .name {\n flex-grow: 1;\n }\n\n .quick-replies {\n margin-top: 0.5em;\n }\n\n .quick-reply {\n background-color: #f0f0f0;\n border: 1px solid #e0e0e0;\n border-radius: calc(var(--curvature) * 1.5);\n padding: 0.2em 1em;\n display: inline-block;\n font-size: 0.8em;\n margin: 0.2em;\n }\n\n .categories {\n display: flex;\n flex-direction: row;\n\n }\n\n .category {\n margin:-1px -0.5px;\n border: 1px solid #f3f3f3;\n padding: 0.75em;\n flex-grow:1;\n text-align: center;\n display: flex;\n flex-direction: column;\n }\n\n .action-exits {\n padding-bottom: 0.6em;\n margin-top: -0.8em;\n }\n\n .category .title {\n font-weight: normal;\n font-size: 1em;\n max-width: 150px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .router .body {\n padding: 0.75em;\n }\n\n .result-name {\n font-weight: bold;\n display: inline-block;\n }\n \n .exit-wrapper {\n display: flex;\n justify-content: center;\n align-items: center;\n position: relative;\n margin-bottom: -1.2em;\n padding-top:0.2em;\n }\n\n .exit {\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background-color: tomato;\n position: relative;\n box-shadow: 0 2px 2px rgba(0, 0, 0, .1);\n cursor: pointer;\n pointer-events: none;\n }\n\n .exit.jtk-connected {\n background: var(--color-connectors, #e6e6e6);\n }\n\n .exit.connected {\n background-color: #fff;\n pointer-events: all;\n }\n\n .exit.connected:hover {\n background-color: var(--color-connectors, #e6e6e6);\n }\n \n .exit.removing, .exit.removing:hover {\n background-color: var(--color-error);\n pointer-events: all;\n }\n \n .exit.removing::before {\n content: '✕';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 8px;\n color: white;\n line-height: 1;\n }\n \n /* Connector in removing state */\n :host {\n --color-connector-removing: var(--color-error);\n }\n \n body svg.plumb-connector.removing path {\n stroke: var(--color-connector-removing, tomato) !important;\n stroke-width: 3px;\n }\n \n body .plumb-connector.removing .plumb-arrow {\n fill: var(--color-connector-removing, tomato) !important;\n stroke: var(--color-connector-removing, transparent) !important;\n }\n\n .category:first-child {\n border-bottom-left-radius: var(--curvature);\n }\n\n .category:last-child {\n border-bottom-right-radius: var(--curvature);\n }\n\n .router .title {\n border-top-left-radius: var(--curvature);\n border-top-right-radius: var(--curvature);\n }\n\n .action{\n overflow: hidden;\n }\n\n .action:first-child .title {\n border-top-left-radius: var(--curvature);\n border-top-right-radius: var(--curvature);\n }\n }`;\n }\n\n constructor() {\n super();\n this.handleActionOrderChanged = this.handleActionOrderChanged.bind(this);\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('node')) {\n // Only proceed if plumber is available (for tests that don't set it up)\n if (this.plumber) {\n this.plumber.removeNodeConnections(this.node.uuid);\n // make our initial connections\n for (const exit of this.node.exits) {\n if (!exit.destination_uuid) {\n // if we have no destination, then we are a source\n // so make our source endpoint\n this.plumber.makeSource(exit.uuid);\n } else {\n this.plumber.connectIds(\n this.node.uuid,\n exit.uuid,\n exit.destination_uuid\n );\n }\n }\n\n this.plumber.revalidate([this.node.uuid]);\n }\n\n const ele = this.parentElement;\n if (ele) {\n const rect = ele.getBoundingClientRect();\n\n getStore()\n ?.getState()\n .expandCanvas(\n this.ui.position.left + rect.width,\n this.ui.position.top + rect.height\n );\n }\n }\n }\n\n disconnectedCallback() {\n // Remove the event listener when the component is removed\n super.disconnectedCallback();\n\n // Clear any pending exit removal timeouts\n this.exitRemovalTimeouts.forEach((timeoutId) => {\n clearTimeout(timeoutId);\n });\n this.exitRemovalTimeouts.clear();\n\n // Clear any pending action removal timeouts\n this.actionRemovalTimeouts.forEach((timeoutId) => {\n clearTimeout(timeoutId);\n });\n this.actionRemovalTimeouts.clear();\n\n // Clear the removing state\n this.exitRemovingState.clear();\n this.actionRemovingState.clear();\n }\n\n private handleExitClick(event: MouseEvent, exit: Exit) {\n event.preventDefault();\n event.stopPropagation();\n\n const exitId = exit.uuid;\n\n // If exit is not connected, do nothing\n if (!exit.destination_uuid) return;\n\n // If the exit is already in removing state, perform the disconnect\n if (this.exitRemovingState.has(exitId)) {\n this.disconnectExit(exit);\n return;\n }\n\n // Start removal UI state\n this.exitRemovingState.add(exitId);\n this.requestUpdate();\n\n // Set the connection to removing state\n this.plumber.setConnectionRemovingState(exitId, true);\n\n // Clear any existing timeout for this exit\n if (this.exitRemovalTimeouts.has(exitId)) {\n clearTimeout(this.exitRemovalTimeouts.get(exitId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.exitRemovingState.delete(exitId);\n this.exitRemovalTimeouts.delete(exitId);\n\n // Reset the connection to normal state\n this.plumber.setConnectionRemovingState(exitId, false);\n\n this.requestUpdate();\n }, 1500);\n\n this.exitRemovalTimeouts.set(exitId, timeoutId);\n }\n\n private disconnectExit(exit: Exit) {\n const exitId = exit.uuid;\n\n // Clear the UI state\n this.exitRemovingState.delete(exitId);\n\n // Reset the connection to normal state (this will be redundant as we're about to remove it,\n // but it's safer to do this in case there's any timing issue)\n this.plumber.setConnectionRemovingState(exitId, false);\n\n // Clear any timeout\n if (this.exitRemovalTimeouts.has(exitId)) {\n clearTimeout(this.exitRemovalTimeouts.get(exitId));\n this.exitRemovalTimeouts.delete(exitId);\n }\n\n // Remove the JSPlumb connection\n this.plumber.removeExitConnection(exitId);\n\n // Update the flow definition\n const updatedExit = { ...exit, destination_uuid: null };\n const updatedExits = this.node.exits.map((e) =>\n e.uuid === exitId ? updatedExit : e\n );\n\n // Update the node\n const updatedNode = { ...this.node, exits: updatedExits };\n getStore()?.getState().updateNode(this.node.uuid, updatedNode);\n\n // Request update to reflect changes\n this.requestUpdate();\n }\n\n private handleActionRemoveClick(\n event: MouseEvent,\n action: Action,\n index: number\n ) {\n event.preventDefault();\n event.stopPropagation();\n\n const actionId = action.uuid;\n\n // If the action is already in removing state, perform the removal\n if (this.actionRemovingState.has(actionId)) {\n this.removeAction(action, index);\n return;\n }\n\n // Start removal UI state\n this.actionRemovingState.add(actionId);\n this.requestUpdate();\n\n // Clear any existing timeout for this action\n if (this.actionRemovalTimeouts.has(actionId)) {\n clearTimeout(this.actionRemovalTimeouts.get(actionId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.actionRemovingState.delete(actionId);\n this.actionRemovalTimeouts.delete(actionId);\n this.requestUpdate();\n }, 1000); // 1 second as per requirements\n\n this.actionRemovalTimeouts.set(actionId, timeoutId);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n private removeAction(action: Action, _index: number) {\n const actionId = action.uuid;\n\n // Clear the UI state\n this.actionRemovingState.delete(actionId);\n\n // Clear any timeout\n if (this.actionRemovalTimeouts.has(actionId)) {\n clearTimeout(this.actionRemovalTimeouts.get(actionId));\n this.actionRemovalTimeouts.delete(actionId);\n }\n\n // Remove the action from the node\n const updatedActions = this.node.actions.filter((a) => a.uuid !== actionId);\n\n // If no actions remain, remove the entire node\n if (updatedActions.length === 0) {\n this.fireCustomEvent(CustomEventType.NodeDeleted, {\n uuid: this.node.uuid\n });\n } else {\n // Update the node with remaining actions\n const updatedNode = { ...this.node, actions: updatedActions };\n getStore()?.getState().updateNode(this.node.uuid, updatedNode);\n\n // Request update to reflect changes\n this.requestUpdate();\n }\n }\n\n private handleNodeRemoveClick(event: MouseEvent) {\n event.preventDefault();\n event.stopPropagation();\n\n const nodeId = this.node.uuid;\n\n // If the node is already in removing state, perform the removal\n if (this.actionRemovingState.has(nodeId)) {\n this.removeNode();\n return;\n }\n\n // Start removal UI state\n this.actionRemovingState.add(nodeId);\n this.requestUpdate();\n\n // Clear any existing timeout for this node\n if (this.actionRemovalTimeouts.has(nodeId)) {\n clearTimeout(this.actionRemovalTimeouts.get(nodeId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.actionRemovingState.delete(nodeId);\n this.actionRemovalTimeouts.delete(nodeId);\n this.requestUpdate();\n }, 1000); // 1 second as per requirements\n\n this.actionRemovalTimeouts.set(nodeId, timeoutId);\n }\n\n private removeNode() {\n const nodeId = this.node.uuid;\n\n // Clear the UI state\n this.actionRemovingState.delete(nodeId);\n\n // Clear any timeout\n if (this.actionRemovalTimeouts.has(nodeId)) {\n clearTimeout(this.actionRemovalTimeouts.get(nodeId));\n this.actionRemovalTimeouts.delete(nodeId);\n }\n\n // Fire the node deleted event\n this.fireCustomEvent(CustomEventType.NodeDeleted, {\n uuid: this.node.uuid\n });\n }\n\n private handleActionOrderChanged(event: CustomEvent) {\n const [fromIdx, toIdx] = event.detail.swap;\n\n // swap our actions\n const newActions = [...this.node.actions];\n const movedAction = newActions.splice(fromIdx, 1)[0];\n newActions.splice(toIdx, 0, movedAction);\n\n // udate our internal reprensentation, this isn't strictly necessary\n // since the editor will update us from it's definition subscription\n // but it makes testing a lot easier\n this.node = { ...this.node, actions: newActions };\n\n getStore()\n ?.getState()\n .updateNode(this.node.uuid, { ...this.node, actions: newActions });\n }\n\n private handleActionMouseDown(event: MouseEvent, action: Action): void {\n // Don't handle clicks on the remove button or when action is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(action.uuid)\n ) {\n return;\n }\n\n // Store the starting position and action for later comparison\n // Don't prevent default - let the Editor's drag system work normally\n this.actionClickStartPos = { x: event.clientX, y: event.clientY };\n this.pendingActionClick = { action, event };\n }\n\n private handleActionMouseUp(event: MouseEvent, action: Action): void {\n // Don't handle if we don't have a pending click or if it's not the same action\n if (\n !this.pendingActionClick ||\n this.pendingActionClick.action.uuid !== action.uuid\n ) {\n this.actionClickStartPos = null;\n this.pendingActionClick = null;\n return;\n }\n\n // Don't handle clicks on the remove button or when action is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(action.uuid)\n ) {\n this.actionClickStartPos = null;\n this.pendingActionClick = null;\n return;\n }\n\n // Check if the mouse moved beyond the drag threshold\n if (this.actionClickStartPos) {\n const deltaX = event.clientX - this.actionClickStartPos.x;\n const deltaY = event.clientY - this.actionClickStartPos.y;\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n\n // Check if the Editor is currently in dragging mode\n const editor = this.closest('temba-flow-editor') as any;\n const editorWasDragging = editor?.dragging;\n\n // Only fire the action edit event if we haven't dragged beyond the threshold\n // AND either there's no Editor parent (test case) or the Editor didn't drag the node\n if (distance <= DRAG_THRESHOLD && (!editor || !editorWasDragging)) {\n // Fire event to request action editing\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action,\n nodeUuid: this.node.uuid\n });\n }\n }\n\n // Clean up\n this.actionClickStartPos = null;\n this.pendingActionClick = null;\n }\n\n private handleActionClick(event: MouseEvent, action: Action): void {\n // This method is kept for backward compatibility but should not be used\n // The new mousedown/mouseup approach handles click vs drag properly\n event.preventDefault();\n event.stopPropagation();\n\n // Don't handle clicks on the remove button or when action is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(action.uuid)\n ) {\n return;\n }\n\n // Fire event to request action editing\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action,\n nodeUuid: this.node.uuid\n });\n }\n\n private handleNodeEditClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n // Don't handle clicks on the remove button or when node is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(this.node.uuid)\n ) {\n return;\n }\n\n // Fire node edit requested event if the node has a router\n if (this.node.router) {\n // If router node has exactly one action, open the action editor directly\n if (this.node.actions && this.node.actions.length === 1) {\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action: this.node.actions[0],\n nodeUuid: this.node.uuid\n });\n } else {\n // Otherwise open the node editor as before\n this.fireCustomEvent(CustomEventType.NodeEditRequested, {\n node: this.node,\n nodeUI: this.ui\n });\n }\n }\n }\n\n private handleNodeMouseDown(event: MouseEvent): void {\n // Don't handle clicks on the remove button, exits, or when node is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n target.closest('.exit') ||\n target.closest('.exit-wrapper') ||\n this.actionRemovingState.has(this.node.uuid)\n ) {\n return;\n }\n\n // Store the starting position for later comparison\n // Don't prevent default - let the Editor's drag system work normally\n this.nodeClickStartPos = { x: event.clientX, y: event.clientY };\n this.pendingNodeClick = { event };\n }\n\n private handleNodeMouseUp(event: MouseEvent): void {\n // Don't handle if we don't have a pending click\n if (!this.pendingNodeClick) {\n this.nodeClickStartPos = null;\n this.pendingNodeClick = null;\n return;\n }\n\n // Don't handle clicks on the remove button, exits, or when node is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n target.closest('.exit') ||\n target.closest('.exit-wrapper') ||\n this.actionRemovingState.has(this.node.uuid)\n ) {\n this.nodeClickStartPos = null;\n this.pendingNodeClick = null;\n return;\n }\n\n // Check if the mouse moved beyond the drag threshold\n if (this.nodeClickStartPos) {\n const deltaX = event.clientX - this.nodeClickStartPos.x;\n const deltaY = event.clientY - this.nodeClickStartPos.y;\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n\n // Check if the Editor is currently in dragging mode\n const editor = this.closest('temba-flow-editor') as any;\n const editorWasDragging = editor?.dragging;\n\n // Only fire the node edit event if we haven't dragged beyond the threshold\n // AND either there's no Editor parent (test case) or the Editor didn't drag the node\n if (distance <= 5 && (!editor || !editorWasDragging)) {\n // Using literal 5 instead of DRAG_THRESHOLD since it's not imported\n // Fire event to request node editing if the node has a router\n if (this.node.router) {\n // If router node has exactly one action, open the action editor directly\n if (this.node.actions && this.node.actions.length === 1) {\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action: this.node.actions[0],\n nodeUuid: this.node.uuid\n });\n } else {\n // Otherwise open the node editor as before\n this.fireCustomEvent(CustomEventType.NodeEditRequested, {\n node: this.node,\n nodeUI: this.ui\n });\n }\n }\n }\n }\n\n // Clean up\n this.nodeClickStartPos = null;\n this.pendingNodeClick = null;\n }\n\n private renderTitle(config: ActionConfig, isRemoving: boolean = false) {\n return html`<div class=\"title\" style=\"background:${config.color}\">\n ${this.node?.actions?.length > 1\n ? html`<temba-icon class=\"drag-handle\" name=\"sort\"></temba-icon>`\n : null}\n\n <div class=\"name\">${isRemoving ? 'Remove?' : config.name}</div>\n </div>`;\n }\n\n private renderNodeTitle(config: NodeConfig, isRemoving: boolean = false) {\n return html`<div\n class=\"title ${isRemoving ? 'removing' : ''}\"\n style=\"background:${config.color}\"\n >\n <div class=\"name\">${isRemoving ? 'Remove?' : config.name}</div>\n </div>`;\n }\n\n private renderAction(node: Node, action: Action, index: number) {\n const config = ACTION_CONFIG[action.type];\n const isRemoving = this.actionRemovingState.has(action.uuid);\n\n if (config) {\n return html`<div\n class=\"action sortable ${action.type} ${isRemoving ? 'removing' : ''}\"\n id=\"action-${index}\"\n >\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) =>\n this.handleActionRemoveClick(e, action, index)}\n title=\"Remove action\"\n >\n ✕\n </button>\n <div\n class=\"action-content\"\n @mousedown=${(e: MouseEvent) => this.handleActionMouseDown(e, action)}\n @mouseup=${(e: MouseEvent) => this.handleActionMouseUp(e, action)}\n style=\"cursor: pointer;\"\n >\n ${this.renderTitle(config, isRemoving)}\n <div class=\"body\">\n ${config.render\n ? config.render(node, action)\n : html`<pre>${action.type}</pre>`}\n </div>\n </div>\n </div>`;\n }\n return html`<div\n class=\"action sortable ${isRemoving ? 'removing' : ''}\"\n id=\"action-${index}\"\n >\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) =>\n this.handleActionRemoveClick(e, action, index)}\n title=\"Remove action\"\n >\n ✕\n </button>\n ${action.type}\n </div>`;\n }\n\n private renderRouter(router: Router, ui: NodeUI) {\n const nodeConfig = NODE_CONFIG[ui.type];\n if (nodeConfig) {\n return html`<div class=\"router\" style=\"position: relative;\">\n ${router.result_name\n ? html`<div\n class=\"body\"\n @mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}\n @mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}\n style=\"cursor: pointer;\"\n >\n Save as\n <div class=\"result-name\">${router.result_name}</div>\n </div>`\n : null}\n </div>`;\n }\n }\n\n private renderCategories(node: Node) {\n if (!node.router || !node.router.categories) {\n return null;\n }\n\n return html`<div class=\"categories\">\n ${repeat(\n node.router.categories,\n (category) => category.uuid,\n (category) => {\n const exit = node.exits.find(\n (exit: Exit) => exit.uuid == category.exit_uuid\n );\n\n return html`<div\n class=\"category\"\n @mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}\n @mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}\n style=\"cursor: pointer;\"\n >\n <div class=\"title\">${category.name}</div>\n ${this.renderExit(exit)}\n </div>`;\n }\n )}\n </div>`;\n }\n\n private renderExit(exit: Exit): TemplateResult {\n return html`<div class=\"exit-wrapper\">\n <div\n id=\"${exit.uuid}\"\n class=${getClasses({\n exit: true,\n connected: !!exit.destination_uuid,\n removing: this.exitRemovingState.has(exit.uuid)\n })}\n @click=${(e: MouseEvent) => this.handleExitClick(e, exit)}\n ></div>\n </div>`;\n }\n\n public render() {\n if (!this.node || !this.ui) {\n return html`<div class=\"node\">Loading...</div>`;\n }\n\n const nodeConfig = NODE_CONFIG[this.ui.type];\n\n return html`\n <div\n id=\"${this.node.uuid}\"\n class=\"node ${this.ui.type === 'execute_actions'\n ? 'execute-actions'\n : ''}\"\n style=\"left:${this.ui.position.left}px;top:${this.ui.position.top}px\"\n >\n ${nodeConfig && nodeConfig.type !== 'execute_actions'\n ? html`<div class=\"router\" style=\"position: relative;\">\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) => this.handleNodeRemoveClick(e)}\n title=\"Remove node\"\n >\n ✕\n </button>\n <div\n @mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}\n @mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}\n style=\"cursor: pointer;\"\n >\n ${this.renderNodeTitle(\n nodeConfig,\n this.actionRemovingState.has(this.node.uuid)\n )}\n ${nodeConfig.render ? nodeConfig.render(this.node) : null}\n </div>\n </div>`\n : this.node.actions.length > 0\n ? this.ui.type === 'execute_actions'\n ? html`<temba-sortable-list\n dragHandle=\"drag-handle\"\n @temba-order-changed=\"${this.handleActionOrderChanged}\"\n >\n ${repeat(\n this.node.actions,\n (action) => action.uuid,\n (action, index) => this.renderAction(this.node, action, index)\n )}\n </temba-sortable-list>`\n : html`${repeat(\n this.node.actions,\n (action) => action.uuid,\n (action, index) => this.renderAction(this.node, action, index)\n )}`\n : ''}\n ${this.node.router\n ? html` ${this.renderRouter(this.node.router, this.ui)}\n ${this.renderCategories(this.node)}`\n : html`<div class=\"action-exits\">\n ${repeat(\n this.node.exits,\n (exit) => exit.uuid,\n (exit) => this.renderExit(exit)\n )}\n </div>`}\n </div>\n `;\n }\n}\n"]}
@@ -498,13 +498,13 @@ export class Editor extends RapidElement {
498
498
  const boxBottom = Math.max(this.selectionBox.startY, this.selectionBox.endY);
499
499
  // Check nodes
500
500
  (_a = this.definition) === null || _a === void 0 ? void 0 : _a.nodes.forEach((node) => {
501
- var _a, _b;
501
+ var _a, _b, _c;
502
502
  const nodeElement = this.querySelector(`[id="${node.uuid}"]`);
503
503
  if (nodeElement) {
504
- const position = (_a = this.definition._ui.nodes[node.uuid]) === null || _a === void 0 ? void 0 : _a.position;
504
+ const position = (_b = (_a = this.definition._ui) === null || _a === void 0 ? void 0 : _a.nodes[node.uuid]) === null || _b === void 0 ? void 0 : _b.position;
505
505
  if (position) {
506
506
  const rect = nodeElement.getBoundingClientRect();
507
- const canvasRect = (_b = this.querySelector('#canvas')) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect();
507
+ const canvasRect = (_c = this.querySelector('#canvas')) === null || _c === void 0 ? void 0 : _c.getBoundingClientRect();
508
508
  if (canvasRect) {
509
509
  const nodeLeft = position.left;
510
510
  const nodeTop = position.top;
@@ -852,10 +852,13 @@ export class Editor extends RapidElement {
852
852
  <div id="canvas">
853
853
  ${this.definition
854
854
  ? repeat(this.definition.nodes, (node) => node.uuid, (node) => {
855
- var _a;
856
- const position = this.definition._ui.nodes[node.uuid].position;
855
+ var _a, _b, _c;
856
+ const position = ((_b = (_a = this.definition._ui) === null || _a === void 0 ? void 0 : _a.nodes[node.uuid]) === null || _b === void 0 ? void 0 : _b.position) || {
857
+ left: 0,
858
+ top: 0
859
+ };
857
860
  const dragging = this.isDragging &&
858
- ((_a = this.currentDragItem) === null || _a === void 0 ? void 0 : _a.uuid) === node.uuid;
861
+ ((_c = this.currentDragItem) === null || _c === void 0 ? void 0 : _c.uuid) === node.uuid;
859
862
  const selected = this.selectedItems.has(node.uuid);
860
863
  return html `<temba-flow-node
861
864
  class="draggable ${dragging ? 'dragging' : ''} ${selected