@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
@@ -1,358 +0,0 @@
1
- import { html } from 'lit-html';
2
- import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
3
- import { Icon } from '../Icons';
4
- // URN scheme mapping for user-friendly display
5
- const urnSchemeMap = {
6
- tel: 'Phone Number',
7
- email: 'Email',
8
- twitter: 'Twitter',
9
- facebook: 'Facebook',
10
- telegram: 'Telegram',
11
- whatsapp: 'WhatsApp',
12
- viber: 'Viber',
13
- line: 'Line',
14
- discord: 'Discord',
15
- slack: 'Slack',
16
- external: 'External ID'
17
- };
18
- const renderLineItem = (name, icon) => {
19
- return html `<div style="display:flex;items-align:center">
20
- ${icon
21
- ? html `<temba-icon name=${icon} style="margin-right:0.5em"></temba-icon>`
22
- : null}
23
- <div
24
- style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
25
- >
26
- ${name}
27
- </div>
28
- </div>`;
29
- };
30
- const renderNamedObjects = (assets, icon) => {
31
- const items = [];
32
- const maxDisplay = 3;
33
- // Show up to 3 items, or all 4 if exactly 4 items
34
- const displayCount = assets.length === 4 ? 4 : Math.min(maxDisplay, assets.length);
35
- for (let i = 0; i < displayCount; i++) {
36
- const asset = assets[i];
37
- items.push(renderLineItem(asset.name, icon));
38
- }
39
- // Add "+X more" if there are more than 3 items (and not exactly 4)
40
- if (assets.length > maxDisplay && assets.length !== 4) {
41
- const remainingCount = assets.length - maxDisplay;
42
- items.push(html `<div style="display:flex;items-align:center; color: #666;">
43
- ${icon
44
- ? html `<div style="margin-right:0.5em; width: 1em;"></div>` // spacing placeholder
45
- : null}
46
- <div>+${remainingCount} more</div>
47
- </div>`);
48
- }
49
- return items;
50
- };
51
- export const renderSendMsg = (node, action) => {
52
- const text = action.text.replace(/\n/g, '<br>');
53
- return html `
54
- ${unsafeHTML(text)}
55
- ${action.quick_replies.length > 0
56
- ? html `<div class="quick-replies">
57
- ${action.quick_replies.map((reply) => {
58
- return html `<div class="quick-reply">${reply}</div>`;
59
- })}
60
- </div>`
61
- : null}
62
- `;
63
- };
64
- export const renderSetContactName = (node, action) => {
65
- return html `<div>Set contact name to <b>${action.name}</b></div>`;
66
- };
67
- export const renderSetRunResult = (node, action) => {
68
- return html `<div>Save ${action.value} as <b>${action.name}</b></div>`;
69
- };
70
- export const renderCallWebhook = (node, action) => {
71
- return html `<div
72
- style="word-break: break-all; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
73
- >
74
- ${action.url}
75
- </div>`;
76
- };
77
- export const renderAddToGroups = (node, action) => {
78
- return html `<div>${renderNamedObjects(action.groups, 'group')}</div>`;
79
- };
80
- export const renderRemoveFromGroups = (node, action) => {
81
- return html `<div>${renderNamedObjects(action.groups, 'group')}</div>`;
82
- };
83
- export const renderSetContactField = (node, action) => {
84
- return html `<div>
85
- Set <b>${action.field.name}</b> to <b>${action.value}</b>
86
- </div>`;
87
- };
88
- export const renderSetContactLanguage = (node, action) => {
89
- return html `<div>Set contact language to <b>${action.language}</b></div>`;
90
- };
91
- export const renderSetContactStatus = (node, action) => {
92
- return html `<div>Set contact status to <b>${action.status}</b></div>`;
93
- };
94
- export const renderSetContactChannel = (node, action) => {
95
- return html `<div>Set contact channel to <b>${action.channel.name}</b></div>`;
96
- };
97
- export const renderAddContactUrn = (node, action) => {
98
- const friendlyScheme = urnSchemeMap[action.scheme] || action.scheme;
99
- return html `<div
100
- style="word-wrap: break-word; overflow: hidden; text-overflow: ellipsis;"
101
- >
102
- Add ${friendlyScheme} <b>${action.path}</b>
103
- </div>`;
104
- };
105
- export const renderSendEmail = (node, action) => {
106
- const addressList = action.addresses.join(', ');
107
- return html `<div>
108
- <div
109
- style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
110
- >
111
- <b>${addressList}</b>
112
- </div>
113
- <div style="margin-top: 0.5em">
114
- <div
115
- style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
116
- >
117
- ${action.subject}
118
- </div>
119
- <div
120
- style="margin-top: 0.25em; word-wrap: break-word; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"
121
- >
122
- ${action.body}
123
- </div>
124
- </div>
125
- </div>`;
126
- };
127
- export const renderSendBroadcast = (node, action) => {
128
- const hasGroups = action.groups && action.groups.length > 0;
129
- const hasContacts = action.contacts && action.contacts.length > 0;
130
- return html `<div>
131
- <div style="word-wrap: break-word; margin-bottom: 0.5em">
132
- ${action.text}
133
- </div>
134
- ${hasGroups
135
- ? html `<div style="margin-bottom: 0.25em">
136
- <div style="font-weight: bold; margin-bottom: 0.25em">Groups:</div>
137
- ${renderNamedObjects(action.groups, 'group')}
138
- </div>`
139
- : null}
140
- ${hasContacts
141
- ? html `<div>
142
- <div style="font-weight: bold; margin-bottom: 0.25em">Contacts:</div>
143
- ${renderNamedObjects(action.contacts, 'contact')}
144
- </div>`
145
- : null}
146
- </div>`;
147
- };
148
- export const renderEnterFlow = (node, action) => {
149
- return html `<div>Enter flow <b>${action.flow.name}</b></div>`;
150
- };
151
- export const renderStartSession = (node, action) => {
152
- const hasGroups = action.groups && action.groups.length > 0;
153
- const hasContacts = action.contacts && action.contacts.length > 0;
154
- return html `<div>
155
- ${hasGroups
156
- ? html `<div style="margin-top: 0.5em">
157
- <div style="font-weight: bold; margin-bottom: 0.25em">Groups:</div>
158
- ${renderNamedObjects(action.groups, 'group')}
159
- </div>`
160
- : null}
161
- ${hasContacts
162
- ? html `<div style="margin-top: 0.5em">
163
- <div style="font-weight: bold; margin-bottom: 0.25em">Contacts:</div>
164
- ${renderNamedObjects(action.contacts, 'contact')}
165
- </div>`
166
- : null}
167
- ${action.create_contact
168
- ? renderLineItem('Create contact', Icon.contact)
169
- : null}
170
- ${renderLineItem(action.flow.name, Icon.flow)}
171
- </div>`;
172
- };
173
- export const renderTransferAirtime = (node, action) => {
174
- const amounts = action.amounts.join(', ');
175
- return html `<div>
176
- Transfer airtime amounts: <b>${amounts}</b>
177
- <div>Save result as <b>${action.result_name}</b></div>
178
- </div>`;
179
- };
180
- export const renderCallClassifier = (node, action) => {
181
- return html `<div>
182
- <div>Call classifier <b>${action.classifier.name}</b></div>
183
- <div style="margin-top: 0.25em; word-wrap: break-word">
184
- Input: <b>${action.input}</b>
185
- </div>
186
- <div style="margin-top: 0.25em">
187
- Save result as <b>${action.result_name}</b>
188
- </div>
189
- </div>`;
190
- };
191
- export const renderCallResthook = (node, action) => {
192
- return html `<div>
193
- <div>Call resthook <b>${action.resthook}</b></div>
194
- <div style="margin-top: 0.25em">
195
- Save result as <b>${action.result_name}</b>
196
- </div>
197
- </div>`;
198
- };
199
- export const renderCallLLM = (node, action) => {
200
- return html `<div>
201
- <div style="margin-top: 0.25em; display: flex; align-items: center;">
202
- <temba-icon name="ai" style="margin-right: 0.5em"></temba-icon>
203
- <span
204
- style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
205
- >
206
- ${action.llm.name}
207
- </span>
208
- </div>
209
- <div
210
- style="margin-top: 0.25em; word-wrap: break-word; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"
211
- >
212
- ${action.instructions}
213
- </div>
214
- </div>`;
215
- };
216
- export const renderOpenTicket = (node, action) => {
217
- return html `<div>
218
- <div
219
- style="word-wrap: break-word; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"
220
- >
221
- ${action.body}
222
- </div>
223
- ${action.assignee
224
- ? html `<div
225
- style="margin-top: 0.25em; display: flex; align-items: center;"
226
- >
227
- <temba-icon name="user" style="margin-right: 0.5em"></temba-icon>
228
- <span
229
- style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
230
- >
231
- ${action.assignee.name}
232
- </span>
233
- </div>`
234
- : null}
235
- ${action.topic
236
- ? html `<div
237
- style="margin-top: 0.25em; display: flex; align-items: center;"
238
- >
239
- <temba-icon name="topic" style="margin-right: 0.5em"></temba-icon>
240
- <span
241
- style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
242
- >
243
- ${action.topic.name}
244
- </span>
245
- </div>`
246
- : null}
247
- </div>`;
248
- };
249
- export const renderRequestOptin = (node, action) => {
250
- return html `<div>Request opt-in for <b>${action.optin.name}</b></div>`;
251
- };
252
- export const renderAddInputLabels = (node, action) => {
253
- return html `<div>${renderNamedObjects(action.labels, 'label')}</div>`;
254
- };
255
- export const renderSayMsg = (node, action) => {
256
- return html `<div>
257
- <div
258
- style="word-wrap: break-word; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
259
- >
260
- ${action.text}
261
- </div>
262
- ${action.audio_url
263
- ? html `<div
264
- style="margin-top: 0.5em; display: flex; align-items: center;"
265
- >
266
- <temba-icon name="audio" style="margin-right: 0.25em"></temba-icon>
267
- <span
268
- style="word-break: break-all; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
269
- >${action.audio_url}</span
270
- >
271
- </div>`
272
- : null}
273
- </div>`;
274
- };
275
- export const renderPlayAudio = (node, action) => {
276
- return html `<div style="display: flex; align-items: center;">
277
- <temba-icon name="audio" style="margin-right: 0.25em"></temba-icon>
278
- <span
279
- style="word-break: break-all; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
280
- >${action.audio_url}</span
281
- >
282
- </div>`;
283
- };
284
- export const renderWaitForResponse = (node, action) => {
285
- return html `<div>
286
- Wait for message response
287
- ${action.timeout
288
- ? html `<div style="margin-top: 0.25em">
289
- Timeout after <b>${action.timeout}</b> seconds
290
- </div>`
291
- : null}
292
- </div>`;
293
- };
294
- export const renderWaitForMenu = (node, action) => {
295
- return html `<div>
296
- Wait for menu selection: <b>${action.menu.name}</b>
297
- ${action.timeout
298
- ? html `<div style="margin-top: 0.25em">
299
- Timeout after <b>${action.timeout}</b> seconds
300
- </div>`
301
- : null}
302
- </div>`;
303
- };
304
- export const renderWaitForDigits = (node, action) => {
305
- return html `<div>
306
- Wait for <b>${action.count}</b> digit${action.count !== 1 ? 's' : ''}
307
- ${action.timeout
308
- ? html `<div style="margin-top: 0.25em">
309
- Timeout after <b>${action.timeout}</b> seconds
310
- </div>`
311
- : null}
312
- </div>`;
313
- };
314
- export const renderWaitForAudio = (node, action) => {
315
- return html `<div>
316
- <temba-icon name="audio" style="margin-right: 0.25em"></temba-icon>
317
- Wait for audio recording
318
- ${action.timeout
319
- ? html `<div style="margin-top: 0.25em">
320
- Timeout after <b>${action.timeout}</b> seconds
321
- </div>`
322
- : null}
323
- </div>`;
324
- };
325
- export const renderWaitForVideo = (node, action) => {
326
- return html `<div>
327
- <temba-icon name="video" style="margin-right: 0.25em"></temba-icon>
328
- Wait for video recording
329
- ${action.timeout
330
- ? html `<div style="margin-top: 0.25em">
331
- Timeout after <b>${action.timeout}</b> seconds
332
- </div>`
333
- : null}
334
- </div>`;
335
- };
336
- export const renderWaitForImage = (node, action) => {
337
- return html `<div>
338
- <temba-icon name="image" style="margin-right: 0.25em"></temba-icon>
339
- Wait for image
340
- ${action.timeout
341
- ? html `<div style="margin-top: 0.25em">
342
- Timeout after <b>${action.timeout}</b> seconds
343
- </div>`
344
- : null}
345
- </div>`;
346
- };
347
- export const renderWaitForLocation = (node, action) => {
348
- return html `<div>
349
- <temba-icon name="location" style="margin-right: 0.25em"></temba-icon>
350
- Wait for location
351
- ${action.timeout
352
- ? html `<div style="margin-top: 0.25em">
353
- Timeout after <b>${action.timeout}</b> seconds
354
- </div>`
355
- : null}
356
- </div>`;
357
- };
358
- //# sourceMappingURL=render.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/flow/render.ts"],"names":[],"mappings":"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","sourcesContent":["import { html } from 'lit-html';\nimport { unsafeHTML } from 'lit-html/directives/unsafe-html.js';\n\nimport {\n AddContactUrn,\n AddInputLabels,\n AddToGroup,\n CallClassifier,\n CallLLM,\n CallResthook,\n CallWebhook,\n EnterFlow,\n Node,\n NamedObject,\n OpenTicket,\n PlayAudio,\n RemoveFromGroup,\n RequestOptin,\n SayMsg,\n SendBroadcast,\n SendEmail,\n SendMsg,\n SetContactChannel,\n SetContactField,\n SetContactLanguage,\n SetContactName,\n SetContactStatus,\n SetRunResult,\n StartSession,\n TransferAirtime,\n WaitForAudio,\n WaitForDigits,\n WaitForImage,\n WaitForLocation,\n WaitForMenu,\n WaitForResponse,\n WaitForVideo\n} from '../store/flow-definition';\nimport { Icon } from '../Icons';\n\n// URN scheme mapping for user-friendly display\nconst urnSchemeMap: Record<string, string> = {\n tel: 'Phone Number',\n email: 'Email',\n twitter: 'Twitter',\n facebook: 'Facebook',\n telegram: 'Telegram',\n whatsapp: 'WhatsApp',\n viber: 'Viber',\n line: 'Line',\n discord: 'Discord',\n slack: 'Slack',\n external: 'External ID'\n};\n\nconst renderLineItem = (name: string, icon?: string) => {\n return html`<div style=\"display:flex;items-align:center\">\n ${icon\n ? html`<temba-icon name=${icon} style=\"margin-right:0.5em\"></temba-icon>`\n : null}\n <div\n style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\"\n >\n ${name}\n </div>\n </div>`;\n};\n\nconst renderNamedObjects = (assets: NamedObject[], icon?: string) => {\n const items = [];\n const maxDisplay = 3;\n\n // Show up to 3 items, or all 4 if exactly 4 items\n const displayCount =\n assets.length === 4 ? 4 : Math.min(maxDisplay, assets.length);\n\n for (let i = 0; i < displayCount; i++) {\n const asset = assets[i];\n items.push(renderLineItem(asset.name, icon));\n }\n\n // Add \"+X more\" if there are more than 3 items (and not exactly 4)\n if (assets.length > maxDisplay && assets.length !== 4) {\n const remainingCount = assets.length - maxDisplay;\n items.push(html`<div style=\"display:flex;items-align:center; color: #666;\">\n ${icon\n ? html`<div style=\"margin-right:0.5em; width: 1em;\"></div>` // spacing placeholder\n : null}\n <div>+${remainingCount} more</div>\n </div>`);\n }\n\n return items;\n};\n\nexport const renderSendMsg = (node: Node, action: SendMsg) => {\n const text = action.text.replace(/\\n/g, '<br>');\n return html`\n ${unsafeHTML(text)}\n ${action.quick_replies.length > 0\n ? html`<div class=\"quick-replies\">\n ${action.quick_replies.map((reply) => {\n return html`<div class=\"quick-reply\">${reply}</div>`;\n })}\n </div>`\n : null}\n `;\n};\n\nexport const renderSetContactName = (node: Node, action: SetContactName) => {\n return html`<div>Set contact name to <b>${action.name}</b></div>`;\n};\n\nexport const renderSetRunResult = (node: Node, action: SetRunResult) => {\n return html`<div>Save ${action.value} as <b>${action.name}</b></div>`;\n};\n\nexport const renderCallWebhook = (node: Node, action: CallWebhook) => {\n return html`<div\n style=\"word-break: break-all; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\"\n >\n ${action.url}\n </div>`;\n};\n\nexport const renderAddToGroups = (node: Node, action: AddToGroup) => {\n return html`<div>${renderNamedObjects(action.groups, 'group')}</div>`;\n};\n\nexport const renderRemoveFromGroups = (node: Node, action: RemoveFromGroup) => {\n return html`<div>${renderNamedObjects(action.groups, 'group')}</div>`;\n};\n\nexport const renderSetContactField = (node: Node, action: SetContactField) => {\n return html`<div>\n Set <b>${action.field.name}</b> to <b>${action.value}</b>\n </div>`;\n};\n\nexport const renderSetContactLanguage = (\n node: Node,\n action: SetContactLanguage\n) => {\n return html`<div>Set contact language to <b>${action.language}</b></div>`;\n};\n\nexport const renderSetContactStatus = (\n node: Node,\n action: SetContactStatus\n) => {\n return html`<div>Set contact status to <b>${action.status}</b></div>`;\n};\n\nexport const renderSetContactChannel = (\n node: Node,\n action: SetContactChannel\n) => {\n return html`<div>Set contact channel to <b>${action.channel.name}</b></div>`;\n};\n\nexport const renderAddContactUrn = (node: Node, action: AddContactUrn) => {\n const friendlyScheme = urnSchemeMap[action.scheme] || action.scheme;\n return html`<div\n style=\"word-wrap: break-word; overflow: hidden; text-overflow: ellipsis;\"\n >\n Add ${friendlyScheme} <b>${action.path}</b>\n </div>`;\n};\n\nexport const renderSendEmail = (node: Node, action: SendEmail) => {\n const addressList = action.addresses.join(', ');\n return html`<div>\n <div\n style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\"\n >\n <b>${addressList}</b>\n </div>\n <div style=\"margin-top: 0.5em\">\n <div\n style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\"\n >\n ${action.subject}\n </div>\n <div\n style=\"margin-top: 0.25em; word-wrap: break-word; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;\"\n >\n ${action.body}\n </div>\n </div>\n </div>`;\n};\n\nexport const renderSendBroadcast = (node: Node, action: SendBroadcast) => {\n const hasGroups = action.groups && action.groups.length > 0;\n const hasContacts = action.contacts && action.contacts.length > 0;\n\n return html`<div>\n <div style=\"word-wrap: break-word; margin-bottom: 0.5em\">\n ${action.text}\n </div>\n ${hasGroups\n ? html`<div style=\"margin-bottom: 0.25em\">\n <div style=\"font-weight: bold; margin-bottom: 0.25em\">Groups:</div>\n ${renderNamedObjects(action.groups, 'group')}\n </div>`\n : null}\n ${hasContacts\n ? html`<div>\n <div style=\"font-weight: bold; margin-bottom: 0.25em\">Contacts:</div>\n ${renderNamedObjects(action.contacts, 'contact')}\n </div>`\n : null}\n </div>`;\n};\n\nexport const renderEnterFlow = (node: Node, action: EnterFlow) => {\n return html`<div>Enter flow <b>${action.flow.name}</b></div>`;\n};\n\nexport const renderStartSession = (node: Node, action: StartSession) => {\n const hasGroups = action.groups && action.groups.length > 0;\n const hasContacts = action.contacts && action.contacts.length > 0;\n\n return html`<div>\n ${hasGroups\n ? html`<div style=\"margin-top: 0.5em\">\n <div style=\"font-weight: bold; margin-bottom: 0.25em\">Groups:</div>\n ${renderNamedObjects(action.groups, 'group')}\n </div>`\n : null}\n ${hasContacts\n ? html`<div style=\"margin-top: 0.5em\">\n <div style=\"font-weight: bold; margin-bottom: 0.25em\">Contacts:</div>\n ${renderNamedObjects(action.contacts, 'contact')}\n </div>`\n : null}\n ${action.create_contact\n ? renderLineItem('Create contact', Icon.contact)\n : null}\n ${renderLineItem(action.flow.name, Icon.flow)}\n </div>`;\n};\n\nexport const renderTransferAirtime = (node: Node, action: TransferAirtime) => {\n const amounts = action.amounts.join(', ');\n return html`<div>\n Transfer airtime amounts: <b>${amounts}</b>\n <div>Save result as <b>${action.result_name}</b></div>\n </div>`;\n};\n\nexport const renderCallClassifier = (node: Node, action: CallClassifier) => {\n return html`<div>\n <div>Call classifier <b>${action.classifier.name}</b></div>\n <div style=\"margin-top: 0.25em; word-wrap: break-word\">\n Input: <b>${action.input}</b>\n </div>\n <div style=\"margin-top: 0.25em\">\n Save result as <b>${action.result_name}</b>\n </div>\n </div>`;\n};\n\nexport const renderCallResthook = (node: Node, action: CallResthook) => {\n return html`<div>\n <div>Call resthook <b>${action.resthook}</b></div>\n <div style=\"margin-top: 0.25em\">\n Save result as <b>${action.result_name}</b>\n </div>\n </div>`;\n};\n\nexport const renderCallLLM = (node: Node, action: CallLLM) => {\n return html`<div>\n <div style=\"margin-top: 0.25em; display: flex; align-items: center;\">\n <temba-icon name=\"ai\" style=\"margin-right: 0.5em\"></temba-icon>\n <span\n style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\"\n >\n ${action.llm.name}\n </span>\n </div>\n <div\n style=\"margin-top: 0.25em; word-wrap: break-word; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;\"\n >\n ${action.instructions}\n </div>\n </div>`;\n};\n\nexport const renderOpenTicket = (node: Node, action: OpenTicket) => {\n return html`<div>\n <div\n style=\"word-wrap: break-word; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;\"\n >\n ${action.body}\n </div>\n ${action.assignee\n ? html`<div\n style=\"margin-top: 0.25em; display: flex; align-items: center;\"\n >\n <temba-icon name=\"user\" style=\"margin-right: 0.5em\"></temba-icon>\n <span\n style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\"\n >\n ${action.assignee.name}\n </span>\n </div>`\n : null}\n ${action.topic\n ? html`<div\n style=\"margin-top: 0.25em; display: flex; align-items: center;\"\n >\n <temba-icon name=\"topic\" style=\"margin-right: 0.5em\"></temba-icon>\n <span\n style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\"\n >\n ${action.topic.name}\n </span>\n </div>`\n : null}\n </div>`;\n};\n\nexport const renderRequestOptin = (node: Node, action: RequestOptin) => {\n return html`<div>Request opt-in for <b>${action.optin.name}</b></div>`;\n};\n\nexport const renderAddInputLabels = (node: Node, action: AddInputLabels) => {\n return html`<div>${renderNamedObjects(action.labels, 'label')}</div>`;\n};\n\nexport const renderSayMsg = (node: Node, action: SayMsg) => {\n return html`<div>\n <div\n style=\"word-wrap: break-word; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\"\n >\n ${action.text}\n </div>\n ${action.audio_url\n ? html`<div\n style=\"margin-top: 0.5em; display: flex; align-items: center;\"\n >\n <temba-icon name=\"audio\" style=\"margin-right: 0.25em\"></temba-icon>\n <span\n style=\"word-break: break-all; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\"\n >${action.audio_url}</span\n >\n </div>`\n : null}\n </div>`;\n};\n\nexport const renderPlayAudio = (node: Node, action: PlayAudio) => {\n return html`<div style=\"display: flex; align-items: center;\">\n <temba-icon name=\"audio\" style=\"margin-right: 0.25em\"></temba-icon>\n <span\n style=\"word-break: break-all; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\"\n >${action.audio_url}</span\n >\n </div>`;\n};\n\nexport const renderWaitForResponse = (node: Node, action: WaitForResponse) => {\n return html`<div>\n Wait for message response\n ${action.timeout\n ? html`<div style=\"margin-top: 0.25em\">\n Timeout after <b>${action.timeout}</b> seconds\n </div>`\n : null}\n </div>`;\n};\n\nexport const renderWaitForMenu = (node: Node, action: WaitForMenu) => {\n return html`<div>\n Wait for menu selection: <b>${action.menu.name}</b>\n ${action.timeout\n ? html`<div style=\"margin-top: 0.25em\">\n Timeout after <b>${action.timeout}</b> seconds\n </div>`\n : null}\n </div>`;\n};\n\nexport const renderWaitForDigits = (node: Node, action: WaitForDigits) => {\n return html`<div>\n Wait for <b>${action.count}</b> digit${action.count !== 1 ? 's' : ''}\n ${action.timeout\n ? html`<div style=\"margin-top: 0.25em\">\n Timeout after <b>${action.timeout}</b> seconds\n </div>`\n : null}\n </div>`;\n};\n\nexport const renderWaitForAudio = (node: Node, action: WaitForAudio) => {\n return html`<div>\n <temba-icon name=\"audio\" style=\"margin-right: 0.25em\"></temba-icon>\n Wait for audio recording\n ${action.timeout\n ? html`<div style=\"margin-top: 0.25em\">\n Timeout after <b>${action.timeout}</b> seconds\n </div>`\n : null}\n </div>`;\n};\n\nexport const renderWaitForVideo = (node: Node, action: WaitForVideo) => {\n return html`<div>\n <temba-icon name=\"video\" style=\"margin-right: 0.25em\"></temba-icon>\n Wait for video recording\n ${action.timeout\n ? html`<div style=\"margin-top: 0.25em\">\n Timeout after <b>${action.timeout}</b> seconds\n </div>`\n : null}\n </div>`;\n};\n\nexport const renderWaitForImage = (node: Node, action: WaitForImage) => {\n return html`<div>\n <temba-icon name=\"image\" style=\"margin-right: 0.25em\"></temba-icon>\n Wait for image\n ${action.timeout\n ? html`<div style=\"margin-top: 0.25em\">\n Timeout after <b>${action.timeout}</b> seconds\n </div>`\n : null}\n </div>`;\n};\n\nexport const renderWaitForLocation = (node: Node, action: WaitForLocation) => {\n return html`<div>\n <temba-icon name=\"location\" style=\"margin-right: 0.25em\"></temba-icon>\n Wait for location\n ${action.timeout\n ? html`<div style=\"margin-top: 0.25em\">\n Timeout after <b>${action.timeout}</b> seconds\n </div>`\n : null}\n </div>`;\n};\n"]}