@nyaruka/temba-components 0.129.3 → 0.129.5

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 (304) hide show
  1. package/.eslintrc.js +1 -0
  2. package/.github/workflows/build.yml +135 -3
  3. package/CHANGELOG.md +19 -0
  4. package/demo/data/flows/sample-flow.json +110 -87
  5. package/demo/field-config-demo.html +135 -0
  6. package/dist/temba-components.js +1257 -675
  7. package/dist/temba-components.js.map +1 -1
  8. package/docs/ActionEditor-Migration.md +118 -0
  9. package/out-tsc/src/events.js.map +1 -1
  10. package/out-tsc/src/flow/{EditorNode.js → CanvasNode.js} +345 -42
  11. package/out-tsc/src/flow/CanvasNode.js.map +1 -0
  12. package/out-tsc/src/flow/Editor.js +107 -3
  13. package/out-tsc/src/flow/Editor.js.map +1 -1
  14. package/out-tsc/src/flow/NodeEditor.js +1211 -0
  15. package/out-tsc/src/flow/NodeEditor.js.map +1 -0
  16. package/out-tsc/src/flow/Plumber.js +0 -6
  17. package/out-tsc/src/flow/Plumber.js.map +1 -1
  18. package/out-tsc/src/flow/actions/add_contact_groups.js +40 -0
  19. package/out-tsc/src/flow/actions/add_contact_groups.js.map +1 -0
  20. package/out-tsc/src/flow/actions/add_contact_urn.js +16 -0
  21. package/out-tsc/src/flow/actions/add_contact_urn.js.map +1 -0
  22. package/out-tsc/src/flow/actions/add_input_labels.js +11 -0
  23. package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -0
  24. package/out-tsc/src/flow/actions/call_classifier.js +11 -0
  25. package/out-tsc/src/flow/actions/call_classifier.js.map +1 -0
  26. package/out-tsc/src/flow/actions/call_llm.js +11 -0
  27. package/out-tsc/src/flow/actions/call_llm.js.map +1 -0
  28. package/out-tsc/src/flow/actions/call_resthook.js +11 -0
  29. package/out-tsc/src/flow/actions/call_resthook.js.map +1 -0
  30. package/out-tsc/src/flow/actions/call_webhook.js +122 -0
  31. package/out-tsc/src/flow/actions/call_webhook.js.map +1 -0
  32. package/out-tsc/src/flow/actions/enter_flow.js +14 -0
  33. package/out-tsc/src/flow/actions/enter_flow.js.map +1 -0
  34. package/out-tsc/src/flow/actions/open_ticket.js +11 -0
  35. package/out-tsc/src/flow/actions/open_ticket.js.map +1 -0
  36. package/out-tsc/src/flow/actions/play_audio.js +11 -0
  37. package/out-tsc/src/flow/actions/play_audio.js.map +1 -0
  38. package/out-tsc/src/flow/actions/remove_contact_groups.js +62 -0
  39. package/out-tsc/src/flow/actions/remove_contact_groups.js.map +1 -0
  40. package/out-tsc/src/flow/actions/request_optin.js +11 -0
  41. package/out-tsc/src/flow/actions/request_optin.js.map +1 -0
  42. package/out-tsc/src/flow/actions/say_msg.js +11 -0
  43. package/out-tsc/src/flow/actions/say_msg.js.map +1 -0
  44. package/out-tsc/src/flow/actions/send_broadcast.js +33 -0
  45. package/out-tsc/src/flow/actions/send_broadcast.js.map +1 -0
  46. package/out-tsc/src/flow/actions/send_email.js +56 -0
  47. package/out-tsc/src/flow/actions/send_email.js.map +1 -0
  48. package/out-tsc/src/flow/actions/send_msg.js +55 -0
  49. package/out-tsc/src/flow/actions/send_msg.js.map +1 -0
  50. package/out-tsc/src/flow/actions/set_contact_channel.js +12 -0
  51. package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -0
  52. package/out-tsc/src/flow/actions/set_contact_field.js +12 -0
  53. package/out-tsc/src/flow/actions/set_contact_field.js.map +1 -0
  54. package/out-tsc/src/flow/actions/set_contact_language.js +10 -0
  55. package/out-tsc/src/flow/actions/set_contact_language.js.map +1 -0
  56. package/out-tsc/src/flow/actions/set_contact_name.js +10 -0
  57. package/out-tsc/src/flow/actions/set_contact_name.js.map +1 -0
  58. package/out-tsc/src/flow/actions/set_contact_status.js +10 -0
  59. package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -0
  60. package/out-tsc/src/flow/actions/set_run_result.js +10 -0
  61. package/out-tsc/src/flow/actions/set_run_result.js.map +1 -0
  62. package/out-tsc/src/flow/actions/split_by_expression_example.js +77 -0
  63. package/out-tsc/src/flow/actions/split_by_expression_example.js.map +1 -0
  64. package/out-tsc/src/flow/actions/start_session.js +11 -0
  65. package/out-tsc/src/flow/actions/start_session.js.map +1 -0
  66. package/out-tsc/src/flow/actions/transfer_airtime.js +11 -0
  67. package/out-tsc/src/flow/actions/transfer_airtime.js.map +1 -0
  68. package/out-tsc/src/flow/config.js +88 -193
  69. package/out-tsc/src/flow/config.js.map +1 -1
  70. package/out-tsc/src/flow/nodes/execute_actions.js +4 -0
  71. package/out-tsc/src/flow/nodes/execute_actions.js.map +1 -0
  72. package/out-tsc/src/flow/nodes/split_by_airtime.js +9 -0
  73. package/out-tsc/src/flow/nodes/split_by_airtime.js.map +1 -0
  74. package/out-tsc/src/flow/nodes/split_by_contact_field.js +7 -0
  75. package/out-tsc/src/flow/nodes/split_by_contact_field.js.map +1 -0
  76. package/out-tsc/src/flow/nodes/split_by_expression.js +7 -0
  77. package/out-tsc/src/flow/nodes/split_by_expression.js.map +1 -0
  78. package/out-tsc/src/flow/nodes/split_by_groups.js +7 -0
  79. package/out-tsc/src/flow/nodes/split_by_groups.js.map +1 -0
  80. package/out-tsc/src/flow/nodes/split_by_random.js +10 -0
  81. package/out-tsc/src/flow/nodes/split_by_random.js.map +1 -0
  82. package/out-tsc/src/flow/nodes/split_by_run_result.js +7 -0
  83. package/out-tsc/src/flow/nodes/split_by_run_result.js.map +1 -0
  84. package/out-tsc/src/flow/nodes/split_by_scheme.js +7 -0
  85. package/out-tsc/src/flow/nodes/split_by_scheme.js.map +1 -0
  86. package/out-tsc/src/flow/nodes/split_by_subflow.js +9 -0
  87. package/out-tsc/src/flow/nodes/split_by_subflow.js.map +1 -0
  88. package/out-tsc/src/flow/nodes/split_by_webhook.js +18 -0
  89. package/out-tsc/src/flow/nodes/split_by_webhook.js.map +1 -0
  90. package/out-tsc/src/flow/nodes/wait_for_audio.js +7 -0
  91. package/out-tsc/src/flow/nodes/wait_for_audio.js.map +1 -0
  92. package/out-tsc/src/flow/nodes/wait_for_digits.js +7 -0
  93. package/out-tsc/src/flow/nodes/wait_for_digits.js.map +1 -0
  94. package/out-tsc/src/flow/nodes/wait_for_image.js +7 -0
  95. package/out-tsc/src/flow/nodes/wait_for_image.js.map +1 -0
  96. package/out-tsc/src/flow/nodes/wait_for_location.js +7 -0
  97. package/out-tsc/src/flow/nodes/wait_for_location.js.map +1 -0
  98. package/out-tsc/src/flow/nodes/wait_for_menu.js +7 -0
  99. package/out-tsc/src/flow/nodes/wait_for_menu.js.map +1 -0
  100. package/out-tsc/src/flow/nodes/wait_for_response.js +7 -0
  101. package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -0
  102. package/out-tsc/src/flow/nodes/wait_for_video.js +7 -0
  103. package/out-tsc/src/flow/nodes/wait_for_video.js.map +1 -0
  104. package/out-tsc/src/flow/types.js +79 -0
  105. package/out-tsc/src/flow/types.js.map +1 -0
  106. package/out-tsc/src/flow/utils.js +65 -0
  107. package/out-tsc/src/flow/utils.js.map +1 -0
  108. package/out-tsc/src/form/ArrayEditor.js +199 -0
  109. package/out-tsc/src/form/ArrayEditor.js.map +1 -0
  110. package/out-tsc/src/form/BaseListEditor.js +128 -0
  111. package/out-tsc/src/form/BaseListEditor.js.map +1 -0
  112. package/out-tsc/src/form/Checkbox.js +17 -2
  113. package/out-tsc/src/form/Checkbox.js.map +1 -1
  114. package/out-tsc/src/form/Completion.js +6 -0
  115. package/out-tsc/src/form/Completion.js.map +1 -1
  116. package/out-tsc/src/form/FormField.js +110 -11
  117. package/out-tsc/src/form/FormField.js.map +1 -1
  118. package/out-tsc/src/form/KeyValueEditor.js +223 -0
  119. package/out-tsc/src/form/KeyValueEditor.js.map +1 -0
  120. package/out-tsc/src/form/select/Select.js +92 -32
  121. package/out-tsc/src/form/select/Select.js.map +1 -1
  122. package/out-tsc/src/interfaces.js +6 -0
  123. package/out-tsc/src/interfaces.js.map +1 -1
  124. package/out-tsc/src/live/ContactChat.js +2 -76
  125. package/out-tsc/src/live/ContactChat.js.map +1 -1
  126. package/out-tsc/temba-modules.js +9 -2
  127. package/out-tsc/temba-modules.js.map +1 -1
  128. package/out-tsc/test/ActionHelper.js +116 -0
  129. package/out-tsc/test/ActionHelper.js.map +1 -0
  130. package/out-tsc/test/actions/add_contact_groups.test.js +66 -0
  131. package/out-tsc/test/actions/add_contact_groups.test.js.map +1 -0
  132. package/out-tsc/test/actions/remove_contact_groups.test.js +226 -0
  133. package/out-tsc/test/actions/remove_contact_groups.test.js.map +1 -0
  134. package/out-tsc/test/actions/send_email.test.js +160 -0
  135. package/out-tsc/test/actions/send_email.test.js.map +1 -0
  136. package/out-tsc/test/actions/send_msg.test.js +95 -0
  137. package/out-tsc/test/actions/send_msg.test.js.map +1 -0
  138. package/out-tsc/test/temba-action-editing-integration.test.js +183 -0
  139. package/out-tsc/test/temba-action-editing-integration.test.js.map +1 -0
  140. package/out-tsc/test/temba-checkbox.test.js +1 -1
  141. package/out-tsc/test/temba-checkbox.test.js.map +1 -1
  142. package/out-tsc/test/temba-field-config.test.js +133 -0
  143. package/out-tsc/test/temba-field-config.test.js.map +1 -0
  144. package/out-tsc/test/temba-flow-editor-node.test.js +14 -14
  145. package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
  146. package/out-tsc/test/temba-node-editor.test.js +283 -0
  147. package/out-tsc/test/temba-node-editor.test.js.map +1 -0
  148. package/out-tsc/test/temba-select.test.js +158 -0
  149. package/out-tsc/test/temba-select.test.js.map +1 -1
  150. package/package.json +1 -1
  151. package/screenshots/truth/actions/add_contact_groups/editor/descriptive-group-names.png +0 -0
  152. package/screenshots/truth/actions/add_contact_groups/editor/long-group-names.png +0 -0
  153. package/screenshots/truth/actions/add_contact_groups/editor/many-groups.png +0 -0
  154. package/screenshots/truth/actions/add_contact_groups/editor/multiple-groups.png +0 -0
  155. package/screenshots/truth/actions/add_contact_groups/editor/single-group.png +0 -0
  156. package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
  157. package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
  158. package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
  159. package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
  160. package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
  161. package/screenshots/truth/actions/remove_contact_groups/editor/cleanup-groups.png +0 -0
  162. package/screenshots/truth/actions/remove_contact_groups/editor/long-descriptive-group-names.png +0 -0
  163. package/screenshots/truth/actions/remove_contact_groups/editor/many-groups.png +0 -0
  164. package/screenshots/truth/actions/remove_contact_groups/editor/multiple-groups.png +0 -0
  165. package/screenshots/truth/actions/remove_contact_groups/editor/remove-from-all-groups.png +0 -0
  166. package/screenshots/truth/actions/remove_contact_groups/editor/single-group.png +0 -0
  167. package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
  168. package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
  169. package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
  170. package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
  171. package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
  172. package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
  173. package/screenshots/truth/actions/send_email/editor/complex-business-email.png +0 -0
  174. package/screenshots/truth/actions/send_email/editor/empty-body.png +0 -0
  175. package/screenshots/truth/actions/send_email/editor/empty-subject.png +0 -0
  176. package/screenshots/truth/actions/send_email/editor/long-subject.png +0 -0
  177. package/screenshots/truth/actions/send_email/editor/multiline-body.png +0 -0
  178. package/screenshots/truth/actions/send_email/editor/multiple-recipients.png +0 -0
  179. package/screenshots/truth/actions/send_email/editor/simple-email.png +0 -0
  180. package/screenshots/truth/actions/send_email/editor/with-expressions.png +0 -0
  181. package/screenshots/truth/actions/send_email/render/complex-business-email.png +0 -0
  182. package/screenshots/truth/actions/send_email/render/empty-body.png +0 -0
  183. package/screenshots/truth/actions/send_email/render/empty-subject.png +0 -0
  184. package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
  185. package/screenshots/truth/actions/send_email/render/multiline-body.png +0 -0
  186. package/screenshots/truth/actions/send_email/render/multiple-recipients.png +0 -0
  187. package/screenshots/truth/actions/send_email/render/simple-email.png +0 -0
  188. package/screenshots/truth/actions/send_email/render/with-expressions.png +0 -0
  189. package/screenshots/truth/actions/send_msg/editor/long-quick-replies.png +0 -0
  190. package/screenshots/truth/actions/send_msg/editor/multiline-text-with-replies.png +0 -0
  191. package/screenshots/truth/actions/send_msg/editor/simple-text.png +0 -0
  192. package/screenshots/truth/actions/send_msg/editor/text-with-linebreaks.png +0 -0
  193. package/screenshots/truth/actions/send_msg/editor/text-with-many-quick-replies.png +0 -0
  194. package/screenshots/truth/actions/send_msg/editor/text-with-quick-replies.png +0 -0
  195. package/screenshots/truth/actions/send_msg/editor/text-without-quick-replies.png +0 -0
  196. package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
  197. package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
  198. package/screenshots/truth/actions/send_msg/render/simple-text.png +0 -0
  199. package/screenshots/truth/actions/send_msg/render/text-with-linebreaks.png +0 -0
  200. package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
  201. package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
  202. package/screenshots/truth/actions/send_msg/render/text-without-quick-replies.png +0 -0
  203. package/screenshots/truth/editor/router.png +0 -0
  204. package/screenshots/truth/editor/send_msg.png +0 -0
  205. package/screenshots/truth/editor/set_contact_language.png +0 -0
  206. package/screenshots/truth/editor/set_contact_name.png +0 -0
  207. package/screenshots/truth/editor/set_run_result.png +0 -0
  208. package/screenshots/truth/editor/wait.png +0 -0
  209. package/screenshots/truth/formfield/markdown-errors.png +0 -0
  210. package/screenshots/truth/formfield/plain-text-errors.png +0 -0
  211. package/screenshots/truth/formfield/widget-only-markdown-errors.png +0 -0
  212. package/screenshots/truth/integration/checkbox-markdown-errors.png +0 -0
  213. package/src/events.ts +1 -40
  214. package/src/flow/{EditorNode.ts → CanvasNode.ts} +424 -48
  215. package/src/flow/Editor.ts +140 -4
  216. package/src/flow/NodeEditor.ts +1454 -0
  217. package/src/flow/Plumber.ts +0 -9
  218. package/src/flow/actions/add_contact_groups.ts +42 -0
  219. package/src/flow/actions/add_contact_urn.ts +17 -0
  220. package/src/flow/actions/add_input_labels.ts +12 -0
  221. package/src/flow/actions/call_classifier.ts +12 -0
  222. package/src/flow/actions/call_llm.ts +12 -0
  223. package/src/flow/actions/call_resthook.ts +12 -0
  224. package/src/flow/actions/call_webhook.ts +133 -0
  225. package/src/flow/actions/enter_flow.ts +15 -0
  226. package/src/flow/actions/open_ticket.ts +12 -0
  227. package/src/flow/actions/play_audio.ts +12 -0
  228. package/src/flow/actions/remove_contact_groups.ts +66 -0
  229. package/src/flow/actions/request_optin.ts +12 -0
  230. package/src/flow/actions/say_msg.ts +12 -0
  231. package/src/flow/actions/send_broadcast.ts +35 -0
  232. package/src/flow/actions/send_email.ts +60 -0
  233. package/src/flow/actions/send_msg.ts +58 -0
  234. package/src/flow/actions/set_contact_channel.ts +13 -0
  235. package/src/flow/actions/set_contact_field.ts +13 -0
  236. package/src/flow/actions/set_contact_language.ts +11 -0
  237. package/src/flow/actions/set_contact_name.ts +11 -0
  238. package/src/flow/actions/set_contact_status.ts +11 -0
  239. package/src/flow/actions/set_run_result.ts +11 -0
  240. package/src/flow/actions/split_by_expression_example.ts +88 -0
  241. package/src/flow/actions/start_session.ts +12 -0
  242. package/src/flow/actions/transfer_airtime.ts +12 -0
  243. package/src/flow/config.ts +93 -232
  244. package/src/flow/nodes/execute_actions.ts +5 -0
  245. package/src/flow/nodes/split_by_airtime.ts +9 -0
  246. package/src/flow/nodes/split_by_contact_field.ts +7 -0
  247. package/src/flow/nodes/split_by_expression.ts +7 -0
  248. package/src/flow/nodes/split_by_groups.ts +7 -0
  249. package/src/flow/nodes/split_by_random.ts +10 -0
  250. package/src/flow/nodes/split_by_run_result.ts +7 -0
  251. package/src/flow/nodes/split_by_scheme.ts +7 -0
  252. package/src/flow/nodes/split_by_subflow.ts +9 -0
  253. package/src/flow/nodes/split_by_webhook.ts +19 -0
  254. package/src/flow/nodes/wait_for_audio.ts +7 -0
  255. package/src/flow/nodes/wait_for_digits.ts +7 -0
  256. package/src/flow/nodes/wait_for_image.ts +7 -0
  257. package/src/flow/nodes/wait_for_location.ts +7 -0
  258. package/src/flow/nodes/wait_for_menu.ts +7 -0
  259. package/src/flow/nodes/wait_for_response.ts +7 -0
  260. package/src/flow/nodes/wait_for_video.ts +7 -0
  261. package/src/flow/types.ts +352 -0
  262. package/src/flow/utils.ts +76 -0
  263. package/src/form/ArrayEditor.ts +240 -0
  264. package/src/form/BaseListEditor.ts +177 -0
  265. package/src/form/Checkbox.ts +22 -3
  266. package/src/form/Completion.ts +6 -0
  267. package/src/form/FormField.ts +115 -11
  268. package/src/form/KeyValueEditor.ts +251 -0
  269. package/src/form/select/Select.ts +105 -32
  270. package/src/interfaces.ts +7 -2
  271. package/src/live/ContactChat.ts +3 -97
  272. package/src/store/flow-definition.d.ts +6 -1
  273. package/static/api/contacts.json +30 -0
  274. package/static/api/groups.json +4 -426
  275. package/static/api/locations.json +24 -0
  276. package/static/api/media.json +5 -0
  277. package/static/api/optins.json +16 -0
  278. package/static/api/orgs.json +13 -0
  279. package/static/api/topics.json +21 -0
  280. package/static/api/users.json +26 -0
  281. package/static/css/temba-components.css +3 -6
  282. package/temba-modules.ts +9 -2
  283. package/test/ActionHelper.ts +142 -0
  284. package/test/actions/add_contact_groups.test.ts +89 -0
  285. package/test/actions/remove_contact_groups.test.ts +265 -0
  286. package/test/actions/send_email.test.ts +214 -0
  287. package/test/actions/send_msg.test.ts +130 -0
  288. package/test/temba-action-editing-integration.test.ts +240 -0
  289. package/test/temba-checkbox.test.ts +1 -1
  290. package/test/temba-field-config.test.ts +152 -0
  291. package/test/temba-flow-editor-node.test.ts +18 -18
  292. package/test/temba-node-editor.test.ts +353 -0
  293. package/test/temba-select.test.ts +234 -0
  294. package/test-assets/contacts/history.json +11 -33
  295. package/web-dev-server.config.mjs +34 -0
  296. package/.github/workflows/coverage.yml +0 -80
  297. package/demo/sticky-note-demo.html +0 -155
  298. package/out-tsc/src/flow/EditorNode.js.map +0 -1
  299. package/out-tsc/src/flow/render.js +0 -358
  300. package/out-tsc/src/flow/render.js.map +0 -1
  301. package/out-tsc/test/temba-flow-render.test.js +0 -794
  302. package/out-tsc/test/temba-flow-render.test.js.map +0 -1
  303. package/src/flow/render.ts +0 -443
  304. package/test/temba-flow-render.test.ts +0 -1003
@@ -0,0 +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 .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 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 // 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 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 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 ${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"]}
@@ -6,8 +6,9 @@ import { getStore } from '../store/Store';
6
6
  import { fromStore, zustand } from '../store/AppState';
7
7
  import { RapidElement } from '../RapidElement';
8
8
  import { repeat } from 'lit-html/directives/repeat.js';
9
+ import { CustomEventType } from '../interfaces';
9
10
  import { Plumber } from './Plumber';
10
- import { EditorNode } from './EditorNode';
11
+ import { CanvasNode } from './CanvasNode';
11
12
  export function snapToGrid(value) {
12
13
  const snapped = Math.round(value / 20) * 20;
13
14
  return Math.max(snapped, 0);
@@ -28,6 +29,10 @@ export class Editor extends RapidElement {
28
29
  createRenderRoot() {
29
30
  return this;
30
31
  }
32
+ // Public getter for drag state
33
+ get dragging() {
34
+ return this.isDragging;
35
+ }
31
36
  static get styles() {
32
37
  return css `
33
38
  #editor {
@@ -190,6 +195,10 @@ export class Editor extends RapidElement {
190
195
  this.sourceId = null;
191
196
  this.dragFromNodeId = null;
192
197
  this.isValidTarget = true;
198
+ // NodeEditor state - handles both node and action editing
199
+ this.editingNode = null;
200
+ this.editingNodeUI = null;
201
+ this.editingAction = null;
193
202
  this.canvasMouseDown = false;
194
203
  // Bound event handlers to maintain proper 'this' context
195
204
  this.boundMouseMove = this.handleMouseMove.bind(this);
@@ -297,6 +306,10 @@ export class Editor extends RapidElement {
297
306
  if (canvas) {
298
307
  canvas.addEventListener('dblclick', this.boundCanvasDoubleClick);
299
308
  }
309
+ // Listen for action edit requests from flow nodes
310
+ this.addEventListener(CustomEventType.ActionEditRequested, this.handleActionEditRequested.bind(this));
311
+ // Listen for node edit requests from flow nodes
312
+ this.addEventListener(CustomEventType.NodeEditRequested, this.handleNodeEditRequested.bind(this));
300
313
  }
301
314
  getPosition(uuid, type) {
302
315
  var _a, _b, _c;
@@ -740,12 +753,83 @@ export class Editor extends RapidElement {
740
753
  event.preventDefault();
741
754
  event.stopPropagation();
742
755
  }
756
+ handleActionEditRequested(event) {
757
+ // For action editing, we set the action and find the corresponding node
758
+ this.editingAction = event.detail.action;
759
+ // Find the node that contains this action
760
+ const nodeUuid = event.detail.nodeUuid;
761
+ const node = this.definition.nodes.find((n) => n.uuid === nodeUuid);
762
+ if (node) {
763
+ this.editingNode = node;
764
+ this.editingNodeUI = this.definition._ui.nodes[nodeUuid];
765
+ }
766
+ }
767
+ handleNodeEditRequested(event) {
768
+ this.editingNode = event.detail.node;
769
+ this.editingNodeUI = event.detail.nodeUI;
770
+ }
771
+ handleActionSaved(updatedAction) {
772
+ var _a;
773
+ if (this.editingNode && this.editingAction) {
774
+ // Update the specific action in the node
775
+ const updatedActions = this.editingNode.actions.map((action) => action.uuid === this.editingAction.uuid ? updatedAction : action);
776
+ const updatedNode = { ...this.editingNode, actions: updatedActions };
777
+ // Update the node in the store
778
+ (_a = getStore()) === null || _a === void 0 ? void 0 : _a.getState().updateNode(this.editingNode.uuid, updatedNode);
779
+ // Repaint jsplumb connections in case node size changed
780
+ if (this.plumber) {
781
+ // Use requestAnimationFrame to ensure DOM has been updated first
782
+ requestAnimationFrame(() => {
783
+ this.plumber.repaintEverything();
784
+ });
785
+ }
786
+ }
787
+ this.closeNodeEditor();
788
+ }
789
+ closeNodeEditor() {
790
+ this.editingNode = null;
791
+ this.editingNodeUI = null;
792
+ this.editingAction = null;
793
+ }
794
+ handleActionEditCanceled() {
795
+ this.closeNodeEditor();
796
+ }
797
+ handleNodeSaved(updatedNode) {
798
+ var _a;
799
+ if (this.editingNode) {
800
+ // Clean up jsPlumb connections for removed exits before updating the node
801
+ if (this.plumber) {
802
+ const oldExits = this.editingNode.exits || [];
803
+ const newExits = updatedNode.exits || [];
804
+ // Find exits that were removed
805
+ const removedExits = oldExits.filter((oldExit) => !newExits.find((newExit) => newExit.uuid === oldExit.uuid));
806
+ // Remove jsPlumb connections for removed exits
807
+ removedExits.forEach((exit) => {
808
+ this.plumber.removeExitConnection(exit.uuid);
809
+ });
810
+ }
811
+ this.plumber.revalidate([updatedNode.uuid]);
812
+ // Update the node in the store
813
+ (_a = getStore()) === null || _a === void 0 ? void 0 : _a.getState().updateNode(this.editingNode.uuid, updatedNode);
814
+ // Repaint jsplumb connections in case node size changed
815
+ if (this.plumber) {
816
+ // Use requestAnimationFrame to ensure DOM has been updated first
817
+ requestAnimationFrame(() => {
818
+ this.plumber.repaintEverything();
819
+ });
820
+ }
821
+ }
822
+ this.closeNodeEditor();
823
+ }
824
+ handleNodeEditCanceled() {
825
+ this.closeNodeEditor();
826
+ }
743
827
  render() {
744
828
  var _a, _b;
745
829
  // we have to embed our own style since we are in light DOM
746
830
  const style = html `<style>
747
831
  ${unsafeCSS(Editor.styles.cssText)}
748
- ${unsafeCSS(EditorNode.styles.cssText)}
832
+ ${unsafeCSS(CanvasNode.styles.cssText)}
749
833
  </style>`;
750
834
  const stickies = ((_b = (_a = this.definition) === null || _a === void 0 ? void 0 : _a._ui) === null || _b === void 0 ? void 0 : _b.stickies) || {};
751
835
  return html `${style}
@@ -800,7 +884,18 @@ export class Editor extends RapidElement {
800
884
  ${this.renderSelectionBox()}
801
885
  </div>
802
886
  </div>
803
- </div>`;
887
+ </div>
888
+
889
+ ${this.editingNode || this.editingAction
890
+ ? html `<temba-node-editor
891
+ .node=${this.editingNode}
892
+ .nodeUI=${this.editingNodeUI}
893
+ .action=${this.editingAction}
894
+ @temba-node-saved=${(e) => this.handleNodeSaved(e.detail.node)}
895
+ @temba-action-saved=${(e) => this.handleActionSaved(e.detail.action)}
896
+ @temba-node-edit-cancelled=${this.handleNodeEditCanceled}
897
+ ></temba-node-editor>`
898
+ : ''} `;
804
899
  }
805
900
  }
806
901
  __decorate([
@@ -845,4 +940,13 @@ __decorate([
845
940
  __decorate([
846
941
  state()
847
942
  ], Editor.prototype, "isValidTarget", void 0);
943
+ __decorate([
944
+ state()
945
+ ], Editor.prototype, "editingNode", void 0);
946
+ __decorate([
947
+ state()
948
+ ], Editor.prototype, "editingNodeUI", void 0);
949
+ __decorate([
950
+ state()
951
+ ], Editor.prototype, "editingAction", void 0);
848
952
  //# sourceMappingURL=Editor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Editor.js","sourceRoot":"","sources":["../../../src/flow/Editor.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, TemplateResult } from 'lit-html';\nimport { css, PropertyValueMap, unsafeCSS } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { FlowDefinition, FlowPosition } from '../store/flow-definition';\nimport { getStore } from '../store/Store';\nimport { AppState, fromStore, zustand } from '../store/AppState';\nimport { RapidElement } from '../RapidElement';\nimport { repeat } from 'lit-html/directives/repeat.js';\n\nimport { Plumber } from './Plumber';\nimport { EditorNode } from './EditorNode';\nimport { Dialog } from '../layout/Dialog';\nimport { Connection } from '@jsplumb/browser-ui';\n\nexport function snapToGrid(value: number): number {\n const snapped = Math.round(value / 20) * 20;\n return Math.max(snapped, 0);\n}\n\nexport function findNodeForExit(\n definition: FlowDefinition,\n exitUuid: string\n): string | null {\n for (const node of definition.nodes) {\n const exit = node.exits.find((e) => e.uuid === exitUuid);\n if (exit) {\n return node.uuid;\n }\n }\n return null;\n}\n\nconst SAVE_QUIET_TIME = 500;\n\nexport interface DraggableItem {\n uuid: string;\n position: FlowPosition;\n element: HTMLElement;\n type: 'node' | 'sticky';\n}\n\nexport interface SelectionBox {\n startX: number;\n startY: number;\n endX: number;\n endY: number;\n}\n\nconst DRAG_THRESHOLD = 5;\n\nexport class Editor extends RapidElement {\n // unfortunately, jsplumb requires that we be in light DOM\n createRenderRoot() {\n return this;\n }\n\n // this is the master plumber\n private plumber: Plumber;\n\n // timer for debounced saving\n private saveTimer: number | null = null;\n\n @property({ type: String })\n public flow: string;\n\n @property({ type: String })\n public version: string;\n\n @fromStore(zustand, (state: AppState) => state.flowDefinition)\n private definition!: FlowDefinition;\n\n @fromStore(zustand, (state: AppState) => state.canvasSize)\n private canvasSize!: { width: number; height: number };\n\n @fromStore(zustand, (state: AppState) => state.dirtyDate)\n private dirtyDate!: Date;\n\n // Drag state\n @state()\n private isDragging = false;\n private isMouseDown = false;\n private dragStartPos = { x: 0, y: 0 };\n\n @state()\n private currentDragItem: DraggableItem | null = null;\n private startPos = { left: 0, top: 0 };\n\n // Selection state\n @state()\n private selectedItems: Set<string> = new Set();\n\n @state()\n private isSelecting = false;\n\n @state()\n private selectionBox: SelectionBox | null = null;\n\n @state()\n private targetId: string | null = null;\n\n @state()\n private sourceId: string | null = null;\n\n @state()\n private dragFromNodeId: string | null = null;\n\n @state()\n private isValidTarget = true;\n\n private canvasMouseDown = false;\n\n // Bound event handlers to maintain proper 'this' context\n private boundMouseMove = this.handleMouseMove.bind(this);\n private boundMouseUp = this.handleMouseUp.bind(this);\n private boundGlobalMouseDown = this.handleGlobalMouseDown.bind(this);\n private boundKeyDown = this.handleKeyDown.bind(this);\n private boundCanvasDoubleClick = this.handleCanvasDoubleClick.bind(this);\n\n static get styles() {\n return css`\n #editor {\n overflow: scroll;\n flex: 1;\n }\n\n #grid {\n position: relative;\n background-color: #f9f9f9;\n background-image: radial-gradient(\n circle,\n rgba(61, 177, 255, 0.3) 1px,\n transparent 1px\n );\n background-size: 20px 20px;\n background-position: 10px 10px;\n box-shadow: inset -5px 0 10px rgba(0, 0, 0, 0.05);\n border-top: 1px solid #e0e0e0;\n width: 100%;\n display: flex;\n }\n\n #canvas {\n position: relative;\n padding: 0px;\n flex-grow: 1;\n margin: 20px;\n }\n\n #canvas > .draggable {\n position: absolute;\n z-index: 100;\n }\n\n #canvas > .dragging {\n z-index: 99999 !important;\n }\n\n body .jtk-endpoint {\n width: initial;\n height: initial;\n }\n\n .jtk-endpoint {\n z-index: 600;\n opacity: 0;\n }\n\n .plumb-source {\n z-index: 600;\n cursor: pointer;\n opacity: 0;\n }\n\n .plumb-source.connected {\n border-radius: 50%;\n pointer-events: none;\n }\n\n .plumb-source circle {\n fill: purple;\n }\n\n .plumb-target {\n z-index: 600;\n opacity: 0;\n cursor: pointer;\n fill: transparent;\n }\n\n body svg.jtk-connector.plumb-connector path {\n stroke: var(--color-connectors) !important;\n stroke-width: 3px;\n }\n\n body .plumb-connector {\n z-index: 10 !important;\n }\n\n body .plumb-connector .plumb-arrow {\n fill: var(--color-connectors);\n stroke: var(--color-connectors);\n stroke-width: 0px !important;\n margin-top: 6px;\n z-index: 10;\n }\n\n body svg.jtk-connector.jtk-hover path {\n stroke: var(--color-success) !important;\n stroke-width: 3px;\n }\n\n body .plumb-connector.jtk-hover .plumb-arrow {\n fill: var(--color-success) !important;\n stroke-width: 0px;\n z-index: 10;\n }\n\n /* Connection dragging feedback */\n body svg.jtk-connector.jtk-dragging {\n z-index: 99999 !important;\n }\n\n .katavorio-drag-no-select svg.jtk-connector path,\n .katavorio-drag-no-select svg.jtk-endpoint path {\n pointer-events: none !important;\n border: 1px solid purple;\n }\n\n /* Connection target feedback */\n temba-flow-node.connection-target-valid {\n outline: 3px solid var(--color-success, #22c55e) !important;\n outline-offset: 2px;\n border-radius: var(--curvature);\n }\n\n temba-flow-node.connection-target-invalid {\n outline: 3px solid var(--color-error, #ef4444) !important;\n outline-offset: 2px;\n border-radius: var(--curvature);\n }\n\n /* Selection box styles */\n .selection-box {\n position: absolute;\n border: 2px dashed #6298f0ff;\n background-color: rgba(59, 130, 246, 0.1);\n z-index: 9999;\n pointer-events: none;\n }\n\n /* Selected item styles */\n .draggable.selected {\n outline: 3px solid #6298f0ff;\n outline-offset: 0px;\n border-radius: var(--curvature);\n }\n\n .jtk-floating-endpoint {\n pointer-events: none;\n }\n `;\n }\n\n constructor() {\n super();\n }\n\n protected firstUpdated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(changes);\n this.plumber = new Plumber(this.querySelector('#canvas'));\n this.setupGlobalEventListeners();\n if (changes.has('flow')) {\n getStore().getState().fetchRevision(`/flow/revisions/${this.flow}`);\n }\n\n this.plumber.on('connection:drag', (info: Connection) => {\n this.dragFromNodeId = document\n .getElementById(info.sourceId)\n .closest('.node').id;\n this.sourceId = info.sourceId;\n });\n\n this.plumber.on('connection:abort', () => {\n this.makeConnection();\n });\n\n this.plumber.on('connection:detach', () => {\n this.makeConnection();\n });\n }\n\n private makeConnection() {\n if (this.sourceId && this.targetId && this.isValidTarget) {\n this.plumber.connectIds(\n this.dragFromNodeId,\n this.sourceId,\n this.targetId\n );\n getStore()\n .getState()\n .updateConnection(this.dragFromNodeId, this.sourceId, this.targetId);\n\n setTimeout(() => {\n this.plumber.repaintEverything();\n }, 100);\n }\n\n // Clean up visual feedback\n document.querySelectorAll('temba-flow-node').forEach((node) => {\n node.classList.remove(\n 'connection-target-valid',\n 'connection-target-invalid'\n );\n });\n\n this.sourceId = null;\n this.targetId = null;\n this.dragFromNodeId = null;\n this.isValidTarget = true;\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('canvasSize')) {\n // console.log('Setting canvas size', this.canvasSize);\n }\n\n if (changes.has('definition')) {\n this.updateCanvasSize();\n }\n\n if (changes.has('dirtyDate')) {\n if (this.dirtyDate) {\n this.debouncedSave();\n }\n }\n }\n\n private debouncedSave(): void {\n // Clear any existing timer\n if (this.saveTimer !== null) {\n clearTimeout(this.saveTimer);\n }\n\n this.saveTimer = window.setTimeout(() => {\n const now = new Date();\n const timeSinceLastChange = now.getTime() - this.dirtyDate.getTime();\n\n if (timeSinceLastChange >= SAVE_QUIET_TIME) {\n this.saveChanges();\n this.saveTimer = null;\n } else {\n this.debouncedSave();\n }\n }, SAVE_QUIET_TIME);\n }\n\n private saveChanges(): void {\n // post the flow definition to the server\n getStore().postJSON(`/flow/revisions/${this.flow}`, this.definition);\n getStore().getState().setDirtyDate(null);\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this.saveTimer !== null) {\n clearTimeout(this.saveTimer);\n this.saveTimer = null;\n }\n document.removeEventListener('mousemove', this.boundMouseMove);\n document.removeEventListener('mouseup', this.boundMouseUp);\n document.removeEventListener('mousedown', this.boundGlobalMouseDown);\n document.removeEventListener('keydown', this.boundKeyDown);\n\n const canvas = this.querySelector('#canvas');\n if (canvas) {\n canvas.removeEventListener('dblclick', this.boundCanvasDoubleClick);\n }\n }\n\n private setupGlobalEventListeners(): void {\n document.addEventListener('mousemove', this.boundMouseMove);\n document.addEventListener('mouseup', this.boundMouseUp);\n document.addEventListener('mousedown', this.boundGlobalMouseDown);\n document.addEventListener('keydown', this.boundKeyDown);\n\n const canvas = this.querySelector('#canvas');\n if (canvas) {\n canvas.addEventListener('dblclick', this.boundCanvasDoubleClick);\n }\n }\n\n private getPosition(uuid: string, type: 'node' | 'sticky'): FlowPosition {\n if (type === 'node') {\n return this.definition._ui.nodes[uuid]?.position;\n } else {\n return this.definition._ui.stickies?.[uuid]?.position;\n }\n }\n\n private handleMouseDown(event: MouseEvent): void {\n // ignore right clicks\n if (event.button !== 0) return;\n\n const element = event.currentTarget as HTMLElement;\n // Only start dragging if clicking on the element itself, not on exits or other interactive elements\n const target = event.target as HTMLElement;\n if (target.classList.contains('exit') || target.closest('.exit')) {\n return;\n }\n\n const uuid = element.getAttribute('uuid');\n const type = element.tagName === 'TEMBA-FLOW-NODE' ? 'node' : 'sticky';\n\n const position = this.getPosition(uuid, type);\n if (!position) return;\n\n // If clicking on a non-selected item, clear selection unless Ctrl/Cmd is held\n if (!this.selectedItems.has(uuid) && !event.ctrlKey && !event.metaKey) {\n this.selectedItems.clear();\n // Don't add single items to selection - single clicks just clear existing selection\n } else if (!this.selectedItems.has(uuid)) {\n // Add this item to selection only if Ctrl/Cmd is held\n this.selectedItems.add(uuid);\n }\n\n // Always set up drag state regardless of selection status\n // This allows single nodes to be dragged without being selected\n this.isMouseDown = true;\n this.dragStartPos = { x: event.clientX, y: event.clientY };\n this.startPos = { left: position.left, top: position.top };\n this.currentDragItem = {\n uuid,\n position,\n element,\n type\n };\n\n event.preventDefault();\n event.stopPropagation();\n }\n\n private handleGlobalMouseDown(event: MouseEvent): void {\n // ignore right clicks\n if (event.button !== 0) return;\n\n // Check if the click is within our canvas\n const canvasRect = this.querySelector('#grid')?.getBoundingClientRect();\n\n if (!canvasRect) return;\n\n const isWithinCanvas =\n event.clientX >= canvasRect.left &&\n event.clientX <= canvasRect.right &&\n event.clientY >= canvasRect.top &&\n event.clientY <= canvasRect.bottom;\n\n if (!isWithinCanvas) return;\n\n // Check if we clicked on a draggable item (node or sticky)\n const target = event.target as HTMLElement;\n const clickedOnDraggable = target.closest('.draggable');\n\n if (clickedOnDraggable) {\n // This is handled by the individual item mousedown handlers\n return;\n }\n\n // We clicked on empty canvas space, start selection\n this.handleCanvasMouseDown(event);\n }\n\n private handleCanvasMouseDown(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n if (target.id === 'canvas' || target.id === 'grid') {\n // Ignore clicks on exits\n\n // Start selection box\n this.canvasMouseDown = true;\n this.dragStartPos = { x: event.clientX, y: event.clientY };\n\n const canvasRect = this.querySelector('#canvas')?.getBoundingClientRect();\n if (canvasRect) {\n // Clear current selection\n this.selectedItems.clear();\n\n const relativeX = event.clientX - canvasRect.left;\n const relativeY = event.clientY - canvasRect.top;\n\n this.selectionBox = {\n startX: relativeX,\n startY: relativeY,\n endX: relativeX,\n endY: relativeY\n };\n }\n\n event.preventDefault();\n }\n }\n\n private handleKeyDown(event: KeyboardEvent): void {\n if (event.key === 'Delete' || event.key === 'Backspace') {\n if (this.selectedItems.size > 0) {\n this.showDeleteConfirmation();\n }\n }\n if (event.key === 'Escape') {\n this.selectedItems.clear();\n this.requestUpdate();\n }\n }\n\n private showDeleteConfirmation(): void {\n const itemCount = this.selectedItems.size;\n const itemType = itemCount === 1 ? 'item' : 'items';\n\n // Create and show confirmation dialog\n const dialog = document.createElement('temba-dialog') as Dialog;\n dialog.header = 'Delete Items';\n dialog.primaryButtonName = 'Delete';\n dialog.cancelButtonName = 'Cancel';\n dialog.destructive = true;\n dialog.innerHTML = `<div style=\"padding: 20px;\">Are you sure you want to delete ${itemCount} ${itemType}?</div>`;\n\n dialog.addEventListener('temba-button-clicked', (event: any) => {\n if (event.detail.button.name === 'Delete') {\n this.deleteSelectedItems();\n dialog.open = false;\n }\n });\n\n // Add to document and show\n document.body.appendChild(dialog);\n dialog.open = true;\n\n // Clean up dialog when closed\n dialog.addEventListener('temba-dialog-hidden', () => {\n document.body.removeChild(dialog);\n });\n }\n\n private deleteNodes(uuids: string[]): void {\n // Clean up jsPlumb connections for nodes before removing them\n uuids.forEach((uuid) => {\n this.plumber.removeNodeConnections(uuid);\n });\n\n // Now remove them from the definition\n if (uuids.length > 0 && this.plumber) {\n getStore().getState().removeNodes(uuids);\n }\n }\n\n private deleteSelectedItems(): void {\n const nodes = Array.from(this.selectedItems).filter((uuid) =>\n this.definition.nodes.some((node) => node.uuid === uuid)\n );\n this.deleteNodes(Array.from(nodes));\n\n const stickies = Array.from(this.selectedItems).filter(\n (uuid) => this.definition._ui?.stickies?.[uuid]\n );\n\n getStore().getState().removeStickyNotes(stickies);\n\n // Clear selection\n this.selectedItems.clear();\n }\n\n private updateSelectionBox(event: MouseEvent): void {\n if (!this.selectionBox || !this.canvasMouseDown) return;\n\n const canvasRect = this.querySelector('#canvas')?.getBoundingClientRect();\n if (!canvasRect) return;\n\n const relativeX = event.clientX - canvasRect.left;\n const relativeY = event.clientY - canvasRect.top;\n\n this.selectionBox = {\n ...this.selectionBox,\n endX: relativeX,\n endY: relativeY\n };\n\n // Update selected items based on selection box\n this.updateSelectedItemsFromBox();\n }\n\n private updateSelectedItemsFromBox(): void {\n if (!this.selectionBox) return;\n\n const newSelection = new Set<string>();\n\n const boxLeft = Math.min(this.selectionBox.startX, this.selectionBox.endX);\n const boxTop = Math.min(this.selectionBox.startY, this.selectionBox.endY);\n const boxRight = Math.max(this.selectionBox.startX, this.selectionBox.endX);\n const boxBottom = Math.max(\n this.selectionBox.startY,\n this.selectionBox.endY\n );\n\n // Check nodes\n this.definition?.nodes.forEach((node) => {\n const nodeElement = this.querySelector(`[id=\"${node.uuid}\"]`);\n if (nodeElement) {\n const position = this.definition._ui.nodes[node.uuid]?.position;\n if (position) {\n const rect = nodeElement.getBoundingClientRect();\n const canvasRect =\n this.querySelector('#canvas')?.getBoundingClientRect();\n\n if (canvasRect) {\n const nodeLeft = position.left;\n const nodeTop = position.top;\n const nodeRight = nodeLeft + rect.width;\n const nodeBottom = nodeTop + rect.height;\n\n // Check if selection box intersects with node\n if (\n boxLeft < nodeRight &&\n boxRight > nodeLeft &&\n boxTop < nodeBottom &&\n boxBottom > nodeTop\n ) {\n newSelection.add(node.uuid);\n }\n }\n }\n }\n });\n\n // Check sticky notes\n const stickies = this.definition?._ui?.stickies || {};\n Object.entries(stickies).forEach(([uuid, sticky]) => {\n if (sticky.position) {\n const stickyElement = this.querySelector(\n `temba-sticky-note[uuid=\"${uuid}\"]`\n ) as HTMLElement;\n\n if (stickyElement) {\n // Use clientWidth/clientHeight instead of getBoundingClientRect() to get element dimensions\n // This avoids the coordinate system mismatch between viewport and canvas coordinates\n const width = stickyElement.clientWidth;\n const height = stickyElement.clientHeight;\n\n // Use the canvas coordinates from the sticky's position\n const stickyLeft = sticky.position.left;\n const stickyTop = sticky.position.top;\n const stickyRight = stickyLeft + width;\n const stickyBottom = stickyTop + height;\n\n // Check if selection box intersects with sticky\n if (\n boxLeft < stickyRight &&\n boxRight > stickyLeft &&\n boxTop < stickyBottom &&\n boxBottom > stickyTop\n ) {\n newSelection.add(uuid);\n }\n }\n }\n });\n\n this.selectedItems = newSelection;\n }\n\n private renderSelectionBox(): TemplateResult | string {\n if (!this.selectionBox || !this.isSelecting) return '';\n\n const left = Math.min(this.selectionBox.startX, this.selectionBox.endX);\n const top = Math.min(this.selectionBox.startY, this.selectionBox.endY);\n const width = Math.abs(this.selectionBox.endX - this.selectionBox.startX);\n const height = Math.abs(this.selectionBox.endY - this.selectionBox.startY);\n\n return html`<div\n class=\"selection-box\"\n style=\"left: ${left}px; top: ${top}px; width: ${width}px; height: ${height}px;\"\n ></div>`;\n }\n\n private handleMouseMove(event: MouseEvent): void {\n // Handle selection box drawing\n if (this.canvasMouseDown && !this.isMouseDown) {\n this.isSelecting = true;\n this.updateSelectionBox(event);\n this.requestUpdate(); // Force re-render\n return;\n }\n\n if (this.plumber.connectionDragging) {\n const targetNode = document.querySelector('temba-flow-node:hover');\n\n // Clear previous target styles\n document.querySelectorAll('temba-flow-node').forEach((node) => {\n node.classList.remove(\n 'connection-target-valid',\n 'connection-target-invalid'\n );\n });\n\n if (targetNode) {\n this.targetId = targetNode.getAttribute('uuid');\n // Check if target is different from source node (prevent self-targeting)\n this.isValidTarget = this.targetId !== this.dragFromNodeId;\n\n // Apply visual feedback based on validity\n if (this.isValidTarget) {\n targetNode.classList.add('connection-target-valid');\n } else {\n targetNode.classList.add('connection-target-invalid');\n }\n } else {\n this.targetId = null;\n this.isValidTarget = true;\n }\n }\n\n // Handle item dragging\n if (!this.isMouseDown || !this.currentDragItem) return;\n\n const deltaX = event.clientX - this.dragStartPos.x;\n const deltaY = event.clientY - this.dragStartPos.y;\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n\n // Only start dragging if we've moved beyond the threshold\n if (!this.isDragging && distance > DRAG_THRESHOLD) {\n this.isDragging = true;\n }\n\n // If we're actually dragging, update positions\n if (this.isDragging) {\n // Determine what items to move\n const itemsToMove =\n this.selectedItems.has(this.currentDragItem.uuid) &&\n this.selectedItems.size > 1\n ? Array.from(this.selectedItems)\n : [this.currentDragItem.uuid];\n\n itemsToMove.forEach((uuid) => {\n const element = this.querySelector(`[uuid=\"${uuid}\"]`) as HTMLElement;\n if (element) {\n const type =\n element.tagName === 'TEMBA-FLOW-NODE' ? 'node' : 'sticky';\n const position = this.getPosition(uuid, type);\n\n if (position) {\n const newLeft = position.left + deltaX;\n const newTop = position.top + deltaY;\n\n // Update the visual position during drag\n element.style.left = `${newLeft}px`;\n element.style.top = `${newTop}px`;\n\n // Add dragging class to ensure highest z-index\n element.classList.add('dragging');\n }\n }\n });\n\n this.plumber.revalidate(itemsToMove);\n }\n }\n\n private handleMouseUp(event: MouseEvent): void {\n // Handle selection box completion\n if (this.canvasMouseDown && this.isSelecting) {\n this.isSelecting = false;\n this.selectionBox = null;\n this.canvasMouseDown = false;\n this.requestUpdate();\n return;\n }\n\n // Handle canvas click (clear selection)\n if (this.canvasMouseDown && !this.isSelecting) {\n this.canvasMouseDown = false;\n return;\n }\n\n // Handle item drag completion\n if (!this.isMouseDown || !this.currentDragItem) return;\n\n // If we were actually dragging, handle the drag end\n if (this.isDragging) {\n const deltaX = event.clientX - this.dragStartPos.x;\n const deltaY = event.clientY - this.dragStartPos.y;\n\n // Determine what items were moved\n const itemsToMove =\n this.selectedItems.has(this.currentDragItem.uuid) &&\n this.selectedItems.size > 1\n ? Array.from(this.selectedItems)\n : [this.currentDragItem.uuid];\n\n // Update positions for all moved items\n const newPositions: { [uuid: string]: FlowPosition } = {};\n\n itemsToMove.forEach((uuid) => {\n const type = this.definition.nodes.find((node) => node.uuid === uuid)\n ? 'node'\n : 'sticky';\n const position = this.getPosition(uuid, type);\n\n if (position) {\n const newLeft = position.left + deltaX;\n const newTop = position.top + deltaY;\n\n // Snap to 20px grid for final position\n const snappedLeft = snapToGrid(newLeft);\n const snappedTop = snapToGrid(newTop);\n\n const newPosition = { left: snappedLeft, top: snappedTop };\n newPositions[uuid] = newPosition;\n\n // Remove dragging class\n const element = this.querySelector(`[uuid=\"${uuid}\"]`) as HTMLElement;\n if (element) {\n element.classList.remove('dragging');\n element.style.left = `${snappedLeft}px`;\n element.style.top = `${snappedTop}px`;\n }\n }\n });\n\n if (Object.keys(newPositions).length > 0) {\n getStore().getState().updateCanvasPositions(newPositions);\n\n setTimeout(() => {\n this.plumber.repaintEverything();\n }, 0);\n }\n\n this.selectedItems.clear();\n }\n\n // Reset all drag state\n this.isDragging = false;\n this.isMouseDown = false;\n this.currentDragItem = null;\n this.canvasMouseDown = false;\n }\n\n private updateCanvasSize(): void {\n if (!this.definition) return;\n\n const store = getStore();\n if (!store) return;\n\n // Calculate required canvas size based on all elements\n let maxWidth = 0;\n let maxHeight = 0;\n\n // Check node positions\n this.definition.nodes.forEach((node) => {\n const ui = this.definition._ui.nodes[node.uuid];\n if (ui && ui.position) {\n const nodeElement = this.querySelector(`[id=\"${node.uuid}\"]`);\n if (nodeElement) {\n const rect = nodeElement.getBoundingClientRect();\n maxWidth = Math.max(maxWidth, ui.position.left + rect.width);\n maxHeight = Math.max(maxHeight, ui.position.top + rect.height);\n }\n }\n });\n\n // Check sticky note positions\n const stickies = this.definition._ui?.stickies || {};\n Object.entries(stickies).forEach(([uuid, sticky]) => {\n if (sticky.position) {\n const stickyElement = this.querySelector(\n `temba-sticky-note[uuid=\"${uuid}\"]`\n ) as HTMLElement;\n if (stickyElement) {\n // Use clientWidth/clientHeight instead of getBoundingClientRect() to get element dimensions\n // This avoids the coordinate system mismatch between viewport and canvas coordinates\n const width = stickyElement.clientWidth;\n const height = stickyElement.clientHeight;\n\n // Both sticky.position and width/height are now in the same coordinate system\n maxWidth = Math.max(maxWidth, sticky.position.left + width);\n maxHeight = Math.max(maxHeight, sticky.position.top + height);\n } else {\n // Fallback to default sizes if element not found\n maxWidth = Math.max(maxWidth, sticky.position.left + 200);\n maxHeight = Math.max(maxHeight, sticky.position.top + 100);\n }\n }\n });\n\n // Update canvas size in store\n store.getState().expandCanvas(maxWidth, maxHeight);\n }\n\n private handleCanvasDoubleClick(event: MouseEvent): void {\n // Check if we double-clicked on empty canvas space\n const target = event.target as HTMLElement;\n if (target.id !== 'canvas') {\n return;\n }\n\n // Get canvas position\n const canvas = this.querySelector('#canvas');\n if (!canvas) {\n return;\n }\n\n const canvasRect = canvas.getBoundingClientRect();\n const relativeX = event.clientX - canvasRect.left - 10;\n const relativeY = event.clientY - canvasRect.top - 10;\n\n // Snap position to grid\n const snappedLeft = snapToGrid(relativeX);\n const snappedTop = snapToGrid(relativeY);\n\n // Create new sticky note\n const store = getStore();\n store.getState().createStickyNote({\n left: snappedLeft,\n top: snappedTop\n });\n\n event.preventDefault();\n event.stopPropagation();\n }\n\n public render(): TemplateResult {\n // we have to embed our own style since we are in light DOM\n const style = html`<style>\n ${unsafeCSS(Editor.styles.cssText)}\n ${unsafeCSS(EditorNode.styles.cssText)}\n </style>`;\n\n const stickies = this.definition?._ui?.stickies || {};\n\n return html`${style}\n <div id=\"editor\">\n <div\n id=\"grid\"\n style=\"min-width:100%;width:${this.canvasSize.width}px; height:${this\n .canvasSize.height}px\"\n >\n <div id=\"canvas\">\n ${this.definition\n ? repeat(\n this.definition.nodes,\n (node) => node.uuid,\n (node) => {\n const position =\n this.definition._ui.nodes[node.uuid].position;\n\n const dragging =\n this.isDragging &&\n this.currentDragItem?.uuid === node.uuid;\n\n const selected = this.selectedItems.has(node.uuid);\n\n return html`<temba-flow-node\n class=\"draggable ${dragging ? 'dragging' : ''} ${selected\n ? 'selected'\n : ''}\"\n @mousedown=${this.handleMouseDown.bind(this)}\n uuid=${node.uuid}\n style=\"left:${position.left}px; top:${position.top}px\"\n .plumber=${this.plumber}\n .node=${node}\n .ui=${this.definition._ui.nodes[node.uuid]}\n @temba-node-deleted=${(event) => {\n this.deleteNodes([event.detail.uuid]);\n }}\n ></temba-flow-node>`;\n }\n )\n : html`<temba-loading></temba-loading>`}\n ${repeat(\n Object.entries(stickies),\n ([uuid]) => uuid,\n ([uuid, sticky]) => {\n const position = sticky.position || { left: 0, top: 0 };\n const dragging =\n this.isDragging && this.currentDragItem?.uuid === uuid;\n const selected = this.selectedItems.has(uuid);\n return html`<temba-sticky-note\n class=\"draggable ${dragging ? 'dragging' : ''} ${selected\n ? 'selected'\n : ''}\"\n @mousedown=${this.handleMouseDown.bind(this)}\n style=\"left:${position.left}px; top:${position.top}px; z-index: ${1000 +\n position.top}\"\n uuid=${uuid}\n .data=${sticky}\n .dragging=${dragging}\n .selected=${selected}\n ></temba-sticky-note>`;\n }\n )}\n ${this.renderSelectionBox()}\n </div>\n </div>\n </div>`;\n }\n}\n"]}
1
+ {"version":3,"file":"Editor.js","sourceRoot":"","sources":["../../../src/flow/Editor.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, TemplateResult } from 'lit-html';\nimport { css, PropertyValueMap, unsafeCSS } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport {\n FlowDefinition,\n FlowPosition,\n Action,\n Node,\n NodeUI\n} from '../store/flow-definition';\nimport { getStore } from '../store/Store';\nimport { AppState, fromStore, zustand } from '../store/AppState';\nimport { RapidElement } from '../RapidElement';\nimport { repeat } from 'lit-html/directives/repeat.js';\nimport { CustomEventType } from '../interfaces';\n\nimport { Plumber } from './Plumber';\nimport { CanvasNode } from './CanvasNode';\nimport { Dialog } from '../layout/Dialog';\nimport { Connection } from '@jsplumb/browser-ui';\n\nexport function snapToGrid(value: number): number {\n const snapped = Math.round(value / 20) * 20;\n return Math.max(snapped, 0);\n}\n\nexport function findNodeForExit(\n definition: FlowDefinition,\n exitUuid: string\n): string | null {\n for (const node of definition.nodes) {\n const exit = node.exits.find((e) => e.uuid === exitUuid);\n if (exit) {\n return node.uuid;\n }\n }\n return null;\n}\n\nconst SAVE_QUIET_TIME = 500;\n\nexport interface DraggableItem {\n uuid: string;\n position: FlowPosition;\n element: HTMLElement;\n type: 'node' | 'sticky';\n}\n\nexport interface SelectionBox {\n startX: number;\n startY: number;\n endX: number;\n endY: number;\n}\n\nconst DRAG_THRESHOLD = 5;\n\nexport class Editor extends RapidElement {\n // unfortunately, jsplumb requires that we be in light DOM\n createRenderRoot() {\n return this;\n }\n\n // this is the master plumber\n private plumber: Plumber;\n\n // timer for debounced saving\n private saveTimer: number | null = null;\n\n @property({ type: String })\n public flow: string;\n\n @property({ type: String })\n public version: string;\n\n @fromStore(zustand, (state: AppState) => state.flowDefinition)\n private definition!: FlowDefinition;\n\n @fromStore(zustand, (state: AppState) => state.canvasSize)\n private canvasSize!: { width: number; height: number };\n\n @fromStore(zustand, (state: AppState) => state.dirtyDate)\n private dirtyDate!: Date;\n\n // Drag state\n @state()\n private isDragging = false;\n private isMouseDown = false;\n private dragStartPos = { x: 0, y: 0 };\n\n // Public getter for drag state\n public get dragging(): boolean {\n return this.isDragging;\n }\n\n @state()\n private currentDragItem: DraggableItem | null = null;\n private startPos = { left: 0, top: 0 };\n\n // Selection state\n @state()\n private selectedItems: Set<string> = new Set();\n\n @state()\n private isSelecting = false;\n\n @state()\n private selectionBox: SelectionBox | null = null;\n\n @state()\n private targetId: string | null = null;\n\n @state()\n private sourceId: string | null = null;\n\n @state()\n private dragFromNodeId: string | null = null;\n\n @state()\n private isValidTarget = true;\n\n // NodeEditor state - handles both node and action editing\n @state()\n private editingNode: Node | null = null;\n\n @state()\n private editingNodeUI: NodeUI | null = null;\n\n @state()\n private editingAction: Action | null = null;\n\n private canvasMouseDown = false;\n\n // Bound event handlers to maintain proper 'this' context\n private boundMouseMove = this.handleMouseMove.bind(this);\n private boundMouseUp = this.handleMouseUp.bind(this);\n private boundGlobalMouseDown = this.handleGlobalMouseDown.bind(this);\n private boundKeyDown = this.handleKeyDown.bind(this);\n private boundCanvasDoubleClick = this.handleCanvasDoubleClick.bind(this);\n\n static get styles() {\n return css`\n #editor {\n overflow: scroll;\n flex: 1;\n }\n\n #grid {\n position: relative;\n background-color: #f9f9f9;\n background-image: radial-gradient(\n circle,\n rgba(61, 177, 255, 0.3) 1px,\n transparent 1px\n );\n background-size: 20px 20px;\n background-position: 10px 10px;\n box-shadow: inset -5px 0 10px rgba(0, 0, 0, 0.05);\n border-top: 1px solid #e0e0e0;\n width: 100%;\n display: flex;\n }\n\n #canvas {\n position: relative;\n padding: 0px;\n flex-grow: 1;\n margin: 20px;\n }\n\n #canvas > .draggable {\n position: absolute;\n z-index: 100;\n }\n\n #canvas > .dragging {\n z-index: 99999 !important;\n }\n\n body .jtk-endpoint {\n width: initial;\n height: initial;\n }\n\n .jtk-endpoint {\n z-index: 600;\n opacity: 0;\n }\n\n .plumb-source {\n z-index: 600;\n cursor: pointer;\n opacity: 0;\n }\n\n .plumb-source.connected {\n border-radius: 50%;\n pointer-events: none;\n }\n\n .plumb-source circle {\n fill: purple;\n }\n\n .plumb-target {\n z-index: 600;\n opacity: 0;\n cursor: pointer;\n fill: transparent;\n }\n\n body svg.jtk-connector.plumb-connector path {\n stroke: var(--color-connectors) !important;\n stroke-width: 3px;\n }\n\n body .plumb-connector {\n z-index: 10 !important;\n }\n\n body .plumb-connector .plumb-arrow {\n fill: var(--color-connectors);\n stroke: var(--color-connectors);\n stroke-width: 0px !important;\n margin-top: 6px;\n z-index: 10;\n }\n\n body svg.jtk-connector.jtk-hover path {\n stroke: var(--color-success) !important;\n stroke-width: 3px;\n }\n\n body .plumb-connector.jtk-hover .plumb-arrow {\n fill: var(--color-success) !important;\n stroke-width: 0px;\n z-index: 10;\n }\n\n /* Connection dragging feedback */\n body svg.jtk-connector.jtk-dragging {\n z-index: 99999 !important;\n }\n\n .katavorio-drag-no-select svg.jtk-connector path,\n .katavorio-drag-no-select svg.jtk-endpoint path {\n pointer-events: none !important;\n border: 1px solid purple;\n }\n\n /* Connection target feedback */\n temba-flow-node.connection-target-valid {\n outline: 3px solid var(--color-success, #22c55e) !important;\n outline-offset: 2px;\n border-radius: var(--curvature);\n }\n\n temba-flow-node.connection-target-invalid {\n outline: 3px solid var(--color-error, #ef4444) !important;\n outline-offset: 2px;\n border-radius: var(--curvature);\n }\n\n /* Selection box styles */\n .selection-box {\n position: absolute;\n border: 2px dashed #6298f0ff;\n background-color: rgba(59, 130, 246, 0.1);\n z-index: 9999;\n pointer-events: none;\n }\n\n /* Selected item styles */\n .draggable.selected {\n outline: 3px solid #6298f0ff;\n outline-offset: 0px;\n border-radius: var(--curvature);\n }\n\n .jtk-floating-endpoint {\n pointer-events: none;\n }\n `;\n }\n\n constructor() {\n super();\n }\n\n protected firstUpdated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(changes);\n this.plumber = new Plumber(this.querySelector('#canvas'));\n this.setupGlobalEventListeners();\n if (changes.has('flow')) {\n getStore().getState().fetchRevision(`/flow/revisions/${this.flow}`);\n }\n\n this.plumber.on('connection:drag', (info: Connection) => {\n this.dragFromNodeId = document\n .getElementById(info.sourceId)\n .closest('.node').id;\n this.sourceId = info.sourceId;\n });\n\n this.plumber.on('connection:abort', () => {\n this.makeConnection();\n });\n\n this.plumber.on('connection:detach', () => {\n this.makeConnection();\n });\n }\n\n private makeConnection() {\n if (this.sourceId && this.targetId && this.isValidTarget) {\n this.plumber.connectIds(\n this.dragFromNodeId,\n this.sourceId,\n this.targetId\n );\n getStore()\n .getState()\n .updateConnection(this.dragFromNodeId, this.sourceId, this.targetId);\n\n setTimeout(() => {\n this.plumber.repaintEverything();\n }, 100);\n }\n\n // Clean up visual feedback\n document.querySelectorAll('temba-flow-node').forEach((node) => {\n node.classList.remove(\n 'connection-target-valid',\n 'connection-target-invalid'\n );\n });\n\n this.sourceId = null;\n this.targetId = null;\n this.dragFromNodeId = null;\n this.isValidTarget = true;\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('canvasSize')) {\n // console.log('Setting canvas size', this.canvasSize);\n }\n\n if (changes.has('definition')) {\n this.updateCanvasSize();\n }\n\n if (changes.has('dirtyDate')) {\n if (this.dirtyDate) {\n this.debouncedSave();\n }\n }\n }\n\n private debouncedSave(): void {\n // Clear any existing timer\n if (this.saveTimer !== null) {\n clearTimeout(this.saveTimer);\n }\n\n this.saveTimer = window.setTimeout(() => {\n const now = new Date();\n const timeSinceLastChange = now.getTime() - this.dirtyDate.getTime();\n\n if (timeSinceLastChange >= SAVE_QUIET_TIME) {\n this.saveChanges();\n this.saveTimer = null;\n } else {\n this.debouncedSave();\n }\n }, SAVE_QUIET_TIME);\n }\n\n private saveChanges(): void {\n // post the flow definition to the server\n getStore().postJSON(`/flow/revisions/${this.flow}`, this.definition);\n getStore().getState().setDirtyDate(null);\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this.saveTimer !== null) {\n clearTimeout(this.saveTimer);\n this.saveTimer = null;\n }\n document.removeEventListener('mousemove', this.boundMouseMove);\n document.removeEventListener('mouseup', this.boundMouseUp);\n document.removeEventListener('mousedown', this.boundGlobalMouseDown);\n document.removeEventListener('keydown', this.boundKeyDown);\n\n const canvas = this.querySelector('#canvas');\n if (canvas) {\n canvas.removeEventListener('dblclick', this.boundCanvasDoubleClick);\n }\n }\n\n private setupGlobalEventListeners(): void {\n document.addEventListener('mousemove', this.boundMouseMove);\n document.addEventListener('mouseup', this.boundMouseUp);\n document.addEventListener('mousedown', this.boundGlobalMouseDown);\n document.addEventListener('keydown', this.boundKeyDown);\n\n const canvas = this.querySelector('#canvas');\n if (canvas) {\n canvas.addEventListener('dblclick', this.boundCanvasDoubleClick);\n }\n\n // Listen for action edit requests from flow nodes\n this.addEventListener(\n CustomEventType.ActionEditRequested,\n this.handleActionEditRequested.bind(this)\n );\n\n // Listen for node edit requests from flow nodes\n this.addEventListener(\n CustomEventType.NodeEditRequested,\n this.handleNodeEditRequested.bind(this)\n );\n }\n\n private getPosition(uuid: string, type: 'node' | 'sticky'): FlowPosition {\n if (type === 'node') {\n return this.definition._ui.nodes[uuid]?.position;\n } else {\n return this.definition._ui.stickies?.[uuid]?.position;\n }\n }\n\n private handleMouseDown(event: MouseEvent): void {\n // ignore right clicks\n if (event.button !== 0) return;\n\n const element = event.currentTarget as HTMLElement;\n // Only start dragging if clicking on the element itself, not on exits or other interactive elements\n const target = event.target as HTMLElement;\n if (target.classList.contains('exit') || target.closest('.exit')) {\n return;\n }\n\n const uuid = element.getAttribute('uuid');\n const type = element.tagName === 'TEMBA-FLOW-NODE' ? 'node' : 'sticky';\n\n const position = this.getPosition(uuid, type);\n if (!position) return;\n\n // If clicking on a non-selected item, clear selection unless Ctrl/Cmd is held\n if (!this.selectedItems.has(uuid) && !event.ctrlKey && !event.metaKey) {\n this.selectedItems.clear();\n // Don't add single items to selection - single clicks just clear existing selection\n } else if (!this.selectedItems.has(uuid)) {\n // Add this item to selection only if Ctrl/Cmd is held\n this.selectedItems.add(uuid);\n }\n\n // Always set up drag state regardless of selection status\n // This allows single nodes to be dragged without being selected\n this.isMouseDown = true;\n this.dragStartPos = { x: event.clientX, y: event.clientY };\n this.startPos = { left: position.left, top: position.top };\n this.currentDragItem = {\n uuid,\n position,\n element,\n type\n };\n\n event.preventDefault();\n event.stopPropagation();\n }\n\n private handleGlobalMouseDown(event: MouseEvent): void {\n // ignore right clicks\n if (event.button !== 0) return;\n\n // Check if the click is within our canvas\n const canvasRect = this.querySelector('#grid')?.getBoundingClientRect();\n\n if (!canvasRect) return;\n\n const isWithinCanvas =\n event.clientX >= canvasRect.left &&\n event.clientX <= canvasRect.right &&\n event.clientY >= canvasRect.top &&\n event.clientY <= canvasRect.bottom;\n\n if (!isWithinCanvas) return;\n\n // Check if we clicked on a draggable item (node or sticky)\n const target = event.target as HTMLElement;\n const clickedOnDraggable = target.closest('.draggable');\n\n if (clickedOnDraggable) {\n // This is handled by the individual item mousedown handlers\n return;\n }\n\n // We clicked on empty canvas space, start selection\n this.handleCanvasMouseDown(event);\n }\n\n private handleCanvasMouseDown(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n if (target.id === 'canvas' || target.id === 'grid') {\n // Ignore clicks on exits\n\n // Start selection box\n this.canvasMouseDown = true;\n this.dragStartPos = { x: event.clientX, y: event.clientY };\n\n const canvasRect = this.querySelector('#canvas')?.getBoundingClientRect();\n if (canvasRect) {\n // Clear current selection\n this.selectedItems.clear();\n\n const relativeX = event.clientX - canvasRect.left;\n const relativeY = event.clientY - canvasRect.top;\n\n this.selectionBox = {\n startX: relativeX,\n startY: relativeY,\n endX: relativeX,\n endY: relativeY\n };\n }\n\n event.preventDefault();\n }\n }\n\n private handleKeyDown(event: KeyboardEvent): void {\n if (event.key === 'Delete' || event.key === 'Backspace') {\n if (this.selectedItems.size > 0) {\n this.showDeleteConfirmation();\n }\n }\n if (event.key === 'Escape') {\n this.selectedItems.clear();\n this.requestUpdate();\n }\n }\n\n private showDeleteConfirmation(): void {\n const itemCount = this.selectedItems.size;\n const itemType = itemCount === 1 ? 'item' : 'items';\n\n // Create and show confirmation dialog\n const dialog = document.createElement('temba-dialog') as Dialog;\n dialog.header = 'Delete Items';\n dialog.primaryButtonName = 'Delete';\n dialog.cancelButtonName = 'Cancel';\n dialog.destructive = true;\n dialog.innerHTML = `<div style=\"padding: 20px;\">Are you sure you want to delete ${itemCount} ${itemType}?</div>`;\n\n dialog.addEventListener('temba-button-clicked', (event: any) => {\n if (event.detail.button.name === 'Delete') {\n this.deleteSelectedItems();\n dialog.open = false;\n }\n });\n\n // Add to document and show\n document.body.appendChild(dialog);\n dialog.open = true;\n\n // Clean up dialog when closed\n dialog.addEventListener('temba-dialog-hidden', () => {\n document.body.removeChild(dialog);\n });\n }\n\n private deleteNodes(uuids: string[]): void {\n // Clean up jsPlumb connections for nodes before removing them\n uuids.forEach((uuid) => {\n this.plumber.removeNodeConnections(uuid);\n });\n\n // Now remove them from the definition\n if (uuids.length > 0 && this.plumber) {\n getStore().getState().removeNodes(uuids);\n }\n }\n\n private deleteSelectedItems(): void {\n const nodes = Array.from(this.selectedItems).filter((uuid) =>\n this.definition.nodes.some((node) => node.uuid === uuid)\n );\n this.deleteNodes(Array.from(nodes));\n\n const stickies = Array.from(this.selectedItems).filter(\n (uuid) => this.definition._ui?.stickies?.[uuid]\n );\n\n getStore().getState().removeStickyNotes(stickies);\n\n // Clear selection\n this.selectedItems.clear();\n }\n\n private updateSelectionBox(event: MouseEvent): void {\n if (!this.selectionBox || !this.canvasMouseDown) return;\n\n const canvasRect = this.querySelector('#canvas')?.getBoundingClientRect();\n if (!canvasRect) return;\n\n const relativeX = event.clientX - canvasRect.left;\n const relativeY = event.clientY - canvasRect.top;\n\n this.selectionBox = {\n ...this.selectionBox,\n endX: relativeX,\n endY: relativeY\n };\n\n // Update selected items based on selection box\n this.updateSelectedItemsFromBox();\n }\n\n private updateSelectedItemsFromBox(): void {\n if (!this.selectionBox) return;\n\n const newSelection = new Set<string>();\n\n const boxLeft = Math.min(this.selectionBox.startX, this.selectionBox.endX);\n const boxTop = Math.min(this.selectionBox.startY, this.selectionBox.endY);\n const boxRight = Math.max(this.selectionBox.startX, this.selectionBox.endX);\n const boxBottom = Math.max(\n this.selectionBox.startY,\n this.selectionBox.endY\n );\n\n // Check nodes\n this.definition?.nodes.forEach((node) => {\n const nodeElement = this.querySelector(`[id=\"${node.uuid}\"]`);\n if (nodeElement) {\n const position = this.definition._ui.nodes[node.uuid]?.position;\n if (position) {\n const rect = nodeElement.getBoundingClientRect();\n const canvasRect =\n this.querySelector('#canvas')?.getBoundingClientRect();\n\n if (canvasRect) {\n const nodeLeft = position.left;\n const nodeTop = position.top;\n const nodeRight = nodeLeft + rect.width;\n const nodeBottom = nodeTop + rect.height;\n\n // Check if selection box intersects with node\n if (\n boxLeft < nodeRight &&\n boxRight > nodeLeft &&\n boxTop < nodeBottom &&\n boxBottom > nodeTop\n ) {\n newSelection.add(node.uuid);\n }\n }\n }\n }\n });\n\n // Check sticky notes\n const stickies = this.definition?._ui?.stickies || {};\n Object.entries(stickies).forEach(([uuid, sticky]) => {\n if (sticky.position) {\n const stickyElement = this.querySelector(\n `temba-sticky-note[uuid=\"${uuid}\"]`\n ) as HTMLElement;\n\n if (stickyElement) {\n // Use clientWidth/clientHeight instead of getBoundingClientRect() to get element dimensions\n // This avoids the coordinate system mismatch between viewport and canvas coordinates\n const width = stickyElement.clientWidth;\n const height = stickyElement.clientHeight;\n\n // Use the canvas coordinates from the sticky's position\n const stickyLeft = sticky.position.left;\n const stickyTop = sticky.position.top;\n const stickyRight = stickyLeft + width;\n const stickyBottom = stickyTop + height;\n\n // Check if selection box intersects with sticky\n if (\n boxLeft < stickyRight &&\n boxRight > stickyLeft &&\n boxTop < stickyBottom &&\n boxBottom > stickyTop\n ) {\n newSelection.add(uuid);\n }\n }\n }\n });\n\n this.selectedItems = newSelection;\n }\n\n private renderSelectionBox(): TemplateResult | string {\n if (!this.selectionBox || !this.isSelecting) return '';\n\n const left = Math.min(this.selectionBox.startX, this.selectionBox.endX);\n const top = Math.min(this.selectionBox.startY, this.selectionBox.endY);\n const width = Math.abs(this.selectionBox.endX - this.selectionBox.startX);\n const height = Math.abs(this.selectionBox.endY - this.selectionBox.startY);\n\n return html`<div\n class=\"selection-box\"\n style=\"left: ${left}px; top: ${top}px; width: ${width}px; height: ${height}px;\"\n ></div>`;\n }\n\n private handleMouseMove(event: MouseEvent): void {\n // Handle selection box drawing\n if (this.canvasMouseDown && !this.isMouseDown) {\n this.isSelecting = true;\n this.updateSelectionBox(event);\n this.requestUpdate(); // Force re-render\n return;\n }\n\n if (this.plumber.connectionDragging) {\n const targetNode = document.querySelector('temba-flow-node:hover');\n\n // Clear previous target styles\n document.querySelectorAll('temba-flow-node').forEach((node) => {\n node.classList.remove(\n 'connection-target-valid',\n 'connection-target-invalid'\n );\n });\n\n if (targetNode) {\n this.targetId = targetNode.getAttribute('uuid');\n // Check if target is different from source node (prevent self-targeting)\n this.isValidTarget = this.targetId !== this.dragFromNodeId;\n\n // Apply visual feedback based on validity\n if (this.isValidTarget) {\n targetNode.classList.add('connection-target-valid');\n } else {\n targetNode.classList.add('connection-target-invalid');\n }\n } else {\n this.targetId = null;\n this.isValidTarget = true;\n }\n }\n\n // Handle item dragging\n if (!this.isMouseDown || !this.currentDragItem) return;\n\n const deltaX = event.clientX - this.dragStartPos.x;\n const deltaY = event.clientY - this.dragStartPos.y;\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n\n // Only start dragging if we've moved beyond the threshold\n if (!this.isDragging && distance > DRAG_THRESHOLD) {\n this.isDragging = true;\n }\n\n // If we're actually dragging, update positions\n if (this.isDragging) {\n // Determine what items to move\n const itemsToMove =\n this.selectedItems.has(this.currentDragItem.uuid) &&\n this.selectedItems.size > 1\n ? Array.from(this.selectedItems)\n : [this.currentDragItem.uuid];\n\n itemsToMove.forEach((uuid) => {\n const element = this.querySelector(`[uuid=\"${uuid}\"]`) as HTMLElement;\n if (element) {\n const type =\n element.tagName === 'TEMBA-FLOW-NODE' ? 'node' : 'sticky';\n const position = this.getPosition(uuid, type);\n\n if (position) {\n const newLeft = position.left + deltaX;\n const newTop = position.top + deltaY;\n\n // Update the visual position during drag\n element.style.left = `${newLeft}px`;\n element.style.top = `${newTop}px`;\n\n // Add dragging class to ensure highest z-index\n element.classList.add('dragging');\n }\n }\n });\n\n this.plumber.revalidate(itemsToMove);\n }\n }\n\n private handleMouseUp(event: MouseEvent): void {\n // Handle selection box completion\n if (this.canvasMouseDown && this.isSelecting) {\n this.isSelecting = false;\n this.selectionBox = null;\n this.canvasMouseDown = false;\n this.requestUpdate();\n return;\n }\n\n // Handle canvas click (clear selection)\n if (this.canvasMouseDown && !this.isSelecting) {\n this.canvasMouseDown = false;\n return;\n }\n\n // Handle item drag completion\n if (!this.isMouseDown || !this.currentDragItem) return;\n\n // If we were actually dragging, handle the drag end\n if (this.isDragging) {\n const deltaX = event.clientX - this.dragStartPos.x;\n const deltaY = event.clientY - this.dragStartPos.y;\n\n // Determine what items were moved\n const itemsToMove =\n this.selectedItems.has(this.currentDragItem.uuid) &&\n this.selectedItems.size > 1\n ? Array.from(this.selectedItems)\n : [this.currentDragItem.uuid];\n\n // Update positions for all moved items\n const newPositions: { [uuid: string]: FlowPosition } = {};\n\n itemsToMove.forEach((uuid) => {\n const type = this.definition.nodes.find((node) => node.uuid === uuid)\n ? 'node'\n : 'sticky';\n const position = this.getPosition(uuid, type);\n\n if (position) {\n const newLeft = position.left + deltaX;\n const newTop = position.top + deltaY;\n\n // Snap to 20px grid for final position\n const snappedLeft = snapToGrid(newLeft);\n const snappedTop = snapToGrid(newTop);\n\n const newPosition = { left: snappedLeft, top: snappedTop };\n newPositions[uuid] = newPosition;\n\n // Remove dragging class\n const element = this.querySelector(`[uuid=\"${uuid}\"]`) as HTMLElement;\n if (element) {\n element.classList.remove('dragging');\n element.style.left = `${snappedLeft}px`;\n element.style.top = `${snappedTop}px`;\n }\n }\n });\n\n if (Object.keys(newPositions).length > 0) {\n getStore().getState().updateCanvasPositions(newPositions);\n\n setTimeout(() => {\n this.plumber.repaintEverything();\n }, 0);\n }\n\n this.selectedItems.clear();\n }\n\n // Reset all drag state\n this.isDragging = false;\n this.isMouseDown = false;\n this.currentDragItem = null;\n this.canvasMouseDown = false;\n }\n\n private updateCanvasSize(): void {\n if (!this.definition) return;\n\n const store = getStore();\n if (!store) return;\n\n // Calculate required canvas size based on all elements\n let maxWidth = 0;\n let maxHeight = 0;\n\n // Check node positions\n this.definition.nodes.forEach((node) => {\n const ui = this.definition._ui.nodes[node.uuid];\n if (ui && ui.position) {\n const nodeElement = this.querySelector(`[id=\"${node.uuid}\"]`);\n if (nodeElement) {\n const rect = nodeElement.getBoundingClientRect();\n maxWidth = Math.max(maxWidth, ui.position.left + rect.width);\n maxHeight = Math.max(maxHeight, ui.position.top + rect.height);\n }\n }\n });\n\n // Check sticky note positions\n const stickies = this.definition._ui?.stickies || {};\n Object.entries(stickies).forEach(([uuid, sticky]) => {\n if (sticky.position) {\n const stickyElement = this.querySelector(\n `temba-sticky-note[uuid=\"${uuid}\"]`\n ) as HTMLElement;\n if (stickyElement) {\n // Use clientWidth/clientHeight instead of getBoundingClientRect() to get element dimensions\n // This avoids the coordinate system mismatch between viewport and canvas coordinates\n const width = stickyElement.clientWidth;\n const height = stickyElement.clientHeight;\n\n // Both sticky.position and width/height are now in the same coordinate system\n maxWidth = Math.max(maxWidth, sticky.position.left + width);\n maxHeight = Math.max(maxHeight, sticky.position.top + height);\n } else {\n // Fallback to default sizes if element not found\n maxWidth = Math.max(maxWidth, sticky.position.left + 200);\n maxHeight = Math.max(maxHeight, sticky.position.top + 100);\n }\n }\n });\n\n // Update canvas size in store\n store.getState().expandCanvas(maxWidth, maxHeight);\n }\n\n private handleCanvasDoubleClick(event: MouseEvent): void {\n // Check if we double-clicked on empty canvas space\n const target = event.target as HTMLElement;\n if (target.id !== 'canvas') {\n return;\n }\n\n // Get canvas position\n const canvas = this.querySelector('#canvas');\n if (!canvas) {\n return;\n }\n\n const canvasRect = canvas.getBoundingClientRect();\n const relativeX = event.clientX - canvasRect.left - 10;\n const relativeY = event.clientY - canvasRect.top - 10;\n\n // Snap position to grid\n const snappedLeft = snapToGrid(relativeX);\n const snappedTop = snapToGrid(relativeY);\n\n // Create new sticky note\n const store = getStore();\n store.getState().createStickyNote({\n left: snappedLeft,\n top: snappedTop\n });\n\n event.preventDefault();\n event.stopPropagation();\n }\n\n private handleActionEditRequested(event: CustomEvent): void {\n // For action editing, we set the action and find the corresponding node\n this.editingAction = event.detail.action;\n\n // Find the node that contains this action\n const nodeUuid = event.detail.nodeUuid;\n const node = this.definition.nodes.find((n) => n.uuid === nodeUuid);\n\n if (node) {\n this.editingNode = node;\n this.editingNodeUI = this.definition._ui.nodes[nodeUuid];\n }\n }\n private handleNodeEditRequested(event: CustomEvent): void {\n this.editingNode = event.detail.node;\n this.editingNodeUI = event.detail.nodeUI;\n }\n\n private handleActionSaved(updatedAction: Action): void {\n if (this.editingNode && this.editingAction) {\n // Update the specific action in the node\n const updatedActions = this.editingNode.actions.map((action) =>\n action.uuid === this.editingAction.uuid ? updatedAction : action\n );\n const updatedNode = { ...this.editingNode, actions: updatedActions };\n\n // Update the node in the store\n getStore()?.getState().updateNode(this.editingNode.uuid, updatedNode);\n\n // Repaint jsplumb connections in case node size changed\n if (this.plumber) {\n // Use requestAnimationFrame to ensure DOM has been updated first\n requestAnimationFrame(() => {\n this.plumber.repaintEverything();\n });\n }\n }\n this.closeNodeEditor();\n }\n\n private closeNodeEditor(): void {\n this.editingNode = null;\n this.editingNodeUI = null;\n this.editingAction = null;\n }\n\n private handleActionEditCanceled(): void {\n this.closeNodeEditor();\n }\n\n private handleNodeSaved(updatedNode: Node): void {\n if (this.editingNode) {\n // Clean up jsPlumb connections for removed exits before updating the node\n if (this.plumber) {\n const oldExits = this.editingNode.exits || [];\n const newExits = updatedNode.exits || [];\n\n // Find exits that were removed\n const removedExits = oldExits.filter(\n (oldExit) =>\n !newExits.find((newExit) => newExit.uuid === oldExit.uuid)\n );\n\n // Remove jsPlumb connections for removed exits\n removedExits.forEach((exit) => {\n this.plumber.removeExitConnection(exit.uuid);\n });\n }\n\n this.plumber.revalidate([updatedNode.uuid]);\n\n // Update the node in the store\n getStore()?.getState().updateNode(this.editingNode.uuid, updatedNode);\n\n // Repaint jsplumb connections in case node size changed\n if (this.plumber) {\n // Use requestAnimationFrame to ensure DOM has been updated first\n requestAnimationFrame(() => {\n this.plumber.repaintEverything();\n });\n }\n }\n this.closeNodeEditor();\n }\n\n private handleNodeEditCanceled(): void {\n this.closeNodeEditor();\n }\n\n public render(): TemplateResult {\n // we have to embed our own style since we are in light DOM\n const style = html`<style>\n ${unsafeCSS(Editor.styles.cssText)}\n ${unsafeCSS(CanvasNode.styles.cssText)}\n </style>`;\n\n const stickies = this.definition?._ui?.stickies || {};\n\n return html`${style}\n <div id=\"editor\">\n <div\n id=\"grid\"\n style=\"min-width:100%;width:${this.canvasSize.width}px; height:${this\n .canvasSize.height}px\"\n >\n <div id=\"canvas\">\n ${this.definition\n ? repeat(\n this.definition.nodes,\n (node) => node.uuid,\n (node) => {\n const position =\n this.definition._ui.nodes[node.uuid].position;\n\n const dragging =\n this.isDragging &&\n this.currentDragItem?.uuid === node.uuid;\n\n const selected = this.selectedItems.has(node.uuid);\n\n return html`<temba-flow-node\n class=\"draggable ${dragging ? 'dragging' : ''} ${selected\n ? 'selected'\n : ''}\"\n @mousedown=${this.handleMouseDown.bind(this)}\n uuid=${node.uuid}\n style=\"left:${position.left}px; top:${position.top}px\"\n .plumber=${this.plumber}\n .node=${node}\n .ui=${this.definition._ui.nodes[node.uuid]}\n @temba-node-deleted=${(event) => {\n this.deleteNodes([event.detail.uuid]);\n }}\n ></temba-flow-node>`;\n }\n )\n : html`<temba-loading></temba-loading>`}\n ${repeat(\n Object.entries(stickies),\n ([uuid]) => uuid,\n ([uuid, sticky]) => {\n const position = sticky.position || { left: 0, top: 0 };\n const dragging =\n this.isDragging && this.currentDragItem?.uuid === uuid;\n const selected = this.selectedItems.has(uuid);\n return html`<temba-sticky-note\n class=\"draggable ${dragging ? 'dragging' : ''} ${selected\n ? 'selected'\n : ''}\"\n @mousedown=${this.handleMouseDown.bind(this)}\n style=\"left:${position.left}px; top:${position.top}px; z-index: ${1000 +\n position.top}\"\n uuid=${uuid}\n .data=${sticky}\n .dragging=${dragging}\n .selected=${selected}\n ></temba-sticky-note>`;\n }\n )}\n ${this.renderSelectionBox()}\n </div>\n </div>\n </div>\n\n ${this.editingNode || this.editingAction\n ? html`<temba-node-editor\n .node=${this.editingNode}\n .nodeUI=${this.editingNodeUI}\n .action=${this.editingAction}\n @temba-node-saved=${(e: CustomEvent) =>\n this.handleNodeSaved(e.detail.node)}\n @temba-action-saved=${(e: CustomEvent) =>\n this.handleActionSaved(e.detail.action)}\n @temba-node-edit-cancelled=${this.handleNodeEditCanceled}\n ></temba-node-editor>`\n : ''} `;\n }\n}\n"]}