@nyaruka/temba-components 0.129.2 → 0.129.4

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 (773) hide show
  1. package/.eslintrc.js +1 -0
  2. package/.github/workflows/build.yml +141 -8
  3. package/CHANGELOG.md +40 -0
  4. package/README.md +6 -0
  5. package/check-coverage.js +133 -0
  6. package/demo/data/flows/sample-flow.json +158 -128
  7. package/demo/field-config-demo.html +135 -0
  8. package/dist/temba-components.js +1750 -751
  9. package/dist/temba-components.js.map +1 -1
  10. package/docs/ActionEditor-Migration.md +118 -0
  11. package/generate-coverage-badge.sh +69 -0
  12. package/out-tsc/src/{vectoricon/index.js → Icons.js} +1 -1
  13. package/out-tsc/src/Icons.js.map +1 -0
  14. package/out-tsc/src/display/Alert.js.map +1 -0
  15. package/out-tsc/src/display/Anchor.js.map +1 -0
  16. package/out-tsc/src/display/Button.js.map +1 -0
  17. package/out-tsc/src/{charcount → display}/CharCount.js +159 -2
  18. package/out-tsc/src/display/CharCount.js.map +1 -0
  19. package/out-tsc/src/display/Chat.js.map +1 -0
  20. package/out-tsc/src/display/ContactName.js.map +1 -0
  21. package/out-tsc/src/display/ContactUrn.js.map +1 -0
  22. package/out-tsc/src/display/Dropdown.js.map +1 -0
  23. package/out-tsc/src/{vectoricon/VectorIcon.js → display/Icon.js} +2 -2
  24. package/out-tsc/src/display/Icon.js.map +1 -0
  25. package/out-tsc/src/display/Label.js.map +1 -0
  26. package/out-tsc/src/{leafletmap → display}/LeafletMap.js +16 -1
  27. package/out-tsc/src/display/LeafletMap.js.map +1 -0
  28. package/out-tsc/src/display/Lightbox.js.map +1 -0
  29. package/out-tsc/src/{loading → display}/Loading.js.map +1 -1
  30. package/out-tsc/src/{options → display}/Options.js.map +1 -1
  31. package/out-tsc/src/display/ProgressBar.js.map +1 -0
  32. package/out-tsc/src/display/TembaDate.js.map +1 -0
  33. package/out-tsc/src/display/TembaUser.js.map +1 -0
  34. package/out-tsc/src/display/Thumbnail.js.map +1 -0
  35. package/out-tsc/src/{tip → display}/Tip.js +1 -2
  36. package/out-tsc/src/display/Tip.js.map +1 -0
  37. package/out-tsc/src/display/Toast.js.map +1 -0
  38. package/out-tsc/src/display/sms/gsmsplitter.js.map +1 -0
  39. package/out-tsc/src/display/sms/gsmvalidator.js.map +1 -0
  40. package/out-tsc/src/display/sms/index.js.map +1 -0
  41. package/out-tsc/src/display/sms/unicodesplitter.js.map +1 -0
  42. package/out-tsc/src/events.js +2 -0
  43. package/out-tsc/src/events.js.map +1 -0
  44. package/out-tsc/src/excellent/ExcellentParser.js.map +1 -0
  45. package/out-tsc/src/excellent/helpers.js.map +1 -0
  46. package/out-tsc/src/flow/CanvasNode.js +861 -0
  47. package/out-tsc/src/flow/CanvasNode.js.map +1 -0
  48. package/out-tsc/src/flow/Editor.js +640 -143
  49. package/out-tsc/src/flow/Editor.js.map +1 -1
  50. package/out-tsc/src/flow/NodeEditor.js +1200 -0
  51. package/out-tsc/src/flow/NodeEditor.js.map +1 -0
  52. package/out-tsc/src/flow/Plumber.js +148 -74
  53. package/out-tsc/src/flow/Plumber.js.map +1 -1
  54. package/out-tsc/src/flow/StickyNote.js +153 -9
  55. package/out-tsc/src/flow/StickyNote.js.map +1 -1
  56. package/out-tsc/src/flow/actions/add_contact_groups.js +40 -0
  57. package/out-tsc/src/flow/actions/add_contact_groups.js.map +1 -0
  58. package/out-tsc/src/flow/actions/add_contact_urn.js +16 -0
  59. package/out-tsc/src/flow/actions/add_contact_urn.js.map +1 -0
  60. package/out-tsc/src/flow/actions/add_input_labels.js +11 -0
  61. package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -0
  62. package/out-tsc/src/flow/actions/call_classifier.js +11 -0
  63. package/out-tsc/src/flow/actions/call_classifier.js.map +1 -0
  64. package/out-tsc/src/flow/actions/call_llm.js +11 -0
  65. package/out-tsc/src/flow/actions/call_llm.js.map +1 -0
  66. package/out-tsc/src/flow/actions/call_resthook.js +11 -0
  67. package/out-tsc/src/flow/actions/call_resthook.js.map +1 -0
  68. package/out-tsc/src/flow/actions/call_webhook.js +122 -0
  69. package/out-tsc/src/flow/actions/call_webhook.js.map +1 -0
  70. package/out-tsc/src/flow/actions/enter_flow.js +14 -0
  71. package/out-tsc/src/flow/actions/enter_flow.js.map +1 -0
  72. package/out-tsc/src/flow/actions/open_ticket.js +11 -0
  73. package/out-tsc/src/flow/actions/open_ticket.js.map +1 -0
  74. package/out-tsc/src/flow/actions/play_audio.js +11 -0
  75. package/out-tsc/src/flow/actions/play_audio.js.map +1 -0
  76. package/out-tsc/src/flow/actions/remove_contact_groups.js +62 -0
  77. package/out-tsc/src/flow/actions/remove_contact_groups.js.map +1 -0
  78. package/out-tsc/src/flow/actions/request_optin.js +11 -0
  79. package/out-tsc/src/flow/actions/request_optin.js.map +1 -0
  80. package/out-tsc/src/flow/actions/say_msg.js +11 -0
  81. package/out-tsc/src/flow/actions/say_msg.js.map +1 -0
  82. package/out-tsc/src/flow/actions/send_broadcast.js +33 -0
  83. package/out-tsc/src/flow/actions/send_broadcast.js.map +1 -0
  84. package/out-tsc/src/flow/actions/send_email.js +56 -0
  85. package/out-tsc/src/flow/actions/send_email.js.map +1 -0
  86. package/out-tsc/src/flow/actions/send_msg.js +55 -0
  87. package/out-tsc/src/flow/actions/send_msg.js.map +1 -0
  88. package/out-tsc/src/flow/actions/set_contact_channel.js +12 -0
  89. package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -0
  90. package/out-tsc/src/flow/actions/set_contact_field.js +12 -0
  91. package/out-tsc/src/flow/actions/set_contact_field.js.map +1 -0
  92. package/out-tsc/src/flow/actions/set_contact_language.js +10 -0
  93. package/out-tsc/src/flow/actions/set_contact_language.js.map +1 -0
  94. package/out-tsc/src/flow/actions/set_contact_name.js +10 -0
  95. package/out-tsc/src/flow/actions/set_contact_name.js.map +1 -0
  96. package/out-tsc/src/flow/actions/set_contact_status.js +10 -0
  97. package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -0
  98. package/out-tsc/src/flow/actions/set_run_result.js +10 -0
  99. package/out-tsc/src/flow/actions/set_run_result.js.map +1 -0
  100. package/out-tsc/src/flow/actions/split_by_expression_example.js +77 -0
  101. package/out-tsc/src/flow/actions/split_by_expression_example.js.map +1 -0
  102. package/out-tsc/src/flow/actions/start_session.js +11 -0
  103. package/out-tsc/src/flow/actions/start_session.js.map +1 -0
  104. package/out-tsc/src/flow/actions/transfer_airtime.js +11 -0
  105. package/out-tsc/src/flow/actions/transfer_airtime.js.map +1 -0
  106. package/out-tsc/src/flow/config.js +88 -123
  107. package/out-tsc/src/flow/config.js.map +1 -1
  108. package/out-tsc/src/flow/nodes/execute_actions.js +4 -0
  109. package/out-tsc/src/flow/nodes/execute_actions.js.map +1 -0
  110. package/out-tsc/src/flow/nodes/split_by_airtime.js +9 -0
  111. package/out-tsc/src/flow/nodes/split_by_airtime.js.map +1 -0
  112. package/out-tsc/src/flow/nodes/split_by_contact_field.js +7 -0
  113. package/out-tsc/src/flow/nodes/split_by_contact_field.js.map +1 -0
  114. package/out-tsc/src/flow/nodes/split_by_expression.js +7 -0
  115. package/out-tsc/src/flow/nodes/split_by_expression.js.map +1 -0
  116. package/out-tsc/src/flow/nodes/split_by_groups.js +7 -0
  117. package/out-tsc/src/flow/nodes/split_by_groups.js.map +1 -0
  118. package/out-tsc/src/flow/nodes/split_by_random.js +10 -0
  119. package/out-tsc/src/flow/nodes/split_by_random.js.map +1 -0
  120. package/out-tsc/src/flow/nodes/split_by_run_result.js +7 -0
  121. package/out-tsc/src/flow/nodes/split_by_run_result.js.map +1 -0
  122. package/out-tsc/src/flow/nodes/split_by_scheme.js +7 -0
  123. package/out-tsc/src/flow/nodes/split_by_scheme.js.map +1 -0
  124. package/out-tsc/src/flow/nodes/split_by_subflow.js +9 -0
  125. package/out-tsc/src/flow/nodes/split_by_subflow.js.map +1 -0
  126. package/out-tsc/src/flow/nodes/split_by_webhook.js +18 -0
  127. package/out-tsc/src/flow/nodes/split_by_webhook.js.map +1 -0
  128. package/out-tsc/src/flow/nodes/wait_for_audio.js +7 -0
  129. package/out-tsc/src/flow/nodes/wait_for_audio.js.map +1 -0
  130. package/out-tsc/src/flow/nodes/wait_for_digits.js +7 -0
  131. package/out-tsc/src/flow/nodes/wait_for_digits.js.map +1 -0
  132. package/out-tsc/src/flow/nodes/wait_for_image.js +7 -0
  133. package/out-tsc/src/flow/nodes/wait_for_image.js.map +1 -0
  134. package/out-tsc/src/flow/nodes/wait_for_location.js +7 -0
  135. package/out-tsc/src/flow/nodes/wait_for_location.js.map +1 -0
  136. package/out-tsc/src/flow/nodes/wait_for_menu.js +7 -0
  137. package/out-tsc/src/flow/nodes/wait_for_menu.js.map +1 -0
  138. package/out-tsc/src/flow/nodes/wait_for_response.js +7 -0
  139. package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -0
  140. package/out-tsc/src/flow/nodes/wait_for_video.js +7 -0
  141. package/out-tsc/src/flow/nodes/wait_for_video.js.map +1 -0
  142. package/out-tsc/src/flow/types.js +79 -0
  143. package/out-tsc/src/flow/types.js.map +1 -0
  144. package/out-tsc/src/flow/utils.js +65 -0
  145. package/out-tsc/src/flow/utils.js.map +1 -0
  146. package/out-tsc/src/form/ArrayEditor.js +199 -0
  147. package/out-tsc/src/form/ArrayEditor.js.map +1 -0
  148. package/out-tsc/src/form/BaseListEditor.js +128 -0
  149. package/out-tsc/src/form/BaseListEditor.js.map +1 -0
  150. package/out-tsc/src/{checkbox → form}/Checkbox.js +19 -4
  151. package/out-tsc/src/form/Checkbox.js.map +1 -0
  152. package/out-tsc/src/{colorpicker → form}/ColorPicker.js +1 -1
  153. package/out-tsc/src/form/ColorPicker.js.map +1 -0
  154. package/out-tsc/src/{completion → form}/Completion.js +8 -2
  155. package/out-tsc/src/form/Completion.js.map +1 -0
  156. package/out-tsc/src/{compose → form}/Compose.js +1 -1
  157. package/out-tsc/src/form/Compose.js.map +1 -0
  158. package/out-tsc/src/{contactsearch → form}/ContactSearch.js +2 -2
  159. package/out-tsc/src/form/ContactSearch.js.map +1 -0
  160. package/out-tsc/src/form/CroppieCSS.js.map +1 -0
  161. package/out-tsc/src/{datepicker → form}/DatePicker.js +1 -1
  162. package/out-tsc/src/form/DatePicker.js.map +1 -0
  163. package/out-tsc/src/{FormElement.js → form/FormElement.js} +1 -1
  164. package/out-tsc/src/form/FormElement.js.map +1 -0
  165. package/out-tsc/src/form/FormField.js +243 -0
  166. package/out-tsc/src/form/FormField.js.map +1 -0
  167. package/out-tsc/src/{imagepicker → form}/ImagePicker.js +2 -2
  168. package/out-tsc/src/form/ImagePicker.js.map +1 -0
  169. package/out-tsc/src/form/KeyValueEditor.js +223 -0
  170. package/out-tsc/src/form/KeyValueEditor.js.map +1 -0
  171. package/out-tsc/src/{mediapicker → form}/MediaPicker.js +1 -1
  172. package/out-tsc/src/form/MediaPicker.js.map +1 -0
  173. package/out-tsc/src/form/RangePicker.js.map +1 -0
  174. package/out-tsc/src/{slider → form}/TembaSlider.js +1 -1
  175. package/out-tsc/src/form/TembaSlider.js.map +1 -0
  176. package/out-tsc/src/{templates → form}/TemplateEditor.js +1 -1
  177. package/out-tsc/src/form/TemplateEditor.js.map +1 -0
  178. package/out-tsc/src/{textinput → form}/TextInput.js +3 -3
  179. package/out-tsc/src/form/TextInput.js.map +1 -0
  180. package/out-tsc/src/{omnibox → form/select}/Omnibox.js +2 -2
  181. package/out-tsc/src/form/select/Omnibox.js.map +1 -0
  182. package/out-tsc/src/{select → form/select}/PopupSelect.js +1 -1
  183. package/out-tsc/src/form/select/PopupSelect.js.map +1 -0
  184. package/out-tsc/src/{select → form/select}/Select.js +157 -113
  185. package/out-tsc/src/form/select/Select.js.map +1 -0
  186. package/out-tsc/src/{select → form/select}/UserSelect.js +1 -1
  187. package/out-tsc/src/form/select/UserSelect.js.map +1 -0
  188. package/out-tsc/src/{select → form/select}/WorkspaceSelect.js +1 -1
  189. package/out-tsc/src/form/select/WorkspaceSelect.js.map +1 -0
  190. package/out-tsc/src/interfaces.js +7 -0
  191. package/out-tsc/src/interfaces.js.map +1 -1
  192. package/out-tsc/src/layout/Dialog.js.map +1 -0
  193. package/out-tsc/src/layout/Mask.js.map +1 -0
  194. package/out-tsc/src/{dialog → layout}/Modax.js.map +1 -1
  195. package/out-tsc/src/layout/Resizer.js.map +1 -0
  196. package/out-tsc/src/layout/Tab.js.map +1 -0
  197. package/out-tsc/src/layout/TabPane.js.map +1 -0
  198. package/out-tsc/src/list/NotificationList.js +1 -1
  199. package/out-tsc/src/list/NotificationList.js.map +1 -1
  200. package/out-tsc/src/list/RunList.js +1 -1
  201. package/out-tsc/src/list/RunList.js.map +1 -1
  202. package/out-tsc/src/list/ShortcutList.js.map +1 -1
  203. package/out-tsc/src/list/TembaMenu.js +1 -1
  204. package/out-tsc/src/list/TembaMenu.js.map +1 -1
  205. package/out-tsc/src/list/TicketList.js +1 -1
  206. package/out-tsc/src/list/TicketList.js.map +1 -1
  207. package/out-tsc/src/{aliaseditor → live}/AliasEditor.js +1 -1
  208. package/out-tsc/src/live/AliasEditor.js.map +1 -0
  209. package/out-tsc/src/{contacts → live}/ContactBadges.js +1 -1
  210. package/out-tsc/src/live/ContactBadges.js.map +1 -0
  211. package/out-tsc/src/{contacts → live}/ContactChat.js +80 -78
  212. package/out-tsc/src/live/ContactChat.js.map +1 -0
  213. package/out-tsc/src/{contacts → live}/ContactDetails.js +1 -1
  214. package/out-tsc/src/live/ContactDetails.js.map +1 -0
  215. package/out-tsc/src/{contacts → live}/ContactFieldEditor.js +2 -2
  216. package/out-tsc/src/live/ContactFieldEditor.js.map +1 -0
  217. package/out-tsc/src/live/ContactFields.js.map +1 -0
  218. package/out-tsc/src/live/ContactNameFetch.js.map +1 -0
  219. package/out-tsc/src/{contacts → live}/ContactNotepad.js +1 -1
  220. package/out-tsc/src/{contacts → live}/ContactNotepad.js.map +1 -1
  221. package/out-tsc/src/{contacts → live}/ContactPending.js +1 -1
  222. package/out-tsc/src/live/ContactPending.js.map +1 -0
  223. package/out-tsc/src/live/ContactStoreElement.js.map +1 -0
  224. package/out-tsc/src/live/FieldManager.js.map +1 -0
  225. package/out-tsc/src/live/StartProgress.js.map +1 -0
  226. package/out-tsc/src/live/TembaChart.js.map +1 -0
  227. package/out-tsc/src/store/AppState.js +54 -24
  228. package/out-tsc/src/store/AppState.js.map +1 -1
  229. package/out-tsc/src/store/Store.js +1 -1
  230. package/out-tsc/src/store/Store.js.map +1 -1
  231. package/out-tsc/src/{utils/index.js → utils.js} +22 -1
  232. package/out-tsc/src/utils.js.map +1 -0
  233. package/out-tsc/src/webchat/WebChat.js +1 -1
  234. package/out-tsc/src/webchat/WebChat.js.map +1 -1
  235. package/out-tsc/temba-components.js +2 -2
  236. package/out-tsc/temba-components.js.map +1 -1
  237. package/out-tsc/temba-modules.js +63 -56
  238. package/out-tsc/temba-modules.js.map +1 -1
  239. package/out-tsc/temba-webchat.js +2 -2
  240. package/out-tsc/temba-webchat.js.map +1 -1
  241. package/out-tsc/test/ActionHelper.js +116 -0
  242. package/out-tsc/test/ActionHelper.js.map +1 -0
  243. package/out-tsc/test/actions/add_contact_groups.test.js +66 -0
  244. package/out-tsc/test/actions/add_contact_groups.test.js.map +1 -0
  245. package/out-tsc/test/actions/remove_contact_groups.test.js +226 -0
  246. package/out-tsc/test/actions/remove_contact_groups.test.js.map +1 -0
  247. package/out-tsc/test/actions/send_email.test.js +160 -0
  248. package/out-tsc/test/actions/send_email.test.js.map +1 -0
  249. package/out-tsc/test/actions/send_msg.test.js +95 -0
  250. package/out-tsc/test/actions/send_msg.test.js.map +1 -0
  251. package/out-tsc/test/temba-action-editing-integration.test.js +183 -0
  252. package/out-tsc/test/temba-action-editing-integration.test.js.map +1 -0
  253. package/out-tsc/test/temba-alert.test.js +1 -1
  254. package/out-tsc/test/temba-alert.test.js.map +1 -1
  255. package/out-tsc/test/temba-appstate-language.test.js +90 -0
  256. package/out-tsc/test/temba-appstate-language.test.js.map +1 -1
  257. package/out-tsc/test/temba-charcount.test.js.map +1 -1
  258. package/out-tsc/test/temba-chart.test.js +1 -1
  259. package/out-tsc/test/temba-chart.test.js.map +1 -1
  260. package/out-tsc/test/temba-checkbox.test.js +1 -1
  261. package/out-tsc/test/temba-checkbox.test.js.map +1 -1
  262. package/out-tsc/test/temba-color-picker.test.js +1 -1
  263. package/out-tsc/test/temba-color-picker.test.js.map +1 -1
  264. package/out-tsc/test/temba-completion.test.js +1 -1
  265. package/out-tsc/test/temba-completion.test.js.map +1 -1
  266. package/out-tsc/test/temba-compose.test.js +1 -1
  267. package/out-tsc/test/temba-compose.test.js.map +1 -1
  268. package/out-tsc/test/temba-contact-badges.test.js +1 -1
  269. package/out-tsc/test/temba-contact-badges.test.js.map +1 -1
  270. package/out-tsc/test/temba-contact-chat.test.js +3 -1
  271. package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
  272. package/out-tsc/test/temba-contact-details.test.js +1 -1
  273. package/out-tsc/test/temba-contact-details.test.js.map +1 -1
  274. package/out-tsc/test/temba-contact-fields.test.js +1 -1
  275. package/out-tsc/test/temba-contact-fields.test.js.map +1 -1
  276. package/out-tsc/test/temba-contact-search.test.js +1 -1
  277. package/out-tsc/test/temba-contact-search.test.js.map +1 -1
  278. package/out-tsc/test/temba-date.test.js +5 -1
  279. package/out-tsc/test/temba-date.test.js.map +1 -1
  280. package/out-tsc/test/temba-datepicker.test.js +1 -1
  281. package/out-tsc/test/temba-datepicker.test.js.map +1 -1
  282. package/out-tsc/test/temba-dialog.test.js +1 -1
  283. package/out-tsc/test/temba-dialog.test.js.map +1 -1
  284. package/out-tsc/test/temba-dropdown.test.js +1 -1
  285. package/out-tsc/test/temba-dropdown.test.js.map +1 -1
  286. package/out-tsc/test/temba-excellent-helpers.test.js +316 -0
  287. package/out-tsc/test/temba-excellent-helpers.test.js.map +1 -0
  288. package/out-tsc/test/temba-field-config.test.js +133 -0
  289. package/out-tsc/test/temba-field-config.test.js.map +1 -0
  290. package/out-tsc/test/temba-field-manager.test.js.map +1 -1
  291. package/out-tsc/test/temba-flow-editor-node.test.js +426 -13
  292. package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
  293. package/out-tsc/test/temba-flow-editor.test.js +185 -0
  294. package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
  295. package/out-tsc/test/temba-flow-plumber-connections.test.js +113 -0
  296. package/out-tsc/test/temba-flow-plumber-connections.test.js.map +1 -0
  297. package/out-tsc/test/temba-flow-plumber.test.js +73 -93
  298. package/out-tsc/test/temba-flow-plumber.test.js.map +1 -1
  299. package/out-tsc/test/temba-flow-self-routing.test.js +172 -0
  300. package/out-tsc/test/temba-flow-self-routing.test.js.map +1 -0
  301. package/out-tsc/test/temba-formfield.test.js.map +1 -1
  302. package/out-tsc/test/temba-icon.test.js +1 -1
  303. package/out-tsc/test/temba-icon.test.js.map +1 -1
  304. package/out-tsc/test/temba-integration-markdown.test.js.map +1 -1
  305. package/out-tsc/test/temba-label.test.js +1 -1
  306. package/out-tsc/test/temba-label.test.js.map +1 -1
  307. package/out-tsc/test/temba-lightbox.test.js +1 -1
  308. package/out-tsc/test/temba-lightbox.test.js.map +1 -1
  309. package/out-tsc/test/temba-markdown.test.js +127 -0
  310. package/out-tsc/test/temba-markdown.test.js.map +1 -0
  311. package/out-tsc/test/temba-menu.test.js +1 -1
  312. package/out-tsc/test/temba-menu.test.js.map +1 -1
  313. package/out-tsc/test/temba-modax.test.js +1 -1
  314. package/out-tsc/test/temba-modax.test.js.map +1 -1
  315. package/out-tsc/test/temba-modules.test.js +47 -0
  316. package/out-tsc/test/temba-modules.test.js.map +1 -0
  317. package/out-tsc/test/temba-node-editor.test.js +283 -0
  318. package/out-tsc/test/temba-node-editor.test.js.map +1 -0
  319. package/out-tsc/test/temba-omnibox.test.js +1 -1
  320. package/out-tsc/test/temba-omnibox.test.js.map +1 -1
  321. package/out-tsc/test/temba-options.test.js.map +1 -1
  322. package/out-tsc/test/temba-range-picker.test.js +9 -2
  323. package/out-tsc/test/temba-range-picker.test.js.map +1 -1
  324. package/out-tsc/test/temba-rapid-element.test.js +273 -0
  325. package/out-tsc/test/temba-rapid-element.test.js.map +1 -0
  326. package/out-tsc/test/temba-resize-element.test.js +85 -0
  327. package/out-tsc/test/temba-resize-element.test.js.map +1 -0
  328. package/out-tsc/test/temba-select.test.js +87 -2
  329. package/out-tsc/test/temba-select.test.js.map +1 -1
  330. package/out-tsc/test/temba-slider.test.js.map +1 -1
  331. package/out-tsc/test/temba-sticky-note.test.js +194 -0
  332. package/out-tsc/test/temba-sticky-note.test.js.map +1 -0
  333. package/out-tsc/test/temba-template-editor.test.js.map +1 -1
  334. package/out-tsc/test/temba-textinput.test.js +1 -1
  335. package/out-tsc/test/temba-textinput.test.js.map +1 -1
  336. package/out-tsc/test/temba-tip.test.js +1 -1
  337. package/out-tsc/test/temba-tip.test.js.map +1 -1
  338. package/out-tsc/test/temba-toast.test.js +1 -1
  339. package/out-tsc/test/temba-toast.test.js.map +1 -1
  340. package/out-tsc/test/temba-utils-index.test.js +1 -1
  341. package/out-tsc/test/temba-utils-index.test.js.map +1 -1
  342. package/out-tsc/test/temba-utils-uuid.test.js +38 -0
  343. package/out-tsc/test/temba-utils-uuid.test.js.map +1 -0
  344. package/out-tsc/test/temba-webchat.test.js +28 -12
  345. package/out-tsc/test/temba-webchat.test.js.map +1 -1
  346. package/out-tsc/test/utils.test.js +2 -6
  347. package/out-tsc/test/utils.test.js.map +1 -1
  348. package/package.json +18 -9
  349. package/rollup.components.mjs +1 -1
  350. package/screenshots/truth/actions/add_contact_groups/editor/descriptive-group-names.png +0 -0
  351. package/screenshots/truth/actions/add_contact_groups/editor/long-group-names.png +0 -0
  352. package/screenshots/truth/actions/add_contact_groups/editor/many-groups.png +0 -0
  353. package/screenshots/truth/actions/add_contact_groups/editor/multiple-groups.png +0 -0
  354. package/screenshots/truth/actions/add_contact_groups/editor/single-group.png +0 -0
  355. package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
  356. package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
  357. package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
  358. package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
  359. package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
  360. package/screenshots/truth/actions/remove_contact_groups/editor/cleanup-groups.png +0 -0
  361. package/screenshots/truth/actions/remove_contact_groups/editor/long-descriptive-group-names.png +0 -0
  362. package/screenshots/truth/actions/remove_contact_groups/editor/many-groups.png +0 -0
  363. package/screenshots/truth/actions/remove_contact_groups/editor/multiple-groups.png +0 -0
  364. package/screenshots/truth/actions/remove_contact_groups/editor/remove-from-all-groups.png +0 -0
  365. package/screenshots/truth/actions/remove_contact_groups/editor/single-group.png +0 -0
  366. package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
  367. package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
  368. package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
  369. package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
  370. package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
  371. package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
  372. package/screenshots/truth/actions/send_email/editor/complex-business-email.png +0 -0
  373. package/screenshots/truth/actions/send_email/editor/empty-body.png +0 -0
  374. package/screenshots/truth/actions/send_email/editor/empty-subject.png +0 -0
  375. package/screenshots/truth/actions/send_email/editor/long-subject.png +0 -0
  376. package/screenshots/truth/actions/send_email/editor/multiline-body.png +0 -0
  377. package/screenshots/truth/actions/send_email/editor/multiple-recipients.png +0 -0
  378. package/screenshots/truth/actions/send_email/editor/simple-email.png +0 -0
  379. package/screenshots/truth/actions/send_email/editor/with-expressions.png +0 -0
  380. package/screenshots/truth/actions/send_email/render/complex-business-email.png +0 -0
  381. package/screenshots/truth/actions/send_email/render/empty-body.png +0 -0
  382. package/screenshots/truth/actions/send_email/render/empty-subject.png +0 -0
  383. package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
  384. package/screenshots/truth/actions/send_email/render/multiline-body.png +0 -0
  385. package/screenshots/truth/actions/send_email/render/multiple-recipients.png +0 -0
  386. package/screenshots/truth/actions/send_email/render/simple-email.png +0 -0
  387. package/screenshots/truth/actions/send_email/render/with-expressions.png +0 -0
  388. package/screenshots/truth/actions/send_msg/editor/long-quick-replies.png +0 -0
  389. package/screenshots/truth/actions/send_msg/editor/multiline-text-with-replies.png +0 -0
  390. package/screenshots/truth/actions/send_msg/editor/simple-text.png +0 -0
  391. package/screenshots/truth/actions/send_msg/editor/text-with-linebreaks.png +0 -0
  392. package/screenshots/truth/actions/send_msg/editor/text-with-many-quick-replies.png +0 -0
  393. package/screenshots/truth/actions/send_msg/editor/text-with-quick-replies.png +0 -0
  394. package/screenshots/truth/actions/send_msg/editor/text-without-quick-replies.png +0 -0
  395. package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
  396. package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
  397. package/screenshots/truth/actions/send_msg/render/simple-text.png +0 -0
  398. package/screenshots/truth/actions/send_msg/render/text-with-linebreaks.png +0 -0
  399. package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
  400. package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
  401. package/screenshots/truth/actions/send_msg/render/text-without-quick-replies.png +0 -0
  402. package/screenshots/truth/datepicker/range-picker-all.png +0 -0
  403. package/screenshots/truth/datepicker/range-picker-button-states.png +0 -0
  404. package/screenshots/truth/datepicker/range-picker-default.png +0 -0
  405. package/screenshots/truth/datepicker/range-picker-editing-start.png +0 -0
  406. package/screenshots/truth/datepicker/range-picker-initial-values.png +0 -0
  407. package/screenshots/truth/datepicker/range-picker-week.png +0 -0
  408. package/screenshots/truth/datepicker/range-picker-year.png +0 -0
  409. package/screenshots/truth/editor/router.png +0 -0
  410. package/screenshots/truth/editor/send_msg.png +0 -0
  411. package/screenshots/truth/editor/set_contact_language.png +0 -0
  412. package/screenshots/truth/editor/set_contact_name.png +0 -0
  413. package/screenshots/truth/editor/set_run_result.png +0 -0
  414. package/screenshots/truth/editor/wait.png +0 -0
  415. package/screenshots/truth/formfield/markdown-errors.png +0 -0
  416. package/screenshots/truth/formfield/plain-text-errors.png +0 -0
  417. package/screenshots/truth/formfield/widget-only-markdown-errors.png +0 -0
  418. package/screenshots/truth/integration/checkbox-markdown-errors.png +0 -0
  419. package/screenshots/truth/sticky-note/blue-color.png +0 -0
  420. package/screenshots/truth/sticky-note/blue.png +0 -0
  421. package/screenshots/truth/sticky-note/color-picker-expanded.png +0 -0
  422. package/screenshots/truth/sticky-note/default.png +0 -0
  423. package/screenshots/truth/sticky-note/gray-color.png +0 -0
  424. package/screenshots/truth/sticky-note/gray.png +0 -0
  425. package/screenshots/truth/sticky-note/green-color.png +0 -0
  426. package/screenshots/truth/sticky-note/green.png +0 -0
  427. package/screenshots/truth/sticky-note/pink-color.png +0 -0
  428. package/screenshots/truth/sticky-note/pink.png +0 -0
  429. package/screenshots/truth/sticky-note/yellow-color.png +0 -0
  430. package/screenshots/truth/sticky-note/yellow.png +0 -0
  431. package/src/{charcount → display}/CharCount.ts +164 -2
  432. package/src/{vectoricon/VectorIcon.ts → display/Icon.ts} +1 -1
  433. package/src/{leafletmap → display}/LeafletMap.ts +19 -1
  434. package/src/{thumbnail → display}/Thumbnail.ts +1 -1
  435. package/src/{tip → display}/Tip.ts +1 -2
  436. package/src/events.ts +108 -0
  437. package/src/flow/CanvasNode.ts +1009 -0
  438. package/src/flow/Editor.ts +795 -169
  439. package/src/flow/NodeEditor.ts +1443 -0
  440. package/src/flow/Plumber.ts +177 -79
  441. package/src/flow/StickyNote.ts +165 -9
  442. package/src/flow/actions/add_contact_groups.ts +42 -0
  443. package/src/flow/actions/add_contact_urn.ts +17 -0
  444. package/src/flow/actions/add_input_labels.ts +12 -0
  445. package/src/flow/actions/call_classifier.ts +12 -0
  446. package/src/flow/actions/call_llm.ts +12 -0
  447. package/src/flow/actions/call_resthook.ts +12 -0
  448. package/src/flow/actions/call_webhook.ts +133 -0
  449. package/src/flow/actions/enter_flow.ts +15 -0
  450. package/src/flow/actions/open_ticket.ts +12 -0
  451. package/src/flow/actions/play_audio.ts +12 -0
  452. package/src/flow/actions/remove_contact_groups.ts +66 -0
  453. package/src/flow/actions/request_optin.ts +12 -0
  454. package/src/flow/actions/say_msg.ts +12 -0
  455. package/src/flow/actions/send_broadcast.ts +35 -0
  456. package/src/flow/actions/send_email.ts +60 -0
  457. package/src/flow/actions/send_msg.ts +58 -0
  458. package/src/flow/actions/set_contact_channel.ts +13 -0
  459. package/src/flow/actions/set_contact_field.ts +13 -0
  460. package/src/flow/actions/set_contact_language.ts +11 -0
  461. package/src/flow/actions/set_contact_name.ts +11 -0
  462. package/src/flow/actions/set_contact_status.ts +11 -0
  463. package/src/flow/actions/set_run_result.ts +11 -0
  464. package/src/flow/actions/split_by_expression_example.ts +88 -0
  465. package/src/flow/actions/start_session.ts +12 -0
  466. package/src/flow/actions/transfer_airtime.ts +12 -0
  467. package/src/flow/config.ts +93 -136
  468. package/src/flow/nodes/execute_actions.ts +5 -0
  469. package/src/flow/nodes/split_by_airtime.ts +9 -0
  470. package/src/flow/nodes/split_by_contact_field.ts +7 -0
  471. package/src/flow/nodes/split_by_expression.ts +7 -0
  472. package/src/flow/nodes/split_by_groups.ts +7 -0
  473. package/src/flow/nodes/split_by_random.ts +10 -0
  474. package/src/flow/nodes/split_by_run_result.ts +7 -0
  475. package/src/flow/nodes/split_by_scheme.ts +7 -0
  476. package/src/flow/nodes/split_by_subflow.ts +9 -0
  477. package/src/flow/nodes/split_by_webhook.ts +19 -0
  478. package/src/flow/nodes/wait_for_audio.ts +7 -0
  479. package/src/flow/nodes/wait_for_digits.ts +7 -0
  480. package/src/flow/nodes/wait_for_image.ts +7 -0
  481. package/src/flow/nodes/wait_for_location.ts +7 -0
  482. package/src/flow/nodes/wait_for_menu.ts +7 -0
  483. package/src/flow/nodes/wait_for_response.ts +7 -0
  484. package/src/flow/nodes/wait_for_video.ts +7 -0
  485. package/src/flow/types.ts +352 -0
  486. package/src/flow/utils.ts +76 -0
  487. package/src/form/ArrayEditor.ts +240 -0
  488. package/src/form/BaseListEditor.ts +177 -0
  489. package/src/{checkbox → form}/Checkbox.ts +24 -5
  490. package/src/{colorpicker → form}/ColorPicker.ts +2 -2
  491. package/src/{completion → form}/Completion.ts +9 -3
  492. package/src/{compose → form}/Compose.ts +7 -7
  493. package/src/{contactsearch → form}/ContactSearch.ts +6 -6
  494. package/src/{datepicker → form}/DatePicker.ts +1 -1
  495. package/src/{FormElement.ts → form/FormElement.ts} +1 -1
  496. package/src/form/FormField.ts +238 -0
  497. package/src/{imagepicker → form}/ImagePicker.ts +2 -2
  498. package/src/form/KeyValueEditor.ts +251 -0
  499. package/src/{mediapicker → form}/MediaPicker.ts +1 -1
  500. package/src/{slider → form}/TembaSlider.ts +1 -1
  501. package/src/{templates → form}/TemplateEditor.ts +2 -2
  502. package/src/{textinput → form}/TextInput.ts +5 -5
  503. package/src/{omnibox → form/select}/Omnibox.ts +2 -2
  504. package/src/{select → form/select}/PopupSelect.ts +1 -1
  505. package/src/{select → form/select}/Select.ts +207 -152
  506. package/src/{select → form/select}/UserSelect.ts +1 -1
  507. package/src/{select → form/select}/WorkspaceSelect.ts +1 -1
  508. package/src/interfaces.ts +8 -2
  509. package/src/{dialog → layout}/Dialog.ts +1 -1
  510. package/src/list/NotificationList.ts +2 -2
  511. package/src/list/RunList.ts +3 -3
  512. package/src/list/ShortcutList.ts +1 -1
  513. package/src/list/TembaMenu.ts +2 -2
  514. package/src/list/TicketList.ts +1 -1
  515. package/src/{aliaseditor → live}/AliasEditor.ts +3 -3
  516. package/src/{contacts → live}/ContactBadges.ts +1 -1
  517. package/src/{contacts → live}/ContactChat.ts +120 -104
  518. package/src/{contacts → live}/ContactDetails.ts +1 -1
  519. package/src/{contacts → live}/ContactFieldEditor.ts +4 -4
  520. package/src/{contacts → live}/ContactFields.ts +1 -1
  521. package/src/{contacts → live}/ContactNotepad.ts +1 -1
  522. package/src/{contacts → live}/ContactPending.ts +1 -1
  523. package/src/{chart → live}/TembaChart.ts +1 -1
  524. package/src/store/AppState.ts +75 -29
  525. package/src/store/Store.ts +1 -1
  526. package/src/store/flow-definition.d.ts +131 -1
  527. package/src/{utils/index.ts → utils.ts} +26 -10
  528. package/src/webchat/WebChat.ts +1 -1
  529. package/static/api/contacts.json +30 -0
  530. package/static/api/groups.json +4 -426
  531. package/static/api/locations.json +24 -0
  532. package/static/api/media.json +5 -0
  533. package/static/api/optins.json +16 -0
  534. package/static/api/orgs.json +13 -0
  535. package/static/api/topics.json +21 -0
  536. package/static/api/users.json +26 -0
  537. package/static/css/temba-components.css +4 -6
  538. package/svg.js +1 -4
  539. package/temba-components.ts +2 -2
  540. package/temba-modules.ts +63 -56
  541. package/temba-webchat.ts +2 -2
  542. package/test/ActionHelper.ts +142 -0
  543. package/test/actions/add_contact_groups.test.ts +89 -0
  544. package/test/actions/remove_contact_groups.test.ts +265 -0
  545. package/test/actions/send_email.test.ts +214 -0
  546. package/test/actions/send_msg.test.ts +130 -0
  547. package/test/temba-action-editing-integration.test.ts +240 -0
  548. package/test/temba-alert.test.ts +1 -1
  549. package/test/temba-appstate-language.test.ts +108 -0
  550. package/test/temba-charcount.test.ts +1 -1
  551. package/test/temba-chart.test.ts +1 -1
  552. package/test/temba-checkbox.test.ts +2 -2
  553. package/test/temba-color-picker.test.ts +1 -1
  554. package/test/temba-completion.test.ts +1 -1
  555. package/test/temba-compose.test.ts +1 -1
  556. package/test/temba-contact-badges.test.ts +1 -1
  557. package/test/temba-contact-chat.test.ts +6 -4
  558. package/test/temba-contact-details.test.ts +1 -1
  559. package/test/temba-contact-fields.test.ts +1 -1
  560. package/test/temba-contact-search.test.ts +2 -2
  561. package/test/temba-date.test.ts +8 -3
  562. package/test/temba-datepicker.test.ts +1 -1
  563. package/test/temba-dialog.test.ts +1 -1
  564. package/test/temba-dropdown.test.ts +1 -1
  565. package/test/temba-excellent-helpers.test.ts +417 -0
  566. package/test/temba-field-config.test.ts +152 -0
  567. package/test/temba-field-manager.test.ts +2 -2
  568. package/test/temba-flow-editor-node.test.ts +551 -16
  569. package/test/temba-flow-editor.test.ts +224 -0
  570. package/test/temba-flow-editor.test.ts.backup +563 -0
  571. package/test/temba-flow-plumber-connections.test.ts +142 -0
  572. package/test/temba-flow-plumber.test.ts +83 -120
  573. package/test/temba-flow-self-routing.test.ts +215 -0
  574. package/test/temba-formfield.test.ts +1 -1
  575. package/test/temba-icon.test.ts +1 -1
  576. package/test/temba-integration-markdown.test.ts +1 -1
  577. package/test/temba-label.test.ts +1 -1
  578. package/test/temba-lightbox.test.ts +1 -1
  579. package/test/temba-markdown.test.ts +162 -0
  580. package/test/temba-menu.test.ts +1 -1
  581. package/test/temba-modax.test.ts +2 -2
  582. package/test/temba-modules.test.ts +56 -0
  583. package/test/temba-node-editor.test.ts +353 -0
  584. package/test/temba-omnibox.test.ts +1 -1
  585. package/test/temba-options.test.ts +1 -1
  586. package/test/temba-range-picker.test.ts +17 -2
  587. package/test/temba-rapid-element.test.ts +341 -0
  588. package/test/temba-resize-element.test.ts +104 -0
  589. package/test/temba-select.test.ts +129 -2
  590. package/test/temba-slider.test.ts +1 -1
  591. package/test/temba-sticky-note.test.ts +281 -0
  592. package/test/temba-template-editor.test.ts +1 -1
  593. package/test/temba-textinput.test.ts +1 -1
  594. package/test/temba-tip.test.ts +1 -1
  595. package/test/temba-toast.test.ts +1 -1
  596. package/test/temba-utils-index.test.ts +1 -1
  597. package/test/temba-utils-index.test.ts.backup +1737 -0
  598. package/test/temba-utils-uuid.test.ts +48 -0
  599. package/test/temba-webchat.test.ts +30 -12
  600. package/test/utils.test.ts +5 -9
  601. package/test-assets/contacts/history.json +11 -33
  602. package/web-dev-server.config.mjs +35 -1
  603. package/demo/sticky-note-demo.html +0 -155
  604. package/out-tsc/src/FormElement.js.map +0 -1
  605. package/out-tsc/src/alert/Alert.js.map +0 -1
  606. package/out-tsc/src/aliaseditor/AliasEditor.js.map +0 -1
  607. package/out-tsc/src/anchor/Anchor.js.map +0 -1
  608. package/out-tsc/src/button/Button.js.map +0 -1
  609. package/out-tsc/src/charcount/CharCount.js.map +0 -1
  610. package/out-tsc/src/charcount/helpers.js +0 -159
  611. package/out-tsc/src/charcount/helpers.js.map +0 -1
  612. package/out-tsc/src/chart/TembaChart.js.map +0 -1
  613. package/out-tsc/src/chat/Chat.js.map +0 -1
  614. package/out-tsc/src/checkbox/Checkbox.js.map +0 -1
  615. package/out-tsc/src/colorpicker/ColorPicker.js.map +0 -1
  616. package/out-tsc/src/completion/Completion.js.map +0 -1
  617. package/out-tsc/src/completion/ExcellentParser.js.map +0 -1
  618. package/out-tsc/src/completion/helpers.js.map +0 -1
  619. package/out-tsc/src/compose/Compose.js.map +0 -1
  620. package/out-tsc/src/contacts/ContactBadges.js.map +0 -1
  621. package/out-tsc/src/contacts/ContactChat.js.map +0 -1
  622. package/out-tsc/src/contacts/ContactDetails.js.map +0 -1
  623. package/out-tsc/src/contacts/ContactFieldEditor.js.map +0 -1
  624. package/out-tsc/src/contacts/ContactFields.js.map +0 -1
  625. package/out-tsc/src/contacts/ContactName.js.map +0 -1
  626. package/out-tsc/src/contacts/ContactNameFetch.js.map +0 -1
  627. package/out-tsc/src/contacts/ContactPending.js.map +0 -1
  628. package/out-tsc/src/contacts/ContactStoreElement.js.map +0 -1
  629. package/out-tsc/src/contacts/ContactUrn.js.map +0 -1
  630. package/out-tsc/src/contacts/events.js +0 -65
  631. package/out-tsc/src/contacts/events.js.map +0 -1
  632. package/out-tsc/src/contacts/helpers.js +0 -77
  633. package/out-tsc/src/contacts/helpers.js.map +0 -1
  634. package/out-tsc/src/contactsearch/ContactSearch.js.map +0 -1
  635. package/out-tsc/src/date/TembaDate.js.map +0 -1
  636. package/out-tsc/src/datepicker/DatePicker.js.map +0 -1
  637. package/out-tsc/src/datepicker/RangePicker.js.map +0 -1
  638. package/out-tsc/src/dialog/Dialog.js.map +0 -1
  639. package/out-tsc/src/dropdown/Dropdown.js.map +0 -1
  640. package/out-tsc/src/fields/FieldManager.js.map +0 -1
  641. package/out-tsc/src/flow/EditorNode.js +0 -291
  642. package/out-tsc/src/flow/EditorNode.js.map +0 -1
  643. package/out-tsc/src/flow/render.js +0 -41
  644. package/out-tsc/src/flow/render.js.map +0 -1
  645. package/out-tsc/src/formfield/FormField.js +0 -144
  646. package/out-tsc/src/formfield/FormField.js.map +0 -1
  647. package/out-tsc/src/imagepicker/CroppieCSS.js.map +0 -1
  648. package/out-tsc/src/imagepicker/ImagePicker.js.map +0 -1
  649. package/out-tsc/src/label/Label.js.map +0 -1
  650. package/out-tsc/src/leafletmap/LeafletMap.js.map +0 -1
  651. package/out-tsc/src/leafletmap/helpers.js +0 -17
  652. package/out-tsc/src/leafletmap/helpers.js.map +0 -1
  653. package/out-tsc/src/lightbox/Lightbox.js.map +0 -1
  654. package/out-tsc/src/mask/Mask.js.map +0 -1
  655. package/out-tsc/src/mediapicker/MediaPicker.js.map +0 -1
  656. package/out-tsc/src/omnibox/Omnibox.js.map +0 -1
  657. package/out-tsc/src/options/helpers.js +0 -28
  658. package/out-tsc/src/options/helpers.js.map +0 -1
  659. package/out-tsc/src/progress/ProgressBar.js.map +0 -1
  660. package/out-tsc/src/progress/StartProgress.js.map +0 -1
  661. package/out-tsc/src/resizer/Resizer.js.map +0 -1
  662. package/out-tsc/src/select/PopupSelect.js.map +0 -1
  663. package/out-tsc/src/select/Select.js.map +0 -1
  664. package/out-tsc/src/select/UserSelect.js.map +0 -1
  665. package/out-tsc/src/select/WorkspaceSelect.js.map +0 -1
  666. package/out-tsc/src/select/helpers.js +0 -1
  667. package/out-tsc/src/select/helpers.js.map +0 -1
  668. package/out-tsc/src/shadowless/Shadowless.js +0 -33
  669. package/out-tsc/src/shadowless/Shadowless.js.map +0 -1
  670. package/out-tsc/src/slider/TembaSlider.js.map +0 -1
  671. package/out-tsc/src/sms/gsmsplitter.js.map +0 -1
  672. package/out-tsc/src/sms/gsmvalidator.js.map +0 -1
  673. package/out-tsc/src/sms/index.js.map +0 -1
  674. package/out-tsc/src/sms/unicodesplitter.js.map +0 -1
  675. package/out-tsc/src/tabpane/Tab.js.map +0 -1
  676. package/out-tsc/src/tabpane/TabPane.js.map +0 -1
  677. package/out-tsc/src/templates/TemplateEditor.js.map +0 -1
  678. package/out-tsc/src/textinput/TextInput.js.map +0 -1
  679. package/out-tsc/src/textinput/helpers.js +0 -12
  680. package/out-tsc/src/textinput/helpers.js.map +0 -1
  681. package/out-tsc/src/thumbnail/Thumbnail.js.map +0 -1
  682. package/out-tsc/src/tip/Tip.js.map +0 -1
  683. package/out-tsc/src/tip/helpers.js +0 -7
  684. package/out-tsc/src/tip/helpers.js.map +0 -1
  685. package/out-tsc/src/toast/Toast.js.map +0 -1
  686. package/out-tsc/src/user/TembaUser.js.map +0 -1
  687. package/out-tsc/src/utils/index.js.map +0 -1
  688. package/out-tsc/src/vectoricon/VectorIcon.js.map +0 -1
  689. package/out-tsc/src/vectoricon/index.js.map +0 -1
  690. package/out-tsc/test/temba-flow-render.test.js +0 -171
  691. package/out-tsc/test/temba-flow-render.test.js.map +0 -1
  692. package/src/charcount/helpers.ts +0 -162
  693. package/src/contacts/events.ts +0 -210
  694. package/src/contacts/helpers.ts +0 -103
  695. package/src/flow/EditorNode.ts +0 -318
  696. package/src/flow/render.ts +0 -56
  697. package/src/formfield/FormField.ts +0 -134
  698. package/src/leafletmap/helpers.ts +0 -18
  699. package/src/options/helpers.ts +0 -37
  700. package/src/select/helpers.ts +0 -0
  701. package/src/shadowless/Shadowless.ts +0 -32
  702. package/src/textinput/helpers.ts +0 -11
  703. package/src/tip/helpers.ts +0 -7
  704. package/test/temba-flow-render.test.ts +0 -220
  705. /package/out-tsc/src/{alert → display}/Alert.js +0 -0
  706. /package/out-tsc/src/{anchor → display}/Anchor.js +0 -0
  707. /package/out-tsc/src/{button → display}/Button.js +0 -0
  708. /package/out-tsc/src/{chat → display}/Chat.js +0 -0
  709. /package/out-tsc/src/{contacts → display}/ContactName.js +0 -0
  710. /package/out-tsc/src/{contacts → display}/ContactUrn.js +0 -0
  711. /package/out-tsc/src/{dropdown → display}/Dropdown.js +0 -0
  712. /package/out-tsc/src/{label → display}/Label.js +0 -0
  713. /package/out-tsc/src/{lightbox → display}/Lightbox.js +0 -0
  714. /package/out-tsc/src/{loading → display}/Loading.js +0 -0
  715. /package/out-tsc/src/{options → display}/Options.js +0 -0
  716. /package/out-tsc/src/{progress → display}/ProgressBar.js +0 -0
  717. /package/out-tsc/src/{date → display}/TembaDate.js +0 -0
  718. /package/out-tsc/src/{user → display}/TembaUser.js +0 -0
  719. /package/out-tsc/src/{thumbnail → display}/Thumbnail.js +0 -0
  720. /package/out-tsc/src/{toast → display}/Toast.js +0 -0
  721. /package/out-tsc/src/{sms → display/sms}/gsmsplitter.js +0 -0
  722. /package/out-tsc/src/{sms → display/sms}/gsmvalidator.js +0 -0
  723. /package/out-tsc/src/{sms → display/sms}/index.js +0 -0
  724. /package/out-tsc/src/{sms → display/sms}/unicodesplitter.js +0 -0
  725. /package/out-tsc/src/{completion → excellent}/ExcellentParser.js +0 -0
  726. /package/out-tsc/src/{completion → excellent}/helpers.js +0 -0
  727. /package/out-tsc/src/{imagepicker → form}/CroppieCSS.js +0 -0
  728. /package/out-tsc/src/{datepicker → form}/RangePicker.js +0 -0
  729. /package/out-tsc/src/{dialog → layout}/Dialog.js +0 -0
  730. /package/out-tsc/src/{mask → layout}/Mask.js +0 -0
  731. /package/out-tsc/src/{dialog → layout}/Modax.js +0 -0
  732. /package/out-tsc/src/{resizer → layout}/Resizer.js +0 -0
  733. /package/out-tsc/src/{tabpane → layout}/Tab.js +0 -0
  734. /package/out-tsc/src/{tabpane → layout}/TabPane.js +0 -0
  735. /package/out-tsc/src/{contacts → live}/ContactFields.js +0 -0
  736. /package/out-tsc/src/{contacts → live}/ContactNameFetch.js +0 -0
  737. /package/out-tsc/src/{contacts → live}/ContactStoreElement.js +0 -0
  738. /package/out-tsc/src/{fields → live}/FieldManager.js +0 -0
  739. /package/out-tsc/src/{progress → live}/StartProgress.js +0 -0
  740. /package/out-tsc/src/{chart → live}/TembaChart.js +0 -0
  741. /package/src/{vectoricon/index.ts → Icons.ts} +0 -0
  742. /package/src/{alert → display}/Alert.ts +0 -0
  743. /package/src/{anchor → display}/Anchor.ts +0 -0
  744. /package/src/{button → display}/Button.ts +0 -0
  745. /package/src/{chat → display}/Chat.ts +0 -0
  746. /package/src/{contacts → display}/ContactName.ts +0 -0
  747. /package/src/{contacts → display}/ContactUrn.ts +0 -0
  748. /package/src/{dropdown → display}/Dropdown.ts +0 -0
  749. /package/src/{label → display}/Label.ts +0 -0
  750. /package/src/{lightbox → display}/Lightbox.ts +0 -0
  751. /package/src/{loading → display}/Loading.ts +0 -0
  752. /package/src/{options → display}/Options.ts +0 -0
  753. /package/src/{progress → display}/ProgressBar.ts +0 -0
  754. /package/src/{date → display}/TembaDate.ts +0 -0
  755. /package/src/{user → display}/TembaUser.ts +0 -0
  756. /package/src/{toast → display}/Toast.ts +0 -0
  757. /package/src/{sms → display/sms}/gsmsplitter.ts +0 -0
  758. /package/src/{sms → display/sms}/gsmvalidator.ts +0 -0
  759. /package/src/{sms → display/sms}/index.ts +0 -0
  760. /package/src/{sms → display/sms}/unicodesplitter.ts +0 -0
  761. /package/src/{completion → excellent}/ExcellentParser.ts +0 -0
  762. /package/src/{completion → excellent}/helpers.ts +0 -0
  763. /package/src/{imagepicker → form}/CroppieCSS.ts +0 -0
  764. /package/src/{datepicker → form}/RangePicker.ts +0 -0
  765. /package/src/{mask → layout}/Mask.ts +0 -0
  766. /package/src/{dialog → layout}/Modax.ts +0 -0
  767. /package/src/{resizer → layout}/Resizer.ts +0 -0
  768. /package/src/{tabpane → layout}/Tab.ts +0 -0
  769. /package/src/{tabpane → layout}/TabPane.ts +0 -0
  770. /package/src/{contacts → live}/ContactNameFetch.ts +0 -0
  771. /package/src/{contacts → live}/ContactStoreElement.ts +0 -0
  772. /package/src/{fields → live}/FieldManager.ts +0 -0
  773. /package/src/{progress → live}/StartProgress.ts +0 -0
@@ -5,18 +5,34 @@ import { property, state } from 'lit/decorators.js';
5
5
  import { getStore } from '../store/Store';
6
6
  import { fromStore, zustand } from '../store/AppState';
7
7
  import { RapidElement } from '../RapidElement';
8
+ import { repeat } from 'lit-html/directives/repeat.js';
9
+ import { CustomEventType } from '../interfaces';
8
10
  import { Plumber } from './Plumber';
9
- import { EditorNode } from './EditorNode';
11
+ import { CanvasNode } from './CanvasNode';
10
12
  export function snapToGrid(value) {
11
- return Math.round(value / 20) * 20;
13
+ const snapped = Math.round(value / 20) * 20;
14
+ return Math.max(snapped, 0);
15
+ }
16
+ export function findNodeForExit(definition, exitUuid) {
17
+ for (const node of definition.nodes) {
18
+ const exit = node.exits.find((e) => e.uuid === exitUuid);
19
+ if (exit) {
20
+ return node.uuid;
21
+ }
22
+ }
23
+ return null;
12
24
  }
13
25
  const SAVE_QUIET_TIME = 500;
14
- const DRAG_THRESHOLD = 10;
26
+ const DRAG_THRESHOLD = 5;
15
27
  export class Editor extends RapidElement {
16
28
  // unfortunately, jsplumb requires that we be in light DOM
17
29
  createRenderRoot() {
18
30
  return this;
19
31
  }
32
+ // Public getter for drag state
33
+ get dragging() {
34
+ return this.isDragging;
35
+ }
20
36
  static get styles() {
21
37
  return css `
22
38
  #editor {
@@ -27,41 +43,23 @@ export class Editor extends RapidElement {
27
43
  #grid {
28
44
  position: relative;
29
45
  background-color: #f9f9f9;
46
+ background-image: radial-gradient(
47
+ circle,
48
+ rgba(61, 177, 255, 0.3) 1px,
49
+ transparent 1px
50
+ );
51
+ background-size: 20px 20px;
30
52
  background-position: 10px 10px;
31
- background-image: linear-gradient(
32
- 0deg,
33
- transparent 24%,
34
- rgba(61, 177, 255, 0.15) 25%,
35
- rgba(61, 177, 255, 0.15) 26%,
36
- transparent 27%,
37
- transparent 74%,
38
- rgba(61, 177, 255, 0.15) 75%,
39
- rgba(61, 177, 255, 0.15) 76%,
40
- transparent 77%,
41
- transparent
42
- ),
43
- linear-gradient(
44
- 90deg,
45
- transparent 24%,
46
- rgba(61, 177, 255, 0.15) 25%,
47
- rgba(61, 177, 255, 0.15) 26%,
48
- transparent 27%,
49
- transparent 74%,
50
- rgba(61, 177, 255, 0.15) 75%,
51
- rgba(61, 177, 255, 0.15) 76%,
52
- transparent 77%,
53
- transparent
54
- );
55
- background-size: 40px 40px;
56
53
  box-shadow: inset -5px 0 10px rgba(0, 0, 0, 0.05);
57
54
  border-top: 1px solid #e0e0e0;
58
- display: inline-block;
59
55
  width: 100%;
56
+ display: flex;
60
57
  }
61
58
 
62
59
  #canvas {
63
60
  position: relative;
64
- padding: 20px;
61
+ padding: 0px;
62
+ flex-grow: 1;
65
63
  margin: 20px;
66
64
  }
67
65
 
@@ -71,7 +69,7 @@ export class Editor extends RapidElement {
71
69
  }
72
70
 
73
71
  #canvas > .dragging {
74
- z-index: 10000 !important;
72
+ z-index: 99999 !important;
75
73
  }
76
74
 
77
75
  body .jtk-endpoint {
@@ -81,70 +79,44 @@ export class Editor extends RapidElement {
81
79
 
82
80
  .jtk-endpoint {
83
81
  z-index: 600;
82
+ opacity: 0;
84
83
  }
85
84
 
86
85
  .plumb-source {
87
86
  z-index: 600;
88
- border: 0px solid var(--color-connectors);
87
+ cursor: pointer;
88
+ opacity: 0;
89
89
  }
90
90
 
91
91
  .plumb-source.connected {
92
- box-shadow: 0 3px 3px 0px rgba(0, 0, 0, 0.1);
93
92
  border-radius: 50%;
93
+ pointer-events: none;
94
94
  }
95
95
 
96
96
  .plumb-source circle {
97
- fill: tomato;
98
- }
99
-
100
- .plumb-source.connected circle {
101
- fill: #fff;
102
- }
103
-
104
- .plumb-source svg {
105
- fill: var(--color-connectors) !important;
106
- stroke: var(--color-connectors);
97
+ fill: purple;
107
98
  }
108
99
 
109
100
  .plumb-target {
110
- margin-top: -6px;
111
101
  z-index: 600;
112
102
  opacity: 0;
113
103
  cursor: pointer;
104
+ fill: transparent;
114
105
  }
115
106
 
116
- body .plumb-connector path {
107
+ body svg.jtk-connector.plumb-connector path {
117
108
  stroke: var(--color-connectors) !important;
118
109
  stroke-width: 3px;
119
- z-index: 10;
120
110
  }
121
111
 
122
112
  body .plumb-connector {
123
- z-index: 10;
124
- }
125
-
126
- body .plumb-connector.elevated {
127
- z-index: 550;
128
- }
129
-
130
- body .plumb-connector.elevated path {
131
- stroke: var(--color-connectors) !important;
132
- stroke-width: 3px;
133
- z-index: 550;
134
- }
135
-
136
- body .plumb-connector.elevated .plumb-arrow {
137
- fill: var(--color-connectors);
138
- stroke: var(--color-connectors);
139
- stroke-width: 0px;
140
- margin-top: 6px;
141
- z-index: 550;
113
+ z-index: 10 !important;
142
114
  }
143
115
 
144
116
  body .plumb-connector .plumb-arrow {
145
117
  fill: var(--color-connectors);
146
118
  stroke: var(--color-connectors);
147
- stroke-width: 0px;
119
+ stroke-width: 0px !important;
148
120
  margin-top: 6px;
149
121
  z-index: 10;
150
122
  }
@@ -159,6 +131,50 @@ export class Editor extends RapidElement {
159
131
  stroke-width: 0px;
160
132
  z-index: 10;
161
133
  }
134
+
135
+ /* Connection dragging feedback */
136
+ body svg.jtk-connector.jtk-dragging {
137
+ z-index: 99999 !important;
138
+ }
139
+
140
+ .katavorio-drag-no-select svg.jtk-connector path,
141
+ .katavorio-drag-no-select svg.jtk-endpoint path {
142
+ pointer-events: none !important;
143
+ border: 1px solid purple;
144
+ }
145
+
146
+ /* Connection target feedback */
147
+ temba-flow-node.connection-target-valid {
148
+ outline: 3px solid var(--color-success, #22c55e) !important;
149
+ outline-offset: 2px;
150
+ border-radius: var(--curvature);
151
+ }
152
+
153
+ temba-flow-node.connection-target-invalid {
154
+ outline: 3px solid var(--color-error, #ef4444) !important;
155
+ outline-offset: 2px;
156
+ border-radius: var(--curvature);
157
+ }
158
+
159
+ /* Selection box styles */
160
+ .selection-box {
161
+ position: absolute;
162
+ border: 2px dashed #6298f0ff;
163
+ background-color: rgba(59, 130, 246, 0.1);
164
+ z-index: 9999;
165
+ pointer-events: none;
166
+ }
167
+
168
+ /* Selected item styles */
169
+ .draggable.selected {
170
+ outline: 3px solid #6298f0ff;
171
+ outline-offset: 0px;
172
+ border-radius: var(--curvature);
173
+ }
174
+
175
+ .jtk-floating-endpoint {
176
+ pointer-events: none;
177
+ }
162
178
  `;
163
179
  }
164
180
  constructor() {
@@ -171,9 +187,25 @@ export class Editor extends RapidElement {
171
187
  this.dragStartPos = { x: 0, y: 0 };
172
188
  this.currentDragItem = null;
173
189
  this.startPos = { left: 0, top: 0 };
190
+ // Selection state
191
+ this.selectedItems = new Set();
192
+ this.isSelecting = false;
193
+ this.selectionBox = null;
194
+ this.targetId = null;
195
+ this.sourceId = null;
196
+ this.dragFromNodeId = null;
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;
202
+ this.canvasMouseDown = false;
174
203
  // Bound event handlers to maintain proper 'this' context
175
204
  this.boundMouseMove = this.handleMouseMove.bind(this);
176
205
  this.boundMouseUp = this.handleMouseUp.bind(this);
206
+ this.boundGlobalMouseDown = this.handleGlobalMouseDown.bind(this);
207
+ this.boundKeyDown = this.handleKeyDown.bind(this);
208
+ this.boundCanvasDoubleClick = this.handleCanvasDoubleClick.bind(this);
177
209
  }
178
210
  firstUpdated(changes) {
179
211
  super.firstUpdated(changes);
@@ -182,6 +214,37 @@ export class Editor extends RapidElement {
182
214
  if (changes.has('flow')) {
183
215
  getStore().getState().fetchRevision(`/flow/revisions/${this.flow}`);
184
216
  }
217
+ this.plumber.on('connection:drag', (info) => {
218
+ this.dragFromNodeId = document
219
+ .getElementById(info.sourceId)
220
+ .closest('.node').id;
221
+ this.sourceId = info.sourceId;
222
+ });
223
+ this.plumber.on('connection:abort', () => {
224
+ this.makeConnection();
225
+ });
226
+ this.plumber.on('connection:detach', () => {
227
+ this.makeConnection();
228
+ });
229
+ }
230
+ makeConnection() {
231
+ if (this.sourceId && this.targetId && this.isValidTarget) {
232
+ this.plumber.connectIds(this.dragFromNodeId, this.sourceId, this.targetId);
233
+ getStore()
234
+ .getState()
235
+ .updateConnection(this.dragFromNodeId, this.sourceId, this.targetId);
236
+ setTimeout(() => {
237
+ this.plumber.repaintEverything();
238
+ }, 100);
239
+ }
240
+ // Clean up visual feedback
241
+ document.querySelectorAll('temba-flow-node').forEach((node) => {
242
+ node.classList.remove('connection-target-valid', 'connection-target-invalid');
243
+ });
244
+ this.sourceId = null;
245
+ this.targetId = null;
246
+ this.dragFromNodeId = null;
247
+ this.isValidTarget = true;
185
248
  }
186
249
  updated(changes) {
187
250
  super.updated(changes);
@@ -227,10 +290,26 @@ export class Editor extends RapidElement {
227
290
  }
228
291
  document.removeEventListener('mousemove', this.boundMouseMove);
229
292
  document.removeEventListener('mouseup', this.boundMouseUp);
293
+ document.removeEventListener('mousedown', this.boundGlobalMouseDown);
294
+ document.removeEventListener('keydown', this.boundKeyDown);
295
+ const canvas = this.querySelector('#canvas');
296
+ if (canvas) {
297
+ canvas.removeEventListener('dblclick', this.boundCanvasDoubleClick);
298
+ }
230
299
  }
231
300
  setupGlobalEventListeners() {
232
301
  document.addEventListener('mousemove', this.boundMouseMove);
233
302
  document.addEventListener('mouseup', this.boundMouseUp);
303
+ document.addEventListener('mousedown', this.boundGlobalMouseDown);
304
+ document.addEventListener('keydown', this.boundKeyDown);
305
+ const canvas = this.querySelector('#canvas');
306
+ if (canvas) {
307
+ canvas.addEventListener('dblclick', this.boundCanvasDoubleClick);
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));
234
313
  }
235
314
  getPosition(uuid, type) {
236
315
  var _a, _b, _c;
@@ -241,24 +320,10 @@ export class Editor extends RapidElement {
241
320
  return (_c = (_b = this.definition._ui.stickies) === null || _b === void 0 ? void 0 : _b[uuid]) === null || _c === void 0 ? void 0 : _c.position;
242
321
  }
243
322
  }
244
- updatePosition(uuid, type, position) {
245
- var _a;
246
- if (type === 'node') {
247
- getStore().getState().updateNodePosition(uuid, position);
248
- }
249
- else {
250
- const currentSticky = (_a = this.definition._ui.stickies) === null || _a === void 0 ? void 0 : _a[uuid];
251
- if (currentSticky) {
252
- getStore()
253
- .getState()
254
- .updateStickyNote(uuid, {
255
- ...currentSticky,
256
- position
257
- });
258
- }
259
- }
260
- }
261
323
  handleMouseDown(event) {
324
+ // ignore right clicks
325
+ if (event.button !== 0)
326
+ return;
262
327
  const element = event.currentTarget;
263
328
  // Only start dragging if clicking on the element itself, not on exits or other interactive elements
264
329
  const target = event.target;
@@ -270,7 +335,17 @@ export class Editor extends RapidElement {
270
335
  const position = this.getPosition(uuid, type);
271
336
  if (!position)
272
337
  return;
273
- // Set up potential drag state, but don't start dragging yet
338
+ // If clicking on a non-selected item, clear selection unless Ctrl/Cmd is held
339
+ if (!this.selectedItems.has(uuid) && !event.ctrlKey && !event.metaKey) {
340
+ this.selectedItems.clear();
341
+ // Don't add single items to selection - single clicks just clear existing selection
342
+ }
343
+ else if (!this.selectedItems.has(uuid)) {
344
+ // Add this item to selection only if Ctrl/Cmd is held
345
+ this.selectedItems.add(uuid);
346
+ }
347
+ // Always set up drag state regardless of selection status
348
+ // This allows single nodes to be dragged without being selected
274
349
  this.isMouseDown = true;
275
350
  this.dragStartPos = { x: event.clientX, y: event.clientY };
276
351
  this.startPos = { left: position.left, top: position.top };
@@ -283,7 +358,230 @@ export class Editor extends RapidElement {
283
358
  event.preventDefault();
284
359
  event.stopPropagation();
285
360
  }
361
+ handleGlobalMouseDown(event) {
362
+ var _a;
363
+ // ignore right clicks
364
+ if (event.button !== 0)
365
+ return;
366
+ // Check if the click is within our canvas
367
+ const canvasRect = (_a = this.querySelector('#grid')) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
368
+ if (!canvasRect)
369
+ return;
370
+ const isWithinCanvas = event.clientX >= canvasRect.left &&
371
+ event.clientX <= canvasRect.right &&
372
+ event.clientY >= canvasRect.top &&
373
+ event.clientY <= canvasRect.bottom;
374
+ if (!isWithinCanvas)
375
+ return;
376
+ // Check if we clicked on a draggable item (node or sticky)
377
+ const target = event.target;
378
+ const clickedOnDraggable = target.closest('.draggable');
379
+ if (clickedOnDraggable) {
380
+ // This is handled by the individual item mousedown handlers
381
+ return;
382
+ }
383
+ // We clicked on empty canvas space, start selection
384
+ this.handleCanvasMouseDown(event);
385
+ }
386
+ handleCanvasMouseDown(event) {
387
+ var _a;
388
+ const target = event.target;
389
+ if (target.id === 'canvas' || target.id === 'grid') {
390
+ // Ignore clicks on exits
391
+ // Start selection box
392
+ this.canvasMouseDown = true;
393
+ this.dragStartPos = { x: event.clientX, y: event.clientY };
394
+ const canvasRect = (_a = this.querySelector('#canvas')) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
395
+ if (canvasRect) {
396
+ // Clear current selection
397
+ this.selectedItems.clear();
398
+ const relativeX = event.clientX - canvasRect.left;
399
+ const relativeY = event.clientY - canvasRect.top;
400
+ this.selectionBox = {
401
+ startX: relativeX,
402
+ startY: relativeY,
403
+ endX: relativeX,
404
+ endY: relativeY
405
+ };
406
+ }
407
+ event.preventDefault();
408
+ }
409
+ }
410
+ handleKeyDown(event) {
411
+ if (event.key === 'Delete' || event.key === 'Backspace') {
412
+ if (this.selectedItems.size > 0) {
413
+ this.showDeleteConfirmation();
414
+ }
415
+ }
416
+ if (event.key === 'Escape') {
417
+ this.selectedItems.clear();
418
+ this.requestUpdate();
419
+ }
420
+ }
421
+ showDeleteConfirmation() {
422
+ const itemCount = this.selectedItems.size;
423
+ const itemType = itemCount === 1 ? 'item' : 'items';
424
+ // Create and show confirmation dialog
425
+ const dialog = document.createElement('temba-dialog');
426
+ dialog.header = 'Delete Items';
427
+ dialog.primaryButtonName = 'Delete';
428
+ dialog.cancelButtonName = 'Cancel';
429
+ dialog.destructive = true;
430
+ dialog.innerHTML = `<div style="padding: 20px;">Are you sure you want to delete ${itemCount} ${itemType}?</div>`;
431
+ dialog.addEventListener('temba-button-clicked', (event) => {
432
+ if (event.detail.button.name === 'Delete') {
433
+ this.deleteSelectedItems();
434
+ dialog.open = false;
435
+ }
436
+ });
437
+ // Add to document and show
438
+ document.body.appendChild(dialog);
439
+ dialog.open = true;
440
+ // Clean up dialog when closed
441
+ dialog.addEventListener('temba-dialog-hidden', () => {
442
+ document.body.removeChild(dialog);
443
+ });
444
+ }
445
+ deleteNodes(uuids) {
446
+ // Clean up jsPlumb connections for nodes before removing them
447
+ uuids.forEach((uuid) => {
448
+ this.plumber.removeNodeConnections(uuid);
449
+ });
450
+ // Now remove them from the definition
451
+ if (uuids.length > 0 && this.plumber) {
452
+ getStore().getState().removeNodes(uuids);
453
+ }
454
+ }
455
+ deleteSelectedItems() {
456
+ const nodes = Array.from(this.selectedItems).filter((uuid) => this.definition.nodes.some((node) => node.uuid === uuid));
457
+ this.deleteNodes(Array.from(nodes));
458
+ const stickies = Array.from(this.selectedItems).filter((uuid) => { var _a, _b; return (_b = (_a = this.definition._ui) === null || _a === void 0 ? void 0 : _a.stickies) === null || _b === void 0 ? void 0 : _b[uuid]; });
459
+ getStore().getState().removeStickyNotes(stickies);
460
+ // Clear selection
461
+ this.selectedItems.clear();
462
+ }
463
+ updateSelectionBox(event) {
464
+ var _a;
465
+ if (!this.selectionBox || !this.canvasMouseDown)
466
+ return;
467
+ const canvasRect = (_a = this.querySelector('#canvas')) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
468
+ if (!canvasRect)
469
+ return;
470
+ const relativeX = event.clientX - canvasRect.left;
471
+ const relativeY = event.clientY - canvasRect.top;
472
+ this.selectionBox = {
473
+ ...this.selectionBox,
474
+ endX: relativeX,
475
+ endY: relativeY
476
+ };
477
+ // Update selected items based on selection box
478
+ this.updateSelectedItemsFromBox();
479
+ }
480
+ updateSelectedItemsFromBox() {
481
+ var _a, _b, _c;
482
+ if (!this.selectionBox)
483
+ return;
484
+ const newSelection = new Set();
485
+ const boxLeft = Math.min(this.selectionBox.startX, this.selectionBox.endX);
486
+ const boxTop = Math.min(this.selectionBox.startY, this.selectionBox.endY);
487
+ const boxRight = Math.max(this.selectionBox.startX, this.selectionBox.endX);
488
+ const boxBottom = Math.max(this.selectionBox.startY, this.selectionBox.endY);
489
+ // Check nodes
490
+ (_a = this.definition) === null || _a === void 0 ? void 0 : _a.nodes.forEach((node) => {
491
+ var _a, _b;
492
+ const nodeElement = this.querySelector(`[id="${node.uuid}"]`);
493
+ if (nodeElement) {
494
+ const position = (_a = this.definition._ui.nodes[node.uuid]) === null || _a === void 0 ? void 0 : _a.position;
495
+ if (position) {
496
+ const rect = nodeElement.getBoundingClientRect();
497
+ const canvasRect = (_b = this.querySelector('#canvas')) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect();
498
+ if (canvasRect) {
499
+ const nodeLeft = position.left;
500
+ const nodeTop = position.top;
501
+ const nodeRight = nodeLeft + rect.width;
502
+ const nodeBottom = nodeTop + rect.height;
503
+ // Check if selection box intersects with node
504
+ if (boxLeft < nodeRight &&
505
+ boxRight > nodeLeft &&
506
+ boxTop < nodeBottom &&
507
+ boxBottom > nodeTop) {
508
+ newSelection.add(node.uuid);
509
+ }
510
+ }
511
+ }
512
+ }
513
+ });
514
+ // Check sticky notes
515
+ const stickies = ((_c = (_b = this.definition) === null || _b === void 0 ? void 0 : _b._ui) === null || _c === void 0 ? void 0 : _c.stickies) || {};
516
+ Object.entries(stickies).forEach(([uuid, sticky]) => {
517
+ if (sticky.position) {
518
+ const stickyElement = this.querySelector(`temba-sticky-note[uuid="${uuid}"]`);
519
+ if (stickyElement) {
520
+ // Use clientWidth/clientHeight instead of getBoundingClientRect() to get element dimensions
521
+ // This avoids the coordinate system mismatch between viewport and canvas coordinates
522
+ const width = stickyElement.clientWidth;
523
+ const height = stickyElement.clientHeight;
524
+ // Use the canvas coordinates from the sticky's position
525
+ const stickyLeft = sticky.position.left;
526
+ const stickyTop = sticky.position.top;
527
+ const stickyRight = stickyLeft + width;
528
+ const stickyBottom = stickyTop + height;
529
+ // Check if selection box intersects with sticky
530
+ if (boxLeft < stickyRight &&
531
+ boxRight > stickyLeft &&
532
+ boxTop < stickyBottom &&
533
+ boxBottom > stickyTop) {
534
+ newSelection.add(uuid);
535
+ }
536
+ }
537
+ }
538
+ });
539
+ this.selectedItems = newSelection;
540
+ }
541
+ renderSelectionBox() {
542
+ if (!this.selectionBox || !this.isSelecting)
543
+ return '';
544
+ const left = Math.min(this.selectionBox.startX, this.selectionBox.endX);
545
+ const top = Math.min(this.selectionBox.startY, this.selectionBox.endY);
546
+ const width = Math.abs(this.selectionBox.endX - this.selectionBox.startX);
547
+ const height = Math.abs(this.selectionBox.endY - this.selectionBox.startY);
548
+ return html `<div
549
+ class="selection-box"
550
+ style="left: ${left}px; top: ${top}px; width: ${width}px; height: ${height}px;"
551
+ ></div>`;
552
+ }
286
553
  handleMouseMove(event) {
554
+ // Handle selection box drawing
555
+ if (this.canvasMouseDown && !this.isMouseDown) {
556
+ this.isSelecting = true;
557
+ this.updateSelectionBox(event);
558
+ this.requestUpdate(); // Force re-render
559
+ return;
560
+ }
561
+ if (this.plumber.connectionDragging) {
562
+ const targetNode = document.querySelector('temba-flow-node:hover');
563
+ // Clear previous target styles
564
+ document.querySelectorAll('temba-flow-node').forEach((node) => {
565
+ node.classList.remove('connection-target-valid', 'connection-target-invalid');
566
+ });
567
+ if (targetNode) {
568
+ this.targetId = targetNode.getAttribute('uuid');
569
+ // Check if target is different from source node (prevent self-targeting)
570
+ this.isValidTarget = this.targetId !== this.dragFromNodeId;
571
+ // Apply visual feedback based on validity
572
+ if (this.isValidTarget) {
573
+ targetNode.classList.add('connection-target-valid');
574
+ }
575
+ else {
576
+ targetNode.classList.add('connection-target-invalid');
577
+ }
578
+ }
579
+ else {
580
+ this.targetId = null;
581
+ this.isValidTarget = true;
582
+ }
583
+ }
584
+ // Handle item dragging
287
585
  if (!this.isMouseDown || !this.currentDragItem)
288
586
  return;
289
587
  const deltaX = event.clientX - this.dragStartPos.x;
@@ -292,60 +590,96 @@ export class Editor extends RapidElement {
292
590
  // Only start dragging if we've moved beyond the threshold
293
591
  if (!this.isDragging && distance > DRAG_THRESHOLD) {
294
592
  this.isDragging = true;
295
- // If this is a node, elevate connections
296
- if (this.currentDragItem.type === 'node' && this.plumber) {
297
- this.plumber.elevateNodeConnections(this.currentDragItem.uuid);
298
- }
299
593
  }
300
594
  // If we're actually dragging, update positions
301
595
  if (this.isDragging) {
302
- const newLeft = this.startPos.left + deltaX;
303
- const newTop = this.startPos.top + deltaY;
304
- // Update the visual position during drag
305
- this.currentDragItem.element.style.left = `${newLeft}px`;
306
- this.currentDragItem.element.style.top = `${newTop}px`;
307
- // Repaint connections if this is a node
308
- if (this.currentDragItem.type === 'node' && this.plumber) {
309
- this.plumber.repaintEverything();
310
- }
596
+ // Determine what items to move
597
+ const itemsToMove = this.selectedItems.has(this.currentDragItem.uuid) &&
598
+ this.selectedItems.size > 1
599
+ ? Array.from(this.selectedItems)
600
+ : [this.currentDragItem.uuid];
601
+ itemsToMove.forEach((uuid) => {
602
+ const element = this.querySelector(`[uuid="${uuid}"]`);
603
+ if (element) {
604
+ const type = element.tagName === 'TEMBA-FLOW-NODE' ? 'node' : 'sticky';
605
+ const position = this.getPosition(uuid, type);
606
+ if (position) {
607
+ const newLeft = position.left + deltaX;
608
+ const newTop = position.top + deltaY;
609
+ // Update the visual position during drag
610
+ element.style.left = `${newLeft}px`;
611
+ element.style.top = `${newTop}px`;
612
+ // Add dragging class to ensure highest z-index
613
+ element.classList.add('dragging');
614
+ }
615
+ }
616
+ });
617
+ this.plumber.revalidate(itemsToMove);
311
618
  }
312
619
  }
313
620
  handleMouseUp(event) {
621
+ // Handle selection box completion
622
+ if (this.canvasMouseDown && this.isSelecting) {
623
+ this.isSelecting = false;
624
+ this.selectionBox = null;
625
+ this.canvasMouseDown = false;
626
+ this.requestUpdate();
627
+ return;
628
+ }
629
+ // Handle canvas click (clear selection)
630
+ if (this.canvasMouseDown && !this.isSelecting) {
631
+ this.canvasMouseDown = false;
632
+ return;
633
+ }
634
+ // Handle item drag completion
314
635
  if (!this.isMouseDown || !this.currentDragItem)
315
636
  return;
316
637
  // If we were actually dragging, handle the drag end
317
638
  if (this.isDragging) {
318
- // Restore normal z-index for node connections
319
- if (this.currentDragItem.type === 'node' && this.plumber) {
320
- this.plumber.restoreNodeConnections(this.currentDragItem.uuid);
321
- }
322
639
  const deltaX = event.clientX - this.dragStartPos.x;
323
640
  const deltaY = event.clientY - this.dragStartPos.y;
324
- const newLeft = this.startPos.left + deltaX;
325
- const newTop = this.startPos.top + deltaY;
326
- // Snap to 20px grid for final position
327
- const snappedLeft = snapToGrid(newLeft);
328
- const snappedTop = snapToGrid(newTop);
329
- const newPosition = { left: snappedLeft, top: snappedTop };
330
- // Update the store with the new snapped position
331
- this.updatePosition(this.currentDragItem.uuid, this.currentDragItem.type, newPosition);
332
- // Update canvas positions for nodes
333
- if (this.currentDragItem.type === 'node') {
334
- getStore()
335
- .getState()
336
- .updateCanvasPositions({
337
- [this.currentDragItem.uuid]: newPosition
338
- });
339
- }
340
- // Repaint connections if this is a node
341
- if (this.currentDragItem.type === 'node' && this.plumber) {
342
- this.plumber.repaintEverything();
641
+ // Determine what items were moved
642
+ const itemsToMove = this.selectedItems.has(this.currentDragItem.uuid) &&
643
+ this.selectedItems.size > 1
644
+ ? Array.from(this.selectedItems)
645
+ : [this.currentDragItem.uuid];
646
+ // Update positions for all moved items
647
+ const newPositions = {};
648
+ itemsToMove.forEach((uuid) => {
649
+ const type = this.definition.nodes.find((node) => node.uuid === uuid)
650
+ ? 'node'
651
+ : 'sticky';
652
+ const position = this.getPosition(uuid, type);
653
+ if (position) {
654
+ const newLeft = position.left + deltaX;
655
+ const newTop = position.top + deltaY;
656
+ // Snap to 20px grid for final position
657
+ const snappedLeft = snapToGrid(newLeft);
658
+ const snappedTop = snapToGrid(newTop);
659
+ const newPosition = { left: snappedLeft, top: snappedTop };
660
+ newPositions[uuid] = newPosition;
661
+ // Remove dragging class
662
+ const element = this.querySelector(`[uuid="${uuid}"]`);
663
+ if (element) {
664
+ element.classList.remove('dragging');
665
+ element.style.left = `${snappedLeft}px`;
666
+ element.style.top = `${snappedTop}px`;
667
+ }
668
+ }
669
+ });
670
+ if (Object.keys(newPositions).length > 0) {
671
+ getStore().getState().updateCanvasPositions(newPositions);
672
+ setTimeout(() => {
673
+ this.plumber.repaintEverything();
674
+ }, 0);
343
675
  }
676
+ this.selectedItems.clear();
344
677
  }
345
678
  // Reset all drag state
346
679
  this.isDragging = false;
347
680
  this.isMouseDown = false;
348
681
  this.currentDragItem = null;
682
+ this.canvasMouseDown = false;
349
683
  }
350
684
  updateCanvasSize() {
351
685
  var _a;
@@ -371,21 +705,131 @@ export class Editor extends RapidElement {
371
705
  });
372
706
  // Check sticky note positions
373
707
  const stickies = ((_a = this.definition._ui) === null || _a === void 0 ? void 0 : _a.stickies) || {};
374
- Object.values(stickies).forEach((sticky) => {
708
+ Object.entries(stickies).forEach(([uuid, sticky]) => {
375
709
  if (sticky.position) {
376
- maxWidth = Math.max(maxWidth, sticky.position.left + 200); // Sticky note width
377
- maxHeight = Math.max(maxHeight, sticky.position.top + 100); // Sticky note height
710
+ const stickyElement = this.querySelector(`temba-sticky-note[uuid="${uuid}"]`);
711
+ if (stickyElement) {
712
+ // Use clientWidth/clientHeight instead of getBoundingClientRect() to get element dimensions
713
+ // This avoids the coordinate system mismatch between viewport and canvas coordinates
714
+ const width = stickyElement.clientWidth;
715
+ const height = stickyElement.clientHeight;
716
+ // Both sticky.position and width/height are now in the same coordinate system
717
+ maxWidth = Math.max(maxWidth, sticky.position.left + width);
718
+ maxHeight = Math.max(maxHeight, sticky.position.top + height);
719
+ }
720
+ else {
721
+ // Fallback to default sizes if element not found
722
+ maxWidth = Math.max(maxWidth, sticky.position.left + 200);
723
+ maxHeight = Math.max(maxHeight, sticky.position.top + 100);
724
+ }
378
725
  }
379
726
  });
380
727
  // Update canvas size in store
381
728
  store.getState().expandCanvas(maxWidth, maxHeight);
382
729
  }
730
+ handleCanvasDoubleClick(event) {
731
+ // Check if we double-clicked on empty canvas space
732
+ const target = event.target;
733
+ if (target.id !== 'canvas') {
734
+ return;
735
+ }
736
+ // Get canvas position
737
+ const canvas = this.querySelector('#canvas');
738
+ if (!canvas) {
739
+ return;
740
+ }
741
+ const canvasRect = canvas.getBoundingClientRect();
742
+ const relativeX = event.clientX - canvasRect.left - 10;
743
+ const relativeY = event.clientY - canvasRect.top - 10;
744
+ // Snap position to grid
745
+ const snappedLeft = snapToGrid(relativeX);
746
+ const snappedTop = snapToGrid(relativeY);
747
+ // Create new sticky note
748
+ const store = getStore();
749
+ store.getState().createStickyNote({
750
+ left: snappedLeft,
751
+ top: snappedTop
752
+ });
753
+ event.preventDefault();
754
+ event.stopPropagation();
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
+ }
383
827
  render() {
384
828
  var _a, _b;
385
829
  // we have to embed our own style since we are in light DOM
386
830
  const style = html `<style>
387
831
  ${unsafeCSS(Editor.styles.cssText)}
388
- ${unsafeCSS(EditorNode.styles.cssText)}
832
+ ${unsafeCSS(CanvasNode.styles.cssText)}
389
833
  </style>`;
390
834
  const stickies = ((_b = (_a = this.definition) === null || _a === void 0 ? void 0 : _a._ui) === null || _b === void 0 ? void 0 : _b.stickies) || {};
391
835
  return html `${style}
@@ -397,38 +841,61 @@ export class Editor extends RapidElement {
397
841
  >
398
842
  <div id="canvas">
399
843
  ${this.definition
400
- ? this.definition.nodes.map((node) => {
844
+ ? repeat(this.definition.nodes, (node) => node.uuid, (node) => {
401
845
  var _a;
402
846
  const position = this.definition._ui.nodes[node.uuid].position;
403
- const dragging = this.isDragging && ((_a = this.currentDragItem) === null || _a === void 0 ? void 0 : _a.uuid) === node.uuid;
847
+ const dragging = this.isDragging &&
848
+ ((_a = this.currentDragItem) === null || _a === void 0 ? void 0 : _a.uuid) === node.uuid;
849
+ const selected = this.selectedItems.has(node.uuid);
404
850
  return html `<temba-flow-node
405
- class="draggable ${dragging ? 'dragging' : ''}"
406
- @mousedown=${this.handleMouseDown.bind(this)}
407
- uuid=${node.uuid}
408
- style="left:${position.left}px; top:${position.top}px"
409
- .plumber=${this.plumber}
410
- .node=${node}
411
- .ui=${this.definition._ui.nodes[node.uuid]}
412
- ></temba-flow-node>`;
851
+ class="draggable ${dragging ? 'dragging' : ''} ${selected
852
+ ? 'selected'
853
+ : ''}"
854
+ @mousedown=${this.handleMouseDown.bind(this)}
855
+ uuid=${node.uuid}
856
+ style="left:${position.left}px; top:${position.top}px"
857
+ .plumber=${this.plumber}
858
+ .node=${node}
859
+ .ui=${this.definition._ui.nodes[node.uuid]}
860
+ @temba-node-deleted=${(event) => {
861
+ this.deleteNodes([event.detail.uuid]);
862
+ }}
863
+ ></temba-flow-node>`;
413
864
  })
414
865
  : html `<temba-loading></temba-loading>`}
415
- ${Object.entries(stickies).map(([uuid, sticky]) => {
866
+ ${repeat(Object.entries(stickies), ([uuid]) => uuid, ([uuid, sticky]) => {
416
867
  var _a;
417
868
  const position = sticky.position || { left: 0, top: 0 };
418
869
  const dragging = this.isDragging && ((_a = this.currentDragItem) === null || _a === void 0 ? void 0 : _a.uuid) === uuid;
870
+ const selected = this.selectedItems.has(uuid);
419
871
  return html `<temba-sticky-note
420
- class="draggable ${dragging ? 'dragging' : ''}"
421
- @mousedown=${this.handleMouseDown.bind(this)}
422
- style="left:${position.left}px; top:${position.top}px; z-index: ${1000 +
872
+ class="draggable ${dragging ? 'dragging' : ''} ${selected
873
+ ? 'selected'
874
+ : ''}"
875
+ @mousedown=${this.handleMouseDown.bind(this)}
876
+ style="left:${position.left}px; top:${position.top}px; z-index: ${1000 +
423
877
  position.top}"
424
- uuid=${uuid}
425
- .data=${sticky}
426
- .dragging=${dragging}
427
- ></temba-sticky-note>`;
878
+ uuid=${uuid}
879
+ .data=${sticky}
880
+ .dragging=${dragging}
881
+ .selected=${selected}
882
+ ></temba-sticky-note>`;
428
883
  })}
884
+ ${this.renderSelectionBox()}
429
885
  </div>
430
886
  </div>
431
- </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
+ : ''} `;
432
899
  }
433
900
  }
434
901
  __decorate([
@@ -452,4 +919,34 @@ __decorate([
452
919
  __decorate([
453
920
  state()
454
921
  ], Editor.prototype, "currentDragItem", void 0);
922
+ __decorate([
923
+ state()
924
+ ], Editor.prototype, "selectedItems", void 0);
925
+ __decorate([
926
+ state()
927
+ ], Editor.prototype, "isSelecting", void 0);
928
+ __decorate([
929
+ state()
930
+ ], Editor.prototype, "selectionBox", void 0);
931
+ __decorate([
932
+ state()
933
+ ], Editor.prototype, "targetId", void 0);
934
+ __decorate([
935
+ state()
936
+ ], Editor.prototype, "sourceId", void 0);
937
+ __decorate([
938
+ state()
939
+ ], Editor.prototype, "dragFromNodeId", void 0);
940
+ __decorate([
941
+ state()
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);
455
952
  //# sourceMappingURL=Editor.js.map