@nyaruka/temba-components 0.129.3 → 0.129.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (304) hide show
  1. package/.eslintrc.js +1 -0
  2. package/.github/workflows/build.yml +135 -3
  3. package/CHANGELOG.md +19 -0
  4. package/demo/data/flows/sample-flow.json +110 -87
  5. package/demo/field-config-demo.html +135 -0
  6. package/dist/temba-components.js +1257 -675
  7. package/dist/temba-components.js.map +1 -1
  8. package/docs/ActionEditor-Migration.md +118 -0
  9. package/out-tsc/src/events.js.map +1 -1
  10. package/out-tsc/src/flow/{EditorNode.js → CanvasNode.js} +345 -42
  11. package/out-tsc/src/flow/CanvasNode.js.map +1 -0
  12. package/out-tsc/src/flow/Editor.js +107 -3
  13. package/out-tsc/src/flow/Editor.js.map +1 -1
  14. package/out-tsc/src/flow/NodeEditor.js +1211 -0
  15. package/out-tsc/src/flow/NodeEditor.js.map +1 -0
  16. package/out-tsc/src/flow/Plumber.js +0 -6
  17. package/out-tsc/src/flow/Plumber.js.map +1 -1
  18. package/out-tsc/src/flow/actions/add_contact_groups.js +40 -0
  19. package/out-tsc/src/flow/actions/add_contact_groups.js.map +1 -0
  20. package/out-tsc/src/flow/actions/add_contact_urn.js +16 -0
  21. package/out-tsc/src/flow/actions/add_contact_urn.js.map +1 -0
  22. package/out-tsc/src/flow/actions/add_input_labels.js +11 -0
  23. package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -0
  24. package/out-tsc/src/flow/actions/call_classifier.js +11 -0
  25. package/out-tsc/src/flow/actions/call_classifier.js.map +1 -0
  26. package/out-tsc/src/flow/actions/call_llm.js +11 -0
  27. package/out-tsc/src/flow/actions/call_llm.js.map +1 -0
  28. package/out-tsc/src/flow/actions/call_resthook.js +11 -0
  29. package/out-tsc/src/flow/actions/call_resthook.js.map +1 -0
  30. package/out-tsc/src/flow/actions/call_webhook.js +122 -0
  31. package/out-tsc/src/flow/actions/call_webhook.js.map +1 -0
  32. package/out-tsc/src/flow/actions/enter_flow.js +14 -0
  33. package/out-tsc/src/flow/actions/enter_flow.js.map +1 -0
  34. package/out-tsc/src/flow/actions/open_ticket.js +11 -0
  35. package/out-tsc/src/flow/actions/open_ticket.js.map +1 -0
  36. package/out-tsc/src/flow/actions/play_audio.js +11 -0
  37. package/out-tsc/src/flow/actions/play_audio.js.map +1 -0
  38. package/out-tsc/src/flow/actions/remove_contact_groups.js +62 -0
  39. package/out-tsc/src/flow/actions/remove_contact_groups.js.map +1 -0
  40. package/out-tsc/src/flow/actions/request_optin.js +11 -0
  41. package/out-tsc/src/flow/actions/request_optin.js.map +1 -0
  42. package/out-tsc/src/flow/actions/say_msg.js +11 -0
  43. package/out-tsc/src/flow/actions/say_msg.js.map +1 -0
  44. package/out-tsc/src/flow/actions/send_broadcast.js +33 -0
  45. package/out-tsc/src/flow/actions/send_broadcast.js.map +1 -0
  46. package/out-tsc/src/flow/actions/send_email.js +56 -0
  47. package/out-tsc/src/flow/actions/send_email.js.map +1 -0
  48. package/out-tsc/src/flow/actions/send_msg.js +55 -0
  49. package/out-tsc/src/flow/actions/send_msg.js.map +1 -0
  50. package/out-tsc/src/flow/actions/set_contact_channel.js +12 -0
  51. package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -0
  52. package/out-tsc/src/flow/actions/set_contact_field.js +12 -0
  53. package/out-tsc/src/flow/actions/set_contact_field.js.map +1 -0
  54. package/out-tsc/src/flow/actions/set_contact_language.js +10 -0
  55. package/out-tsc/src/flow/actions/set_contact_language.js.map +1 -0
  56. package/out-tsc/src/flow/actions/set_contact_name.js +10 -0
  57. package/out-tsc/src/flow/actions/set_contact_name.js.map +1 -0
  58. package/out-tsc/src/flow/actions/set_contact_status.js +10 -0
  59. package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -0
  60. package/out-tsc/src/flow/actions/set_run_result.js +10 -0
  61. package/out-tsc/src/flow/actions/set_run_result.js.map +1 -0
  62. package/out-tsc/src/flow/actions/split_by_expression_example.js +77 -0
  63. package/out-tsc/src/flow/actions/split_by_expression_example.js.map +1 -0
  64. package/out-tsc/src/flow/actions/start_session.js +11 -0
  65. package/out-tsc/src/flow/actions/start_session.js.map +1 -0
  66. package/out-tsc/src/flow/actions/transfer_airtime.js +11 -0
  67. package/out-tsc/src/flow/actions/transfer_airtime.js.map +1 -0
  68. package/out-tsc/src/flow/config.js +88 -193
  69. package/out-tsc/src/flow/config.js.map +1 -1
  70. package/out-tsc/src/flow/nodes/execute_actions.js +4 -0
  71. package/out-tsc/src/flow/nodes/execute_actions.js.map +1 -0
  72. package/out-tsc/src/flow/nodes/split_by_airtime.js +9 -0
  73. package/out-tsc/src/flow/nodes/split_by_airtime.js.map +1 -0
  74. package/out-tsc/src/flow/nodes/split_by_contact_field.js +7 -0
  75. package/out-tsc/src/flow/nodes/split_by_contact_field.js.map +1 -0
  76. package/out-tsc/src/flow/nodes/split_by_expression.js +7 -0
  77. package/out-tsc/src/flow/nodes/split_by_expression.js.map +1 -0
  78. package/out-tsc/src/flow/nodes/split_by_groups.js +7 -0
  79. package/out-tsc/src/flow/nodes/split_by_groups.js.map +1 -0
  80. package/out-tsc/src/flow/nodes/split_by_random.js +10 -0
  81. package/out-tsc/src/flow/nodes/split_by_random.js.map +1 -0
  82. package/out-tsc/src/flow/nodes/split_by_run_result.js +7 -0
  83. package/out-tsc/src/flow/nodes/split_by_run_result.js.map +1 -0
  84. package/out-tsc/src/flow/nodes/split_by_scheme.js +7 -0
  85. package/out-tsc/src/flow/nodes/split_by_scheme.js.map +1 -0
  86. package/out-tsc/src/flow/nodes/split_by_subflow.js +9 -0
  87. package/out-tsc/src/flow/nodes/split_by_subflow.js.map +1 -0
  88. package/out-tsc/src/flow/nodes/split_by_webhook.js +18 -0
  89. package/out-tsc/src/flow/nodes/split_by_webhook.js.map +1 -0
  90. package/out-tsc/src/flow/nodes/wait_for_audio.js +7 -0
  91. package/out-tsc/src/flow/nodes/wait_for_audio.js.map +1 -0
  92. package/out-tsc/src/flow/nodes/wait_for_digits.js +7 -0
  93. package/out-tsc/src/flow/nodes/wait_for_digits.js.map +1 -0
  94. package/out-tsc/src/flow/nodes/wait_for_image.js +7 -0
  95. package/out-tsc/src/flow/nodes/wait_for_image.js.map +1 -0
  96. package/out-tsc/src/flow/nodes/wait_for_location.js +7 -0
  97. package/out-tsc/src/flow/nodes/wait_for_location.js.map +1 -0
  98. package/out-tsc/src/flow/nodes/wait_for_menu.js +7 -0
  99. package/out-tsc/src/flow/nodes/wait_for_menu.js.map +1 -0
  100. package/out-tsc/src/flow/nodes/wait_for_response.js +7 -0
  101. package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -0
  102. package/out-tsc/src/flow/nodes/wait_for_video.js +7 -0
  103. package/out-tsc/src/flow/nodes/wait_for_video.js.map +1 -0
  104. package/out-tsc/src/flow/types.js +79 -0
  105. package/out-tsc/src/flow/types.js.map +1 -0
  106. package/out-tsc/src/flow/utils.js +65 -0
  107. package/out-tsc/src/flow/utils.js.map +1 -0
  108. package/out-tsc/src/form/ArrayEditor.js +199 -0
  109. package/out-tsc/src/form/ArrayEditor.js.map +1 -0
  110. package/out-tsc/src/form/BaseListEditor.js +128 -0
  111. package/out-tsc/src/form/BaseListEditor.js.map +1 -0
  112. package/out-tsc/src/form/Checkbox.js +17 -2
  113. package/out-tsc/src/form/Checkbox.js.map +1 -1
  114. package/out-tsc/src/form/Completion.js +6 -0
  115. package/out-tsc/src/form/Completion.js.map +1 -1
  116. package/out-tsc/src/form/FormField.js +110 -11
  117. package/out-tsc/src/form/FormField.js.map +1 -1
  118. package/out-tsc/src/form/KeyValueEditor.js +223 -0
  119. package/out-tsc/src/form/KeyValueEditor.js.map +1 -0
  120. package/out-tsc/src/form/select/Select.js +92 -32
  121. package/out-tsc/src/form/select/Select.js.map +1 -1
  122. package/out-tsc/src/interfaces.js +6 -0
  123. package/out-tsc/src/interfaces.js.map +1 -1
  124. package/out-tsc/src/live/ContactChat.js +2 -76
  125. package/out-tsc/src/live/ContactChat.js.map +1 -1
  126. package/out-tsc/temba-modules.js +9 -2
  127. package/out-tsc/temba-modules.js.map +1 -1
  128. package/out-tsc/test/ActionHelper.js +116 -0
  129. package/out-tsc/test/ActionHelper.js.map +1 -0
  130. package/out-tsc/test/actions/add_contact_groups.test.js +66 -0
  131. package/out-tsc/test/actions/add_contact_groups.test.js.map +1 -0
  132. package/out-tsc/test/actions/remove_contact_groups.test.js +226 -0
  133. package/out-tsc/test/actions/remove_contact_groups.test.js.map +1 -0
  134. package/out-tsc/test/actions/send_email.test.js +160 -0
  135. package/out-tsc/test/actions/send_email.test.js.map +1 -0
  136. package/out-tsc/test/actions/send_msg.test.js +95 -0
  137. package/out-tsc/test/actions/send_msg.test.js.map +1 -0
  138. package/out-tsc/test/temba-action-editing-integration.test.js +183 -0
  139. package/out-tsc/test/temba-action-editing-integration.test.js.map +1 -0
  140. package/out-tsc/test/temba-checkbox.test.js +1 -1
  141. package/out-tsc/test/temba-checkbox.test.js.map +1 -1
  142. package/out-tsc/test/temba-field-config.test.js +133 -0
  143. package/out-tsc/test/temba-field-config.test.js.map +1 -0
  144. package/out-tsc/test/temba-flow-editor-node.test.js +14 -14
  145. package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
  146. package/out-tsc/test/temba-node-editor.test.js +283 -0
  147. package/out-tsc/test/temba-node-editor.test.js.map +1 -0
  148. package/out-tsc/test/temba-select.test.js +158 -0
  149. package/out-tsc/test/temba-select.test.js.map +1 -1
  150. package/package.json +1 -1
  151. package/screenshots/truth/actions/add_contact_groups/editor/descriptive-group-names.png +0 -0
  152. package/screenshots/truth/actions/add_contact_groups/editor/long-group-names.png +0 -0
  153. package/screenshots/truth/actions/add_contact_groups/editor/many-groups.png +0 -0
  154. package/screenshots/truth/actions/add_contact_groups/editor/multiple-groups.png +0 -0
  155. package/screenshots/truth/actions/add_contact_groups/editor/single-group.png +0 -0
  156. package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
  157. package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
  158. package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
  159. package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
  160. package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
  161. package/screenshots/truth/actions/remove_contact_groups/editor/cleanup-groups.png +0 -0
  162. package/screenshots/truth/actions/remove_contact_groups/editor/long-descriptive-group-names.png +0 -0
  163. package/screenshots/truth/actions/remove_contact_groups/editor/many-groups.png +0 -0
  164. package/screenshots/truth/actions/remove_contact_groups/editor/multiple-groups.png +0 -0
  165. package/screenshots/truth/actions/remove_contact_groups/editor/remove-from-all-groups.png +0 -0
  166. package/screenshots/truth/actions/remove_contact_groups/editor/single-group.png +0 -0
  167. package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
  168. package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
  169. package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
  170. package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
  171. package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
  172. package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
  173. package/screenshots/truth/actions/send_email/editor/complex-business-email.png +0 -0
  174. package/screenshots/truth/actions/send_email/editor/empty-body.png +0 -0
  175. package/screenshots/truth/actions/send_email/editor/empty-subject.png +0 -0
  176. package/screenshots/truth/actions/send_email/editor/long-subject.png +0 -0
  177. package/screenshots/truth/actions/send_email/editor/multiline-body.png +0 -0
  178. package/screenshots/truth/actions/send_email/editor/multiple-recipients.png +0 -0
  179. package/screenshots/truth/actions/send_email/editor/simple-email.png +0 -0
  180. package/screenshots/truth/actions/send_email/editor/with-expressions.png +0 -0
  181. package/screenshots/truth/actions/send_email/render/complex-business-email.png +0 -0
  182. package/screenshots/truth/actions/send_email/render/empty-body.png +0 -0
  183. package/screenshots/truth/actions/send_email/render/empty-subject.png +0 -0
  184. package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
  185. package/screenshots/truth/actions/send_email/render/multiline-body.png +0 -0
  186. package/screenshots/truth/actions/send_email/render/multiple-recipients.png +0 -0
  187. package/screenshots/truth/actions/send_email/render/simple-email.png +0 -0
  188. package/screenshots/truth/actions/send_email/render/with-expressions.png +0 -0
  189. package/screenshots/truth/actions/send_msg/editor/long-quick-replies.png +0 -0
  190. package/screenshots/truth/actions/send_msg/editor/multiline-text-with-replies.png +0 -0
  191. package/screenshots/truth/actions/send_msg/editor/simple-text.png +0 -0
  192. package/screenshots/truth/actions/send_msg/editor/text-with-linebreaks.png +0 -0
  193. package/screenshots/truth/actions/send_msg/editor/text-with-many-quick-replies.png +0 -0
  194. package/screenshots/truth/actions/send_msg/editor/text-with-quick-replies.png +0 -0
  195. package/screenshots/truth/actions/send_msg/editor/text-without-quick-replies.png +0 -0
  196. package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
  197. package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
  198. package/screenshots/truth/actions/send_msg/render/simple-text.png +0 -0
  199. package/screenshots/truth/actions/send_msg/render/text-with-linebreaks.png +0 -0
  200. package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
  201. package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
  202. package/screenshots/truth/actions/send_msg/render/text-without-quick-replies.png +0 -0
  203. package/screenshots/truth/editor/router.png +0 -0
  204. package/screenshots/truth/editor/send_msg.png +0 -0
  205. package/screenshots/truth/editor/set_contact_language.png +0 -0
  206. package/screenshots/truth/editor/set_contact_name.png +0 -0
  207. package/screenshots/truth/editor/set_run_result.png +0 -0
  208. package/screenshots/truth/editor/wait.png +0 -0
  209. package/screenshots/truth/formfield/markdown-errors.png +0 -0
  210. package/screenshots/truth/formfield/plain-text-errors.png +0 -0
  211. package/screenshots/truth/formfield/widget-only-markdown-errors.png +0 -0
  212. package/screenshots/truth/integration/checkbox-markdown-errors.png +0 -0
  213. package/src/events.ts +1 -40
  214. package/src/flow/{EditorNode.ts → CanvasNode.ts} +424 -48
  215. package/src/flow/Editor.ts +140 -4
  216. package/src/flow/NodeEditor.ts +1454 -0
  217. package/src/flow/Plumber.ts +0 -9
  218. package/src/flow/actions/add_contact_groups.ts +42 -0
  219. package/src/flow/actions/add_contact_urn.ts +17 -0
  220. package/src/flow/actions/add_input_labels.ts +12 -0
  221. package/src/flow/actions/call_classifier.ts +12 -0
  222. package/src/flow/actions/call_llm.ts +12 -0
  223. package/src/flow/actions/call_resthook.ts +12 -0
  224. package/src/flow/actions/call_webhook.ts +133 -0
  225. package/src/flow/actions/enter_flow.ts +15 -0
  226. package/src/flow/actions/open_ticket.ts +12 -0
  227. package/src/flow/actions/play_audio.ts +12 -0
  228. package/src/flow/actions/remove_contact_groups.ts +66 -0
  229. package/src/flow/actions/request_optin.ts +12 -0
  230. package/src/flow/actions/say_msg.ts +12 -0
  231. package/src/flow/actions/send_broadcast.ts +35 -0
  232. package/src/flow/actions/send_email.ts +60 -0
  233. package/src/flow/actions/send_msg.ts +58 -0
  234. package/src/flow/actions/set_contact_channel.ts +13 -0
  235. package/src/flow/actions/set_contact_field.ts +13 -0
  236. package/src/flow/actions/set_contact_language.ts +11 -0
  237. package/src/flow/actions/set_contact_name.ts +11 -0
  238. package/src/flow/actions/set_contact_status.ts +11 -0
  239. package/src/flow/actions/set_run_result.ts +11 -0
  240. package/src/flow/actions/split_by_expression_example.ts +88 -0
  241. package/src/flow/actions/start_session.ts +12 -0
  242. package/src/flow/actions/transfer_airtime.ts +12 -0
  243. package/src/flow/config.ts +93 -232
  244. package/src/flow/nodes/execute_actions.ts +5 -0
  245. package/src/flow/nodes/split_by_airtime.ts +9 -0
  246. package/src/flow/nodes/split_by_contact_field.ts +7 -0
  247. package/src/flow/nodes/split_by_expression.ts +7 -0
  248. package/src/flow/nodes/split_by_groups.ts +7 -0
  249. package/src/flow/nodes/split_by_random.ts +10 -0
  250. package/src/flow/nodes/split_by_run_result.ts +7 -0
  251. package/src/flow/nodes/split_by_scheme.ts +7 -0
  252. package/src/flow/nodes/split_by_subflow.ts +9 -0
  253. package/src/flow/nodes/split_by_webhook.ts +19 -0
  254. package/src/flow/nodes/wait_for_audio.ts +7 -0
  255. package/src/flow/nodes/wait_for_digits.ts +7 -0
  256. package/src/flow/nodes/wait_for_image.ts +7 -0
  257. package/src/flow/nodes/wait_for_location.ts +7 -0
  258. package/src/flow/nodes/wait_for_menu.ts +7 -0
  259. package/src/flow/nodes/wait_for_response.ts +7 -0
  260. package/src/flow/nodes/wait_for_video.ts +7 -0
  261. package/src/flow/types.ts +352 -0
  262. package/src/flow/utils.ts +76 -0
  263. package/src/form/ArrayEditor.ts +240 -0
  264. package/src/form/BaseListEditor.ts +177 -0
  265. package/src/form/Checkbox.ts +22 -3
  266. package/src/form/Completion.ts +6 -0
  267. package/src/form/FormField.ts +115 -11
  268. package/src/form/KeyValueEditor.ts +251 -0
  269. package/src/form/select/Select.ts +105 -32
  270. package/src/interfaces.ts +7 -2
  271. package/src/live/ContactChat.ts +3 -97
  272. package/src/store/flow-definition.d.ts +6 -1
  273. package/static/api/contacts.json +30 -0
  274. package/static/api/groups.json +4 -426
  275. package/static/api/locations.json +24 -0
  276. package/static/api/media.json +5 -0
  277. package/static/api/optins.json +16 -0
  278. package/static/api/orgs.json +13 -0
  279. package/static/api/topics.json +21 -0
  280. package/static/api/users.json +26 -0
  281. package/static/css/temba-components.css +3 -6
  282. package/temba-modules.ts +9 -2
  283. package/test/ActionHelper.ts +142 -0
  284. package/test/actions/add_contact_groups.test.ts +89 -0
  285. package/test/actions/remove_contact_groups.test.ts +265 -0
  286. package/test/actions/send_email.test.ts +214 -0
  287. package/test/actions/send_msg.test.ts +130 -0
  288. package/test/temba-action-editing-integration.test.ts +240 -0
  289. package/test/temba-checkbox.test.ts +1 -1
  290. package/test/temba-field-config.test.ts +152 -0
  291. package/test/temba-flow-editor-node.test.ts +18 -18
  292. package/test/temba-node-editor.test.ts +353 -0
  293. package/test/temba-select.test.ts +234 -0
  294. package/test-assets/contacts/history.json +11 -33
  295. package/web-dev-server.config.mjs +34 -0
  296. package/.github/workflows/coverage.yml +0 -80
  297. package/demo/sticky-note-demo.html +0 -155
  298. package/out-tsc/src/flow/EditorNode.js.map +0 -1
  299. package/out-tsc/src/flow/render.js +0 -358
  300. package/out-tsc/src/flow/render.js.map +0 -1
  301. package/out-tsc/test/temba-flow-render.test.js +0 -794
  302. package/out-tsc/test/temba-flow-render.test.js.map +0 -1
  303. package/src/flow/render.ts +0 -443
  304. package/test/temba-flow-render.test.ts +0 -1003
@@ -0,0 +1,88 @@
1
+ import { html } from 'lit-html';
2
+ import { ActionConfig, COLORS } from '../types';
3
+
4
+ // utility function to generate category from operand
5
+ const generateCategoryFromOperand = (operand: string): string => {
6
+ if (!operand) return '';
7
+
8
+ // clean up the operand to make a reasonable category name
9
+ return operand
10
+ .toLowerCase()
11
+ .replace(/[^a-z0-9\s]/g, '') // remove special chars
12
+ .replace(/\s+/g, '_') // replace spaces with underscores
13
+ .slice(0, 20); // limit length
14
+ };
15
+
16
+ export const split_by_expression: ActionConfig = {
17
+ name: 'Split by Expression',
18
+ color: COLORS.split,
19
+ form: {
20
+ operand: {
21
+ type: 'text',
22
+ label: 'Split by',
23
+ required: true,
24
+ evaluated: true,
25
+ placeholder: 'Enter expression to evaluate'
26
+ },
27
+ rules: {
28
+ type: 'array',
29
+ label: 'Rules',
30
+ sortable: true,
31
+ minItems: 1,
32
+ itemLabel: 'Rule',
33
+ itemConfig: {
34
+ operator: {
35
+ type: 'select',
36
+ label: 'Operator',
37
+ required: true,
38
+ options: [
39
+ { value: 'contains', label: 'contains' },
40
+ { value: 'equals', label: 'equals' },
41
+ { value: 'starts_with', label: 'starts with' },
42
+ { value: 'regex', label: 'regex' }
43
+ ]
44
+ },
45
+ operand: {
46
+ type: 'text',
47
+ label: 'Value',
48
+ required: true,
49
+ evaluated: true,
50
+ placeholder: 'Value to compare against'
51
+ },
52
+ category: {
53
+ type: 'text',
54
+ label: 'Category',
55
+ required: true,
56
+ placeholder: 'Category name for this rule'
57
+ }
58
+ },
59
+ // handle changes at the item level
60
+ onItemChange: (
61
+ itemIndex: number,
62
+ field: string,
63
+ value: any,
64
+ allItems: any[]
65
+ ) => {
66
+ const updatedItems = [...allItems];
67
+ const item = { ...updatedItems[itemIndex] };
68
+
69
+ // update the changed field
70
+ item[field] = value;
71
+
72
+ // if operand changed and category is empty, auto-generate category
73
+ if (
74
+ field === 'operand' &&
75
+ (!item.category || item.category.trim() === '')
76
+ ) {
77
+ item.category = generateCategoryFromOperand(value);
78
+ }
79
+
80
+ updatedItems[itemIndex] = item;
81
+ return updatedItems;
82
+ }
83
+ }
84
+ },
85
+ render: (_node: any, action: any) => {
86
+ return html`<div>${action.operand || 'Split by expression'}</div>`;
87
+ }
88
+ };
@@ -0,0 +1,12 @@
1
+ import { html } from 'lit-html';
2
+ import { ActionConfig, COLORS } from '../types';
3
+ import { Node, StartSession } from '../../store/flow-definition';
4
+
5
+ export const start_session: ActionConfig = {
6
+ name: 'Start Session',
7
+ color: COLORS.execute,
8
+ render: (_node: Node, _action: StartSession) => {
9
+ // This will need to be implemented based on the actual render logic
10
+ return html`<div>Start Session</div>`;
11
+ }
12
+ };
@@ -0,0 +1,12 @@
1
+ import { html } from 'lit-html';
2
+ import { ActionConfig, COLORS } from '../types';
3
+ import { Node, TransferAirtime } from '../../store/flow-definition';
4
+
5
+ export const transfer_airtime: ActionConfig = {
6
+ name: 'Transfer Airtime',
7
+ color: COLORS.send,
8
+ render: (_node: Node, _action: TransferAirtime) => {
9
+ // This will need to be implemented based on the actual render logic
10
+ return html`<div>Transfer Airtime</div>`;
11
+ }
12
+ };
@@ -1,238 +1,99 @@
1
- import { TemplateResult } from 'lit-html';
2
- import {
3
- renderAddContactUrn,
4
- renderAddInputLabels,
5
- renderAddToGroups,
6
- renderCallClassifier,
7
- renderCallLLM,
8
- renderCallResthook,
9
- renderCallWebhook,
10
- renderEnterFlow,
11
- renderOpenTicket,
12
- renderPlayAudio,
13
- renderRemoveFromGroups,
14
- renderRequestOptin,
15
- renderSayMsg,
16
- renderSendBroadcast,
17
- renderSendEmail,
18
- renderSendMsg,
19
- renderSetContactChannel,
20
- renderSetContactField,
21
- renderSetContactLanguage,
22
- renderSetContactName,
23
- renderSetContactStatus,
24
- renderSetRunResult,
25
- renderStartSession,
26
- renderTransferAirtime,
27
- renderWaitForAudio,
28
- renderWaitForDigits,
29
- renderWaitForImage,
30
- renderWaitForLocation,
31
- renderWaitForMenu,
32
- renderWaitForResponse,
33
- renderWaitForVideo
34
- } from './render';
1
+ // Re-export all types and utilities
2
+ export * from './types';
3
+ import type { ActionConfig, NodeConfig } from './types';
35
4
 
36
- export interface UIConfig {
37
- name: string;
38
- color: string;
39
- render?: (node: any, action: any) => TemplateResult;
40
- }
5
+ // Import all action configurations
6
+ import { add_input_labels } from './actions/add_input_labels';
7
+ import { add_contact_urn } from './actions/add_contact_urn';
8
+ import { set_contact_field } from './actions/set_contact_field';
9
+ import { set_contact_channel } from './actions/set_contact_channel';
10
+ import { set_contact_language } from './actions/set_contact_language';
11
+ import { set_contact_status } from './actions/set_contact_status';
12
+ import { send_broadcast } from './actions/send_broadcast';
13
+ import { set_run_result } from './actions/set_run_result';
14
+ import { send_msg } from './actions/send_msg';
15
+ import { send_email } from './actions/send_email';
16
+ import { start_session } from './actions/start_session';
17
+ import { open_ticket } from './actions/open_ticket';
18
+ import { call_webhook } from './actions/call_webhook';
19
+ import { call_classifier } from './actions/call_classifier';
20
+ import { call_resthook } from './actions/call_resthook';
21
+ import { call_llm } from './actions/call_llm';
22
+ import { transfer_airtime } from './actions/transfer_airtime';
23
+ import { set_contact_name } from './actions/set_contact_name';
24
+ import { add_contact_groups } from './actions/add_contact_groups';
25
+ import { remove_contact_groups } from './actions/remove_contact_groups';
26
+ import { request_optin } from './actions/request_optin';
27
+ import { say_msg } from './actions/say_msg';
28
+ import { play_audio } from './actions/play_audio';
29
+ import { enter_flow } from './actions/enter_flow';
41
30
 
42
- const COLORS = {
43
- send: '#3498db',
44
- update: '#01c1af',
45
- broadcast: '#8e5ea7',
46
- call: '#e68628',
47
- create: '#df419f',
48
- save: '#1a777c',
49
- split: '#aaaaaa',
50
- execute: '#666666',
51
- wait: '#4d7dad',
52
- add: '#309c42',
53
- remove: '#e74c3c'
31
+ // Import all node configurations
32
+ import { execute_actions } from './nodes/execute_actions';
33
+ import { split_by_airtime } from './nodes/split_by_airtime';
34
+ import { split_by_contact_field } from './nodes/split_by_contact_field';
35
+ import { split_by_expression } from './nodes/split_by_expression';
36
+ import { split_by_groups } from './nodes/split_by_groups';
37
+ import { split_by_random } from './nodes/split_by_random';
38
+ import { split_by_run_result } from './nodes/split_by_run_result';
39
+ import { split_by_scheme } from './nodes/split_by_scheme';
40
+ import { split_by_subflow } from './nodes/split_by_subflow';
41
+ import { split_by_webhook } from './nodes/split_by_webhook';
42
+ import { wait_for_audio } from './nodes/wait_for_audio';
43
+ import { wait_for_digits } from './nodes/wait_for_digits';
44
+ import { wait_for_image } from './nodes/wait_for_image';
45
+ import { wait_for_location } from './nodes/wait_for_location';
46
+ import { wait_for_menu } from './nodes/wait_for_menu';
47
+ import { wait_for_response } from './nodes/wait_for_response';
48
+ import { wait_for_video } from './nodes/wait_for_video';
49
+
50
+ export const ACTION_CONFIG: {
51
+ [key: string]: ActionConfig;
52
+ } = {
53
+ add_input_labels,
54
+ add_contact_urn,
55
+ set_contact_field,
56
+ set_contact_channel,
57
+ set_contact_language,
58
+ set_contact_status,
59
+ send_broadcast,
60
+ set_run_result,
61
+ send_msg,
62
+ send_email,
63
+ start_session,
64
+ open_ticket,
65
+ call_webhook,
66
+ call_classifier,
67
+ call_resthook,
68
+ call_llm,
69
+ enter_flow,
70
+ transfer_airtime,
71
+ set_contact_name,
72
+ add_contact_groups,
73
+ remove_contact_groups,
74
+ request_optin,
75
+ say_msg,
76
+ play_audio
54
77
  };
55
78
 
56
- export const EDITOR_CONFIG: {
57
- [key: string]: UIConfig;
79
+ export const NODE_CONFIG: {
80
+ [key: string]: NodeConfig;
58
81
  } = {
59
- add_input_labels: {
60
- name: 'Add Labels',
61
- color: COLORS.update,
62
- render: renderAddInputLabels
63
- },
64
- add_contact_urn: {
65
- name: 'Add Contact URN',
66
- color: COLORS.update,
67
- render: renderAddContactUrn
68
- },
69
- set_contact_field: {
70
- name: 'Update Contact Field',
71
- color: COLORS.update,
72
- render: renderSetContactField
73
- },
74
- set_contact_channel: {
75
- name: 'Update Contact Channel',
76
- color: COLORS.update,
77
- render: renderSetContactChannel
78
- },
79
- set_contact_language: {
80
- name: 'Update Contact Language',
81
- color: COLORS.update,
82
- render: renderSetContactLanguage
83
- },
84
- set_contact_status: {
85
- name: 'Update Contact Status',
86
- color: COLORS.update,
87
- render: renderSetContactStatus
88
- },
89
- send_broadcast: {
90
- name: 'Send Broadcast',
91
- color: COLORS.broadcast,
92
- render: renderSendBroadcast
93
- },
94
- set_run_result: {
95
- name: 'Save Flow Result',
96
- color: COLORS.save,
97
- render: renderSetRunResult
98
- },
99
- send_msg: {
100
- name: 'Send Message',
101
- color: COLORS.send,
102
- render: renderSendMsg
103
- },
104
- send_email: {
105
- name: 'Send Email',
106
- color: COLORS.broadcast,
107
- render: renderSendEmail
108
- },
109
- start_session: {
110
- name: 'Start Somebody Else',
111
- color: COLORS.broadcast,
112
- render: renderStartSession
113
- },
114
- open_ticket: {
115
- name: 'Open Ticket',
116
- color: COLORS.execute,
117
- render: renderOpenTicket
118
- },
119
- call_webhook: {
120
- name: 'Call Webhook',
121
- color: COLORS.call,
122
- render: renderCallWebhook
123
- },
124
- call_classifier: {
125
- name: 'Call Classifier',
126
- color: COLORS.call,
127
- render: renderCallClassifier
128
- },
129
- call_resthook: {
130
- name: 'Call Resthook',
131
- color: COLORS.call,
132
- render: renderCallResthook
133
- },
134
- call_llm: {
135
- name: 'Call AI',
136
- color: COLORS.call,
137
- render: renderCallLLM
138
- },
139
- enter_flow: {
140
- name: 'Enter Subflow',
141
- color: COLORS.execute,
142
- render: renderEnterFlow
143
- },
144
- transfer_airtime: {
145
- name: 'Send Airtime',
146
- color: COLORS.call,
147
- render: renderTransferAirtime
148
- },
149
- wait_for_response: {
150
- name: 'Wait for Response',
151
- color: COLORS.wait,
152
- render: renderWaitForResponse
153
- },
154
- wait_for_menu: {
155
- name: 'Wait for Menu Selection',
156
- color: COLORS.wait,
157
- render: renderWaitForMenu
158
- },
159
- wait_for_digits: {
160
- name: 'Wait for Digits',
161
- color: COLORS.wait,
162
- render: renderWaitForDigits
163
- },
164
- wait_for_audio: {
165
- name: 'Wait for Audio',
166
- color: COLORS.wait,
167
- render: renderWaitForAudio
168
- },
169
- wait_for_video: {
170
- name: 'Wait for Video',
171
- color: COLORS.wait,
172
- render: renderWaitForVideo
173
- },
174
- wait_for_image: {
175
- name: 'Wait for Image',
176
- color: COLORS.wait,
177
- render: renderWaitForImage
178
- },
179
- wait_for_location: {
180
- name: 'Wait for Location',
181
- color: COLORS.wait,
182
- render: renderWaitForLocation
183
- },
184
- set_contact_name: {
185
- name: 'Update Contact',
186
- color: '#01c1af',
187
- render: renderSetContactName
188
- },
189
- add_contact_groups: {
190
- name: 'Add to Group',
191
- color: COLORS.add,
192
- render: renderAddToGroups
193
- },
194
- remove_contact_groups: {
195
- name: 'Remove from Group',
196
- color: COLORS.remove,
197
- render: renderRemoveFromGroups
198
- },
199
- request_optin: {
200
- name: 'Request Opt-in',
201
- color: COLORS.send,
202
- render: renderRequestOptin
203
- },
204
- say_msg: {
205
- name: 'Say Message',
206
- color: COLORS.send,
207
- render: renderSayMsg
208
- },
209
- play_audio: {
210
- name: 'Play Audio',
211
- color: COLORS.send,
212
- render: renderPlayAudio
213
- },
214
- split_by_run_result: {
215
- name: 'Split by Flow Result',
216
- color: COLORS.split
217
- },
218
- split_by_expression: {
219
- name: 'Split by Expression',
220
- color: COLORS.split
221
- },
222
- split_by_contact_field: {
223
- name: 'Split by <Contact Field Name>',
224
- color: COLORS.split
225
- },
226
- split_by_groups: {
227
- name: 'Split by Group',
228
- color: COLORS.split
229
- },
230
- split_by_scheme: {
231
- name: 'Split by URN Type',
232
- color: COLORS.split
233
- },
234
- split_by_random: {
235
- name: 'Split by Random',
236
- color: COLORS.split
237
- }
82
+ execute_actions,
83
+ split_by_airtime,
84
+ split_by_contact_field,
85
+ split_by_expression,
86
+ split_by_groups,
87
+ split_by_random,
88
+ split_by_run_result,
89
+ split_by_scheme,
90
+ split_by_subflow,
91
+ split_by_webhook,
92
+ wait_for_audio,
93
+ wait_for_digits,
94
+ wait_for_image,
95
+ wait_for_location,
96
+ wait_for_menu,
97
+ wait_for_response,
98
+ wait_for_video
238
99
  };
@@ -0,0 +1,5 @@
1
+ import { NodeConfig } from '../types';
2
+
3
+ export const execute_actions: NodeConfig = {
4
+ type: 'execute_actions'
5
+ };
@@ -0,0 +1,9 @@
1
+ import { transfer_airtime } from '../actions/transfer_airtime';
2
+ import { COLORS, NodeConfig } from '../types';
3
+
4
+ export const split_by_airtime: NodeConfig = {
5
+ type: 'split_by_airtime',
6
+ name: 'Split by Airtime Transfer',
7
+ color: COLORS.send,
8
+ action: transfer_airtime
9
+ };
@@ -0,0 +1,7 @@
1
+ import { COLORS, NodeConfig } from '../types';
2
+
3
+ export const split_by_contact_field: NodeConfig = {
4
+ type: 'split_by_contact_field',
5
+ name: 'Split by <Contact Field Name>',
6
+ color: COLORS.split
7
+ };
@@ -0,0 +1,7 @@
1
+ import { COLORS, NodeConfig } from '../types';
2
+
3
+ export const split_by_expression: NodeConfig = {
4
+ type: 'split_by_expression',
5
+ name: 'Split by Expression',
6
+ color: COLORS.split
7
+ };
@@ -0,0 +1,7 @@
1
+ import { COLORS, NodeConfig } from '../types';
2
+
3
+ export const split_by_groups: NodeConfig = {
4
+ type: 'split_by_groups',
5
+ name: 'Split by Group',
6
+ color: COLORS.split
7
+ };
@@ -0,0 +1,10 @@
1
+ import { COLORS, NodeConfig } from '../types';
2
+
3
+ export const split_by_random: NodeConfig = {
4
+ type: 'split_by_random',
5
+ name: 'Split by Random',
6
+ color: COLORS.split,
7
+ router: {
8
+ type: 'random'
9
+ }
10
+ };
@@ -0,0 +1,7 @@
1
+ import { COLORS, NodeConfig } from '../types';
2
+
3
+ export const split_by_run_result: NodeConfig = {
4
+ type: 'split_by_run_result',
5
+ name: 'Split by Flow Result',
6
+ color: COLORS.split
7
+ };
@@ -0,0 +1,7 @@
1
+ import { COLORS, NodeConfig } from '../types';
2
+
3
+ export const split_by_scheme: NodeConfig = {
4
+ type: 'split_by_scheme',
5
+ name: 'Split by URN Type',
6
+ color: COLORS.split
7
+ };
@@ -0,0 +1,9 @@
1
+ import { enter_flow } from '../actions/enter_flow';
2
+ import { COLORS, NodeConfig } from '../types';
3
+
4
+ export const split_by_subflow: NodeConfig = {
5
+ type: 'split_by_subflow',
6
+ name: 'Split by Subflow',
7
+ color: COLORS.execute,
8
+ action: enter_flow
9
+ };
@@ -0,0 +1,19 @@
1
+ import { call_webhook } from '../actions/call_webhook';
2
+ import { NodeConfig } from '../types';
3
+
4
+ export const split_by_webhook: NodeConfig = {
5
+ type: 'split_by_webhook',
6
+ action: call_webhook,
7
+ router: {
8
+ type: 'switch',
9
+ defaultCategory: 'Failure',
10
+ operand: '@webhook.status',
11
+ rules: [
12
+ {
13
+ type: 'has_number_between',
14
+ arguments: ['200', '299'],
15
+ categoryName: 'Success'
16
+ }
17
+ ]
18
+ }
19
+ };
@@ -0,0 +1,7 @@
1
+ import { COLORS, NodeConfig } from '../types';
2
+
3
+ export const wait_for_audio: NodeConfig = {
4
+ type: 'wait_for_audio',
5
+ name: 'Wait for Audio',
6
+ color: COLORS.wait
7
+ };
@@ -0,0 +1,7 @@
1
+ import { COLORS, NodeConfig } from '../types';
2
+
3
+ export const wait_for_digits: NodeConfig = {
4
+ type: 'wait_for_digits',
5
+ name: 'Wait for Digits',
6
+ color: COLORS.wait
7
+ };
@@ -0,0 +1,7 @@
1
+ import { COLORS, NodeConfig } from '../types';
2
+
3
+ export const wait_for_image: NodeConfig = {
4
+ type: 'wait_for_image',
5
+ name: 'Wait for Image',
6
+ color: COLORS.wait
7
+ };
@@ -0,0 +1,7 @@
1
+ import { COLORS, NodeConfig } from '../types';
2
+
3
+ export const wait_for_location: NodeConfig = {
4
+ type: 'wait_for_location',
5
+ name: 'Wait for Location',
6
+ color: COLORS.wait
7
+ };
@@ -0,0 +1,7 @@
1
+ import { COLORS, NodeConfig } from '../types';
2
+
3
+ export const wait_for_menu: NodeConfig = {
4
+ type: 'wait_for_menu',
5
+ name: 'Wait for Menu Selection',
6
+ color: COLORS.wait
7
+ };
@@ -0,0 +1,7 @@
1
+ import { COLORS, NodeConfig } from '../types';
2
+
3
+ export const wait_for_response: NodeConfig = {
4
+ type: 'wait_for_response',
5
+ name: 'Wait for Response',
6
+ color: COLORS.wait
7
+ };
@@ -0,0 +1,7 @@
1
+ import { COLORS, NodeConfig } from '../types';
2
+
3
+ export const wait_for_video: NodeConfig = {
4
+ type: 'wait_for_video',
5
+ name: 'Wait for Video',
6
+ color: COLORS.wait
7
+ };