@nyaruka/temba-components 0.129.8 → 0.129.10

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 (282) hide show
  1. package/CHANGELOG.md +37 -3
  2. package/demo/data/flows/sample-flow.json +186 -96
  3. package/demo/test-colorpicker.html +30 -0
  4. package/dist/temba-components.js +1126 -1111
  5. package/dist/temba-components.js.map +1 -1
  6. package/out-tsc/src/events.js.map +1 -1
  7. package/out-tsc/src/excellent/helpers.js +2 -2
  8. package/out-tsc/src/excellent/helpers.js.map +1 -1
  9. package/out-tsc/src/flow/CanvasNode.js +25 -7
  10. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  11. package/out-tsc/src/flow/Editor.js +11 -1
  12. package/out-tsc/src/flow/Editor.js.map +1 -1
  13. package/out-tsc/src/flow/NodeEditor.js +133 -290
  14. package/out-tsc/src/flow/NodeEditor.js.map +1 -1
  15. package/out-tsc/src/flow/actions/add_input_labels.js +40 -0
  16. package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -1
  17. package/out-tsc/src/flow/actions/call_llm.js +56 -3
  18. package/out-tsc/src/flow/actions/call_llm.js.map +1 -1
  19. package/out-tsc/src/flow/actions/call_webhook.js +1 -1
  20. package/out-tsc/src/flow/actions/call_webhook.js.map +1 -1
  21. package/out-tsc/src/flow/actions/open_ticket.js +65 -3
  22. package/out-tsc/src/flow/actions/open_ticket.js.map +1 -1
  23. package/out-tsc/src/flow/actions/set_run_result.js +75 -0
  24. package/out-tsc/src/flow/actions/set_run_result.js.map +1 -1
  25. package/out-tsc/src/flow/config.js +4 -0
  26. package/out-tsc/src/flow/config.js.map +1 -1
  27. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +227 -0
  28. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -0
  29. package/out-tsc/src/flow/nodes/split_by_ticket.js +18 -0
  30. package/out-tsc/src/flow/nodes/split_by_ticket.js.map +1 -0
  31. package/out-tsc/src/flow/nodes/wait_for_response.js +27 -1
  32. package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
  33. package/out-tsc/src/flow/types.js +0 -65
  34. package/out-tsc/src/flow/types.js.map +1 -1
  35. package/out-tsc/src/form/ArrayEditor.js +63 -117
  36. package/out-tsc/src/form/ArrayEditor.js.map +1 -1
  37. package/out-tsc/src/form/BaseListEditor.js +4 -3
  38. package/out-tsc/src/form/BaseListEditor.js.map +1 -1
  39. package/out-tsc/src/form/Checkbox.js +77 -24
  40. package/out-tsc/src/form/Checkbox.js.map +1 -1
  41. package/out-tsc/src/form/ColorPicker.js +28 -40
  42. package/out-tsc/src/form/ColorPicker.js.map +1 -1
  43. package/out-tsc/src/form/Completion.js +44 -53
  44. package/out-tsc/src/form/Completion.js.map +1 -1
  45. package/out-tsc/src/form/Compose.js +7 -8
  46. package/out-tsc/src/form/Compose.js.map +1 -1
  47. package/out-tsc/src/form/ContactSearch.js +3 -4
  48. package/out-tsc/src/form/ContactSearch.js.map +1 -1
  49. package/out-tsc/src/form/DatePicker.js +29 -36
  50. package/out-tsc/src/form/DatePicker.js.map +1 -1
  51. package/out-tsc/src/form/{FormField.js → FieldElement.js} +81 -53
  52. package/out-tsc/src/form/FieldElement.js.map +1 -0
  53. package/out-tsc/src/form/FieldRenderer.js +306 -0
  54. package/out-tsc/src/form/FieldRenderer.js.map +1 -0
  55. package/out-tsc/src/form/ImagePicker.js +122 -126
  56. package/out-tsc/src/form/ImagePicker.js.map +1 -1
  57. package/out-tsc/src/form/KeyValueEditor.js +41 -37
  58. package/out-tsc/src/form/KeyValueEditor.js.map +1 -1
  59. package/out-tsc/src/form/MessageEditor.js +55 -63
  60. package/out-tsc/src/form/MessageEditor.js.map +1 -1
  61. package/out-tsc/src/form/TembaSlider.js +3 -3
  62. package/out-tsc/src/form/TembaSlider.js.map +1 -1
  63. package/out-tsc/src/form/TemplateEditor.js +3 -3
  64. package/out-tsc/src/form/TemplateEditor.js.map +1 -1
  65. package/out-tsc/src/form/TextInput.js +23 -27
  66. package/out-tsc/src/form/TextInput.js.map +1 -1
  67. package/out-tsc/src/form/select/Select.js +57 -35
  68. package/out-tsc/src/form/select/Select.js.map +1 -1
  69. package/out-tsc/src/form/select/UserSelect.js +8 -9
  70. package/out-tsc/src/form/select/UserSelect.js.map +1 -1
  71. package/out-tsc/src/form/select/WorkspaceSelect.js +7 -8
  72. package/out-tsc/src/form/select/WorkspaceSelect.js.map +1 -1
  73. package/out-tsc/src/live/ContactChat.js +62 -44
  74. package/out-tsc/src/live/ContactChat.js.map +1 -1
  75. package/out-tsc/src/live/ContactFieldEditor.js.map +1 -1
  76. package/out-tsc/src/markdown.js +13 -11
  77. package/out-tsc/src/markdown.js.map +1 -1
  78. package/out-tsc/temba-modules.js +3 -2
  79. package/out-tsc/temba-modules.js.map +1 -1
  80. package/out-tsc/test/ActionHelper.js +2 -0
  81. package/out-tsc/test/ActionHelper.js.map +1 -1
  82. package/out-tsc/test/NodeHelper.js +148 -0
  83. package/out-tsc/test/NodeHelper.js.map +1 -0
  84. package/out-tsc/test/actions/call_llm.test.js +103 -0
  85. package/out-tsc/test/actions/call_llm.test.js.map +1 -0
  86. package/out-tsc/test/nodes/split_by_llm_categorize.test.js +532 -0
  87. package/out-tsc/test/nodes/split_by_llm_categorize.test.js.map +1 -0
  88. package/out-tsc/test/nodes/split_by_random.test.js +150 -0
  89. package/out-tsc/test/nodes/split_by_random.test.js.map +1 -0
  90. package/out-tsc/test/nodes/wait_for_digits.test.js +150 -0
  91. package/out-tsc/test/nodes/wait_for_digits.test.js.map +1 -0
  92. package/out-tsc/test/nodes/wait_for_response.test.js +171 -0
  93. package/out-tsc/test/nodes/wait_for_response.test.js.map +1 -0
  94. package/out-tsc/test/temba-add-input-labels.test.js +70 -0
  95. package/out-tsc/test/temba-add-input-labels.test.js.map +1 -0
  96. package/out-tsc/test/temba-checkbox.test.js +16 -0
  97. package/out-tsc/test/temba-checkbox.test.js.map +1 -1
  98. package/out-tsc/test/temba-field-renderer.test.js +296 -0
  99. package/out-tsc/test/temba-field-renderer.test.js.map +1 -0
  100. package/out-tsc/test/temba-integration-markdown.test.js +2 -4
  101. package/out-tsc/test/temba-integration-markdown.test.js.map +1 -1
  102. package/out-tsc/test/temba-markdown.test.js +1 -1
  103. package/out-tsc/test/temba-markdown.test.js.map +1 -1
  104. package/out-tsc/test/temba-node-editor.test.js +400 -0
  105. package/out-tsc/test/temba-node-editor.test.js.map +1 -1
  106. package/out-tsc/test/temba-select.test.js +6 -3
  107. package/out-tsc/test/temba-select.test.js.map +1 -1
  108. package/out-tsc/test/temba-slider.test.js +0 -1
  109. package/out-tsc/test/temba-slider.test.js.map +1 -1
  110. package/out-tsc/test/temba-webchat.test.js +1 -1
  111. package/out-tsc/test/temba-webchat.test.js.map +1 -1
  112. package/package.json +1 -1
  113. package/screenshots/truth/actions/add_contact_groups/editor/descriptive-group-names.png +0 -0
  114. package/screenshots/truth/actions/add_contact_groups/editor/long-group-names.png +0 -0
  115. package/screenshots/truth/actions/add_contact_groups/editor/many-groups.png +0 -0
  116. package/screenshots/truth/actions/call_llm/editor/information-extraction.png +0 -0
  117. package/screenshots/truth/actions/call_llm/editor/sentiment-analysis.png +0 -0
  118. package/screenshots/truth/actions/call_llm/editor/summarization.png +0 -0
  119. package/screenshots/truth/actions/call_llm/editor/translation-task.png +0 -0
  120. package/screenshots/truth/actions/call_llm/render/information-extraction.png +0 -0
  121. package/screenshots/truth/actions/call_llm/render/sentiment-analysis.png +0 -0
  122. package/screenshots/truth/actions/call_llm/render/summarization.png +0 -0
  123. package/screenshots/truth/actions/call_llm/render/translation-task.png +0 -0
  124. package/screenshots/truth/actions/remove_contact_groups/editor/cleanup-groups.png +0 -0
  125. package/screenshots/truth/actions/remove_contact_groups/editor/long-descriptive-group-names.png +0 -0
  126. package/screenshots/truth/actions/remove_contact_groups/editor/many-groups.png +0 -0
  127. package/screenshots/truth/actions/remove_contact_groups/editor/multiple-groups.png +0 -0
  128. package/screenshots/truth/actions/remove_contact_groups/editor/remove-from-all-groups.png +0 -0
  129. package/screenshots/truth/actions/remove_contact_groups/editor/single-group.png +0 -0
  130. package/screenshots/truth/actions/send_email/editor/complex-business-email.png +0 -0
  131. package/screenshots/truth/actions/send_email/editor/multiple-recipients.png +0 -0
  132. package/screenshots/truth/actions/send_msg/editor/long-quick-replies.png +0 -0
  133. package/screenshots/truth/actions/send_msg/editor/multiline-text-with-replies.png +0 -0
  134. package/screenshots/truth/actions/send_msg/editor/simple-text.png +0 -0
  135. package/screenshots/truth/actions/send_msg/editor/text-with-linebreaks.png +0 -0
  136. package/screenshots/truth/actions/send_msg/editor/text-with-many-quick-replies.png +0 -0
  137. package/screenshots/truth/actions/send_msg/editor/text-with-quick-replies.png +0 -0
  138. package/screenshots/truth/actions/send_msg/editor/text-without-quick-replies.png +0 -0
  139. package/screenshots/truth/checkbox/checkbox-label-background-hover.png +0 -0
  140. package/screenshots/truth/checkbox/checkbox-no-label-no-background-hover.png +0 -0
  141. package/screenshots/truth/checkbox/checkbox-with-help-text.png +0 -0
  142. package/screenshots/truth/checkbox/checked.png +0 -0
  143. package/screenshots/truth/checkbox/default.png +0 -0
  144. package/screenshots/truth/colorpicker/default.png +0 -0
  145. package/screenshots/truth/colorpicker/focused.png +0 -0
  146. package/screenshots/truth/colorpicker/initialized.png +0 -0
  147. package/screenshots/truth/colorpicker/selected.png +0 -0
  148. package/screenshots/truth/editor/router.png +0 -0
  149. package/screenshots/truth/editor/send_msg.png +0 -0
  150. package/screenshots/truth/editor/set_contact_language.png +0 -0
  151. package/screenshots/truth/editor/set_contact_name.png +0 -0
  152. package/screenshots/truth/editor/set_run_result.png +0 -0
  153. package/screenshots/truth/editor/wait.png +0 -0
  154. package/screenshots/truth/field-renderer/checkbox-checked.png +0 -0
  155. package/screenshots/truth/field-renderer/checkbox-unchecked.png +0 -0
  156. package/screenshots/truth/field-renderer/checkbox-with-errors.png +0 -0
  157. package/screenshots/truth/field-renderer/context-comparison.png +0 -0
  158. package/screenshots/truth/field-renderer/key-value-with-label.png +0 -0
  159. package/screenshots/truth/field-renderer/message-editor-with-label.png +0 -0
  160. package/screenshots/truth/field-renderer/select-multi.png +0 -0
  161. package/screenshots/truth/field-renderer/select-no-label.png +0 -0
  162. package/screenshots/truth/field-renderer/select-with-label.png +0 -0
  163. package/screenshots/truth/field-renderer/text-evaluated.png +0 -0
  164. package/screenshots/truth/field-renderer/text-no-label.png +0 -0
  165. package/screenshots/truth/field-renderer/text-with-errors.png +0 -0
  166. package/screenshots/truth/field-renderer/text-with-label.png +0 -0
  167. package/screenshots/truth/field-renderer/textarea-evaluated.png +0 -0
  168. package/screenshots/truth/field-renderer/textarea-with-label.png +0 -0
  169. package/screenshots/truth/integration/checkbox-markdown-errors.png +0 -0
  170. package/screenshots/truth/nodes/split_by_llm_categorize/editor/basic-categorization.png +0 -0
  171. package/screenshots/truth/nodes/split_by_llm_categorize/editor/custom-input-and-result-name.png +0 -0
  172. package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
  173. package/screenshots/truth/nodes/split_by_llm_categorize/editor/many-categories.png +0 -0
  174. package/screenshots/truth/nodes/split_by_llm_categorize/editor/minimal-categories.png +0 -0
  175. package/screenshots/truth/nodes/split_by_llm_categorize/render/basic-categorization.png +0 -0
  176. package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
  177. package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
  178. package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
  179. package/screenshots/truth/nodes/split_by_llm_categorize/render/minimal-categories.png +0 -0
  180. package/screenshots/truth/nodes/split_by_random/editor/ab-test-multiple-variants.png +0 -0
  181. package/screenshots/truth/nodes/split_by_random/editor/sampling-split.png +0 -0
  182. package/screenshots/truth/nodes/split_by_random/editor/three-way-split.png +0 -0
  183. package/screenshots/truth/nodes/split_by_random/editor/two-bucket-split.png +0 -0
  184. package/screenshots/truth/nodes/split_by_random/render/ab-test-multiple-variants.png +0 -0
  185. package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
  186. package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
  187. package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.png +0 -0
  188. package/screenshots/truth/nodes/wait_for_digits/editor/basic-digits-wait.png +0 -0
  189. package/screenshots/truth/nodes/wait_for_digits/editor/phone-number-collection.png +0 -0
  190. package/screenshots/truth/nodes/wait_for_digits/editor/single-digit-with-timeout.png +0 -0
  191. package/screenshots/truth/nodes/wait_for_digits/editor/verification-code.png +0 -0
  192. package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
  193. package/screenshots/truth/nodes/wait_for_digits/render/phone-number-collection.png +0 -0
  194. package/screenshots/truth/nodes/wait_for_digits/render/single-digit-with-timeout.png +0 -0
  195. package/screenshots/truth/nodes/wait_for_digits/render/verification-code.png +0 -0
  196. package/screenshots/truth/nodes/wait_for_response/editor/basic-wait.png +0 -0
  197. package/screenshots/truth/nodes/wait_for_response/editor/custom-result-name.png +0 -0
  198. package/screenshots/truth/nodes/wait_for_response/editor/no-timeout.png +0 -0
  199. package/screenshots/truth/nodes/wait_for_response/editor/short-timeout.png +0 -0
  200. package/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
  201. package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
  202. package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
  203. package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
  204. package/screenshots/truth/omnibox/selected.png +0 -0
  205. package/screenshots/truth/run-list/basic.png +0 -0
  206. package/screenshots/truth/select/functions.png +0 -0
  207. package/screenshots/truth/select/multi-with-endpoint.png +0 -0
  208. package/screenshots/truth/select/search-enabled.png +0 -0
  209. package/src/events.ts +12 -6
  210. package/src/excellent/helpers.ts +2 -2
  211. package/src/flow/CanvasNode.ts +22 -1
  212. package/src/flow/Editor.ts +12 -1
  213. package/src/flow/NodeEditor.ts +186 -374
  214. package/src/flow/actions/add_input_labels.ts +45 -0
  215. package/src/flow/actions/call_llm.ts +57 -3
  216. package/src/flow/actions/call_webhook.ts +1 -1
  217. package/src/flow/actions/open_ticket.ts +74 -3
  218. package/src/flow/actions/set_run_result.ts +83 -0
  219. package/src/flow/config.ts +4 -0
  220. package/src/flow/nodes/split_by_llm_categorize.ts +277 -0
  221. package/src/flow/nodes/split_by_ticket.ts +19 -0
  222. package/src/flow/nodes/wait_for_response.ts +28 -1
  223. package/src/flow/types.ts +26 -127
  224. package/src/form/ArrayEditor.ts +79 -139
  225. package/src/form/BaseListEditor.ts +4 -4
  226. package/src/form/Checkbox.ts +81 -24
  227. package/src/form/ColorPicker.ts +31 -43
  228. package/src/form/Completion.ts +49 -56
  229. package/src/form/Compose.ts +8 -8
  230. package/src/form/ContactSearch.ts +3 -4
  231. package/src/form/DatePicker.ts +32 -38
  232. package/src/form/{FormField.ts → FieldElement.ts} +108 -55
  233. package/src/form/FieldRenderer.ts +466 -0
  234. package/src/form/ImagePicker.ts +107 -110
  235. package/src/form/KeyValueEditor.ts +43 -39
  236. package/src/form/MessageEditor.ts +61 -67
  237. package/src/form/TembaSlider.ts +3 -3
  238. package/src/form/TemplateEditor.ts +3 -3
  239. package/src/form/TextInput.ts +26 -29
  240. package/src/form/select/Select.ts +63 -37
  241. package/src/form/select/UserSelect.ts +10 -11
  242. package/src/form/select/WorkspaceSelect.ts +9 -10
  243. package/src/live/ContactChat.ts +62 -47
  244. package/src/live/ContactFieldEditor.ts +2 -2
  245. package/src/markdown.ts +19 -11
  246. package/src/store/flow-definition.d.ts +5 -2
  247. package/static/api/labels.json +31 -0
  248. package/static/api/topics.json +24 -9
  249. package/static/api/users.json +35 -16
  250. package/static/css/temba-components.css +3 -3
  251. package/stress-test.js +18 -13
  252. package/temba-modules.ts +3 -2
  253. package/test/ActionHelper.ts +2 -0
  254. package/test/NodeHelper.ts +184 -0
  255. package/test/actions/call_llm.test.ts +137 -0
  256. package/test/nodes/README.md +78 -0
  257. package/test/nodes/split_by_llm_categorize.test.ts +698 -0
  258. package/test/nodes/split_by_random.test.ts +177 -0
  259. package/test/nodes/wait_for_digits.test.ts +176 -0
  260. package/test/nodes/wait_for_response.test.ts +206 -0
  261. package/test/temba-add-input-labels.test.ts +87 -0
  262. package/test/temba-checkbox.test.ts +26 -0
  263. package/test/temba-field-renderer.test.ts +482 -0
  264. package/test/temba-integration-markdown.test.ts +2 -4
  265. package/test/temba-markdown.test.ts +1 -1
  266. package/test/temba-node-editor.test.ts +496 -0
  267. package/test/temba-select.test.ts +6 -6
  268. package/test/temba-slider.test.ts +0 -1
  269. package/test/temba-webchat.test.ts +1 -1
  270. package/test-assets/contacts/history.json +7 -20
  271. package/test-assets/select/llms.json +18 -0
  272. package/web-dev-mock.mjs +96 -6
  273. package/web-dev-server.config.mjs +29 -7
  274. package/out-tsc/src/form/FormElement.js +0 -67
  275. package/out-tsc/src/form/FormElement.js.map +0 -1
  276. package/out-tsc/src/form/FormField.js.map +0 -1
  277. package/out-tsc/test/temba-formfield.test.js +0 -94
  278. package/out-tsc/test/temba-formfield.test.js.map +0 -1
  279. package/src/form/FormElement.ts +0 -69
  280. package/test/temba-flow-editor.test.ts.backup +0 -563
  281. package/test/temba-formfield.test.ts +0 -121
  282. package/test/temba-utils-index.test.ts.backup +0 -1737
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/events.ts"],"names":[],"mappings":"","sourcesContent":["import { Msg, ObjectReference, User } from './interfaces';\n\nexport interface EventGroup {\n type: string;\n events: ContactEvent[];\n open: boolean;\n}\n\nexport interface ContactEvent {\n uuid?: string;\n type: string;\n created_on: string;\n created_by?: User;\n}\n\nexport interface ChannelEvent extends ContactEvent {\n channel_event_type: string;\n duration: number;\n\n event: {\n type: string;\n channel: { uuid: string; name: string };\n duration?: number;\n optin?: {\n uuid: string;\n name: string;\n };\n };\n}\n\nexport interface ContactLanguageChangedEvent extends ContactEvent {\n language: string;\n step_uuid: string;\n session_uuid: string;\n}\n\nexport interface OptinRequestedEvent extends ContactEvent {\n optin: {\n uuid: string;\n name: string;\n };\n}\n\nexport interface MsgEvent extends ContactEvent {\n msg: Msg;\n status: string;\n failed_reason?: string;\n failed_reason_display?: string;\n logs_url: string;\n recipient_count?: number;\n created_by?: User;\n optin?: ObjectReference;\n}\n\nexport interface FlowEvent extends ContactEvent {\n flow: ObjectReference;\n status: string;\n}\n\nexport interface RunEvent extends ContactEvent {\n flow: ObjectReference;\n status: string;\n}\n\nexport interface URNsChangedEvent extends ContactEvent {\n urns: string[];\n}\n\nexport interface TicketEvent extends ContactEvent {\n note?: string;\n assignee?: User;\n ticket: {\n uuid: string;\n topic?: ObjectReference;\n closed_on?: string;\n opened_on?: string;\n };\n topic?: ObjectReference;\n created_by?: User;\n}\n\nexport interface NameChangedEvent extends ContactEvent {\n name: string;\n}\n\nexport interface UpdateFieldEvent extends ContactEvent {\n field: { key: string; name: string };\n value: { text: string };\n}\n\nexport interface ContactGroupsEvent extends ContactEvent {\n groups_added: ObjectReference[];\n groups_removed: ObjectReference[];\n}\n\nexport interface AirtimeTransferredEvent extends ContactEvent {\n sender: string;\n recipient: string;\n currency: string;\n amount: string;\n}\n\nexport type CallStartedEvent = ContactEvent;\n\nexport interface ContactHistoryPage {\n has_older: boolean;\n recent_only: boolean;\n next_before: number;\n next_after: number;\n start_date: Date;\n events: ContactEvent[];\n}\n"]}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/events.ts"],"names":[],"mappings":"","sourcesContent":["import { Msg, ObjectReference, User } from './interfaces';\n\nexport interface EventGroup {\n type: string;\n events: ContactEvent[];\n open: boolean;\n}\n\nexport interface ContactEvent {\n uuid?: string;\n type: string;\n created_on: string;\n created_by?: User;\n}\n\nexport interface ChannelEvent extends ContactEvent {\n channel_event_type: string;\n duration: number;\n\n event: {\n type: string;\n channel: { uuid: string; name: string };\n duration?: number;\n optin?: {\n uuid: string;\n name: string;\n };\n };\n}\n\nexport interface ContactLanguageChangedEvent extends ContactEvent {\n language: string;\n step_uuid: string;\n session_uuid: string;\n}\n\nexport interface OptInEvent extends ContactEvent {\n optin: {\n uuid: string;\n name: string;\n };\n}\n\nexport interface CallEvent extends ContactEvent {\n call?: {\n uuid: string;\n urn: string;\n };\n}\n\nexport interface ChatStartedEvent extends ContactEvent {\n params?: object;\n}\n\nexport interface MsgEvent extends ContactEvent {\n msg: Msg;\n status: string;\n failed_reason?: string;\n failed_reason_display?: string;\n logs_url: string;\n recipient_count?: number;\n created_by?: User;\n optin?: ObjectReference;\n}\n\nexport interface RunEvent extends ContactEvent {\n flow: ObjectReference;\n status: string;\n}\n\nexport interface URNsChangedEvent extends ContactEvent {\n urns: string[];\n}\n\nexport interface TicketEvent extends ContactEvent {\n note?: string;\n assignee?: User;\n ticket: {\n uuid: string;\n topic?: ObjectReference;\n closed_on?: string;\n opened_on?: string;\n };\n topic?: ObjectReference;\n created_by?: User;\n}\n\nexport interface NameChangedEvent extends ContactEvent {\n name: string;\n}\n\nexport interface UpdateFieldEvent extends ContactEvent {\n field: { key: string; name: string };\n value: { text: string };\n}\n\nexport interface ContactGroupsEvent extends ContactEvent {\n groups_added: ObjectReference[];\n groups_removed: ObjectReference[];\n}\n\nexport interface AirtimeTransferredEvent extends ContactEvent {\n sender: string;\n recipient: string;\n currency: string;\n amount: string;\n}\n\nexport type CallStartedEvent = ContactEvent;\n\nexport interface ContactHistoryPage {\n has_older: boolean;\n recent_only: boolean;\n next_before: number;\n next_after: number;\n start_date: Date;\n events: ContactEvent[];\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { html } from 'lit';
2
2
  import ExcellentParser from './ExcellentParser';
3
3
  import { getStore } from '../store/Store';
4
- import { renderMarkdown } from '../markdown';
4
+ import { renderMarkdownInline } from '../markdown';
5
5
  const messageParser = new ExcellentParser('@', [
6
6
  'contact',
7
7
  'fields',
@@ -41,7 +41,7 @@ export const renderCompletionOption = (option, selected) => {
41
41
  >
42
42
  ${args}
43
43
  </div>
44
- <div class="detail">${renderMarkdown(option.summary)}</div>
44
+ <div class="detail">${renderMarkdownInline(option.summary)}</div>
45
45
  `
46
46
  : null}
47
47
  </div>
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/excellent/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, TemplateResult } from 'lit';\n\nimport ExcellentParser, { Expression } from './ExcellentParser';\nimport {\n CompletionOption,\n CompletionProperty,\n CompletionResult,\n CompletionSchema,\n CompletionType\n} from '../interfaces';\nimport { getStore, Store } from '../store/Store';\nimport { renderMarkdown } from '../markdown';\n\nconst messageParser = new ExcellentParser('@', [\n 'contact',\n 'fields',\n 'globals',\n 'urns'\n]);\n\nconst sessionParser = new ExcellentParser('@', [\n 'contact',\n 'fields',\n 'globals',\n 'locals',\n 'urns',\n 'results',\n 'input',\n 'run',\n 'child',\n 'parent',\n 'node',\n 'webhook',\n 'ticket',\n 'trigger',\n 'resume'\n]);\n\nexport const renderCompletionOption = (\n option: CompletionOption,\n selected: boolean\n): TemplateResult => {\n if (option.signature) {\n const argStart = option.signature.indexOf('(');\n const name = option.signature.substr(0, argStart);\n const args = option.signature.substr(argStart);\n\n return html`\n <div style=\"${selected ? 'font-weight: 400' : ''}\">\n <div style=\"display:inline-block;margin-right: 5px\">ƒ</div>\n <div style=\"display:inline-block\">${name}</div>\n ${selected\n ? html`\n <div\n style=\"display:inline-block; font-weight: 300; font-size: 85%\"\n >\n ${args}\n </div>\n <div class=\"detail\">${renderMarkdown(option.summary)}</div>\n `\n : null}\n </div>\n `;\n }\n\n return html`\n <div>\n <div style=\"${selected ? 'font-weight: 400' : ''}\">${option.name}</div>\n ${selected\n ? html` <div style=\"font-size: 85%\">${option.summary}</div> `\n : null}\n </div>\n `;\n};\n\nexport const getFunctions = (\n functions: CompletionOption[],\n query: string\n): CompletionOption[] => {\n if (!query) {\n return functions;\n }\n return functions.filter((option: CompletionOption) => {\n if (option.signature) {\n return option.signature.indexOf((query || '').toLowerCase()) === 0;\n }\n return false;\n });\n};\n\n/**\n * Takes a dot query and returns the completions options at the current level\n * @param dotQuery query such as \"contact.first_n\"\n */\nexport const getCompletions = (\n schema: CompletionSchema,\n dotQuery: string,\n session: boolean,\n store: Store\n): CompletionOption[] => {\n const parts = (dotQuery || '').split('.');\n let currentProps: CompletionProperty[] = session\n ? schema.root\n : schema.root_no_session;\n\n if (!currentProps) {\n return [];\n }\n\n let prefix = '';\n let part = '';\n while (parts.length > 0) {\n part = parts.shift();\n if (part) {\n // eslint-disable-next-line\n const nextProp = currentProps.find(\n (prop: CompletionProperty) => prop.key === part\n );\n if (nextProp) {\n // eslint-disable-next-line\n const nextType = schema.types.find(\n (type: CompletionType) => type.name === nextProp.type\n );\n if (nextType && nextType.properties) {\n currentProps = nextType.properties;\n prefix += part + '.';\n } else if (nextType && nextType.property_template) {\n prefix += part + '.';\n const template = nextType.property_template;\n\n const keys = store.getCompletions(nextType.name);\n if (keys) {\n currentProps = keys.map((key: string) => ({\n key: template.key.replace('{key}', key),\n help: template.help.replace('{key}', key),\n type: template.type\n }));\n } else {\n currentProps = [];\n }\n } else {\n // eslint-disable-next-line\n currentProps = currentProps.filter((prop: CompletionProperty) =>\n prop.key.startsWith(part.toLowerCase())\n );\n break;\n }\n } else {\n // eslint-disable-next-line\n currentProps = currentProps.filter((prop: CompletionProperty) =>\n prop.key.startsWith(part.toLowerCase())\n );\n break;\n }\n }\n }\n\n return currentProps.map((prop: CompletionProperty) => {\n const name =\n prop.key === '__default__'\n ? prefix.substr(0, prefix.length - 1)\n : prefix + prop.key;\n return { name, summary: prop.help };\n });\n};\n\nexport const getOffset = (el: HTMLElement) => {\n const rect = el.getBoundingClientRect(),\n scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,\n scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\n};\n\nexport const getVerticalScroll = (ele: Node) => {\n let current = ele;\n const verticalScroll = 0;\n while (current) {\n current = current.parentNode;\n }\n return verticalScroll;\n};\n\nexport const getCompletionName = (option: CompletionOption): string => {\n return (\n option.name || option.signature.substr(0, option.signature.indexOf('('))\n );\n};\n\nexport const getCompletionSignature = (option: CompletionOption): string => {\n return option.signature.substr(option.signature.indexOf('('));\n};\n\n/**\n * Determines the pixel position of position inside a textarea or input\n * TODO: Explore somethign like contenteditable to avoid this madness\n * see: https://jh3y.medium.com/how-to-where-s-the-caret-getting-the-xy-position-of-the-caret-a24ba372990a\n */\nconst getCursorXY = (input, selectionPoint) => {\n const { offsetLeft: inputX, offsetTop: inputY } = input;\n const div = document.createElement('div');\n const copyStyle = getComputedStyle(input);\n for (const prop of copyStyle) {\n div.style[prop] = copyStyle[prop];\n }\n div.style.position = 'relative';\n const swap = '.';\n const inputValue =\n input.tagName === 'INPUT' ? input.value.replace(/ /g, swap) : input.value;\n const textContent = inputValue.substr(0, selectionPoint);\n div.textContent = textContent;\n if (input.tagName === 'TEXTAREA') div.style.height = 'auto';\n if (input.tagName === 'INPUT') div.style.width = 'auto';\n const span = document.createElement('span');\n span.textContent = inputValue.substr(selectionPoint) || '.';\n div.appendChild(span);\n document.body.appendChild(div);\n const { offsetLeft: spanX, offsetTop: spanY } = span;\n document.body.removeChild(div);\n return {\n left: inputX + spanX,\n top: inputY + spanY\n };\n};\n\nexport const updateInputElementWithCompletion = (\n currentQuery: string,\n ele: HTMLInputElement,\n option: CompletionOption\n) => {\n let insertText = '';\n\n if (option.signature) {\n // they selected a function\n insertText = option.signature.substr(0, option.signature.indexOf('(') + 1);\n } else {\n insertText = option.name;\n }\n\n const queryLength = currentQuery.length;\n\n if (ele) {\n const value = ele.value;\n const insertionPoint = ele.selectionStart - queryLength;\n\n // strip out our query\n // const insertionPoint = value.lastIndexOf(value.substring(0, this.inputElement.selectionStart));\n const leftSide = value.substr(0, insertionPoint);\n const remaining = value.substr(insertionPoint + queryLength);\n const caret = leftSide.length + insertText.length;\n\n // set our value and our new caret\n ele.value = leftSide + insertText + remaining;\n ele.setSelectionRange(caret, caret);\n\n // now scroll our text box if necessary\n const position = getCursorXY(ele, caret);\n if (position.left > ele.width) {\n ele.scrollLeft = position.left;\n }\n\n ele.dispatchEvent(new Event('input'));\n }\n};\n\nexport const executeCompletionQuery = (\n ele: HTMLInputElement,\n session: boolean\n): CompletionResult => {\n const result: CompletionResult = {\n currentFunction: null,\n options: [],\n anchorPosition: null,\n query: null\n };\n\n if (!ele) {\n return;\n }\n\n const store = getStore();\n\n // we need a store to do anything useful\n if (!store) {\n return result;\n }\n\n const cursor = ele.selectionStart;\n const input = ele.value.substring(0, cursor);\n\n const parser = session ? sessionParser : messageParser;\n const expressions = parser.findExpressions(input);\n const currentExpression = expressions.find(\n (expr: Expression) =>\n expr.start <= cursor &&\n (expr.end > cursor || (expr.end === cursor && !expr.closed))\n );\n\n if (currentExpression) {\n const includeFunctions = currentExpression.text.indexOf('(') > -1;\n if (includeFunctions) {\n const functionQuery = parser.functionContext(currentExpression.text);\n if (functionQuery) {\n const fns = getFunctions(store.getFunctions(), functionQuery);\n if (fns.length > 0) {\n result.currentFunction = fns[0];\n }\n }\n }\n\n for (let i = currentExpression.text.length; i >= 0; i--) {\n const curr = currentExpression.text[i];\n if (\n curr === '@' ||\n curr === '(' ||\n curr === ' ' ||\n curr === ',' ||\n curr === ')' ||\n i === 0\n ) {\n // don't include non-expression chars\n if (\n curr === '(' ||\n curr === ' ' ||\n curr === ',' ||\n curr === ')' ||\n curr === '@'\n ) {\n i++;\n }\n\n const caret = getCursorXY(ele, currentExpression.start + i);\n\n result.anchorPosition = {\n left: caret.left - 2 - ele.scrollLeft,\n top: caret.top - ele.scrollTop\n };\n\n result.query = currentExpression.text.substr(\n i,\n currentExpression.text.length - i\n );\n\n result.options = [\n ...getCompletions(\n store.getCompletionSchema(),\n result.query,\n\n session,\n store\n ),\n ...(includeFunctions\n ? getFunctions(store.getFunctions(), result.query)\n : [])\n ];\n\n return result;\n }\n }\n } else {\n result.options = [];\n result.query = '';\n }\n return result;\n};\n"]}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/excellent/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, TemplateResult } from 'lit';\n\nimport ExcellentParser, { Expression } from './ExcellentParser';\nimport {\n CompletionOption,\n CompletionProperty,\n CompletionResult,\n CompletionSchema,\n CompletionType\n} from '../interfaces';\nimport { getStore, Store } from '../store/Store';\nimport { renderMarkdownInline } from '../markdown';\n\nconst messageParser = new ExcellentParser('@', [\n 'contact',\n 'fields',\n 'globals',\n 'urns'\n]);\n\nconst sessionParser = new ExcellentParser('@', [\n 'contact',\n 'fields',\n 'globals',\n 'locals',\n 'urns',\n 'results',\n 'input',\n 'run',\n 'child',\n 'parent',\n 'node',\n 'webhook',\n 'ticket',\n 'trigger',\n 'resume'\n]);\n\nexport const renderCompletionOption = (\n option: CompletionOption,\n selected: boolean\n): TemplateResult => {\n if (option.signature) {\n const argStart = option.signature.indexOf('(');\n const name = option.signature.substr(0, argStart);\n const args = option.signature.substr(argStart);\n\n return html`\n <div style=\"${selected ? 'font-weight: 400' : ''}\">\n <div style=\"display:inline-block;margin-right: 5px\">ƒ</div>\n <div style=\"display:inline-block\">${name}</div>\n ${selected\n ? html`\n <div\n style=\"display:inline-block; font-weight: 300; font-size: 85%\"\n >\n ${args}\n </div>\n <div class=\"detail\">${renderMarkdownInline(option.summary)}</div>\n `\n : null}\n </div>\n `;\n }\n\n return html`\n <div>\n <div style=\"${selected ? 'font-weight: 400' : ''}\">${option.name}</div>\n ${selected\n ? html` <div style=\"font-size: 85%\">${option.summary}</div> `\n : null}\n </div>\n `;\n};\n\nexport const getFunctions = (\n functions: CompletionOption[],\n query: string\n): CompletionOption[] => {\n if (!query) {\n return functions;\n }\n return functions.filter((option: CompletionOption) => {\n if (option.signature) {\n return option.signature.indexOf((query || '').toLowerCase()) === 0;\n }\n return false;\n });\n};\n\n/**\n * Takes a dot query and returns the completions options at the current level\n * @param dotQuery query such as \"contact.first_n\"\n */\nexport const getCompletions = (\n schema: CompletionSchema,\n dotQuery: string,\n session: boolean,\n store: Store\n): CompletionOption[] => {\n const parts = (dotQuery || '').split('.');\n let currentProps: CompletionProperty[] = session\n ? schema.root\n : schema.root_no_session;\n\n if (!currentProps) {\n return [];\n }\n\n let prefix = '';\n let part = '';\n while (parts.length > 0) {\n part = parts.shift();\n if (part) {\n // eslint-disable-next-line\n const nextProp = currentProps.find(\n (prop: CompletionProperty) => prop.key === part\n );\n if (nextProp) {\n // eslint-disable-next-line\n const nextType = schema.types.find(\n (type: CompletionType) => type.name === nextProp.type\n );\n if (nextType && nextType.properties) {\n currentProps = nextType.properties;\n prefix += part + '.';\n } else if (nextType && nextType.property_template) {\n prefix += part + '.';\n const template = nextType.property_template;\n\n const keys = store.getCompletions(nextType.name);\n if (keys) {\n currentProps = keys.map((key: string) => ({\n key: template.key.replace('{key}', key),\n help: template.help.replace('{key}', key),\n type: template.type\n }));\n } else {\n currentProps = [];\n }\n } else {\n // eslint-disable-next-line\n currentProps = currentProps.filter((prop: CompletionProperty) =>\n prop.key.startsWith(part.toLowerCase())\n );\n break;\n }\n } else {\n // eslint-disable-next-line\n currentProps = currentProps.filter((prop: CompletionProperty) =>\n prop.key.startsWith(part.toLowerCase())\n );\n break;\n }\n }\n }\n\n return currentProps.map((prop: CompletionProperty) => {\n const name =\n prop.key === '__default__'\n ? prefix.substr(0, prefix.length - 1)\n : prefix + prop.key;\n return { name, summary: prop.help };\n });\n};\n\nexport const getOffset = (el: HTMLElement) => {\n const rect = el.getBoundingClientRect(),\n scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,\n scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\n};\n\nexport const getVerticalScroll = (ele: Node) => {\n let current = ele;\n const verticalScroll = 0;\n while (current) {\n current = current.parentNode;\n }\n return verticalScroll;\n};\n\nexport const getCompletionName = (option: CompletionOption): string => {\n return (\n option.name || option.signature.substr(0, option.signature.indexOf('('))\n );\n};\n\nexport const getCompletionSignature = (option: CompletionOption): string => {\n return option.signature.substr(option.signature.indexOf('('));\n};\n\n/**\n * Determines the pixel position of position inside a textarea or input\n * TODO: Explore somethign like contenteditable to avoid this madness\n * see: https://jh3y.medium.com/how-to-where-s-the-caret-getting-the-xy-position-of-the-caret-a24ba372990a\n */\nconst getCursorXY = (input, selectionPoint) => {\n const { offsetLeft: inputX, offsetTop: inputY } = input;\n const div = document.createElement('div');\n const copyStyle = getComputedStyle(input);\n for (const prop of copyStyle) {\n div.style[prop] = copyStyle[prop];\n }\n div.style.position = 'relative';\n const swap = '.';\n const inputValue =\n input.tagName === 'INPUT' ? input.value.replace(/ /g, swap) : input.value;\n const textContent = inputValue.substr(0, selectionPoint);\n div.textContent = textContent;\n if (input.tagName === 'TEXTAREA') div.style.height = 'auto';\n if (input.tagName === 'INPUT') div.style.width = 'auto';\n const span = document.createElement('span');\n span.textContent = inputValue.substr(selectionPoint) || '.';\n div.appendChild(span);\n document.body.appendChild(div);\n const { offsetLeft: spanX, offsetTop: spanY } = span;\n document.body.removeChild(div);\n return {\n left: inputX + spanX,\n top: inputY + spanY\n };\n};\n\nexport const updateInputElementWithCompletion = (\n currentQuery: string,\n ele: HTMLInputElement,\n option: CompletionOption\n) => {\n let insertText = '';\n\n if (option.signature) {\n // they selected a function\n insertText = option.signature.substr(0, option.signature.indexOf('(') + 1);\n } else {\n insertText = option.name;\n }\n\n const queryLength = currentQuery.length;\n\n if (ele) {\n const value = ele.value;\n const insertionPoint = ele.selectionStart - queryLength;\n\n // strip out our query\n // const insertionPoint = value.lastIndexOf(value.substring(0, this.inputElement.selectionStart));\n const leftSide = value.substr(0, insertionPoint);\n const remaining = value.substr(insertionPoint + queryLength);\n const caret = leftSide.length + insertText.length;\n\n // set our value and our new caret\n ele.value = leftSide + insertText + remaining;\n ele.setSelectionRange(caret, caret);\n\n // now scroll our text box if necessary\n const position = getCursorXY(ele, caret);\n if (position.left > ele.width) {\n ele.scrollLeft = position.left;\n }\n\n ele.dispatchEvent(new Event('input'));\n }\n};\n\nexport const executeCompletionQuery = (\n ele: HTMLInputElement,\n session: boolean\n): CompletionResult => {\n const result: CompletionResult = {\n currentFunction: null,\n options: [],\n anchorPosition: null,\n query: null\n };\n\n if (!ele) {\n return;\n }\n\n const store = getStore();\n\n // we need a store to do anything useful\n if (!store) {\n return result;\n }\n\n const cursor = ele.selectionStart;\n const input = ele.value.substring(0, cursor);\n\n const parser = session ? sessionParser : messageParser;\n const expressions = parser.findExpressions(input);\n const currentExpression = expressions.find(\n (expr: Expression) =>\n expr.start <= cursor &&\n (expr.end > cursor || (expr.end === cursor && !expr.closed))\n );\n\n if (currentExpression) {\n const includeFunctions = currentExpression.text.indexOf('(') > -1;\n if (includeFunctions) {\n const functionQuery = parser.functionContext(currentExpression.text);\n if (functionQuery) {\n const fns = getFunctions(store.getFunctions(), functionQuery);\n if (fns.length > 0) {\n result.currentFunction = fns[0];\n }\n }\n }\n\n for (let i = currentExpression.text.length; i >= 0; i--) {\n const curr = currentExpression.text[i];\n if (\n curr === '@' ||\n curr === '(' ||\n curr === ' ' ||\n curr === ',' ||\n curr === ')' ||\n i === 0\n ) {\n // don't include non-expression chars\n if (\n curr === '(' ||\n curr === ' ' ||\n curr === ',' ||\n curr === ')' ||\n curr === '@'\n ) {\n i++;\n }\n\n const caret = getCursorXY(ele, currentExpression.start + i);\n\n result.anchorPosition = {\n left: caret.left - 2 - ele.scrollLeft,\n top: caret.top - ele.scrollTop\n };\n\n result.query = currentExpression.text.substr(\n i,\n currentExpression.text.length - i\n );\n\n result.options = [\n ...getCompletions(\n store.getCompletionSchema(),\n result.query,\n\n session,\n store\n ),\n ...(includeFunctions\n ? getFunctions(store.getFunctions(), result.query)\n : [])\n ];\n\n return result;\n }\n }\n } else {\n result.options = [];\n result.query = '';\n }\n return result;\n};\n"]}
@@ -826,17 +826,35 @@ export class CanvasNode extends RapidElement {
826
826
  : ''}"
827
827
  style="left:${this.ui.position.left}px;top:${this.ui.position.top}px"
828
828
  >
829
- ${this.node.actions.length > 0
830
- ? this.ui.type === 'execute_actions'
831
- ? html `<temba-sortable-list
829
+ ${nodeConfig && nodeConfig.render
830
+ ? html `<div class="router" style="position: relative;">
831
+ <button
832
+ class="remove-button"
833
+ @click=${(e) => this.handleNodeRemoveClick(e)}
834
+ title="Remove node"
835
+ >
836
+
837
+ </button>
838
+ <div
839
+ @mousedown=${(e) => this.handleNodeMouseDown(e)}
840
+ @mouseup=${(e) => this.handleNodeMouseUp(e)}
841
+ style="cursor: pointer;"
842
+ >
843
+ ${this.renderNodeTitle(nodeConfig, this.actionRemovingState.has(this.node.uuid))}
844
+ ${nodeConfig.render(this.node)}
845
+ </div>
846
+ </div>`
847
+ : this.node.actions.length > 0
848
+ ? this.ui.type === 'execute_actions'
849
+ ? html `<temba-sortable-list
832
850
  dragHandle="drag-handle"
833
851
  @temba-order-changed="${this.handleActionOrderChanged}"
834
852
  >
835
853
  ${repeat(this.node.actions, (action) => action.uuid, (action, index) => this.renderAction(this.node, action, index))}
836
854
  </temba-sortable-list>`
837
- : html `${repeat(this.node.actions, (action) => action.uuid, (action, index) => this.renderAction(this.node, action, index))}`
838
- : !this.node.router && nodeConfig && nodeConfig.name
839
- ? html `<div class="router" style="position: relative;">
855
+ : html `${repeat(this.node.actions, (action) => action.uuid, (action, index) => this.renderAction(this.node, action, index))}`
856
+ : !this.node.router && nodeConfig && nodeConfig.name
857
+ ? html `<div class="router" style="position: relative;">
840
858
  <button
841
859
  class="remove-button"
842
860
  @click=${(e) => this.handleNodeRemoveClick(e)}
@@ -846,7 +864,7 @@ export class CanvasNode extends RapidElement {
846
864
  </button>
847
865
  ${this.renderNodeTitle(nodeConfig, this.actionRemovingState.has(this.node.uuid))}
848
866
  </div>`
849
- : ''}
867
+ : ''}
850
868
  ${this.node.router
851
869
  ? html ` ${this.renderRouter(this.node.router, this.ui)}
852
870
  ${this.renderCategories(this.node)}`
@@ -1 +1 @@
1
- {"version":3,"file":"CanvasNode.js","sourceRoot":"","sources":["../../../src/flow/CanvasNode.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { ACTION_CONFIG, ActionConfig, NODE_CONFIG, NodeConfig } from './config';\nimport { Action, Exit, Node, NodeUI, Router } from '../store/flow-definition';\nimport { property } from 'lit/decorators.js';\nimport { RapidElement } from '../RapidElement';\nimport { getClasses } from '../utils';\nimport { Plumber } from './Plumber';\nimport { getStore } from '../store/Store';\nimport { CustomEventType } from '../interfaces';\n\nconst DRAG_THRESHOLD = 5;\n\nexport class CanvasNode extends RapidElement {\n createRenderRoot() {\n return this;\n }\n\n @property({ type: Object })\n private plumber: Plumber;\n\n @property({ type: Object })\n private node: Node;\n\n @property({ type: Object })\n private ui: NodeUI;\n\n // Track exits that are in \"removing\" state\n private exitRemovalTimeouts: Map<string, number> = new Map();\n\n // Set of exit UUIDs that are in the removing state\n private exitRemovingState: Set<string> = new Set();\n\n // Track actions that are in \"removing\" state\n private actionRemovalTimeouts: Map<string, number> = new Map();\n\n // Set of action UUIDs that are in the removing state\n private actionRemovingState: Set<string> = new Set();\n\n // Track action click state to distinguish from drag\n private actionClickStartPos: { x: number; y: number } | null = null;\n private pendingActionClick: { action: Action; event: MouseEvent } | null =\n null;\n\n // Track node click state to distinguish from drag\n private nodeClickStartPos: { x: number; y: number } | null = null;\n private pendingNodeClick: { event: MouseEvent } | null = null;\n\n static get styles() {\n return css`\n\n .node {\n background-color: #fff;\n box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\n min-width: 200px;\n border-radius: var(--curvature);\n \n color: #333;\n cursor: move;\n user-select: none;\n\n }\n\n /* Cap width for execute_actions nodes */\n .node.execute-actions {\n max-width: 200px;\n }\n\n .node:hover {\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);\n }\n\n .node.dragging {\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.4);\n transform: scale(1.02);\n z-index: 1000;\n }\n\n .action {\n position: relative;\n font-size: 13px;\n }\n\n .action .remove-button {\n position: absolute;\n top: 5px;\n right: 5px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--color-error, #dc3545);\n color: white;\n border: none;\n cursor: pointer;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n line-height: 1;\n z-index: 10;\n }\n\n .action:hover .remove-button,\n .router:hover .remove-button {\n display: flex;\n }\n\n .action.removing .title,\n .router .title.removing {\n background-color: var(--color-error, #dc3545) !important;\n }\n\n .action.removing .title .name,\n .router .title.removing .name {\n color: white;\n }\n\n .router .remove-button {\n position: absolute;\n top: 5px;\n right: 5px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--color-error, #dc3545);\n color: white;\n border: none;\n cursor: pointer;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n line-height: 1;\n z-index: 10;\n }\n\n .action.sortable {\n display: flex;\n align-items: stretch;\n }\n\n .action .action-content {\n flex-grow: 1;\n display: flex;\n flex-direction: column;\n min-width: 0; /* Allow flex item to shrink below its content size */\n overflow: hidden;\n }\n\n .action .body {\n padding: 0.75em;\n word-wrap: break-word;\n overflow-wrap: break-word;\n hyphens: auto;\n white-space: normal;\n overflow: hidden;\n }\n\n .node.execute-actions temba-sortable-list .action:last-child .body {\n padding-bottom: 1.5em;\n } \n\n .action .drag-handle {\n opacity: 0;\n transition: all 200ms ease-in-out;\n cursor: move;\n background: rgba(0, 0, 0, 0.02);\n max-width:0px;\n position: absolute;\n }\n\n .action:hover .drag-handle {\n opacity: 0.5;\n padding: 0.25em;\n max-width: 20px;\n }\n\n .action .drag-handle:hover {\n opacity: 1;\n \n }\n\n .action .title,\n .router .title {\n display: flex;\n color: #fff;\n padding: 5px 1px;\n text-align: center;\n font-size: 1em;\n font-weight: normal;\n\n }\n\n .title .name {\n flex-grow: 1;\n }\n\n .quick-replies {\n margin-top: 0.5em;\n }\n\n .quick-reply {\n background-color: #f0f0f0;\n border: 1px solid #e0e0e0;\n border-radius: calc(var(--curvature) * 1.5);\n padding: 0.2em 1em;\n display: inline-block;\n font-size: 0.8em;\n margin: 0.2em;\n }\n\n .categories {\n display: flex;\n flex-direction: row;\n\n }\n\n .category {\n margin:-1px -0.5px;\n border: 1px solid #f3f3f3;\n padding: 0.75em;\n flex-grow:1;\n text-align: center;\n display: flex;\n flex-direction: column;\n }\n\n .action-exits {\n padding-bottom: 0.6em;\n margin-top: -0.8em;\n }\n\n .category .title {\n font-weight: normal;\n font-size: 1em;\n max-width: 150px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .router .body {\n padding: 0.75em;\n }\n\n .result-name {\n font-weight: bold;\n display: inline-block;\n }\n \n .exit-wrapper {\n display: flex;\n justify-content: center;\n align-items: center;\n position: relative;\n margin-bottom: -1.2em;\n padding-top:0.2em;\n }\n\n .exit {\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background-color: tomato;\n position: relative;\n box-shadow: 0 2px 2px rgba(0, 0, 0, .1);\n cursor: pointer;\n pointer-events: none;\n }\n\n .exit.jtk-connected {\n background: var(--color-connectors, #e6e6e6);\n }\n\n .exit.connected {\n background-color: #fff;\n pointer-events: all;\n }\n\n .exit.connected:hover {\n background-color: var(--color-connectors, #e6e6e6);\n }\n \n .exit.removing, .exit.removing:hover {\n background-color: var(--color-error);\n pointer-events: all;\n }\n \n .exit.removing::before {\n content: '✕';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 8px;\n color: white;\n line-height: 1;\n }\n \n /* Connector in removing state */\n :host {\n --color-connector-removing: var(--color-error);\n }\n \n body svg.plumb-connector.removing path {\n stroke: var(--color-connector-removing, tomato) !important;\n stroke-width: 3px;\n }\n \n body .plumb-connector.removing .plumb-arrow {\n fill: var(--color-connector-removing, tomato) !important;\n stroke: var(--color-connector-removing, transparent) !important;\n }\n\n .category:first-child {\n border-bottom-left-radius: var(--curvature);\n }\n\n .category:last-child {\n border-bottom-right-radius: var(--curvature);\n }\n\n .router .title {\n border-top-left-radius: var(--curvature);\n border-top-right-radius: var(--curvature);\n }\n\n .action{\n overflow: hidden;\n }\n\n .action:first-child .title {\n border-top-left-radius: var(--curvature);\n border-top-right-radius: var(--curvature);\n }\n }`;\n }\n\n constructor() {\n super();\n this.handleActionOrderChanged = this.handleActionOrderChanged.bind(this);\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('node')) {\n // Only proceed if plumber is available (for tests that don't set it up)\n if (this.plumber) {\n this.plumber.removeNodeConnections(this.node.uuid);\n // make our initial connections\n for (const exit of this.node.exits) {\n if (!exit.destination_uuid) {\n // if we have no destination, then we are a source\n // so make our source endpoint\n this.plumber.makeSource(exit.uuid);\n } else {\n this.plumber.connectIds(\n this.node.uuid,\n exit.uuid,\n exit.destination_uuid\n );\n }\n }\n\n this.plumber.revalidate([this.node.uuid]);\n }\n\n const ele = this.parentElement;\n if (ele) {\n const rect = ele.getBoundingClientRect();\n\n getStore()\n ?.getState()\n .expandCanvas(\n this.ui.position.left + rect.width,\n this.ui.position.top + rect.height\n );\n }\n }\n }\n\n disconnectedCallback() {\n // Remove the event listener when the component is removed\n super.disconnectedCallback();\n\n // Clear any pending exit removal timeouts\n this.exitRemovalTimeouts.forEach((timeoutId) => {\n clearTimeout(timeoutId);\n });\n this.exitRemovalTimeouts.clear();\n\n // Clear any pending action removal timeouts\n this.actionRemovalTimeouts.forEach((timeoutId) => {\n clearTimeout(timeoutId);\n });\n this.actionRemovalTimeouts.clear();\n\n // Clear the removing state\n this.exitRemovingState.clear();\n this.actionRemovingState.clear();\n }\n\n private handleExitClick(event: MouseEvent, exit: Exit) {\n event.preventDefault();\n event.stopPropagation();\n\n const exitId = exit.uuid;\n\n // If exit is not connected, do nothing\n if (!exit.destination_uuid) return;\n\n // If the exit is already in removing state, perform the disconnect\n if (this.exitRemovingState.has(exitId)) {\n this.disconnectExit(exit);\n return;\n }\n\n // Start removal UI state\n this.exitRemovingState.add(exitId);\n this.requestUpdate();\n\n // Set the connection to removing state\n this.plumber.setConnectionRemovingState(exitId, true);\n\n // Clear any existing timeout for this exit\n if (this.exitRemovalTimeouts.has(exitId)) {\n clearTimeout(this.exitRemovalTimeouts.get(exitId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.exitRemovingState.delete(exitId);\n this.exitRemovalTimeouts.delete(exitId);\n\n // Reset the connection to normal state\n this.plumber.setConnectionRemovingState(exitId, false);\n\n this.requestUpdate();\n }, 1500);\n\n this.exitRemovalTimeouts.set(exitId, timeoutId);\n }\n\n private disconnectExit(exit: Exit) {\n const exitId = exit.uuid;\n\n // Clear the UI state\n this.exitRemovingState.delete(exitId);\n\n // Reset the connection to normal state (this will be redundant as we're about to remove it,\n // but it's safer to do this in case there's any timing issue)\n this.plumber.setConnectionRemovingState(exitId, false);\n\n // Clear any timeout\n if (this.exitRemovalTimeouts.has(exitId)) {\n clearTimeout(this.exitRemovalTimeouts.get(exitId));\n this.exitRemovalTimeouts.delete(exitId);\n }\n\n // Remove the JSPlumb connection\n this.plumber.removeExitConnection(exitId);\n\n // Update the flow definition\n const updatedExit = { ...exit, destination_uuid: null };\n const updatedExits = this.node.exits.map((e) =>\n e.uuid === exitId ? updatedExit : e\n );\n\n // Update the node\n const updatedNode = { ...this.node, exits: updatedExits };\n getStore()?.getState().updateNode(this.node.uuid, updatedNode);\n\n // Request update to reflect changes\n this.requestUpdate();\n }\n\n private handleActionRemoveClick(\n event: MouseEvent,\n action: Action,\n index: number\n ) {\n event.preventDefault();\n event.stopPropagation();\n\n const actionId = action.uuid;\n\n // If the action is already in removing state, perform the removal\n if (this.actionRemovingState.has(actionId)) {\n this.removeAction(action, index);\n return;\n }\n\n // Start removal UI state\n this.actionRemovingState.add(actionId);\n this.requestUpdate();\n\n // Clear any existing timeout for this action\n if (this.actionRemovalTimeouts.has(actionId)) {\n clearTimeout(this.actionRemovalTimeouts.get(actionId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.actionRemovingState.delete(actionId);\n this.actionRemovalTimeouts.delete(actionId);\n this.requestUpdate();\n }, 1000); // 1 second as per requirements\n\n this.actionRemovalTimeouts.set(actionId, timeoutId);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n private removeAction(action: Action, _index: number) {\n const actionId = action.uuid;\n\n // Clear the UI state\n this.actionRemovingState.delete(actionId);\n\n // Clear any timeout\n if (this.actionRemovalTimeouts.has(actionId)) {\n clearTimeout(this.actionRemovalTimeouts.get(actionId));\n this.actionRemovalTimeouts.delete(actionId);\n }\n\n // Remove the action from the node\n const updatedActions = this.node.actions.filter((a) => a.uuid !== actionId);\n\n // If no actions remain, remove the entire node\n if (updatedActions.length === 0) {\n this.fireCustomEvent(CustomEventType.NodeDeleted, {\n uuid: this.node.uuid\n });\n } else {\n // Update the node with remaining actions\n const updatedNode = { ...this.node, actions: updatedActions };\n getStore()?.getState().updateNode(this.node.uuid, updatedNode);\n\n // Request update to reflect changes\n this.requestUpdate();\n }\n }\n\n private handleNodeRemoveClick(event: MouseEvent) {\n event.preventDefault();\n event.stopPropagation();\n\n const nodeId = this.node.uuid;\n\n // If the node is already in removing state, perform the removal\n if (this.actionRemovingState.has(nodeId)) {\n this.removeNode();\n return;\n }\n\n // Start removal UI state\n this.actionRemovingState.add(nodeId);\n this.requestUpdate();\n\n // Clear any existing timeout for this node\n if (this.actionRemovalTimeouts.has(nodeId)) {\n clearTimeout(this.actionRemovalTimeouts.get(nodeId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.actionRemovingState.delete(nodeId);\n this.actionRemovalTimeouts.delete(nodeId);\n this.requestUpdate();\n }, 1000); // 1 second as per requirements\n\n this.actionRemovalTimeouts.set(nodeId, timeoutId);\n }\n\n private removeNode() {\n const nodeId = this.node.uuid;\n\n // Clear the UI state\n this.actionRemovingState.delete(nodeId);\n\n // Clear any timeout\n if (this.actionRemovalTimeouts.has(nodeId)) {\n clearTimeout(this.actionRemovalTimeouts.get(nodeId));\n this.actionRemovalTimeouts.delete(nodeId);\n }\n\n // Fire the node deleted event\n this.fireCustomEvent(CustomEventType.NodeDeleted, {\n uuid: this.node.uuid\n });\n }\n\n private handleActionOrderChanged(event: CustomEvent) {\n const [fromIdx, toIdx] = event.detail.swap;\n\n // swap our actions\n const newActions = [...this.node.actions];\n const movedAction = newActions.splice(fromIdx, 1)[0];\n newActions.splice(toIdx, 0, movedAction);\n\n // udate our internal reprensentation, this isn't strictly necessary\n // since the editor will update us from it's definition subscription\n // but it makes testing a lot easier\n this.node = { ...this.node, actions: newActions };\n\n getStore()\n ?.getState()\n .updateNode(this.node.uuid, { ...this.node, actions: newActions });\n }\n\n private handleActionMouseDown(event: MouseEvent, action: Action): void {\n // Don't handle clicks on the remove button or when action is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(action.uuid)\n ) {\n return;\n }\n\n // Store the starting position and action for later comparison\n // Don't prevent default - let the Editor's drag system work normally\n this.actionClickStartPos = { x: event.clientX, y: event.clientY };\n this.pendingActionClick = { action, event };\n }\n\n private handleActionMouseUp(event: MouseEvent, action: Action): void {\n // Don't handle if we don't have a pending click or if it's not the same action\n if (\n !this.pendingActionClick ||\n this.pendingActionClick.action.uuid !== action.uuid\n ) {\n this.actionClickStartPos = null;\n this.pendingActionClick = null;\n return;\n }\n\n // Don't handle clicks on the remove button or when action is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(action.uuid)\n ) {\n this.actionClickStartPos = null;\n this.pendingActionClick = null;\n return;\n }\n\n // Check if the mouse moved beyond the drag threshold\n if (this.actionClickStartPos) {\n const deltaX = event.clientX - this.actionClickStartPos.x;\n const deltaY = event.clientY - this.actionClickStartPos.y;\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n\n // Check if the Editor is currently in dragging mode\n const editor = this.closest('temba-flow-editor') as any;\n const editorWasDragging = editor?.dragging;\n\n // Only fire the action edit event if we haven't dragged beyond the threshold\n // AND either there's no Editor parent (test case) or the Editor didn't drag the node\n if (distance <= DRAG_THRESHOLD && (!editor || !editorWasDragging)) {\n // Fire event to request action editing\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action,\n nodeUuid: this.node.uuid\n });\n }\n }\n\n // Clean up\n this.actionClickStartPos = null;\n this.pendingActionClick = null;\n }\n\n private handleActionClick(event: MouseEvent, action: Action): void {\n // This method is kept for backward compatibility but should not be used\n // The new mousedown/mouseup approach handles click vs drag properly\n event.preventDefault();\n event.stopPropagation();\n\n // Don't handle clicks on the remove button or when action is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(action.uuid)\n ) {\n return;\n }\n\n // Fire event to request action editing\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action,\n nodeUuid: this.node.uuid\n });\n }\n\n private handleNodeEditClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n // Don't handle clicks on the remove button or when node is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(this.node.uuid)\n ) {\n return;\n }\n\n // Fire node edit requested event if the node has a router\n if (this.node.router) {\n // If router node has exactly one action, open the action editor directly\n if (this.node.actions && this.node.actions.length === 1) {\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action: this.node.actions[0],\n nodeUuid: this.node.uuid\n });\n } else {\n // Otherwise open the node editor as before\n this.fireCustomEvent(CustomEventType.NodeEditRequested, {\n node: this.node,\n nodeUI: this.ui\n });\n }\n }\n }\n\n private handleNodeMouseDown(event: MouseEvent): void {\n // Don't handle clicks on the remove button, exits, or when node is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n target.closest('.exit') ||\n target.closest('.exit-wrapper') ||\n this.actionRemovingState.has(this.node.uuid)\n ) {\n return;\n }\n\n // Store the starting position for later comparison\n // Don't prevent default - let the Editor's drag system work normally\n this.nodeClickStartPos = { x: event.clientX, y: event.clientY };\n this.pendingNodeClick = { event };\n }\n\n private handleNodeMouseUp(event: MouseEvent): void {\n // Don't handle if we don't have a pending click\n if (!this.pendingNodeClick) {\n this.nodeClickStartPos = null;\n this.pendingNodeClick = null;\n return;\n }\n\n // Don't handle clicks on the remove button, exits, or when node is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n target.closest('.exit') ||\n target.closest('.exit-wrapper') ||\n this.actionRemovingState.has(this.node.uuid)\n ) {\n this.nodeClickStartPos = null;\n this.pendingNodeClick = null;\n return;\n }\n\n // Check if the mouse moved beyond the drag threshold\n if (this.nodeClickStartPos) {\n const deltaX = event.clientX - this.nodeClickStartPos.x;\n const deltaY = event.clientY - this.nodeClickStartPos.y;\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n\n // Check if the Editor is currently in dragging mode\n const editor = this.closest('temba-flow-editor') as any;\n const editorWasDragging = editor?.dragging;\n\n // Only fire the node edit event if we haven't dragged beyond the threshold\n // AND either there's no Editor parent (test case) or the Editor didn't drag the node\n if (distance <= 5 && (!editor || !editorWasDragging)) {\n // Using literal 5 instead of DRAG_THRESHOLD since it's not imported\n // Fire event to request node editing if the node has a router\n if (this.node.router) {\n // If router node has exactly one action, open the action editor directly\n if (this.node.actions && this.node.actions.length === 1) {\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action: this.node.actions[0],\n nodeUuid: this.node.uuid\n });\n } else {\n // Otherwise open the node editor as before\n this.fireCustomEvent(CustomEventType.NodeEditRequested, {\n node: this.node,\n nodeUI: this.ui\n });\n }\n }\n }\n }\n\n // Clean up\n this.nodeClickStartPos = null;\n this.pendingNodeClick = null;\n }\n\n private renderTitle(config: ActionConfig, isRemoving: boolean = false) {\n return html`<div class=\"title\" style=\"background:${config.color}\">\n ${this.node?.actions?.length > 1\n ? html`<temba-icon class=\"drag-handle\" name=\"sort\"></temba-icon>`\n : null}\n\n <div class=\"name\">${isRemoving ? 'Remove?' : config.name}</div>\n </div>`;\n }\n\n private renderNodeTitle(config: NodeConfig, isRemoving: boolean = false) {\n return html`<div\n class=\"title ${isRemoving ? 'removing' : ''}\"\n style=\"background:${config.color}\"\n >\n <div class=\"name\">${isRemoving ? 'Remove?' : config.name}</div>\n </div>`;\n }\n\n private renderAction(node: Node, action: Action, index: number) {\n const config = ACTION_CONFIG[action.type];\n const isRemoving = this.actionRemovingState.has(action.uuid);\n\n if (config) {\n return html`<div\n class=\"action sortable ${action.type} ${isRemoving ? 'removing' : ''}\"\n id=\"action-${index}\"\n >\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) =>\n this.handleActionRemoveClick(e, action, index)}\n title=\"Remove action\"\n >\n ✕\n </button>\n <div\n class=\"action-content\"\n @mousedown=${(e: MouseEvent) => this.handleActionMouseDown(e, action)}\n @mouseup=${(e: MouseEvent) => this.handleActionMouseUp(e, action)}\n style=\"cursor: pointer;\"\n >\n ${this.renderTitle(config, isRemoving)}\n <div class=\"body\">\n ${config.render\n ? config.render(node, action)\n : html`<pre>${action.type}</pre>`}\n </div>\n </div>\n </div>`;\n }\n return html`<div\n class=\"action sortable ${isRemoving ? 'removing' : ''}\"\n id=\"action-${index}\"\n >\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) =>\n this.handleActionRemoveClick(e, action, index)}\n title=\"Remove action\"\n >\n ✕\n </button>\n ${action.type}\n </div>`;\n }\n\n private renderRouter(router: Router, ui: NodeUI) {\n const nodeConfig = NODE_CONFIG[ui.type];\n if (nodeConfig) {\n // For tests that call renderRouter directly without setting this.node\n const hasActions = this.node ? this.node.actions.length > 0 : false;\n const isRemoving =\n this.node &&\n this.node.actions.length === 0 &&\n this.actionRemovingState.has(this.node.uuid);\n\n return html`<div class=\"router\" style=\"position: relative;\">\n ${!hasActions\n ? html` <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) => this.handleNodeRemoveClick(e)}\n title=\"Remove node\"\n >\n ✕\n </button>\n <div\n @mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}\n @mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}\n style=\"cursor: pointer;\"\n >\n ${this.renderNodeTitle(nodeConfig, isRemoving)}\n </div>`\n : ''}\n ${router.result_name\n ? html`<div\n class=\"body\"\n @mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}\n @mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}\n style=\"cursor: pointer;\"\n >\n Save as\n <div class=\"result-name\">${router.result_name}</div>\n </div>`\n : null}\n </div>`;\n }\n }\n\n private renderCategories(node: Node) {\n if (!node.router || !node.router.categories) {\n return null;\n }\n\n return html`<div class=\"categories\">\n ${repeat(\n node.router.categories,\n (category) => category.uuid,\n (category) => {\n const exit = node.exits.find(\n (exit: Exit) => exit.uuid == category.exit_uuid\n );\n\n return html`<div\n class=\"category\"\n @mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}\n @mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}\n style=\"cursor: pointer;\"\n >\n <div class=\"title\">${category.name}</div>\n ${this.renderExit(exit)}\n </div>`;\n }\n )}\n </div>`;\n }\n\n private renderExit(exit: Exit): TemplateResult {\n return html`<div class=\"exit-wrapper\">\n <div\n id=\"${exit.uuid}\"\n class=${getClasses({\n exit: true,\n connected: !!exit.destination_uuid,\n removing: this.exitRemovingState.has(exit.uuid)\n })}\n @click=${(e: MouseEvent) => this.handleExitClick(e, exit)}\n ></div>\n </div>`;\n }\n\n public render() {\n if (!this.node || !this.ui) {\n return html`<div class=\"node\">Loading...</div>`;\n }\n\n const nodeConfig = NODE_CONFIG[this.ui.type];\n\n return html`\n <div\n id=\"${this.node.uuid}\"\n class=\"node ${this.ui.type === 'execute_actions'\n ? 'execute-actions'\n : ''}\"\n style=\"left:${this.ui.position.left}px;top:${this.ui.position.top}px\"\n >\n ${this.node.actions.length > 0\n ? this.ui.type === 'execute_actions'\n ? html`<temba-sortable-list\n dragHandle=\"drag-handle\"\n @temba-order-changed=\"${this.handleActionOrderChanged}\"\n >\n ${repeat(\n this.node.actions,\n (action) => action.uuid,\n (action, index) => this.renderAction(this.node, action, index)\n )}\n </temba-sortable-list>`\n : html`${repeat(\n this.node.actions,\n (action) => action.uuid,\n (action, index) => this.renderAction(this.node, action, index)\n )}`\n : !this.node.router && nodeConfig && nodeConfig.name\n ? html`<div class=\"router\" style=\"position: relative;\">\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) => this.handleNodeRemoveClick(e)}\n title=\"Remove node\"\n >\n ✕\n </button>\n ${this.renderNodeTitle(\n nodeConfig,\n this.actionRemovingState.has(this.node.uuid)\n )}\n </div>`\n : ''}\n ${this.node.router\n ? html` ${this.renderRouter(this.node.router, this.ui)}\n ${this.renderCategories(this.node)}`\n : html`<div class=\"action-exits\">\n ${repeat(\n this.node.exits,\n (exit) => exit.uuid,\n (exit) => this.renderExit(exit)\n )}\n </div>`}\n </div>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"CanvasNode.js","sourceRoot":"","sources":["../../../src/flow/CanvasNode.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { ACTION_CONFIG, ActionConfig, NODE_CONFIG, NodeConfig } from './config';\nimport { Action, Exit, Node, NodeUI, Router } from '../store/flow-definition';\nimport { property } from 'lit/decorators.js';\nimport { RapidElement } from '../RapidElement';\nimport { getClasses } from '../utils';\nimport { Plumber } from './Plumber';\nimport { getStore } from '../store/Store';\nimport { CustomEventType } from '../interfaces';\n\nconst DRAG_THRESHOLD = 5;\n\nexport class CanvasNode extends RapidElement {\n createRenderRoot() {\n return this;\n }\n\n @property({ type: Object })\n private plumber: Plumber;\n\n @property({ type: Object })\n private node: Node;\n\n @property({ type: Object })\n private ui: NodeUI;\n\n // Track exits that are in \"removing\" state\n private exitRemovalTimeouts: Map<string, number> = new Map();\n\n // Set of exit UUIDs that are in the removing state\n private exitRemovingState: Set<string> = new Set();\n\n // Track actions that are in \"removing\" state\n private actionRemovalTimeouts: Map<string, number> = new Map();\n\n // Set of action UUIDs that are in the removing state\n private actionRemovingState: Set<string> = new Set();\n\n // Track action click state to distinguish from drag\n private actionClickStartPos: { x: number; y: number } | null = null;\n private pendingActionClick: { action: Action; event: MouseEvent } | null =\n null;\n\n // Track node click state to distinguish from drag\n private nodeClickStartPos: { x: number; y: number } | null = null;\n private pendingNodeClick: { event: MouseEvent } | null = null;\n\n static get styles() {\n return css`\n\n .node {\n background-color: #fff;\n box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\n min-width: 200px;\n border-radius: var(--curvature);\n \n color: #333;\n cursor: move;\n user-select: none;\n\n }\n\n /* Cap width for execute_actions nodes */\n .node.execute-actions {\n max-width: 200px;\n }\n\n .node:hover {\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);\n }\n\n .node.dragging {\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.4);\n transform: scale(1.02);\n z-index: 1000;\n }\n\n .action {\n position: relative;\n font-size: 13px;\n }\n\n .action .remove-button {\n position: absolute;\n top: 5px;\n right: 5px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--color-error, #dc3545);\n color: white;\n border: none;\n cursor: pointer;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n line-height: 1;\n z-index: 10;\n }\n\n .action:hover .remove-button,\n .router:hover .remove-button {\n display: flex;\n }\n\n .action.removing .title,\n .router .title.removing {\n background-color: var(--color-error, #dc3545) !important;\n }\n\n .action.removing .title .name,\n .router .title.removing .name {\n color: white;\n }\n\n .router .remove-button {\n position: absolute;\n top: 5px;\n right: 5px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--color-error, #dc3545);\n color: white;\n border: none;\n cursor: pointer;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n line-height: 1;\n z-index: 10;\n }\n\n .action.sortable {\n display: flex;\n align-items: stretch;\n }\n\n .action .action-content {\n flex-grow: 1;\n display: flex;\n flex-direction: column;\n min-width: 0; /* Allow flex item to shrink below its content size */\n overflow: hidden;\n }\n\n .action .body {\n padding: 0.75em;\n word-wrap: break-word;\n overflow-wrap: break-word;\n hyphens: auto;\n white-space: normal;\n overflow: hidden;\n }\n\n .node.execute-actions temba-sortable-list .action:last-child .body {\n padding-bottom: 1.5em;\n } \n\n .action .drag-handle {\n opacity: 0;\n transition: all 200ms ease-in-out;\n cursor: move;\n background: rgba(0, 0, 0, 0.02);\n max-width:0px;\n position: absolute;\n }\n\n .action:hover .drag-handle {\n opacity: 0.5;\n padding: 0.25em;\n max-width: 20px;\n }\n\n .action .drag-handle:hover {\n opacity: 1;\n \n }\n\n .action .title,\n .router .title {\n display: flex;\n color: #fff;\n padding: 5px 1px;\n text-align: center;\n font-size: 1em;\n font-weight: normal;\n\n }\n\n .title .name {\n flex-grow: 1;\n }\n\n .quick-replies {\n margin-top: 0.5em;\n }\n\n .quick-reply {\n background-color: #f0f0f0;\n border: 1px solid #e0e0e0;\n border-radius: calc(var(--curvature) * 1.5);\n padding: 0.2em 1em;\n display: inline-block;\n font-size: 0.8em;\n margin: 0.2em;\n }\n\n .categories {\n display: flex;\n flex-direction: row;\n\n }\n\n .category {\n margin:-1px -0.5px;\n border: 1px solid #f3f3f3;\n padding: 0.75em;\n flex-grow:1;\n text-align: center;\n display: flex;\n flex-direction: column;\n }\n\n .action-exits {\n padding-bottom: 0.6em;\n margin-top: -0.8em;\n }\n\n .category .title {\n font-weight: normal;\n font-size: 1em;\n max-width: 150px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .router .body {\n padding: 0.75em;\n }\n\n .result-name {\n font-weight: bold;\n display: inline-block;\n }\n \n .exit-wrapper {\n display: flex;\n justify-content: center;\n align-items: center;\n position: relative;\n margin-bottom: -1.2em;\n padding-top:0.2em;\n }\n\n .exit {\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background-color: tomato;\n position: relative;\n box-shadow: 0 2px 2px rgba(0, 0, 0, .1);\n cursor: pointer;\n pointer-events: none;\n }\n\n .exit.jtk-connected {\n background: var(--color-connectors, #e6e6e6);\n }\n\n .exit.connected {\n background-color: #fff;\n pointer-events: all;\n }\n\n .exit.connected:hover {\n background-color: var(--color-connectors, #e6e6e6);\n }\n \n .exit.removing, .exit.removing:hover {\n background-color: var(--color-error);\n pointer-events: all;\n }\n \n .exit.removing::before {\n content: '✕';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 8px;\n color: white;\n line-height: 1;\n }\n \n /* Connector in removing state */\n :host {\n --color-connector-removing: var(--color-error);\n }\n \n body svg.plumb-connector.removing path {\n stroke: var(--color-connector-removing, tomato) !important;\n stroke-width: 3px;\n }\n \n body .plumb-connector.removing .plumb-arrow {\n fill: var(--color-connector-removing, tomato) !important;\n stroke: var(--color-connector-removing, transparent) !important;\n }\n\n .category:first-child {\n border-bottom-left-radius: var(--curvature);\n }\n\n .category:last-child {\n border-bottom-right-radius: var(--curvature);\n }\n\n .router .title {\n border-top-left-radius: var(--curvature);\n border-top-right-radius: var(--curvature);\n }\n\n .action{\n overflow: hidden;\n }\n\n .action:first-child .title {\n border-top-left-radius: var(--curvature);\n border-top-right-radius: var(--curvature);\n }\n }`;\n }\n\n constructor() {\n super();\n this.handleActionOrderChanged = this.handleActionOrderChanged.bind(this);\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('node')) {\n // Only proceed if plumber is available (for tests that don't set it up)\n if (this.plumber) {\n this.plumber.removeNodeConnections(this.node.uuid);\n // make our initial connections\n for (const exit of this.node.exits) {\n if (!exit.destination_uuid) {\n // if we have no destination, then we are a source\n // so make our source endpoint\n this.plumber.makeSource(exit.uuid);\n } else {\n this.plumber.connectIds(\n this.node.uuid,\n exit.uuid,\n exit.destination_uuid\n );\n }\n }\n\n this.plumber.revalidate([this.node.uuid]);\n }\n\n const ele = this.parentElement;\n if (ele) {\n const rect = ele.getBoundingClientRect();\n\n getStore()\n ?.getState()\n .expandCanvas(\n this.ui.position.left + rect.width,\n this.ui.position.top + rect.height\n );\n }\n }\n }\n\n disconnectedCallback() {\n // Remove the event listener when the component is removed\n super.disconnectedCallback();\n\n // Clear any pending exit removal timeouts\n this.exitRemovalTimeouts.forEach((timeoutId) => {\n clearTimeout(timeoutId);\n });\n this.exitRemovalTimeouts.clear();\n\n // Clear any pending action removal timeouts\n this.actionRemovalTimeouts.forEach((timeoutId) => {\n clearTimeout(timeoutId);\n });\n this.actionRemovalTimeouts.clear();\n\n // Clear the removing state\n this.exitRemovingState.clear();\n this.actionRemovingState.clear();\n }\n\n private handleExitClick(event: MouseEvent, exit: Exit) {\n event.preventDefault();\n event.stopPropagation();\n\n const exitId = exit.uuid;\n\n // If exit is not connected, do nothing\n if (!exit.destination_uuid) return;\n\n // If the exit is already in removing state, perform the disconnect\n if (this.exitRemovingState.has(exitId)) {\n this.disconnectExit(exit);\n return;\n }\n\n // Start removal UI state\n this.exitRemovingState.add(exitId);\n this.requestUpdate();\n\n // Set the connection to removing state\n this.plumber.setConnectionRemovingState(exitId, true);\n\n // Clear any existing timeout for this exit\n if (this.exitRemovalTimeouts.has(exitId)) {\n clearTimeout(this.exitRemovalTimeouts.get(exitId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.exitRemovingState.delete(exitId);\n this.exitRemovalTimeouts.delete(exitId);\n\n // Reset the connection to normal state\n this.plumber.setConnectionRemovingState(exitId, false);\n\n this.requestUpdate();\n }, 1500);\n\n this.exitRemovalTimeouts.set(exitId, timeoutId);\n }\n\n private disconnectExit(exit: Exit) {\n const exitId = exit.uuid;\n\n // Clear the UI state\n this.exitRemovingState.delete(exitId);\n\n // Reset the connection to normal state (this will be redundant as we're about to remove it,\n // but it's safer to do this in case there's any timing issue)\n this.plumber.setConnectionRemovingState(exitId, false);\n\n // Clear any timeout\n if (this.exitRemovalTimeouts.has(exitId)) {\n clearTimeout(this.exitRemovalTimeouts.get(exitId));\n this.exitRemovalTimeouts.delete(exitId);\n }\n\n // Remove the JSPlumb connection\n this.plumber.removeExitConnection(exitId);\n\n // Update the flow definition\n const updatedExit = { ...exit, destination_uuid: null };\n const updatedExits = this.node.exits.map((e) =>\n e.uuid === exitId ? updatedExit : e\n );\n\n // Update the node\n const updatedNode = { ...this.node, exits: updatedExits };\n getStore()?.getState().updateNode(this.node.uuid, updatedNode);\n\n // Request update to reflect changes\n this.requestUpdate();\n }\n\n private handleActionRemoveClick(\n event: MouseEvent,\n action: Action,\n index: number\n ) {\n event.preventDefault();\n event.stopPropagation();\n\n const actionId = action.uuid;\n\n // If the action is already in removing state, perform the removal\n if (this.actionRemovingState.has(actionId)) {\n this.removeAction(action, index);\n return;\n }\n\n // Start removal UI state\n this.actionRemovingState.add(actionId);\n this.requestUpdate();\n\n // Clear any existing timeout for this action\n if (this.actionRemovalTimeouts.has(actionId)) {\n clearTimeout(this.actionRemovalTimeouts.get(actionId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.actionRemovingState.delete(actionId);\n this.actionRemovalTimeouts.delete(actionId);\n this.requestUpdate();\n }, 1000); // 1 second as per requirements\n\n this.actionRemovalTimeouts.set(actionId, timeoutId);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n private removeAction(action: Action, _index: number) {\n const actionId = action.uuid;\n\n // Clear the UI state\n this.actionRemovingState.delete(actionId);\n\n // Clear any timeout\n if (this.actionRemovalTimeouts.has(actionId)) {\n clearTimeout(this.actionRemovalTimeouts.get(actionId));\n this.actionRemovalTimeouts.delete(actionId);\n }\n\n // Remove the action from the node\n const updatedActions = this.node.actions.filter((a) => a.uuid !== actionId);\n\n // If no actions remain, remove the entire node\n if (updatedActions.length === 0) {\n this.fireCustomEvent(CustomEventType.NodeDeleted, {\n uuid: this.node.uuid\n });\n } else {\n // Update the node with remaining actions\n const updatedNode = { ...this.node, actions: updatedActions };\n getStore()?.getState().updateNode(this.node.uuid, updatedNode);\n\n // Request update to reflect changes\n this.requestUpdate();\n }\n }\n\n private handleNodeRemoveClick(event: MouseEvent) {\n event.preventDefault();\n event.stopPropagation();\n\n const nodeId = this.node.uuid;\n\n // If the node is already in removing state, perform the removal\n if (this.actionRemovingState.has(nodeId)) {\n this.removeNode();\n return;\n }\n\n // Start removal UI state\n this.actionRemovingState.add(nodeId);\n this.requestUpdate();\n\n // Clear any existing timeout for this node\n if (this.actionRemovalTimeouts.has(nodeId)) {\n clearTimeout(this.actionRemovalTimeouts.get(nodeId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.actionRemovingState.delete(nodeId);\n this.actionRemovalTimeouts.delete(nodeId);\n this.requestUpdate();\n }, 1000); // 1 second as per requirements\n\n this.actionRemovalTimeouts.set(nodeId, timeoutId);\n }\n\n private removeNode() {\n const nodeId = this.node.uuid;\n\n // Clear the UI state\n this.actionRemovingState.delete(nodeId);\n\n // Clear any timeout\n if (this.actionRemovalTimeouts.has(nodeId)) {\n clearTimeout(this.actionRemovalTimeouts.get(nodeId));\n this.actionRemovalTimeouts.delete(nodeId);\n }\n\n // Fire the node deleted event\n this.fireCustomEvent(CustomEventType.NodeDeleted, {\n uuid: this.node.uuid\n });\n }\n\n private handleActionOrderChanged(event: CustomEvent) {\n const [fromIdx, toIdx] = event.detail.swap;\n\n // swap our actions\n const newActions = [...this.node.actions];\n const movedAction = newActions.splice(fromIdx, 1)[0];\n newActions.splice(toIdx, 0, movedAction);\n\n // udate our internal reprensentation, this isn't strictly necessary\n // since the editor will update us from it's definition subscription\n // but it makes testing a lot easier\n this.node = { ...this.node, actions: newActions };\n\n getStore()\n ?.getState()\n .updateNode(this.node.uuid, { ...this.node, actions: newActions });\n }\n\n private handleActionMouseDown(event: MouseEvent, action: Action): void {\n // Don't handle clicks on the remove button or when action is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(action.uuid)\n ) {\n return;\n }\n\n // Store the starting position and action for later comparison\n // Don't prevent default - let the Editor's drag system work normally\n this.actionClickStartPos = { x: event.clientX, y: event.clientY };\n this.pendingActionClick = { action, event };\n }\n\n private handleActionMouseUp(event: MouseEvent, action: Action): void {\n // Don't handle if we don't have a pending click or if it's not the same action\n if (\n !this.pendingActionClick ||\n this.pendingActionClick.action.uuid !== action.uuid\n ) {\n this.actionClickStartPos = null;\n this.pendingActionClick = null;\n return;\n }\n\n // Don't handle clicks on the remove button or when action is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(action.uuid)\n ) {\n this.actionClickStartPos = null;\n this.pendingActionClick = null;\n return;\n }\n\n // Check if the mouse moved beyond the drag threshold\n if (this.actionClickStartPos) {\n const deltaX = event.clientX - this.actionClickStartPos.x;\n const deltaY = event.clientY - this.actionClickStartPos.y;\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n\n // Check if the Editor is currently in dragging mode\n const editor = this.closest('temba-flow-editor') as any;\n const editorWasDragging = editor?.dragging;\n\n // Only fire the action edit event if we haven't dragged beyond the threshold\n // AND either there's no Editor parent (test case) or the Editor didn't drag the node\n if (distance <= DRAG_THRESHOLD && (!editor || !editorWasDragging)) {\n // Fire event to request action editing\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action,\n nodeUuid: this.node.uuid\n });\n }\n }\n\n // Clean up\n this.actionClickStartPos = null;\n this.pendingActionClick = null;\n }\n\n private handleActionClick(event: MouseEvent, action: Action): void {\n // This method is kept for backward compatibility but should not be used\n // The new mousedown/mouseup approach handles click vs drag properly\n event.preventDefault();\n event.stopPropagation();\n\n // Don't handle clicks on the remove button or when action is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(action.uuid)\n ) {\n return;\n }\n\n // Fire event to request action editing\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action,\n nodeUuid: this.node.uuid\n });\n }\n\n private handleNodeEditClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n // Don't handle clicks on the remove button or when node is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n this.actionRemovingState.has(this.node.uuid)\n ) {\n return;\n }\n\n // Fire node edit requested event if the node has a router\n if (this.node.router) {\n // If router node has exactly one action, open the action editor directly\n if (this.node.actions && this.node.actions.length === 1) {\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action: this.node.actions[0],\n nodeUuid: this.node.uuid\n });\n } else {\n // Otherwise open the node editor as before\n this.fireCustomEvent(CustomEventType.NodeEditRequested, {\n node: this.node,\n nodeUI: this.ui\n });\n }\n }\n }\n\n private handleNodeMouseDown(event: MouseEvent): void {\n // Don't handle clicks on the remove button, exits, or when node is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n target.closest('.exit') ||\n target.closest('.exit-wrapper') ||\n this.actionRemovingState.has(this.node.uuid)\n ) {\n return;\n }\n\n // Store the starting position for later comparison\n // Don't prevent default - let the Editor's drag system work normally\n this.nodeClickStartPos = { x: event.clientX, y: event.clientY };\n this.pendingNodeClick = { event };\n }\n\n private handleNodeMouseUp(event: MouseEvent): void {\n // Don't handle if we don't have a pending click\n if (!this.pendingNodeClick) {\n this.nodeClickStartPos = null;\n this.pendingNodeClick = null;\n return;\n }\n\n // Don't handle clicks on the remove button, exits, or when node is in removing state\n const target = event.target as HTMLElement;\n if (\n target.closest('.remove-button') ||\n target.closest('.exit') ||\n target.closest('.exit-wrapper') ||\n this.actionRemovingState.has(this.node.uuid)\n ) {\n this.nodeClickStartPos = null;\n this.pendingNodeClick = null;\n return;\n }\n\n // Check if the mouse moved beyond the drag threshold\n if (this.nodeClickStartPos) {\n const deltaX = event.clientX - this.nodeClickStartPos.x;\n const deltaY = event.clientY - this.nodeClickStartPos.y;\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n\n // Check if the Editor is currently in dragging mode\n const editor = this.closest('temba-flow-editor') as any;\n const editorWasDragging = editor?.dragging;\n\n // Only fire the node edit event if we haven't dragged beyond the threshold\n // AND either there's no Editor parent (test case) or the Editor didn't drag the node\n if (distance <= 5 && (!editor || !editorWasDragging)) {\n // Using literal 5 instead of DRAG_THRESHOLD since it's not imported\n // Fire event to request node editing if the node has a router\n if (this.node.router) {\n // If router node has exactly one action, open the action editor directly\n if (this.node.actions && this.node.actions.length === 1) {\n this.fireCustomEvent(CustomEventType.ActionEditRequested, {\n action: this.node.actions[0],\n nodeUuid: this.node.uuid\n });\n } else {\n // Otherwise open the node editor as before\n this.fireCustomEvent(CustomEventType.NodeEditRequested, {\n node: this.node,\n nodeUI: this.ui\n });\n }\n }\n }\n }\n\n // Clean up\n this.nodeClickStartPos = null;\n this.pendingNodeClick = null;\n }\n\n private renderTitle(config: ActionConfig, isRemoving: boolean = false) {\n return html`<div class=\"title\" style=\"background:${config.color}\">\n ${this.node?.actions?.length > 1\n ? html`<temba-icon class=\"drag-handle\" name=\"sort\"></temba-icon>`\n : null}\n\n <div class=\"name\">${isRemoving ? 'Remove?' : config.name}</div>\n </div>`;\n }\n\n private renderNodeTitle(config: NodeConfig, isRemoving: boolean = false) {\n return html`<div\n class=\"title ${isRemoving ? 'removing' : ''}\"\n style=\"background:${config.color}\"\n >\n <div class=\"name\">${isRemoving ? 'Remove?' : config.name}</div>\n </div>`;\n }\n\n private renderAction(node: Node, action: Action, index: number) {\n const config = ACTION_CONFIG[action.type];\n const isRemoving = this.actionRemovingState.has(action.uuid);\n\n if (config) {\n return html`<div\n class=\"action sortable ${action.type} ${isRemoving ? 'removing' : ''}\"\n id=\"action-${index}\"\n >\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) =>\n this.handleActionRemoveClick(e, action, index)}\n title=\"Remove action\"\n >\n ✕\n </button>\n <div\n class=\"action-content\"\n @mousedown=${(e: MouseEvent) => this.handleActionMouseDown(e, action)}\n @mouseup=${(e: MouseEvent) => this.handleActionMouseUp(e, action)}\n style=\"cursor: pointer;\"\n >\n ${this.renderTitle(config, isRemoving)}\n <div class=\"body\">\n ${config.render\n ? config.render(node, action)\n : html`<pre>${action.type}</pre>`}\n </div>\n </div>\n </div>`;\n }\n return html`<div\n class=\"action sortable ${isRemoving ? 'removing' : ''}\"\n id=\"action-${index}\"\n >\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) =>\n this.handleActionRemoveClick(e, action, index)}\n title=\"Remove action\"\n >\n ✕\n </button>\n ${action.type}\n </div>`;\n }\n\n private renderRouter(router: Router, ui: NodeUI) {\n const nodeConfig = NODE_CONFIG[ui.type];\n if (nodeConfig) {\n // For tests that call renderRouter directly without setting this.node\n const hasActions = this.node ? this.node.actions.length > 0 : false;\n const isRemoving =\n this.node &&\n this.node.actions.length === 0 &&\n this.actionRemovingState.has(this.node.uuid);\n\n return html`<div class=\"router\" style=\"position: relative;\">\n ${!hasActions\n ? html` <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) => this.handleNodeRemoveClick(e)}\n title=\"Remove node\"\n >\n ✕\n </button>\n <div\n @mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}\n @mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}\n style=\"cursor: pointer;\"\n >\n ${this.renderNodeTitle(nodeConfig, isRemoving)}\n </div>`\n : ''}\n ${router.result_name\n ? html`<div\n class=\"body\"\n @mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}\n @mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}\n style=\"cursor: pointer;\"\n >\n Save as\n <div class=\"result-name\">${router.result_name}</div>\n </div>`\n : null}\n </div>`;\n }\n }\n\n private renderCategories(node: Node) {\n if (!node.router || !node.router.categories) {\n return null;\n }\n\n return html`<div class=\"categories\">\n ${repeat(\n node.router.categories,\n (category) => category.uuid,\n (category) => {\n const exit = node.exits.find(\n (exit: Exit) => exit.uuid == category.exit_uuid\n );\n\n return html`<div\n class=\"category\"\n @mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}\n @mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}\n style=\"cursor: pointer;\"\n >\n <div class=\"title\">${category.name}</div>\n ${this.renderExit(exit)}\n </div>`;\n }\n )}\n </div>`;\n }\n\n private renderExit(exit: Exit): TemplateResult {\n return html`<div class=\"exit-wrapper\">\n <div\n id=\"${exit.uuid}\"\n class=${getClasses({\n exit: true,\n connected: !!exit.destination_uuid,\n removing: this.exitRemovingState.has(exit.uuid)\n })}\n @click=${(e: MouseEvent) => this.handleExitClick(e, exit)}\n ></div>\n </div>`;\n }\n\n public render() {\n if (!this.node || !this.ui) {\n return html`<div class=\"node\">Loading...</div>`;\n }\n\n const nodeConfig = NODE_CONFIG[this.ui.type];\n\n return html`\n <div\n id=\"${this.node.uuid}\"\n class=\"node ${this.ui.type === 'execute_actions'\n ? 'execute-actions'\n : ''}\"\n style=\"left:${this.ui.position.left}px;top:${this.ui.position.top}px\"\n >\n ${nodeConfig && nodeConfig.render\n ? html`<div class=\"router\" style=\"position: relative;\">\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) => this.handleNodeRemoveClick(e)}\n title=\"Remove node\"\n >\n ✕\n </button>\n <div\n @mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}\n @mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}\n style=\"cursor: pointer;\"\n >\n ${this.renderNodeTitle(\n nodeConfig,\n this.actionRemovingState.has(this.node.uuid)\n )}\n ${nodeConfig.render(this.node)}\n </div>\n </div>`\n : this.node.actions.length > 0\n ? this.ui.type === 'execute_actions'\n ? html`<temba-sortable-list\n dragHandle=\"drag-handle\"\n @temba-order-changed=\"${this.handleActionOrderChanged}\"\n >\n ${repeat(\n this.node.actions,\n (action) => action.uuid,\n (action, index) => this.renderAction(this.node, action, index)\n )}\n </temba-sortable-list>`\n : html`${repeat(\n this.node.actions,\n (action) => action.uuid,\n (action, index) => this.renderAction(this.node, action, index)\n )}`\n : !this.node.router && nodeConfig && nodeConfig.name\n ? html`<div class=\"router\" style=\"position: relative;\">\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) => this.handleNodeRemoveClick(e)}\n title=\"Remove node\"\n >\n ✕\n </button>\n ${this.renderNodeTitle(\n nodeConfig,\n this.actionRemovingState.has(this.node.uuid)\n )}\n </div>`\n : ''}\n ${this.node.router\n ? html` ${this.renderRouter(this.node.router, this.ui)}\n ${this.renderCategories(this.node)}`\n : html`<div class=\"action-exits\">\n ${repeat(\n this.node.exits,\n (exit) => exit.uuid,\n (exit) => this.renderExit(exit)\n )}\n </div>`}\n </div>\n `;\n }\n}\n"]}
@@ -279,7 +279,17 @@ export class Editor extends RapidElement {
279
279
  }
280
280
  saveChanges() {
281
281
  // post the flow definition to the server
282
- getStore().postJSON(`/flow/revisions/${this.flow}`, this.definition);
282
+ getStore()
283
+ .postJSON(`/flow/revisions/${this.flow}`, this.definition)
284
+ .then((response) => {
285
+ // Update flow info with the response data
286
+ if (response.json && response.json.info) {
287
+ getStore().getState().setFlowInfo(response.json.info);
288
+ }
289
+ })
290
+ .catch((error) => {
291
+ console.error('Failed to save flow:', error);
292
+ });
283
293
  getStore().getState().setDirtyDate(null);
284
294
  }
285
295
  disconnectedCallback() {