@nyaruka/temba-components 0.139.0 → 0.141.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (385) hide show
  1. package/.github/workflows/cla.yml +1 -1
  2. package/.github/workflows/copilot-setup-steps.yml +6 -1
  3. package/.lintstagedrc.js +10 -0
  4. package/CHANGELOG.md +32 -0
  5. package/demo/data/flows/sample-flow.json +24 -0
  6. package/dist/locales/es.js +5 -5
  7. package/dist/locales/es.js.map +1 -1
  8. package/dist/locales/fr.js +5 -5
  9. package/dist/locales/fr.js.map +1 -1
  10. package/dist/locales/locale-codes.js +11 -2
  11. package/dist/locales/locale-codes.js.map +1 -1
  12. package/dist/locales/pt.js +5 -5
  13. package/dist/locales/pt.js.map +1 -1
  14. package/dist/temba-components.js +702 -338
  15. package/dist/temba-components.js.map +1 -1
  16. package/out-tsc/src/display/Chat.js +10 -7
  17. package/out-tsc/src/display/Chat.js.map +1 -1
  18. package/out-tsc/src/display/Dropdown.js +3 -1
  19. package/out-tsc/src/display/Dropdown.js.map +1 -1
  20. package/out-tsc/src/display/FloatingTab.js +4 -4
  21. package/out-tsc/src/display/FloatingTab.js.map +1 -1
  22. package/out-tsc/src/display/Thumbnail.js +163 -5
  23. package/out-tsc/src/display/Thumbnail.js.map +1 -1
  24. package/out-tsc/src/flow/CanvasNode.js +65 -23
  25. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  26. package/out-tsc/src/flow/Editor.js +369 -49
  27. package/out-tsc/src/flow/Editor.js.map +1 -1
  28. package/out-tsc/src/flow/NodeEditor.js +118 -10
  29. package/out-tsc/src/flow/NodeEditor.js.map +1 -1
  30. package/out-tsc/src/flow/Plumber.js +61 -14
  31. package/out-tsc/src/flow/Plumber.js.map +1 -1
  32. package/out-tsc/src/flow/StickyNote.js +13 -4
  33. package/out-tsc/src/flow/StickyNote.js.map +1 -1
  34. package/out-tsc/src/flow/actions/add_contact_groups.js +4 -1
  35. package/out-tsc/src/flow/actions/add_contact_groups.js.map +1 -1
  36. package/out-tsc/src/flow/actions/add_input_labels.js +4 -1
  37. package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -1
  38. package/out-tsc/src/flow/actions/audio-player.js +112 -0
  39. package/out-tsc/src/flow/actions/audio-player.js.map +1 -0
  40. package/out-tsc/src/flow/actions/enter_flow.js +43 -0
  41. package/out-tsc/src/flow/actions/enter_flow.js.map +1 -0
  42. package/out-tsc/src/flow/actions/play_audio.js +57 -4
  43. package/out-tsc/src/flow/actions/play_audio.js.map +1 -1
  44. package/out-tsc/src/flow/actions/remove_contact_groups.js +6 -1
  45. package/out-tsc/src/flow/actions/remove_contact_groups.js.map +1 -1
  46. package/out-tsc/src/flow/actions/say_msg.js +86 -3
  47. package/out-tsc/src/flow/actions/say_msg.js.map +1 -1
  48. package/out-tsc/src/flow/actions/send_broadcast.js +6 -2
  49. package/out-tsc/src/flow/actions/send_broadcast.js.map +1 -1
  50. package/out-tsc/src/flow/actions/set_contact_channel.js +13 -0
  51. package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -1
  52. package/out-tsc/src/flow/actions/set_contact_status.js +7 -5
  53. package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -1
  54. package/out-tsc/src/flow/actions/start_session.js +10 -3
  55. package/out-tsc/src/flow/actions/start_session.js.map +1 -1
  56. package/out-tsc/src/flow/config.js +11 -3
  57. package/out-tsc/src/flow/config.js.map +1 -1
  58. package/out-tsc/src/flow/nodes/shared-rules.js +1 -1
  59. package/out-tsc/src/flow/nodes/shared-rules.js.map +1 -1
  60. package/out-tsc/src/flow/nodes/split_by_contact_field.js +18 -5
  61. package/out-tsc/src/flow/nodes/split_by_contact_field.js.map +1 -1
  62. package/out-tsc/src/flow/nodes/split_by_expression.js +1 -1
  63. package/out-tsc/src/flow/nodes/split_by_expression.js.map +1 -1
  64. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +0 -1
  65. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -1
  66. package/out-tsc/src/flow/nodes/split_by_random.js +0 -1
  67. package/out-tsc/src/flow/nodes/split_by_random.js.map +1 -1
  68. package/out-tsc/src/flow/nodes/split_by_run_result.js +10 -4
  69. package/out-tsc/src/flow/nodes/split_by_run_result.js.map +1 -1
  70. package/out-tsc/src/flow/nodes/terminal.js +7 -0
  71. package/out-tsc/src/flow/nodes/terminal.js.map +1 -0
  72. package/out-tsc/src/flow/nodes/wait_for_audio.js +77 -0
  73. package/out-tsc/src/flow/nodes/wait_for_audio.js.map +1 -0
  74. package/out-tsc/src/flow/nodes/wait_for_dial.js +151 -0
  75. package/out-tsc/src/flow/nodes/wait_for_dial.js.map +1 -0
  76. package/out-tsc/src/flow/nodes/wait_for_digits.js +61 -1
  77. package/out-tsc/src/flow/nodes/wait_for_digits.js.map +1 -1
  78. package/out-tsc/src/flow/nodes/wait_for_menu.js +173 -2
  79. package/out-tsc/src/flow/nodes/wait_for_menu.js.map +1 -1
  80. package/out-tsc/src/flow/nodes/wait_for_response.js +1 -1
  81. package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
  82. package/out-tsc/src/flow/operators.js +21 -5
  83. package/out-tsc/src/flow/operators.js.map +1 -1
  84. package/out-tsc/src/flow/types.js.map +1 -1
  85. package/out-tsc/src/flow/utils.js +79 -3
  86. package/out-tsc/src/flow/utils.js.map +1 -1
  87. package/out-tsc/src/form/ArrayEditor.js +4 -2
  88. package/out-tsc/src/form/ArrayEditor.js.map +1 -1
  89. package/out-tsc/src/form/FieldRenderer.js +56 -0
  90. package/out-tsc/src/form/FieldRenderer.js.map +1 -1
  91. package/out-tsc/src/interfaces.js +1 -0
  92. package/out-tsc/src/interfaces.js.map +1 -1
  93. package/out-tsc/src/layout/Dialog.js +51 -7
  94. package/out-tsc/src/layout/Dialog.js.map +1 -1
  95. package/out-tsc/src/layout/Modax.js +20 -2
  96. package/out-tsc/src/layout/Modax.js.map +1 -1
  97. package/out-tsc/src/list/ContentMenu.js +14 -1
  98. package/out-tsc/src/list/ContentMenu.js.map +1 -1
  99. package/out-tsc/src/locales/es.js +5 -5
  100. package/out-tsc/src/locales/es.js.map +1 -1
  101. package/out-tsc/src/locales/fr.js +5 -5
  102. package/out-tsc/src/locales/fr.js.map +1 -1
  103. package/out-tsc/src/locales/locale-codes.js +11 -2
  104. package/out-tsc/src/locales/locale-codes.js.map +1 -1
  105. package/out-tsc/src/locales/pt.js +5 -5
  106. package/out-tsc/src/locales/pt.js.map +1 -1
  107. package/out-tsc/src/simulator/Simulator.js +21 -4
  108. package/out-tsc/src/simulator/Simulator.js.map +1 -1
  109. package/out-tsc/src/store/AppState.js +102 -3
  110. package/out-tsc/src/store/AppState.js.map +1 -1
  111. package/out-tsc/test/actions/add_contact_groups.test.js +35 -0
  112. package/out-tsc/test/actions/add_contact_groups.test.js.map +1 -1
  113. package/out-tsc/test/actions/add_input_labels.test.js +53 -0
  114. package/out-tsc/test/actions/add_input_labels.test.js.map +1 -0
  115. package/out-tsc/test/actions/enter_flow.test.js +71 -0
  116. package/out-tsc/test/actions/enter_flow.test.js.map +1 -0
  117. package/out-tsc/test/actions/play_audio.test.js +118 -0
  118. package/out-tsc/test/actions/play_audio.test.js.map +1 -0
  119. package/out-tsc/test/actions/remove_contact_groups.test.js +24 -0
  120. package/out-tsc/test/actions/remove_contact_groups.test.js.map +1 -1
  121. package/out-tsc/test/actions/say_msg.test.js +158 -0
  122. package/out-tsc/test/actions/say_msg.test.js.map +1 -0
  123. package/out-tsc/test/actions/send_broadcast.test.js +41 -0
  124. package/out-tsc/test/actions/send_broadcast.test.js.map +1 -1
  125. package/out-tsc/test/actions/set_contact_channel.test.js +67 -0
  126. package/out-tsc/test/actions/set_contact_channel.test.js.map +1 -0
  127. package/out-tsc/test/actions/set_contact_field.test.js +52 -0
  128. package/out-tsc/test/actions/set_contact_field.test.js.map +1 -0
  129. package/out-tsc/test/actions/set_contact_language.test.js +39 -0
  130. package/out-tsc/test/actions/set_contact_language.test.js.map +1 -0
  131. package/out-tsc/test/actions/set_contact_name.test.js +28 -0
  132. package/out-tsc/test/actions/set_contact_name.test.js.map +1 -0
  133. package/out-tsc/test/actions/set_contact_status.test.js +44 -0
  134. package/out-tsc/test/actions/set_contact_status.test.js.map +1 -0
  135. package/out-tsc/test/actions/set_run_result.test.js +47 -0
  136. package/out-tsc/test/actions/set_run_result.test.js.map +1 -0
  137. package/out-tsc/test/actions/start_session.test.js +76 -0
  138. package/out-tsc/test/actions/start_session.test.js.map +1 -1
  139. package/out-tsc/test/nodes/split_by_contact_field.test.js +50 -0
  140. package/out-tsc/test/nodes/split_by_contact_field.test.js.map +1 -1
  141. package/out-tsc/test/nodes/split_by_run_result.test.js +82 -0
  142. package/out-tsc/test/nodes/split_by_run_result.test.js.map +1 -1
  143. package/out-tsc/test/nodes/split_by_ticket.test.js +139 -0
  144. package/out-tsc/test/nodes/split_by_ticket.test.js.map +1 -0
  145. package/out-tsc/test/nodes/split_by_webhook.test.js +111 -0
  146. package/out-tsc/test/nodes/split_by_webhook.test.js.map +1 -0
  147. package/out-tsc/test/nodes/wait_for_audio.test.js +156 -0
  148. package/out-tsc/test/nodes/wait_for_audio.test.js.map +1 -0
  149. package/out-tsc/test/nodes/wait_for_dial.test.js +336 -0
  150. package/out-tsc/test/nodes/wait_for_dial.test.js.map +1 -0
  151. package/out-tsc/test/nodes/wait_for_digits.test.js +198 -84
  152. package/out-tsc/test/nodes/wait_for_digits.test.js.map +1 -1
  153. package/out-tsc/test/nodes/wait_for_menu.test.js +340 -0
  154. package/out-tsc/test/nodes/wait_for_menu.test.js.map +1 -0
  155. package/out-tsc/test/temba-flow-collision.test.js +261 -6
  156. package/out-tsc/test/temba-flow-collision.test.js.map +1 -1
  157. package/out-tsc/test/temba-flow-editor.test.js +187 -0
  158. package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
  159. package/out-tsc/test/temba-flow-plumber.test.js +19 -0
  160. package/out-tsc/test/temba-flow-plumber.test.js.map +1 -1
  161. package/out-tsc/test/temba-node-type-selector.test.js +6 -6
  162. package/out-tsc/test/temba-node-type-selector.test.js.map +1 -1
  163. package/out-tsc/test/temba-select.test.js +4 -1
  164. package/out-tsc/test/temba-select.test.js.map +1 -1
  165. package/out-tsc/test/utils.test.js +4 -2
  166. package/out-tsc/test/utils.test.js.map +1 -1
  167. package/package.json +3 -9
  168. package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
  169. package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
  170. package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
  171. package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
  172. package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
  173. package/screenshots/truth/actions/add_contact_urn/render/expression-facebook.png +0 -0
  174. package/screenshots/truth/actions/add_contact_urn/render/expression-phone.png +0 -0
  175. package/screenshots/truth/actions/add_contact_urn/render/facebook-id.png +0 -0
  176. package/screenshots/truth/actions/add_contact_urn/render/instagram-handle.png +0 -0
  177. package/screenshots/truth/actions/add_contact_urn/render/line-id.png +0 -0
  178. package/screenshots/truth/actions/add_contact_urn/render/phone-number.png +0 -0
  179. package/screenshots/truth/actions/add_contact_urn/render/telegram-id.png +0 -0
  180. package/screenshots/truth/actions/add_contact_urn/render/viber-id.png +0 -0
  181. package/screenshots/truth/actions/add_contact_urn/render/wechat-id.png +0 -0
  182. package/screenshots/truth/actions/add_contact_urn/render/whatsapp.png +0 -0
  183. package/screenshots/truth/actions/add_input_labels/editor/multiple-labels.png +0 -0
  184. package/screenshots/truth/actions/add_input_labels/editor/single-label.png +0 -0
  185. package/screenshots/truth/actions/add_input_labels/render/multiple-labels.png +0 -0
  186. package/screenshots/truth/actions/add_input_labels/render/single-label.png +0 -0
  187. package/screenshots/truth/actions/enter_flow/editor/basic-flow.png +0 -0
  188. package/screenshots/truth/actions/enter_flow/editor/long-flow-name.png +0 -0
  189. package/screenshots/truth/actions/enter_flow/render/basic-flow.png +0 -0
  190. package/screenshots/truth/actions/enter_flow/render/long-flow-name.png +0 -0
  191. package/screenshots/truth/actions/play_audio/editor/expression-url.png +0 -0
  192. package/screenshots/truth/actions/play_audio/editor/static-url.png +0 -0
  193. package/screenshots/truth/actions/play_audio/render/expression-url.png +0 -0
  194. package/screenshots/truth/actions/play_audio/render/static-url.png +0 -0
  195. package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
  196. package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
  197. package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
  198. package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
  199. package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
  200. package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
  201. package/screenshots/truth/actions/say_msg/editor/multiline-text.png +0 -0
  202. package/screenshots/truth/actions/say_msg/editor/simple-text.png +0 -0
  203. package/screenshots/truth/actions/say_msg/editor/text-with-audio-url.png +0 -0
  204. package/screenshots/truth/actions/say_msg/render/multiline-text.png +0 -0
  205. package/screenshots/truth/actions/say_msg/render/simple-text.png +0 -0
  206. package/screenshots/truth/actions/say_msg/render/text-with-audio-url.png +0 -0
  207. package/screenshots/truth/actions/send_broadcast/render/contacts-only.png +0 -0
  208. package/screenshots/truth/actions/send_broadcast/render/groups-and-contacts.png +0 -0
  209. package/screenshots/truth/actions/send_broadcast/render/groups-only.png +0 -0
  210. package/screenshots/truth/actions/send_broadcast/render/many-groups.png +0 -0
  211. package/screenshots/truth/actions/send_broadcast/render/multiline-text.png +0 -0
  212. package/screenshots/truth/actions/send_email/render/complex-business-email.png +0 -0
  213. package/screenshots/truth/actions/send_email/render/empty-body.png +0 -0
  214. package/screenshots/truth/actions/send_email/render/empty-subject.png +0 -0
  215. package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
  216. package/screenshots/truth/actions/send_email/render/multiline-body.png +0 -0
  217. package/screenshots/truth/actions/send_email/render/multiple-recipients.png +0 -0
  218. package/screenshots/truth/actions/send_email/render/simple-email.png +0 -0
  219. package/screenshots/truth/actions/send_email/render/with-expressions.png +0 -0
  220. package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
  221. package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
  222. package/screenshots/truth/actions/send_msg/render/simple-text.png +0 -0
  223. package/screenshots/truth/actions/send_msg/render/text-with-linebreaks.png +0 -0
  224. package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
  225. package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
  226. package/screenshots/truth/actions/send_msg/render/text-without-quick-replies.png +0 -0
  227. package/screenshots/truth/actions/set_contact_channel/editor/sms-channel.png +0 -0
  228. package/screenshots/truth/actions/set_contact_channel/editor/whatsapp-channel.png +0 -0
  229. package/screenshots/truth/actions/set_contact_channel/render/sms-channel.png +0 -0
  230. package/screenshots/truth/actions/set_contact_channel/render/whatsapp-channel.png +0 -0
  231. package/screenshots/truth/actions/set_contact_field/editor/clear-value.png +0 -0
  232. package/screenshots/truth/actions/set_contact_field/editor/set-value.png +0 -0
  233. package/screenshots/truth/actions/set_contact_field/render/clear-value.png +0 -0
  234. package/screenshots/truth/actions/set_contact_field/render/set-value.png +0 -0
  235. package/screenshots/truth/actions/set_contact_language/editor/english.png +0 -0
  236. package/screenshots/truth/actions/set_contact_language/editor/french.png +0 -0
  237. package/screenshots/truth/actions/set_contact_language/render/english.png +0 -0
  238. package/screenshots/truth/actions/set_contact_language/render/french.png +0 -0
  239. package/screenshots/truth/actions/set_contact_name/editor/expression-name.png +0 -0
  240. package/screenshots/truth/actions/set_contact_name/editor/static-name.png +0 -0
  241. package/screenshots/truth/actions/set_contact_name/render/expression-name.png +0 -0
  242. package/screenshots/truth/actions/set_contact_name/render/static-name.png +0 -0
  243. package/screenshots/truth/actions/set_contact_status/editor/active.png +0 -0
  244. package/screenshots/truth/actions/set_contact_status/editor/archived.png +0 -0
  245. package/screenshots/truth/actions/set_contact_status/editor/blocked.png +0 -0
  246. package/screenshots/truth/actions/set_contact_status/render/active.png +0 -0
  247. package/screenshots/truth/actions/set_contact_status/render/archived.png +0 -0
  248. package/screenshots/truth/actions/set_contact_status/render/blocked.png +0 -0
  249. package/screenshots/truth/actions/set_run_result/editor/expression-value.png +0 -0
  250. package/screenshots/truth/actions/set_run_result/editor/with-category.png +0 -0
  251. package/screenshots/truth/actions/set_run_result/render/expression-value.png +0 -0
  252. package/screenshots/truth/actions/set_run_result/render/with-category.png +0 -0
  253. package/screenshots/truth/actions/start_session/render/contact-query.png +0 -0
  254. package/screenshots/truth/actions/start_session/render/contacts-only.png +0 -0
  255. package/screenshots/truth/actions/start_session/render/create-contact.png +0 -0
  256. package/screenshots/truth/actions/start_session/render/groups-and-contacts.png +0 -0
  257. package/screenshots/truth/actions/start_session/render/groups-only.png +0 -0
  258. package/screenshots/truth/actions/start_session/render/many-recipients.png +0 -0
  259. package/screenshots/truth/editor/router.png +0 -0
  260. package/screenshots/truth/editor/wait.png +0 -0
  261. package/screenshots/truth/nodes/split_by_llm/render/information-extraction.png +0 -0
  262. package/screenshots/truth/nodes/split_by_llm/render/sentiment-analysis.png +0 -0
  263. package/screenshots/truth/nodes/split_by_llm/render/summarization.png +0 -0
  264. package/screenshots/truth/nodes/split_by_llm/render/translation-task.png +0 -0
  265. package/screenshots/truth/nodes/split_by_llm_categorize/editor/basic-categorization.png +0 -0
  266. package/screenshots/truth/nodes/split_by_llm_categorize/editor/custom-input-and-result-name.png +0 -0
  267. package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
  268. package/screenshots/truth/nodes/split_by_llm_categorize/editor/many-categories.png +0 -0
  269. package/screenshots/truth/nodes/split_by_llm_categorize/editor/minimal-categories.png +0 -0
  270. package/screenshots/truth/nodes/split_by_llm_categorize/render/basic-categorization.png +0 -0
  271. package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
  272. package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
  273. package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
  274. package/screenshots/truth/nodes/split_by_llm_categorize/render/minimal-categories.png +0 -0
  275. package/screenshots/truth/nodes/split_by_random/editor/ab-test-multiple-variants.png +0 -0
  276. package/screenshots/truth/nodes/split_by_random/editor/sampling-split.png +0 -0
  277. package/screenshots/truth/nodes/split_by_random/editor/three-way-split.png +0 -0
  278. package/screenshots/truth/nodes/split_by_random/editor/two-bucket-split.png +0 -0
  279. package/screenshots/truth/nodes/split_by_random/render/ab-test-multiple-variants.png +0 -0
  280. package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
  281. package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
  282. package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.png +0 -0
  283. package/screenshots/truth/nodes/wait_for_audio/editor/basic-audio-wait.png +0 -0
  284. package/screenshots/truth/nodes/wait_for_audio/render/basic-audio-wait.png +0 -0
  285. package/screenshots/truth/nodes/wait_for_dial/editor/basic-dial.png +0 -0
  286. package/screenshots/truth/nodes/wait_for_dial/editor/dial-with-limits.png +0 -0
  287. package/screenshots/truth/nodes/wait_for_dial/render/basic-dial.png +0 -0
  288. package/screenshots/truth/nodes/wait_for_dial/render/dial-with-limits.png +0 -0
  289. package/screenshots/truth/nodes/wait_for_digits/editor/basic-digits-wait.png +0 -0
  290. package/screenshots/truth/nodes/wait_for_digits/editor/digits-with-rules.png +0 -0
  291. package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
  292. package/screenshots/truth/nodes/wait_for_digits/render/digits-with-rules.png +0 -0
  293. package/screenshots/truth/nodes/wait_for_menu/editor/menu-with-digits.png +0 -0
  294. package/screenshots/truth/nodes/wait_for_menu/render/menu-with-digits.png +0 -0
  295. package/screenshots/truth/nodes/wait_for_response/editor/basic-wait.png +0 -0
  296. package/screenshots/truth/nodes/wait_for_response/editor/custom-result-name.png +0 -0
  297. package/screenshots/truth/nodes/wait_for_response/editor/no-timeout.png +0 -0
  298. package/screenshots/truth/nodes/wait_for_response/editor/short-timeout.png +0 -0
  299. package/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
  300. package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
  301. package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
  302. package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
  303. package/src/display/Chat.ts +13 -7
  304. package/src/display/Dropdown.ts +3 -1
  305. package/src/display/FloatingTab.ts +4 -4
  306. package/src/display/Thumbnail.ts +162 -2
  307. package/src/flow/CanvasNode.ts +70 -24
  308. package/src/flow/Editor.ts +440 -99
  309. package/src/flow/NodeEditor.ts +137 -9
  310. package/src/flow/Plumber.ts +89 -14
  311. package/src/flow/StickyNote.ts +14 -4
  312. package/src/flow/actions/add_contact_groups.ts +4 -1
  313. package/src/flow/actions/add_input_labels.ts +4 -1
  314. package/src/flow/actions/audio-player.ts +127 -0
  315. package/src/flow/actions/enter_flow.ts +44 -0
  316. package/src/flow/actions/play_audio.ts +64 -5
  317. package/src/flow/actions/remove_contact_groups.ts +6 -1
  318. package/src/flow/actions/say_msg.ts +94 -4
  319. package/src/flow/actions/send_broadcast.ts +6 -2
  320. package/src/flow/actions/set_contact_channel.ts +13 -1
  321. package/src/flow/actions/set_contact_status.ts +7 -5
  322. package/src/flow/actions/start_session.ts +10 -3
  323. package/src/flow/config.ts +11 -3
  324. package/src/flow/nodes/shared-rules.ts +1 -1
  325. package/src/flow/nodes/split_by_contact_field.ts +16 -5
  326. package/src/flow/nodes/split_by_expression.ts +1 -1
  327. package/src/flow/nodes/split_by_llm_categorize.ts +0 -1
  328. package/src/flow/nodes/split_by_random.ts +0 -1
  329. package/src/flow/nodes/split_by_run_result.ts +10 -4
  330. package/src/flow/nodes/terminal.ts +9 -0
  331. package/src/flow/nodes/wait_for_audio.ts +88 -0
  332. package/src/flow/nodes/wait_for_dial.ts +176 -0
  333. package/src/flow/nodes/wait_for_digits.ts +87 -2
  334. package/src/flow/nodes/wait_for_menu.ts +209 -3
  335. package/src/flow/nodes/wait_for_response.ts +1 -1
  336. package/src/flow/operators.ts +23 -5
  337. package/src/flow/types.ts +23 -1
  338. package/src/flow/utils.ts +82 -3
  339. package/src/form/ArrayEditor.ts +4 -2
  340. package/src/form/FieldRenderer.ts +71 -1
  341. package/src/interfaces.ts +2 -1
  342. package/src/layout/Dialog.ts +52 -7
  343. package/src/layout/Modax.ts +19 -2
  344. package/src/list/ContentMenu.ts +15 -1
  345. package/src/locales/es.ts +18 -13
  346. package/src/locales/fr.ts +18 -13
  347. package/src/locales/locale-codes.ts +11 -2
  348. package/src/locales/pt.ts +18 -13
  349. package/src/simulator/Simulator.ts +25 -4
  350. package/src/store/AppState.ts +120 -1
  351. package/src/store/flow-definition.d.ts +2 -0
  352. package/test/actions/add_contact_groups.test.ts +38 -0
  353. package/test/actions/add_input_labels.test.ts +67 -0
  354. package/test/actions/enter_flow.test.ts +88 -0
  355. package/test/actions/play_audio.test.ts +155 -0
  356. package/test/actions/remove_contact_groups.test.ts +29 -0
  357. package/test/actions/say_msg.test.ts +196 -0
  358. package/test/actions/send_broadcast.test.ts +44 -0
  359. package/test/actions/set_contact_channel.test.ts +88 -0
  360. package/test/actions/set_contact_field.test.ts +68 -0
  361. package/test/actions/set_contact_language.test.ts +55 -0
  362. package/test/actions/set_contact_name.test.ts +39 -0
  363. package/test/actions/set_contact_status.test.ts +64 -0
  364. package/test/actions/set_run_result.test.ts +61 -0
  365. package/test/actions/start_session.test.ts +82 -0
  366. package/test/nodes/split_by_contact_field.test.ts +59 -0
  367. package/test/nodes/split_by_run_result.test.ts +100 -0
  368. package/test/nodes/split_by_ticket.test.ts +157 -0
  369. package/test/nodes/split_by_webhook.test.ts +131 -0
  370. package/test/nodes/wait_for_audio.test.ts +182 -0
  371. package/test/nodes/wait_for_dial.test.ts +382 -0
  372. package/test/nodes/wait_for_digits.test.ts +233 -109
  373. package/test/nodes/wait_for_menu.test.ts +383 -0
  374. package/test/temba-flow-collision.test.ts +286 -6
  375. package/test/temba-flow-editor.test.ts +240 -0
  376. package/test/temba-flow-plumber.test.ts +62 -0
  377. package/test/temba-node-type-selector.test.ts +6 -6
  378. package/test/temba-select.test.ts +6 -1
  379. package/test/utils.test.ts +4 -2
  380. package/screenshots/truth/nodes/wait_for_digits/editor/phone-number-collection.png +0 -0
  381. package/screenshots/truth/nodes/wait_for_digits/editor/single-digit-with-timeout.png +0 -0
  382. package/screenshots/truth/nodes/wait_for_digits/editor/verification-code.png +0 -0
  383. package/screenshots/truth/nodes/wait_for_digits/render/phone-number-collection.png +0 -0
  384. package/screenshots/truth/nodes/wait_for_digits/render/single-digit-with-timeout.png +0 -0
  385. package/screenshots/truth/nodes/wait_for_digits/render/verification-code.png +0 -0
@@ -6,6 +6,59 @@ import { property } from 'lit/decorators.js';
6
6
  import { produce } from 'immer';
7
7
  export const FLOW_SPEC_VERSION = '14.3';
8
8
  const CANVAS_PADDING = 800;
9
+ /**
10
+ * Temporary: Reclassify nodes based on whether they contain terminal actions.
11
+ * - execute_actions nodes with a terminal action become "terminal"
12
+ * - terminal nodes that no longer have a terminal action become "execute_actions"
13
+ * This can be removed once we stop supporting terminal nodes.
14
+ */
15
+ function reclassifyTerminalNodes(definition) {
16
+ var _a, _b;
17
+ if (!(definition === null || definition === void 0 ? void 0 : definition.nodes) || !((_a = definition === null || definition === void 0 ? void 0 : definition._ui) === null || _a === void 0 ? void 0 : _a.nodes))
18
+ return;
19
+ for (const node of definition.nodes) {
20
+ const nodeUI = definition._ui.nodes[node.uuid];
21
+ if (!nodeUI)
22
+ continue;
23
+ const hasTerminalAction = (_b = node.actions) === null || _b === void 0 ? void 0 : _b.some((action) => action.terminal === true);
24
+ if (nodeUI.type === 'execute_actions' && hasTerminalAction) {
25
+ nodeUI.type = 'terminal';
26
+ }
27
+ else if (nodeUI.type === 'terminal' && !hasTerminalAction) {
28
+ nodeUI.type = 'execute_actions';
29
+ }
30
+ }
31
+ }
32
+ /**
33
+ * Reclassify wait_for_response nodes that are actually voice-specific wait types.
34
+ * The server stores all voice waits as wait_for_response, but we detect the specific
35
+ * type from the router's wait hint:
36
+ * - hint.type === 'digits' && hint.count === 1 → wait_for_menu
37
+ * - hint.type === 'digits' (no count) → wait_for_digits
38
+ * - hint.type === 'audio' → wait_for_audio
39
+ */
40
+ function reclassifyVoiceWaitNodes(definition) {
41
+ var _a, _b, _c;
42
+ if (!(definition === null || definition === void 0 ? void 0 : definition.nodes) || !((_a = definition === null || definition === void 0 ? void 0 : definition._ui) === null || _a === void 0 ? void 0 : _a.nodes))
43
+ return;
44
+ for (const node of definition.nodes) {
45
+ const nodeUI = definition._ui.nodes[node.uuid];
46
+ if (!nodeUI || nodeUI.type !== 'wait_for_response')
47
+ continue;
48
+ const hint = (_c = (_b = node.router) === null || _b === void 0 ? void 0 : _b.wait) === null || _c === void 0 ? void 0 : _c.hint;
49
+ if (!hint)
50
+ continue;
51
+ if (hint.type === 'digits' && hint.count === 1) {
52
+ nodeUI.type = 'wait_for_menu';
53
+ }
54
+ else if (hint.type === 'digits') {
55
+ nodeUI.type = 'wait_for_digits';
56
+ }
57
+ else if (hint.type === 'audio') {
58
+ nodeUI.type = 'wait_for_audio';
59
+ }
60
+ }
61
+ }
9
62
  /**
10
63
  * Sorts nodes by their position - first by y (top), then by x (left)
11
64
  */
@@ -26,6 +79,23 @@ function sortNodesByPosition(nodes, nodePositions) {
26
79
  return posA.left - posB.left;
27
80
  });
28
81
  }
82
+ function buildIssueMaps(issues = []) {
83
+ const byNode = new Map();
84
+ const byAction = new Map();
85
+ for (const issue of issues) {
86
+ if (issue.action_uuid) {
87
+ const actionList = byAction.get(issue.action_uuid) || [];
88
+ actionList.push(issue);
89
+ byAction.set(issue.action_uuid, actionList);
90
+ }
91
+ else {
92
+ const nodeList = byNode.get(issue.node_uuid) || [];
93
+ nodeList.push(issue);
94
+ byNode.set(issue.node_uuid, nodeList);
95
+ }
96
+ }
97
+ return { byNode, byAction };
98
+ }
29
99
  export const zustand = createStore()(subscribeWithSelector(immer((set, get) => ({
30
100
  languageNames: {},
31
101
  canvasSize: { width: 0, height: 0 },
@@ -33,6 +103,8 @@ export const zustand = createStore()(subscribeWithSelector(immer((set, get) => (
33
103
  workspace: null,
34
104
  flowDefinition: null,
35
105
  flowInfo: null,
106
+ issuesByNode: new Map(),
107
+ issuesByAction: new Map(),
36
108
  isTranslating: false,
37
109
  viewingRevision: false,
38
110
  dirtyDate: null,
@@ -46,6 +118,7 @@ export const zustand = createStore()(subscribeWithSelector(immer((set, get) => (
46
118
  });
47
119
  },
48
120
  fetchRevision: async (endpoint, id = null) => {
121
+ var _a;
49
122
  const viewingRevision = !!id && id !== 'latest';
50
123
  if (!id) {
51
124
  id = 'latest';
@@ -55,10 +128,15 @@ export const zustand = createStore()(subscribeWithSelector(immer((set, get) => (
55
128
  throw new Error('Network response was not ok');
56
129
  }
57
130
  const data = (await response.json());
131
+ reclassifyTerminalNodes(data.definition);
132
+ reclassifyVoiceWaitNodes(data.definition);
133
+ const issueMaps = buildIssueMaps((_a = data.info) === null || _a === void 0 ? void 0 : _a.issues);
58
134
  set({
59
135
  flowInfo: data.info,
60
136
  flowDefinition: data.definition,
61
- viewingRevision
137
+ viewingRevision,
138
+ issuesByNode: issueMaps.byNode,
139
+ issuesByAction: issueMaps.byAction
62
140
  });
63
141
  },
64
142
  fetchWorkspace: async (endpoint) => {
@@ -122,10 +200,23 @@ export const zustand = createStore()(subscribeWithSelector(immer((set, get) => (
122
200
  const languageNames = state.languageNames;
123
201
  return { name: languageNames[languageCode], code: languageCode };
124
202
  },
203
+ clearFlowData: () => {
204
+ set({
205
+ flowDefinition: null,
206
+ flowInfo: null,
207
+ issuesByNode: new Map(),
208
+ issuesByAction: new Map(),
209
+ activity: null,
210
+ simulatorActivity: null,
211
+ simulatorActive: false,
212
+ dirtyDate: null,
213
+ viewingRevision: false
214
+ });
215
+ },
125
216
  // todo: eventually we should be doing the fetching
126
217
  setFlowContents: (flow) => {
127
218
  set((state) => {
128
- var _a, _b, _c;
219
+ var _a, _b, _c, _d;
129
220
  const flowLang = flow.definition.language;
130
221
  // Clone to ensure mutable for sorting
131
222
  state.flowDefinition = {
@@ -133,11 +224,16 @@ export const zustand = createStore()(subscribeWithSelector(immer((set, get) => (
133
224
  nodes: [...(flow.definition.nodes || [])]
134
225
  };
135
226
  state.flowInfo = flow.info;
227
+ const issueMaps = buildIssueMaps((_a = flow.info) === null || _a === void 0 ? void 0 : _a.issues);
228
+ state.issuesByNode = issueMaps.byNode;
229
+ state.issuesByAction = issueMaps.byAction;
136
230
  // Reset to the flow's default language when loading a new flow
137
231
  state.languageCode = flowLang;
138
232
  state.isTranslating = false;
233
+ reclassifyTerminalNodes(state.flowDefinition);
234
+ reclassifyVoiceWaitNodes(state.flowDefinition);
139
235
  // Sort nodes by position when loading flow
140
- if (((_a = state.flowDefinition) === null || _a === void 0 ? void 0 : _a.nodes) && ((_c = (_b = state.flowDefinition) === null || _b === void 0 ? void 0 : _b._ui) === null || _c === void 0 ? void 0 : _c.nodes)) {
236
+ if (((_b = state.flowDefinition) === null || _b === void 0 ? void 0 : _b.nodes) && ((_d = (_c = state.flowDefinition) === null || _c === void 0 ? void 0 : _c._ui) === null || _d === void 0 ? void 0 : _d.nodes)) {
141
237
  sortNodesByPosition(state.flowDefinition.nodes, state.flowDefinition._ui.nodes);
142
238
  }
143
239
  });
@@ -145,6 +241,9 @@ export const zustand = createStore()(subscribeWithSelector(immer((set, get) => (
145
241
  setFlowInfo: (info) => {
146
242
  set((state) => {
147
243
  state.flowInfo = info;
244
+ const issueMaps = buildIssueMaps(info === null || info === void 0 ? void 0 : info.issues);
245
+ state.issuesByNode = issueMaps.byNode;
246
+ state.issuesByAction = issueMaps.byAction;
148
247
  });
149
248
  },
150
249
  setRevision: (revision) => {
@@ -1 +1 @@
1
- {"version":3,"file":"AppState.js","sourceRoot":"","sources":["../../../src/store/AppState.ts"],"names":[],"mappings":"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","sourcesContent":["import { createStore, StoreApi } from 'zustand/vanilla';\nimport { fetchResults, generateUUID } from '../utils';\nimport {\n Action,\n Exit,\n FlowDefinition,\n FlowPosition,\n Node,\n NodeUI,\n Router,\n StickyNote\n} from './flow-definition';\nimport { immer } from 'zustand/middleware/immer';\nimport { subscribeWithSelector } from 'zustand/middleware';\nimport { property } from 'lit/decorators.js';\nimport { produce } from 'immer';\n\nexport const FLOW_SPEC_VERSION = '14.3';\nconst CANVAS_PADDING = 800;\n\n/**\n * Sorts nodes by their position - first by y (top), then by x (left)\n */\nfunction sortNodesByPosition(\n nodes: Node[],\n nodePositions: Record<string, NodeUI>\n): void {\n nodes.sort((a, b) => {\n const posA = nodePositions[a.uuid]?.position;\n const posB = nodePositions[b.uuid]?.position;\n\n // if either position is missing, maintain current order\n if (!posA || !posB) {\n return 0;\n }\n\n // sort by y (top) first\n if (posA.top !== posB.top) {\n return posA.top - posB.top;\n }\n\n // if y is same, sort by x (left)\n return posA.left - posB.left;\n });\n}\n\nexport interface InfoResult {\n key: string;\n name: string;\n categories: string[];\n node_uuids: string[];\n}\n\nexport interface ObjectRef {\n uuid: string;\n name: string;\n}\n\nexport interface TypedObjectRef extends ObjectRef {\n type: string;\n}\n\nexport interface Language {\n code: string;\n name: string;\n}\n\nexport interface FlowInfo {\n results: InfoResult[];\n dependencies: TypedObjectRef[];\n counts: { nodes: number; languages: number };\n locals: string[];\n}\n\nexport interface FlowContents {\n definition: FlowDefinition;\n info: FlowInfo;\n}\n\nexport interface Workspace {\n anon: boolean;\n country: string;\n date_style: string;\n languages: string[];\n name: string;\n primary_language: string;\n timezone: string;\n uuid: string;\n}\n\nexport interface CanvasPositions {\n [uuid: string]: FlowPosition;\n}\n\nexport interface Activity {\n segments: { [exitToDestinationKey: string]: number };\n nodes: { [nodeUuid: string]: number };\n}\n\nexport interface AppState {\n flowDefinition: FlowDefinition;\n flowInfo: FlowInfo;\n\n languageCode: string;\n languageNames: { [code: string]: Language };\n workspace: Workspace;\n isTranslating: boolean;\n viewingRevision: boolean;\n\n dirtyDate: Date | null;\n\n canvasSize: { width: number; height: number };\n activity: Activity | null;\n simulatorActivity: Activity | null;\n activityEndpoint: string | null;\n simulatorActive: boolean;\n\n getCurrentActivity: () => Activity | null;\n fetchRevision: (endpoint: string, id?: string) => void;\n fetchWorkspace: (endpoint: string) => Promise<void>;\n fetchAllLanguages: (endpoint: string) => Promise<void>;\n fetchActivity: (endpoint: string) => Promise<void>;\n setActivityEndpoint: (endpoint: string) => void;\n updateActivity: (activity: Activity) => void;\n updateSimulatorActivity: (activity: Activity) => void;\n setSimulatorActive: (active: boolean) => void;\n\n getFlowResults: () => InfoResult[];\n getResultByKey(id: any): InfoResult;\n\n setFlowContents: (flow: FlowContents) => void;\n setFlowInfo: (info: FlowInfo) => void;\n setRevision: (revision: number) => void;\n setLanguageCode: (languageCode: string) => void;\n setDirtyDate: (date: Date) => void;\n expandCanvas: (width: number, height: number) => void;\n\n updateNode(\n uuid: string,\n node: { actions: Action[]; uuid: string; exits: Exit[]; router?: Router }\n ): unknown;\n updateNodeUIConfig(uuid: string, config: Record<string, any>): unknown;\n updateConnection(\n nodeUuid: string,\n exitUuid: string,\n destinationNodeUuid: string\n ): unknown;\n updateCanvasPositions: (positions: CanvasPositions) => void;\n removeNodes: (uuids: string[]) => void;\n removeStickyNotes: (uuids: string[]) => void;\n updateStickyNote(uuid: string, sticky: StickyNote): void;\n createStickyNote(position: FlowPosition): string;\n createNode(nodeType: string, position: FlowPosition): string;\n addNode(node: Node, nodeUI: NodeUI): void;\n updateLocalization(\n languageCode: string,\n actionUuid: string,\n localizationData: Record<string, any>\n ): void;\n setTranslationFilters: (filters: { categories: boolean }) => void;\n markAutoTranslated: (\n languageCode: string,\n uuid: string,\n attributes: string[]\n ) => void;\n}\n\nexport const zustand = createStore<AppState>()(\n subscribeWithSelector(\n immer((set, get) => ({\n languageNames: {},\n canvasSize: { width: 0, height: 0 },\n languageCode: '',\n workspace: null,\n flowDefinition: null,\n flowInfo: null,\n isTranslating: false,\n viewingRevision: false,\n dirtyDate: null,\n activity: null,\n simulatorActivity: null,\n activityEndpoint: null,\n simulatorActive: false,\n\n setDirtyDate: (date: Date) => {\n set((state: AppState) => {\n state.dirtyDate = date;\n });\n },\n\n fetchRevision: async (endpoint: string, id: string = null) => {\n const viewingRevision = !!id && id !== 'latest';\n if (!id) {\n id = 'latest';\n }\n const response = await fetch(\n `${endpoint}/${id}/?version=${FLOW_SPEC_VERSION}`\n );\n\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n const data = (await response.json()) as FlowContents;\n set({\n flowInfo: data.info,\n flowDefinition: data.definition,\n viewingRevision\n });\n },\n\n fetchWorkspace: async (endpoint) => {\n const response = await fetch(endpoint);\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n const data = await response.json();\n set({ workspace: data });\n },\n\n fetchAllLanguages: async (endpoint) => {\n const results = await fetchResults(endpoint);\n\n // convert array to map for easier lookup\n const allLanguages = results.reduce(function (\n languages: any,\n result: any\n ) {\n languages[result.value] = result.name;\n return languages;\n },\n {});\n\n set({ languageNames: allLanguages });\n },\n\n setActivityEndpoint: (endpoint: string) => {\n set({ activityEndpoint: endpoint });\n },\n\n fetchActivity: async (endpoint: string) => {\n try {\n const response = await fetch(endpoint);\n if (!response.ok) {\n return;\n }\n const data = await response.json();\n set({ activity: data });\n } catch (error) {\n console.error('Failed to fetch activity:', error);\n }\n },\n\n updateActivity: (activity: Activity) => {\n set({ activity });\n },\n\n updateSimulatorActivity: (activity: Activity) => {\n set({ simulatorActivity: activity });\n },\n\n setSimulatorActive: (active: boolean) => {\n set({ simulatorActive: active });\n },\n\n getCurrentActivity: () => {\n const state = get();\n return state.simulatorActive ? state.simulatorActivity : state.activity;\n },\n\n getFlowResults: () => {\n const state = get();\n return state.flowInfo.results;\n },\n\n getResultByKey: (id: any) => {\n const state = get();\n const results = state.flowInfo.results;\n return results.find((result) => result.key === id);\n },\n\n getLanguage: () => {\n const state = get();\n const languageCode = state.languageCode;\n const languageNames = state.languageNames;\n return { name: languageNames[languageCode], code: languageCode };\n },\n\n // todo: eventually we should be doing the fetching\n setFlowContents: (flow: FlowContents) => {\n set((state: AppState) => {\n const flowLang = flow.definition.language;\n // Clone to ensure mutable for sorting\n state.flowDefinition = {\n ...flow.definition,\n nodes: [...(flow.definition.nodes || [])]\n };\n state.flowInfo = flow.info;\n // Reset to the flow's default language when loading a new flow\n state.languageCode = flowLang;\n state.isTranslating = false;\n\n // Sort nodes by position when loading flow\n if (state.flowDefinition?.nodes && state.flowDefinition?._ui?.nodes) {\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n }\n });\n },\n\n setFlowInfo: (info: FlowInfo) => {\n set((state: AppState) => {\n state.flowInfo = info;\n });\n },\n\n setRevision: (revision: number) => {\n set((state: AppState) => {\n state.flowDefinition.revision = revision;\n });\n },\n\n setLanguageCode: (languageCode: string) => {\n set((state: AppState) => {\n state.languageCode = languageCode;\n state.isTranslating = state.flowDefinition.language !== languageCode;\n });\n },\n\n expandCanvas: (width: number, height: number) => {\n set((state: AppState) => {\n const minWidth = Math.max(\n state.canvasSize.width,\n width + CANVAS_PADDING\n );\n const minHeight = Math.max(\n state.canvasSize.height,\n height + CANVAS_PADDING\n );\n\n state.canvasSize.width = minWidth;\n state.canvasSize.height = minHeight;\n });\n },\n\n updateCanvasPositions: (positions: CanvasPositions) => {\n set((state: AppState) => {\n for (const uuid in positions) {\n // todo: add nodes that are created and then moved, for now ignore\n if (state.flowDefinition._ui.nodes[uuid]) {\n state.flowDefinition._ui.nodes[uuid].position = positions[uuid];\n }\n\n // otherwise, it might be a sticky\n else if (state.flowDefinition._ui.stickies[uuid]) {\n state.flowDefinition._ui.stickies[uuid].position =\n positions[uuid];\n }\n }\n\n // Sort nodes by position since positions may have changed\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n\n state.dirtyDate = new Date();\n });\n },\n\n removeNodes: (uuids: string[]) => {\n set((state: AppState) => {\n for (const uuid of uuids) {\n delete state.flowDefinition._ui.nodes[uuid];\n }\n\n state.flowDefinition = produce(state.flowDefinition, (draft) => {\n // For each node being removed, check if we should reroute connections\n uuids.forEach((removedUuid) => {\n const removedNode = draft.nodes.find(\n (n) => n.uuid === removedUuid\n );\n\n if (!removedNode || !removedNode.exits.length) return;\n\n // Get all destinations (filter out null/undefined)\n const destinations = removedNode.exits\n .map((exit) => exit.destination_uuid)\n .filter((dest) => dest);\n\n // Only proceed if all exits have destinations and they all point to the same place\n if (\n destinations.length === removedNode.exits.length &&\n destinations.every((dest) => dest === destinations[0])\n ) {\n const targetDestination = destinations[0];\n // Don't reroute if the target is also being removed\n if (uuids.includes(targetDestination)) return;\n\n // Find all nodes with exits pointing to the node being removed\n draft.nodes.forEach((node) => {\n node.exits.forEach((exit) => {\n if (exit.destination_uuid === removedUuid) {\n // Reroute to the same destination the removed node was going to\n exit.destination_uuid = targetDestination;\n }\n });\n });\n }\n });\n\n // Remove the nodes\n draft.nodes = draft.nodes.filter(\n (node) => !uuids.includes(node.uuid)\n );\n\n // Clear any remaining connections to removed nodes that weren't rerouted\n draft.nodes.forEach((node) => {\n node.exits.forEach((exit) => {\n if (uuids.includes(exit.destination_uuid)) {\n exit.destination_uuid = null;\n }\n });\n });\n\n // Sort nodes by position\n sortNodesByPosition(draft.nodes, draft._ui.nodes);\n });\n\n state.dirtyDate = new Date();\n });\n },\n\n removeStickyNotes: (uuids: string[]) => {\n set((state: AppState) => {\n if (state.flowDefinition._ui?.stickies) {\n for (const uuid of uuids) {\n delete state.flowDefinition._ui.stickies[uuid];\n }\n }\n state.dirtyDate = new Date();\n });\n },\n\n updateNode: (uuid: string, newNode: Node) => {\n set((state: AppState) => {\n const node = state.flowDefinition?.nodes.find((n) => n.uuid === uuid);\n if (node) {\n node.actions = newNode.actions;\n node.uuid = newNode.uuid;\n node.exits = newNode.exits;\n node.router = newNode.router;\n }\n state.dirtyDate = new Date();\n });\n },\n\n updateNodeUIConfig: (uuid: string, config: Record<string, any>) => {\n set((state: AppState) => {\n if (state.flowDefinition._ui.nodes[uuid]) {\n // Handle type separately if provided\n if (config.type !== undefined) {\n state.flowDefinition._ui.nodes[uuid].type = config.type;\n }\n\n // Update config (excluding type)\n if (!state.flowDefinition._ui.nodes[uuid].config) {\n state.flowDefinition._ui.nodes[uuid].config = {};\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { type, ...configWithoutType } = config;\n Object.assign(\n state.flowDefinition._ui.nodes[uuid].config,\n configWithoutType\n );\n }\n state.dirtyDate = new Date();\n });\n },\n\n updateConnection: (\n nodeUuid: string,\n exitUuid: string,\n destinationNodeUuid: string\n ) => {\n /* console.log('Upating connection:', {\n nodeUuid,\n exitUuid,\n destinationNodeUuid\n });*/\n set((state: AppState) => {\n // Find the exit with this UUID\n const node = state.flowDefinition.nodes.find(\n (node) => node.uuid === nodeUuid\n );\n\n const exit = node?.exits.find((e) => e.uuid === exitUuid);\n if (exit) {\n // Update the destination\n exit.destination_uuid = destinationNodeUuid;\n state.dirtyDate = new Date();\n }\n });\n },\n\n updateStickyNote: (uuid: string, sticky: StickyNote) => {\n set((state: AppState) => {\n if (!state.flowDefinition._ui.stickies) {\n state.flowDefinition._ui.stickies = {};\n }\n state.flowDefinition._ui.stickies[uuid] = sticky;\n state.dirtyDate = new Date();\n });\n },\n\n createStickyNote: (position: FlowPosition): string => {\n const uuid = generateUUID();\n set((state: AppState) => {\n if (!state.flowDefinition._ui.stickies) {\n state.flowDefinition._ui.stickies = {};\n }\n\n const newSticky: StickyNote = {\n position,\n title: '',\n body: '',\n color: 'yellow'\n };\n\n state.flowDefinition._ui.stickies[uuid] = newSticky;\n state.dirtyDate = new Date();\n });\n return uuid;\n },\n\n createNode: (nodeType: string, position: FlowPosition): string => {\n const uuid = generateUUID();\n const exitUuid = generateUUID();\n\n set((state: AppState) => {\n // Create a basic node with a single exit\n const newNode: Node = {\n uuid,\n actions: [],\n exits: [\n {\n uuid: exitUuid,\n destination_uuid: null\n }\n ]\n };\n\n // Add the node to the flow definition\n state.flowDefinition.nodes.push(newNode);\n\n // Set up UI for the node\n if (!state.flowDefinition._ui.nodes) {\n state.flowDefinition._ui.nodes = {};\n }\n\n state.flowDefinition._ui.nodes[uuid] = {\n position,\n type: nodeType as any,\n config: {}\n };\n\n // Sort nodes by position\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n\n state.dirtyDate = new Date();\n });\n\n return uuid;\n },\n\n addNode: (node: Node, nodeUI: NodeUI) => {\n set((state: AppState) => {\n // Add the node to the flow definition\n state.flowDefinition.nodes.push(node);\n\n // Set up UI for the node\n if (!state.flowDefinition._ui.nodes) {\n state.flowDefinition._ui.nodes = {};\n }\n\n state.flowDefinition._ui.nodes[node.uuid] = nodeUI;\n\n // Sort nodes by position\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n\n state.dirtyDate = new Date();\n });\n },\n\n updateLocalization: (\n languageCode: string,\n actionUuid: string,\n localizationData: Record<string, any>\n ) => {\n set((state: AppState) => {\n // Initialize localization structure if it doesn't exist\n if (!state.flowDefinition.localization) {\n state.flowDefinition.localization = {};\n }\n\n if (!state.flowDefinition.localization[languageCode]) {\n state.flowDefinition.localization[languageCode] = {};\n }\n\n // Update or remove the localization for this action\n if (Object.keys(localizationData).length > 0) {\n state.flowDefinition.localization[languageCode][actionUuid] =\n localizationData;\n } else {\n // If no localized values, remove the entry\n delete state.flowDefinition.localization[languageCode][actionUuid];\n }\n\n // Clean up empty language sections\n if (\n Object.keys(state.flowDefinition.localization[languageCode])\n .length === 0\n ) {\n delete state.flowDefinition.localization[languageCode];\n }\n\n // Clean up empty localization object\n if (Object.keys(state.flowDefinition.localization).length === 0) {\n delete state.flowDefinition.localization;\n }\n\n state.dirtyDate = new Date();\n });\n },\n\n setTranslationFilters: (filters: { categories: boolean }) => {\n set((state: AppState) => {\n if (!state.flowDefinition?._ui) {\n return;\n }\n\n const currentFilters = state.flowDefinition._ui\n .translation_filters || {\n categories: false\n };\n\n state.flowDefinition._ui.translation_filters = {\n ...currentFilters,\n categories: !!filters.categories\n };\n\n state.dirtyDate = new Date();\n });\n },\n\n markAutoTranslated: (\n languageCode: string,\n uuid: string,\n attributes: string[]\n ) => {\n set((state: AppState) => {\n if (!state.flowDefinition?._ui) {\n return;\n }\n\n if (!state.flowDefinition._ui.auto_translations) {\n state.flowDefinition._ui.auto_translations = {};\n }\n\n if (!state.flowDefinition._ui.auto_translations[languageCode]) {\n state.flowDefinition._ui.auto_translations[languageCode] = {};\n }\n\n const existing =\n state.flowDefinition._ui.auto_translations[languageCode][uuid] ||\n [];\n\n const merged = Array.from(\n new Set([...existing, ...(attributes || [])])\n );\n\n state.flowDefinition._ui.auto_translations[languageCode][uuid] =\n merged;\n state.dirtyDate = new Date();\n });\n }\n }))\n )\n);\n\ntype SelectorAwareStoreApi<S extends object> = StoreApi<S> & {\n subscribe: <U>(\n selector: (state: S) => U,\n listener: (value: U, previous: U) => void\n ) => () => void;\n};\n\n/**\n * Custom Lit property decorator that binds a property to a Zustand store subscription.\n *\n * @param store - The Zustand store to subscribe to.\n * @param selector - A function selecting the slice of state to bind to the property.\n */\nexport function fromStore<S extends object, V = unknown>(\n store: SelectorAwareStoreApi<S>,\n selector: (state: S) => V\n): PropertyDecorator {\n return (proto: any, name: string | symbol) => {\n property()(proto, name as string);\n\n const connectedKey = 'connectedCallback';\n const disconnectedKey = 'disconnectedCallback';\n\n const userConnected = proto[connectedKey];\n const userDisconnected = proto[disconnectedKey];\n\n proto[connectedKey] = function () {\n this._zustandUnsubscribe ??= {};\n this[name] = selector(store.getState());\n\n this._zustandUnsubscribe[name] = store.subscribe(selector, (val: V) => {\n this[name] = val;\n });\n\n if (userConnected) userConnected.call(this);\n };\n\n proto[disconnectedKey] = function () {\n this._zustandUnsubscribe?.[name]?.();\n if (userDisconnected) userDisconnected.call(this);\n };\n };\n}\n"]}
1
+ {"version":3,"file":"AppState.js","sourceRoot":"","sources":["../../../src/store/AppState.ts"],"names":[],"mappings":"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","sourcesContent":["import { createStore, StoreApi } from 'zustand/vanilla';\nimport { fetchResults, generateUUID } from '../utils';\nimport {\n Action,\n Exit,\n FlowDefinition,\n FlowPosition,\n Node,\n NodeUI,\n Router,\n StickyNote\n} from './flow-definition';\nimport { immer } from 'zustand/middleware/immer';\nimport { subscribeWithSelector } from 'zustand/middleware';\nimport { property } from 'lit/decorators.js';\nimport { produce } from 'immer';\n\nexport const FLOW_SPEC_VERSION = '14.3';\nconst CANVAS_PADDING = 800;\n\n/**\n * Temporary: Reclassify nodes based on whether they contain terminal actions.\n * - execute_actions nodes with a terminal action become \"terminal\"\n * - terminal nodes that no longer have a terminal action become \"execute_actions\"\n * This can be removed once we stop supporting terminal nodes.\n */\nfunction reclassifyTerminalNodes(definition: FlowDefinition): void {\n if (!definition?.nodes || !definition?._ui?.nodes) return;\n\n for (const node of definition.nodes) {\n const nodeUI = definition._ui.nodes[node.uuid];\n if (!nodeUI) continue;\n\n const hasTerminalAction = node.actions?.some(\n (action) => (action as any).terminal === true\n );\n\n if (nodeUI.type === 'execute_actions' && hasTerminalAction) {\n nodeUI.type = 'terminal' as any;\n } else if (nodeUI.type === ('terminal' as any) && !hasTerminalAction) {\n nodeUI.type = 'execute_actions';\n }\n }\n}\n\n/**\n * Reclassify wait_for_response nodes that are actually voice-specific wait types.\n * The server stores all voice waits as wait_for_response, but we detect the specific\n * type from the router's wait hint:\n * - hint.type === 'digits' && hint.count === 1 → wait_for_menu\n * - hint.type === 'digits' (no count) → wait_for_digits\n * - hint.type === 'audio' → wait_for_audio\n */\nfunction reclassifyVoiceWaitNodes(definition: FlowDefinition): void {\n if (!definition?.nodes || !definition?._ui?.nodes) return;\n\n for (const node of definition.nodes) {\n const nodeUI = definition._ui.nodes[node.uuid];\n if (!nodeUI || nodeUI.type !== 'wait_for_response') continue;\n\n const hint = node.router?.wait?.hint;\n if (!hint) continue;\n\n if (hint.type === 'digits' && hint.count === 1) {\n nodeUI.type = 'wait_for_menu' as any;\n } else if (hint.type === 'digits') {\n nodeUI.type = 'wait_for_digits' as any;\n } else if (hint.type === 'audio') {\n nodeUI.type = 'wait_for_audio' as any;\n }\n }\n}\n\n/**\n * Sorts nodes by their position - first by y (top), then by x (left)\n */\nfunction sortNodesByPosition(\n nodes: Node[],\n nodePositions: Record<string, NodeUI>\n): void {\n nodes.sort((a, b) => {\n const posA = nodePositions[a.uuid]?.position;\n const posB = nodePositions[b.uuid]?.position;\n\n // if either position is missing, maintain current order\n if (!posA || !posB) {\n return 0;\n }\n\n // sort by y (top) first\n if (posA.top !== posB.top) {\n return posA.top - posB.top;\n }\n\n // if y is same, sort by x (left)\n return posA.left - posB.left;\n });\n}\n\nexport interface InfoResult {\n key: string;\n name: string;\n categories: string[];\n node_uuids: string[];\n}\n\nexport interface ObjectRef {\n uuid: string;\n name: string;\n}\n\nexport interface TypedObjectRef extends ObjectRef {\n type: string;\n}\n\nexport interface Language {\n code: string;\n name: string;\n}\n\nexport interface FlowIssue {\n type: string;\n node_uuid: string;\n action_uuid?: string;\n description: string;\n dependency?: {\n key: string;\n name: string;\n type: string;\n };\n}\n\nexport interface FlowInfo {\n results: InfoResult[];\n dependencies: TypedObjectRef[];\n counts: { nodes: number; languages: number };\n locals: string[];\n issues?: FlowIssue[];\n}\n\nfunction buildIssueMaps(issues: FlowIssue[] = []): {\n byNode: Map<string, FlowIssue[]>;\n byAction: Map<string, FlowIssue[]>;\n} {\n const byNode = new Map<string, FlowIssue[]>();\n const byAction = new Map<string, FlowIssue[]>();\n for (const issue of issues) {\n if (issue.action_uuid) {\n const actionList = byAction.get(issue.action_uuid) || [];\n actionList.push(issue);\n byAction.set(issue.action_uuid, actionList);\n } else {\n const nodeList = byNode.get(issue.node_uuid) || [];\n nodeList.push(issue);\n byNode.set(issue.node_uuid, nodeList);\n }\n }\n return { byNode, byAction };\n}\n\nexport interface FlowContents {\n definition: FlowDefinition;\n info: FlowInfo;\n}\n\nexport interface Workspace {\n anon: boolean;\n country: string;\n date_style: string;\n languages: string[];\n name: string;\n primary_language: string;\n timezone: string;\n uuid: string;\n}\n\nexport interface CanvasPositions {\n [uuid: string]: FlowPosition;\n}\n\nexport interface Activity {\n segments: { [exitToDestinationKey: string]: number };\n nodes: { [nodeUuid: string]: number };\n}\n\nexport interface AppState {\n flowDefinition: FlowDefinition;\n flowInfo: FlowInfo;\n issuesByNode: Map<string, FlowIssue[]>;\n issuesByAction: Map<string, FlowIssue[]>;\n\n languageCode: string;\n languageNames: { [code: string]: Language };\n workspace: Workspace;\n isTranslating: boolean;\n viewingRevision: boolean;\n\n dirtyDate: Date | null;\n\n canvasSize: { width: number; height: number };\n activity: Activity | null;\n simulatorActivity: Activity | null;\n activityEndpoint: string | null;\n simulatorActive: boolean;\n\n getCurrentActivity: () => Activity | null;\n fetchRevision: (endpoint: string, id?: string) => void;\n fetchWorkspace: (endpoint: string) => Promise<void>;\n fetchAllLanguages: (endpoint: string) => Promise<void>;\n fetchActivity: (endpoint: string) => Promise<void>;\n setActivityEndpoint: (endpoint: string) => void;\n updateActivity: (activity: Activity) => void;\n updateSimulatorActivity: (activity: Activity) => void;\n setSimulatorActive: (active: boolean) => void;\n\n getFlowResults: () => InfoResult[];\n getResultByKey(id: any): InfoResult;\n\n setFlowContents: (flow: FlowContents) => void;\n setFlowInfo: (info: FlowInfo) => void;\n setRevision: (revision: number) => void;\n setLanguageCode: (languageCode: string) => void;\n setDirtyDate: (date: Date) => void;\n expandCanvas: (width: number, height: number) => void;\n\n updateNode(\n uuid: string,\n node: { actions: Action[]; uuid: string; exits: Exit[]; router?: Router }\n ): unknown;\n updateNodeUIConfig(uuid: string, config: Record<string, any>): unknown;\n updateConnection(\n nodeUuid: string,\n exitUuid: string,\n destinationNodeUuid: string\n ): unknown;\n updateCanvasPositions: (positions: CanvasPositions) => void;\n removeNodes: (uuids: string[]) => void;\n removeStickyNotes: (uuids: string[]) => void;\n updateStickyNote(uuid: string, sticky: StickyNote): void;\n createStickyNote(position: FlowPosition): string;\n createNode(nodeType: string, position: FlowPosition): string;\n addNode(node: Node, nodeUI: NodeUI): void;\n updateLocalization(\n languageCode: string,\n actionUuid: string,\n localizationData: Record<string, any>\n ): void;\n clearFlowData: () => void;\n setTranslationFilters: (filters: { categories: boolean }) => void;\n markAutoTranslated: (\n languageCode: string,\n uuid: string,\n attributes: string[]\n ) => void;\n}\n\nexport const zustand = createStore<AppState>()(\n subscribeWithSelector(\n immer((set, get) => ({\n languageNames: {},\n canvasSize: { width: 0, height: 0 },\n languageCode: '',\n workspace: null,\n flowDefinition: null,\n flowInfo: null,\n issuesByNode: new Map(),\n issuesByAction: new Map(),\n isTranslating: false,\n viewingRevision: false,\n dirtyDate: null,\n activity: null,\n simulatorActivity: null,\n activityEndpoint: null,\n simulatorActive: false,\n\n setDirtyDate: (date: Date) => {\n set((state: AppState) => {\n state.dirtyDate = date;\n });\n },\n\n fetchRevision: async (endpoint: string, id: string = null) => {\n const viewingRevision = !!id && id !== 'latest';\n if (!id) {\n id = 'latest';\n }\n const response = await fetch(\n `${endpoint}/${id}/?version=${FLOW_SPEC_VERSION}`\n );\n\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n const data = (await response.json()) as FlowContents;\n reclassifyTerminalNodes(data.definition);\n reclassifyVoiceWaitNodes(data.definition);\n const issueMaps = buildIssueMaps(data.info?.issues);\n set({\n flowInfo: data.info,\n flowDefinition: data.definition,\n viewingRevision,\n issuesByNode: issueMaps.byNode,\n issuesByAction: issueMaps.byAction\n });\n },\n\n fetchWorkspace: async (endpoint) => {\n const response = await fetch(endpoint);\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n const data = await response.json();\n set({ workspace: data });\n },\n\n fetchAllLanguages: async (endpoint) => {\n const results = await fetchResults(endpoint);\n\n // convert array to map for easier lookup\n const allLanguages = results.reduce(function (\n languages: any,\n result: any\n ) {\n languages[result.value] = result.name;\n return languages;\n },\n {});\n\n set({ languageNames: allLanguages });\n },\n\n setActivityEndpoint: (endpoint: string) => {\n set({ activityEndpoint: endpoint });\n },\n\n fetchActivity: async (endpoint: string) => {\n try {\n const response = await fetch(endpoint);\n if (!response.ok) {\n return;\n }\n const data = await response.json();\n set({ activity: data });\n } catch (error) {\n console.error('Failed to fetch activity:', error);\n }\n },\n\n updateActivity: (activity: Activity) => {\n set({ activity });\n },\n\n updateSimulatorActivity: (activity: Activity) => {\n set({ simulatorActivity: activity });\n },\n\n setSimulatorActive: (active: boolean) => {\n set({ simulatorActive: active });\n },\n\n getCurrentActivity: () => {\n const state = get();\n return state.simulatorActive ? state.simulatorActivity : state.activity;\n },\n\n getFlowResults: () => {\n const state = get();\n return state.flowInfo.results;\n },\n\n getResultByKey: (id: any) => {\n const state = get();\n const results = state.flowInfo.results;\n return results.find((result) => result.key === id);\n },\n\n getLanguage: () => {\n const state = get();\n const languageCode = state.languageCode;\n const languageNames = state.languageNames;\n return { name: languageNames[languageCode], code: languageCode };\n },\n\n clearFlowData: () => {\n set({\n flowDefinition: null,\n flowInfo: null,\n issuesByNode: new Map(),\n issuesByAction: new Map(),\n activity: null,\n simulatorActivity: null,\n simulatorActive: false,\n dirtyDate: null,\n viewingRevision: false\n });\n },\n\n // todo: eventually we should be doing the fetching\n setFlowContents: (flow: FlowContents) => {\n set((state: AppState) => {\n const flowLang = flow.definition.language;\n // Clone to ensure mutable for sorting\n state.flowDefinition = {\n ...flow.definition,\n nodes: [...(flow.definition.nodes || [])]\n };\n state.flowInfo = flow.info;\n const issueMaps = buildIssueMaps(flow.info?.issues);\n state.issuesByNode = issueMaps.byNode;\n state.issuesByAction = issueMaps.byAction;\n // Reset to the flow's default language when loading a new flow\n state.languageCode = flowLang;\n state.isTranslating = false;\n\n reclassifyTerminalNodes(state.flowDefinition);\n reclassifyVoiceWaitNodes(state.flowDefinition);\n\n // Sort nodes by position when loading flow\n if (state.flowDefinition?.nodes && state.flowDefinition?._ui?.nodes) {\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n }\n });\n },\n\n setFlowInfo: (info: FlowInfo) => {\n set((state: AppState) => {\n state.flowInfo = info;\n const issueMaps = buildIssueMaps(info?.issues);\n state.issuesByNode = issueMaps.byNode;\n state.issuesByAction = issueMaps.byAction;\n });\n },\n\n setRevision: (revision: number) => {\n set((state: AppState) => {\n state.flowDefinition.revision = revision;\n });\n },\n\n setLanguageCode: (languageCode: string) => {\n set((state: AppState) => {\n state.languageCode = languageCode;\n state.isTranslating = state.flowDefinition.language !== languageCode;\n });\n },\n\n expandCanvas: (width: number, height: number) => {\n set((state: AppState) => {\n const minWidth = Math.max(\n state.canvasSize.width,\n width + CANVAS_PADDING\n );\n const minHeight = Math.max(\n state.canvasSize.height,\n height + CANVAS_PADDING\n );\n\n state.canvasSize.width = minWidth;\n state.canvasSize.height = minHeight;\n });\n },\n\n updateCanvasPositions: (positions: CanvasPositions) => {\n set((state: AppState) => {\n for (const uuid in positions) {\n // todo: add nodes that are created and then moved, for now ignore\n if (state.flowDefinition._ui.nodes[uuid]) {\n state.flowDefinition._ui.nodes[uuid].position = positions[uuid];\n }\n\n // otherwise, it might be a sticky\n else if (state.flowDefinition._ui.stickies[uuid]) {\n state.flowDefinition._ui.stickies[uuid].position =\n positions[uuid];\n }\n }\n\n // Sort nodes by position since positions may have changed\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n\n state.dirtyDate = new Date();\n });\n },\n\n removeNodes: (uuids: string[]) => {\n set((state: AppState) => {\n for (const uuid of uuids) {\n delete state.flowDefinition._ui.nodes[uuid];\n }\n\n state.flowDefinition = produce(state.flowDefinition, (draft) => {\n // For each node being removed, check if we should reroute connections\n uuids.forEach((removedUuid) => {\n const removedNode = draft.nodes.find(\n (n) => n.uuid === removedUuid\n );\n\n if (!removedNode || !removedNode.exits.length) return;\n\n // Get all destinations (filter out null/undefined)\n const destinations = removedNode.exits\n .map((exit) => exit.destination_uuid)\n .filter((dest) => dest);\n\n // Only proceed if all exits have destinations and they all point to the same place\n if (\n destinations.length === removedNode.exits.length &&\n destinations.every((dest) => dest === destinations[0])\n ) {\n const targetDestination = destinations[0];\n // Don't reroute if the target is also being removed\n if (uuids.includes(targetDestination)) return;\n\n // Find all nodes with exits pointing to the node being removed\n draft.nodes.forEach((node) => {\n node.exits.forEach((exit) => {\n if (exit.destination_uuid === removedUuid) {\n // Reroute to the same destination the removed node was going to\n exit.destination_uuid = targetDestination;\n }\n });\n });\n }\n });\n\n // Remove the nodes\n draft.nodes = draft.nodes.filter(\n (node) => !uuids.includes(node.uuid)\n );\n\n // Clear any remaining connections to removed nodes that weren't rerouted\n draft.nodes.forEach((node) => {\n node.exits.forEach((exit) => {\n if (uuids.includes(exit.destination_uuid)) {\n exit.destination_uuid = null;\n }\n });\n });\n\n // Sort nodes by position\n sortNodesByPosition(draft.nodes, draft._ui.nodes);\n });\n\n state.dirtyDate = new Date();\n });\n },\n\n removeStickyNotes: (uuids: string[]) => {\n set((state: AppState) => {\n if (state.flowDefinition._ui?.stickies) {\n for (const uuid of uuids) {\n delete state.flowDefinition._ui.stickies[uuid];\n }\n }\n state.dirtyDate = new Date();\n });\n },\n\n updateNode: (uuid: string, newNode: Node) => {\n set((state: AppState) => {\n const node = state.flowDefinition?.nodes.find((n) => n.uuid === uuid);\n if (node) {\n node.actions = newNode.actions;\n node.uuid = newNode.uuid;\n node.exits = newNode.exits;\n node.router = newNode.router;\n }\n state.dirtyDate = new Date();\n });\n },\n\n updateNodeUIConfig: (uuid: string, config: Record<string, any>) => {\n set((state: AppState) => {\n if (state.flowDefinition._ui.nodes[uuid]) {\n // Handle type separately if provided\n if (config.type !== undefined) {\n state.flowDefinition._ui.nodes[uuid].type = config.type;\n }\n\n // Update config (excluding type)\n if (!state.flowDefinition._ui.nodes[uuid].config) {\n state.flowDefinition._ui.nodes[uuid].config = {};\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { type, ...configWithoutType } = config;\n Object.assign(\n state.flowDefinition._ui.nodes[uuid].config,\n configWithoutType\n );\n }\n state.dirtyDate = new Date();\n });\n },\n\n updateConnection: (\n nodeUuid: string,\n exitUuid: string,\n destinationNodeUuid: string\n ) => {\n /* console.log('Upating connection:', {\n nodeUuid,\n exitUuid,\n destinationNodeUuid\n });*/\n set((state: AppState) => {\n // Find the exit with this UUID\n const node = state.flowDefinition.nodes.find(\n (node) => node.uuid === nodeUuid\n );\n\n const exit = node?.exits.find((e) => e.uuid === exitUuid);\n if (exit) {\n // Update the destination\n exit.destination_uuid = destinationNodeUuid;\n state.dirtyDate = new Date();\n }\n });\n },\n\n updateStickyNote: (uuid: string, sticky: StickyNote) => {\n set((state: AppState) => {\n if (!state.flowDefinition._ui.stickies) {\n state.flowDefinition._ui.stickies = {};\n }\n state.flowDefinition._ui.stickies[uuid] = sticky;\n state.dirtyDate = new Date();\n });\n },\n\n createStickyNote: (position: FlowPosition): string => {\n const uuid = generateUUID();\n set((state: AppState) => {\n if (!state.flowDefinition._ui.stickies) {\n state.flowDefinition._ui.stickies = {};\n }\n\n const newSticky: StickyNote = {\n position,\n title: '',\n body: '',\n color: 'yellow'\n };\n\n state.flowDefinition._ui.stickies[uuid] = newSticky;\n state.dirtyDate = new Date();\n });\n return uuid;\n },\n\n createNode: (nodeType: string, position: FlowPosition): string => {\n const uuid = generateUUID();\n const exitUuid = generateUUID();\n\n set((state: AppState) => {\n // Create a basic node with a single exit\n const newNode: Node = {\n uuid,\n actions: [],\n exits: [\n {\n uuid: exitUuid,\n destination_uuid: null\n }\n ]\n };\n\n // Add the node to the flow definition\n state.flowDefinition.nodes.push(newNode);\n\n // Set up UI for the node\n if (!state.flowDefinition._ui.nodes) {\n state.flowDefinition._ui.nodes = {};\n }\n\n state.flowDefinition._ui.nodes[uuid] = {\n position,\n type: nodeType as any,\n config: {}\n };\n\n // Sort nodes by position\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n\n state.dirtyDate = new Date();\n });\n\n return uuid;\n },\n\n addNode: (node: Node, nodeUI: NodeUI) => {\n set((state: AppState) => {\n // Add the node to the flow definition\n state.flowDefinition.nodes.push(node);\n\n // Set up UI for the node\n if (!state.flowDefinition._ui.nodes) {\n state.flowDefinition._ui.nodes = {};\n }\n\n state.flowDefinition._ui.nodes[node.uuid] = nodeUI;\n\n // Sort nodes by position\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n\n state.dirtyDate = new Date();\n });\n },\n\n updateLocalization: (\n languageCode: string,\n actionUuid: string,\n localizationData: Record<string, any>\n ) => {\n set((state: AppState) => {\n // Initialize localization structure if it doesn't exist\n if (!state.flowDefinition.localization) {\n state.flowDefinition.localization = {};\n }\n\n if (!state.flowDefinition.localization[languageCode]) {\n state.flowDefinition.localization[languageCode] = {};\n }\n\n // Update or remove the localization for this action\n if (Object.keys(localizationData).length > 0) {\n state.flowDefinition.localization[languageCode][actionUuid] =\n localizationData;\n } else {\n // If no localized values, remove the entry\n delete state.flowDefinition.localization[languageCode][actionUuid];\n }\n\n // Clean up empty language sections\n if (\n Object.keys(state.flowDefinition.localization[languageCode])\n .length === 0\n ) {\n delete state.flowDefinition.localization[languageCode];\n }\n\n // Clean up empty localization object\n if (Object.keys(state.flowDefinition.localization).length === 0) {\n delete state.flowDefinition.localization;\n }\n\n state.dirtyDate = new Date();\n });\n },\n\n setTranslationFilters: (filters: { categories: boolean }) => {\n set((state: AppState) => {\n if (!state.flowDefinition?._ui) {\n return;\n }\n\n const currentFilters = state.flowDefinition._ui\n .translation_filters || {\n categories: false\n };\n\n state.flowDefinition._ui.translation_filters = {\n ...currentFilters,\n categories: !!filters.categories\n };\n\n state.dirtyDate = new Date();\n });\n },\n\n markAutoTranslated: (\n languageCode: string,\n uuid: string,\n attributes: string[]\n ) => {\n set((state: AppState) => {\n if (!state.flowDefinition?._ui) {\n return;\n }\n\n if (!state.flowDefinition._ui.auto_translations) {\n state.flowDefinition._ui.auto_translations = {};\n }\n\n if (!state.flowDefinition._ui.auto_translations[languageCode]) {\n state.flowDefinition._ui.auto_translations[languageCode] = {};\n }\n\n const existing =\n state.flowDefinition._ui.auto_translations[languageCode][uuid] ||\n [];\n\n const merged = Array.from(\n new Set([...existing, ...(attributes || [])])\n );\n\n state.flowDefinition._ui.auto_translations[languageCode][uuid] =\n merged;\n state.dirtyDate = new Date();\n });\n }\n }))\n )\n);\n\ntype SelectorAwareStoreApi<S extends object> = StoreApi<S> & {\n subscribe: <U>(\n selector: (state: S) => U,\n listener: (value: U, previous: U) => void\n ) => () => void;\n};\n\n/**\n * Custom Lit property decorator that binds a property to a Zustand store subscription.\n *\n * @param store - The Zustand store to subscribe to.\n * @param selector - A function selecting the slice of state to bind to the property.\n */\nexport function fromStore<S extends object, V = unknown>(\n store: SelectorAwareStoreApi<S>,\n selector: (state: S) => V\n): PropertyDecorator {\n return (proto: any, name: string | symbol) => {\n property()(proto, name as string);\n\n const connectedKey = 'connectedCallback';\n const disconnectedKey = 'disconnectedCallback';\n\n const userConnected = proto[connectedKey];\n const userDisconnected = proto[disconnectedKey];\n\n proto[connectedKey] = function () {\n this._zustandUnsubscribe ??= {};\n this[name] = selector(store.getState());\n\n this._zustandUnsubscribe[name] = store.subscribe(selector, (val: V) => {\n this[name] = val;\n });\n\n if (userConnected) userConnected.call(this);\n };\n\n proto[disconnectedKey] = function () {\n this._zustandUnsubscribe?.[name]?.();\n if (userDisconnected) userDisconnected.call(this);\n };\n };\n}\n"]}
@@ -62,5 +62,40 @@ describe('add_contact_groups action config', () => {
62
62
  ]
63
63
  }, 'descriptive-group-names');
64
64
  });
65
+ describe('metadata stripping', () => {
66
+ it('should strip superfluous API metadata from groups', () => {
67
+ const formData = {
68
+ uuid: 'test-uuid',
69
+ groups: [
70
+ {
71
+ uuid: 'group-1',
72
+ name: 'VIP Customers',
73
+ query: 'status = vip',
74
+ status: 'ready',
75
+ count: 150,
76
+ system: false
77
+ },
78
+ {
79
+ uuid: 'group-2',
80
+ name: 'Beta Testers',
81
+ query: null,
82
+ status: 'ready',
83
+ count: 45,
84
+ system: false
85
+ }
86
+ ]
87
+ };
88
+ const action = add_contact_groups.fromFormData(formData);
89
+ expect(action.groups).to.have.lengthOf(2);
90
+ expect(action.groups[0]).to.deep.equal({
91
+ uuid: 'group-1',
92
+ name: 'VIP Customers'
93
+ });
94
+ expect(action.groups[1]).to.deep.equal({
95
+ uuid: 'group-2',
96
+ name: 'Beta Testers'
97
+ });
98
+ });
99
+ });
65
100
  });
66
101
  //# sourceMappingURL=add_contact_groups.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"add_contact_groups.test.js","sourceRoot":"","sources":["../../../test/actions/add_contact_groups.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAE/E,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;GAEG;AACH,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;IAChD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,CAAC;IAExE,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAE7B,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;YAC1B,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;SACvC,EACf,cAAc,CACf,CAAC;QAEF,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE;gBACN,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE;gBAC1C,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,wBAAwB,EAAE;gBACnD,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE;aAC1C;SACY,EACf,iBAAiB,CAClB,CAAC;QAEF,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE;gBACN;oBACE,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,wDAAwD;iBAC/D;gBACD;oBACE,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,sDAAsD;iBAC7D;aACF;SACY,EACf,kBAAkB,CACnB,CAAC;QAEF,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE;gBACN,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE;gBACvC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,gBAAgB,EAAE;gBAC3C,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE;gBACzC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,kBAAkB,EAAE;gBAC7C,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;aACrC;SACY,EACf,aAAa,CACd,CAAC;QAEF,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE;gBACN,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,oCAAoC,EAAE;gBAC/D,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,sCAAsC,EAAE;gBACjE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,iCAAiC,EAAE;aAC7D;SACY,EACf,yBAAyB,CAC1B,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { add_contact_groups } from '../../src/flow/actions/add_contact_groups';\nimport { AddToGroup } from '../../src/store/flow-definition';\nimport { ActionTest } from '../ActionHelper';\n\n/**\n * Test suite for the add_contact_groups action configuration.\n */\ndescribe('add_contact_groups action config', () => {\n const helper = new ActionTest(add_contact_groups, 'add_contact_groups');\n\n describe('basic properties', () => {\n helper.testBasicProperties();\n\n it('has correct name', () => {\n expect(add_contact_groups.name).to.equal('Add to Group');\n });\n });\n\n describe('action scenarios', () => {\n helper.testAction(\n {\n uuid: 'test-action-1',\n type: 'add_contact_groups',\n groups: [{ uuid: 'group-1', name: 'VIP Customers' }]\n } as AddToGroup,\n 'single-group'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-2',\n type: 'add_contact_groups',\n groups: [\n { uuid: 'group-1', name: 'VIP Customers' },\n { uuid: 'group-2', name: 'Newsletter Subscribers' },\n { uuid: 'group-3', name: 'Beta Testers' }\n ]\n } as AddToGroup,\n 'multiple-groups'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-3',\n type: 'add_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'Very Long Group Name That Might Wrap to Multiple Lines'\n },\n {\n uuid: 'group-2',\n name: 'Another Extremely Long Group Name for Testing Layout'\n }\n ]\n } as AddToGroup,\n 'long-group-names'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-4',\n type: 'add_contact_groups',\n groups: [\n { uuid: 'group-1', name: 'Sales Team' },\n { uuid: 'group-2', name: 'Marketing Team' },\n { uuid: 'group-3', name: 'Support Team' },\n { uuid: 'group-4', name: 'Development Team' },\n { uuid: 'group-5', name: 'QA Team' }\n ]\n } as AddToGroup,\n 'many-groups'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-5',\n type: 'add_contact_groups',\n groups: [\n { uuid: 'group-1', name: 'Customers - Premium Plan (Monthly)' },\n { uuid: 'group-2', name: 'Customers - Enterprise Plan (Annual)' },\n { uuid: 'group-3', name: 'Trial Users - 30 Day Free Trial' }\n ]\n } as AddToGroup,\n 'descriptive-group-names'\n );\n });\n});\n"]}
1
+ {"version":3,"file":"add_contact_groups.test.js","sourceRoot":"","sources":["../../../test/actions/add_contact_groups.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { add_contact_groups } from '../../src/flow/actions/add_contact_groups';\nimport { AddToGroup } from '../../src/store/flow-definition';\nimport { ActionTest } from '../ActionHelper';\n\n/**\n * Test suite for the add_contact_groups action configuration.\n */\ndescribe('add_contact_groups action config', () => {\n const helper = new ActionTest(add_contact_groups, 'add_contact_groups');\n\n describe('basic properties', () => {\n helper.testBasicProperties();\n\n it('has correct name', () => {\n expect(add_contact_groups.name).to.equal('Add to Group');\n });\n });\n\n describe('action scenarios', () => {\n helper.testAction(\n {\n uuid: 'test-action-1',\n type: 'add_contact_groups',\n groups: [{ uuid: 'group-1', name: 'VIP Customers' }]\n } as AddToGroup,\n 'single-group'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-2',\n type: 'add_contact_groups',\n groups: [\n { uuid: 'group-1', name: 'VIP Customers' },\n { uuid: 'group-2', name: 'Newsletter Subscribers' },\n { uuid: 'group-3', name: 'Beta Testers' }\n ]\n } as AddToGroup,\n 'multiple-groups'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-3',\n type: 'add_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'Very Long Group Name That Might Wrap to Multiple Lines'\n },\n {\n uuid: 'group-2',\n name: 'Another Extremely Long Group Name for Testing Layout'\n }\n ]\n } as AddToGroup,\n 'long-group-names'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-4',\n type: 'add_contact_groups',\n groups: [\n { uuid: 'group-1', name: 'Sales Team' },\n { uuid: 'group-2', name: 'Marketing Team' },\n { uuid: 'group-3', name: 'Support Team' },\n { uuid: 'group-4', name: 'Development Team' },\n { uuid: 'group-5', name: 'QA Team' }\n ]\n } as AddToGroup,\n 'many-groups'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-5',\n type: 'add_contact_groups',\n groups: [\n { uuid: 'group-1', name: 'Customers - Premium Plan (Monthly)' },\n { uuid: 'group-2', name: 'Customers - Enterprise Plan (Annual)' },\n { uuid: 'group-3', name: 'Trial Users - 30 Day Free Trial' }\n ]\n } as AddToGroup,\n 'descriptive-group-names'\n );\n });\n\n describe('metadata stripping', () => {\n it('should strip superfluous API metadata from groups', () => {\n const formData = {\n uuid: 'test-uuid',\n groups: [\n {\n uuid: 'group-1',\n name: 'VIP Customers',\n query: 'status = vip',\n status: 'ready',\n count: 150,\n system: false\n },\n {\n uuid: 'group-2',\n name: 'Beta Testers',\n query: null,\n status: 'ready',\n count: 45,\n system: false\n }\n ]\n };\n\n const action = add_contact_groups.fromFormData(formData) as AddToGroup;\n\n expect(action.groups).to.have.lengthOf(2);\n expect(action.groups[0]).to.deep.equal({\n uuid: 'group-1',\n name: 'VIP Customers'\n });\n expect(action.groups[1]).to.deep.equal({\n uuid: 'group-2',\n name: 'Beta Testers'\n });\n });\n });\n});\n"]}
@@ -0,0 +1,53 @@
1
+ import { expect } from '@open-wc/testing';
2
+ import { add_input_labels } from '../../src/flow/actions/add_input_labels';
3
+ import { ActionTest } from '../ActionHelper';
4
+ /**
5
+ * Test suite for the add_input_labels action configuration.
6
+ */
7
+ describe('add_input_labels action config', () => {
8
+ const helper = new ActionTest(add_input_labels, 'add_input_labels');
9
+ describe('basic properties', () => {
10
+ helper.testBasicProperties();
11
+ it('has correct name', () => {
12
+ expect(add_input_labels.name).to.equal('Add Input Labels');
13
+ });
14
+ });
15
+ describe('action scenarios', () => {
16
+ helper.testAction({
17
+ uuid: 'test-action-1',
18
+ type: 'add_input_labels',
19
+ labels: [{ uuid: 'label-1', name: 'Important' }]
20
+ }, 'single-label');
21
+ helper.testAction({
22
+ uuid: 'test-action-2',
23
+ type: 'add_input_labels',
24
+ labels: [
25
+ { uuid: 'label-1', name: 'Important' },
26
+ { uuid: 'label-2', name: 'Follow Up' },
27
+ { uuid: 'label-3', name: 'Spam' }
28
+ ]
29
+ }, 'multiple-labels');
30
+ });
31
+ describe('metadata stripping', () => {
32
+ it('should strip superfluous API metadata from labels', () => {
33
+ const formData = {
34
+ uuid: 'test-uuid',
35
+ labels: [
36
+ { uuid: 'label-1', name: 'Important', count: 250 },
37
+ { uuid: 'label-2', name: 'Follow Up', count: 42 }
38
+ ]
39
+ };
40
+ const action = add_input_labels.fromFormData(formData);
41
+ expect(action.labels).to.have.lengthOf(2);
42
+ expect(action.labels[0]).to.deep.equal({
43
+ uuid: 'label-1',
44
+ name: 'Important'
45
+ });
46
+ expect(action.labels[1]).to.deep.equal({
47
+ uuid: 'label-2',
48
+ name: 'Follow Up'
49
+ });
50
+ });
51
+ });
52
+ });
53
+ //# sourceMappingURL=add_input_labels.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add_input_labels.test.js","sourceRoot":"","sources":["../../../test/actions/add_input_labels.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAE3E,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;GAEG;AACH,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;IAEpE,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAE7B,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;YAC1B,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;SAC/B,EACnB,cAAc,CACf,CAAC;QAEF,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE;gBACN,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE;gBACtC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE;gBACtC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE;aAClC;SACgB,EACnB,iBAAiB,CAClB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;YAC3D,MAAM,QAAQ,GAAG;gBACf,IAAI,EAAE,WAAW;gBACjB,MAAM,EAAE;oBACN,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE;oBAClD,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,EAAE;iBAClD;aACF,CAAC;YAEF,MAAM,MAAM,GAAG,gBAAgB,CAAC,YAAY,CAAC,QAAQ,CAAmB,CAAC;YAEzE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC1C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;gBACrC,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,WAAW;aAClB,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;gBACrC,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,WAAW;aAClB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { add_input_labels } from '../../src/flow/actions/add_input_labels';\nimport { AddInputLabels } from '../../src/store/flow-definition';\nimport { ActionTest } from '../ActionHelper';\n\n/**\n * Test suite for the add_input_labels action configuration.\n */\ndescribe('add_input_labels action config', () => {\n const helper = new ActionTest(add_input_labels, 'add_input_labels');\n\n describe('basic properties', () => {\n helper.testBasicProperties();\n\n it('has correct name', () => {\n expect(add_input_labels.name).to.equal('Add Input Labels');\n });\n });\n\n describe('action scenarios', () => {\n helper.testAction(\n {\n uuid: 'test-action-1',\n type: 'add_input_labels',\n labels: [{ uuid: 'label-1', name: 'Important' }]\n } as AddInputLabels,\n 'single-label'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-2',\n type: 'add_input_labels',\n labels: [\n { uuid: 'label-1', name: 'Important' },\n { uuid: 'label-2', name: 'Follow Up' },\n { uuid: 'label-3', name: 'Spam' }\n ]\n } as AddInputLabels,\n 'multiple-labels'\n );\n });\n\n describe('metadata stripping', () => {\n it('should strip superfluous API metadata from labels', () => {\n const formData = {\n uuid: 'test-uuid',\n labels: [\n { uuid: 'label-1', name: 'Important', count: 250 },\n { uuid: 'label-2', name: 'Follow Up', count: 42 }\n ]\n };\n\n const action = add_input_labels.fromFormData(formData) as AddInputLabels;\n\n expect(action.labels).to.have.lengthOf(2);\n expect(action.labels[0]).to.deep.equal({\n uuid: 'label-1',\n name: 'Important'\n });\n expect(action.labels[1]).to.deep.equal({\n uuid: 'label-2',\n name: 'Follow Up'\n });\n });\n });\n});\n"]}
@@ -0,0 +1,71 @@
1
+ import { expect } from '@open-wc/testing';
2
+ import { enter_flow } from '../../src/flow/actions/enter_flow';
3
+ import { ActionTest } from '../ActionHelper';
4
+ /**
5
+ * Test suite for the enter_flow action configuration.
6
+ */
7
+ describe('enter_flow action config', () => {
8
+ const helper = new ActionTest(enter_flow, 'enter_flow');
9
+ describe('basic properties', () => {
10
+ helper.testBasicProperties();
11
+ it('has correct name', () => {
12
+ expect(enter_flow.name).to.equal('Enter a Flow');
13
+ });
14
+ });
15
+ describe('action scenarios', () => {
16
+ helper.testAction({
17
+ uuid: 'test-action-1',
18
+ type: 'enter_flow',
19
+ terminal: true,
20
+ flow: { uuid: 'flow-1', name: 'Registration Flow' }
21
+ }, 'basic-flow');
22
+ helper.testAction({
23
+ uuid: 'test-action-2',
24
+ type: 'enter_flow',
25
+ terminal: true,
26
+ flow: {
27
+ uuid: 'flow-2',
28
+ name: 'Very Long Flow Name That Tests Layout Wrapping'
29
+ }
30
+ }, 'long-flow-name');
31
+ });
32
+ describe('metadata stripping', () => {
33
+ it('should strip superfluous API metadata from flow', () => {
34
+ const formData = {
35
+ uuid: 'test-uuid',
36
+ flow: [
37
+ {
38
+ uuid: 'flow-1',
39
+ name: 'Registration Flow',
40
+ type: 'message',
41
+ archived: false,
42
+ labels: [],
43
+ expires: 720,
44
+ runs: { active: 0, waiting: 5, completed: 100 },
45
+ results: [],
46
+ parent_refs: [],
47
+ created_on: '2024-01-01T00:00:00.000Z',
48
+ modified_on: '2024-06-15T12:00:00.000Z'
49
+ }
50
+ ]
51
+ };
52
+ const action = enter_flow.fromFormData(formData);
53
+ expect(action.flow).to.deep.equal({
54
+ uuid: 'flow-1',
55
+ name: 'Registration Flow'
56
+ });
57
+ });
58
+ it('should handle flow selected via value key', () => {
59
+ const formData = {
60
+ uuid: 'test-uuid',
61
+ flow: [{ value: 'flow-1', name: 'Test Flow' }]
62
+ };
63
+ const action = enter_flow.fromFormData(formData);
64
+ expect(action.flow).to.deep.equal({
65
+ uuid: 'flow-1',
66
+ name: 'Test Flow'
67
+ });
68
+ });
69
+ });
70
+ });
71
+ //# sourceMappingURL=enter_flow.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enter_flow.test.js","sourceRoot":"","sources":["../../../test/actions/enter_flow.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAE/D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;GAEG;AACH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAExD,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAE7B,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;YAC1B,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,YAAY;YAClB,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,mBAAmB,EAAE;SACvC,EACd,YAAY,CACb,CAAC;QAEF,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,YAAY;YAClB,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,gDAAgD;aACvD;SACW,EACd,gBAAgB,CACjB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,QAAQ,GAAG;gBACf,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE;oBACJ;wBACE,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,mBAAmB;wBACzB,IAAI,EAAE,SAAS;wBACf,QAAQ,EAAE,KAAK;wBACf,MAAM,EAAE,EAAE;wBACV,OAAO,EAAE,GAAG;wBACZ,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE;wBAC/C,OAAO,EAAE,EAAE;wBACX,WAAW,EAAE,EAAE;wBACf,UAAU,EAAE,0BAA0B;wBACtC,WAAW,EAAE,0BAA0B;qBACxC;iBACF;aACF,CAAC;YAEF,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAc,CAAC;YAE9D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;gBAChC,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,mBAAmB;aAC1B,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,QAAQ,GAAG;gBACf,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;aAC/C,CAAC;YAEF,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAc,CAAC;YAE9D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;gBAChC,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,WAAW;aAClB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { enter_flow } from '../../src/flow/actions/enter_flow';\nimport { EnterFlow } from '../../src/store/flow-definition';\nimport { ActionTest } from '../ActionHelper';\n\n/**\n * Test suite for the enter_flow action configuration.\n */\ndescribe('enter_flow action config', () => {\n const helper = new ActionTest(enter_flow, 'enter_flow');\n\n describe('basic properties', () => {\n helper.testBasicProperties();\n\n it('has correct name', () => {\n expect(enter_flow.name).to.equal('Enter a Flow');\n });\n });\n\n describe('action scenarios', () => {\n helper.testAction(\n {\n uuid: 'test-action-1',\n type: 'enter_flow',\n terminal: true,\n flow: { uuid: 'flow-1', name: 'Registration Flow' }\n } as EnterFlow,\n 'basic-flow'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-2',\n type: 'enter_flow',\n terminal: true,\n flow: {\n uuid: 'flow-2',\n name: 'Very Long Flow Name That Tests Layout Wrapping'\n }\n } as EnterFlow,\n 'long-flow-name'\n );\n });\n\n describe('metadata stripping', () => {\n it('should strip superfluous API metadata from flow', () => {\n const formData = {\n uuid: 'test-uuid',\n flow: [\n {\n uuid: 'flow-1',\n name: 'Registration Flow',\n type: 'message',\n archived: false,\n labels: [],\n expires: 720,\n runs: { active: 0, waiting: 5, completed: 100 },\n results: [],\n parent_refs: [],\n created_on: '2024-01-01T00:00:00.000Z',\n modified_on: '2024-06-15T12:00:00.000Z'\n }\n ]\n };\n\n const action = enter_flow.fromFormData(formData) as EnterFlow;\n\n expect(action.flow).to.deep.equal({\n uuid: 'flow-1',\n name: 'Registration Flow'\n });\n });\n\n it('should handle flow selected via value key', () => {\n const formData = {\n uuid: 'test-uuid',\n flow: [{ value: 'flow-1', name: 'Test Flow' }]\n };\n\n const action = enter_flow.fromFormData(formData) as EnterFlow;\n\n expect(action.flow).to.deep.equal({\n uuid: 'flow-1',\n name: 'Test Flow'\n });\n });\n });\n});\n"]}