@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
package/.eslintrc.js CHANGED
@@ -16,6 +16,7 @@ module.exports = {
16
16
  '@typescript-eslint/no-explicit-any': 'off',
17
17
  '@typescript-eslint/explicit-function-return-type': 'off',
18
18
  '@typescript-eslint/no-non-null-assertion': 'off',
19
+ '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
19
20
  'import/named': 'off',
20
21
  'import/no-unresolved': 'off',
21
22
  // Block console.log statements unless explicitly disabled
@@ -1,9 +1,10 @@
1
1
  name: 'build'
2
2
 
3
- on: [push]
3
+ on: [push, pull_request]
4
4
 
5
5
  permissions:
6
6
  contents: write
7
+ pull-requests: write
7
8
 
8
9
  jobs:
9
10
  build:
@@ -20,17 +21,148 @@ jobs:
20
21
  fetch-depth: 0
21
22
  - run: docker network create --driver bridge textit_default
22
23
  - name: Build and run dev container task
24
+ id: validate
23
25
  uses: devcontainers/ci@v0.3
26
+ continue-on-error: true
24
27
  with:
25
- runCmd: yarn validate
28
+ runCmd: |
29
+ yarn validate 2>&1 | tee validate_output.log
30
+ exit ${PIPESTATUS[0]}
26
31
  push: never
27
32
  env: |
28
33
  CI=true
29
34
 
35
+ - name: Extract coverage stats
36
+ if: always()
37
+ run: |
38
+ if [ -f validate_output.log ]; then
39
+ echo "Extracting coverage information from validate output..."
40
+
41
+ # Extract coverage report section
42
+ COVERAGE_REPORT=$(grep -A 10 "📊 Coverage Report" validate_output.log | head -15 || echo "Coverage report not found")
43
+
44
+ # Save coverage to environment file for PR comment
45
+ echo "COVERAGE_REPORT<<EOF" >> $GITHUB_ENV
46
+ echo "$COVERAGE_REPORT" >> $GITHUB_ENV
47
+ echo "EOF" >> $GITHUB_ENV
48
+
49
+ # Also save individual metrics for easier parsing
50
+ LINES_COVERAGE=$(grep "Lines:" validate_output.log | grep -o '[0-9.]*%' | tail -1 || echo "N/A")
51
+ FUNCTIONS_COVERAGE=$(grep "Functions:" validate_output.log | grep -o '[0-9.]*%' | tail -1 || echo "N/A")
52
+ BRANCHES_COVERAGE=$(grep "Branches:" validate_output.log | grep -o '[0-9.]*%' | tail -1 || echo "N/A")
53
+
54
+ echo "LINES_COVERAGE=$LINES_COVERAGE" >> $GITHUB_ENV
55
+ echo "FUNCTIONS_COVERAGE=$FUNCTIONS_COVERAGE" >> $GITHUB_ENV
56
+ echo "BRANCHES_COVERAGE=$BRANCHES_COVERAGE" >> $GITHUB_ENV
57
+
58
+ echo "Coverage extracted:"
59
+ echo "Lines: $LINES_COVERAGE"
60
+ echo "Functions: $FUNCTIONS_COVERAGE"
61
+ echo "Branches: $BRANCHES_COVERAGE"
62
+
63
+ # Debug: show what coverage files we have
64
+ echo "Available coverage files:"
65
+ find . -name "coverage" -type d 2>/dev/null || echo "No coverage directories found"
66
+ find . -name "lcov-report" -type d 2>/dev/null || echo "No lcov-report directories found"
67
+ else
68
+ echo "No validate output found"
69
+ fi
70
+
71
+ - name: Comment coverage on PR
72
+ if: github.event_name == 'pull_request' && always()
73
+ uses: actions/github-script@v7
74
+ with:
75
+ script: |
76
+ const coverageReport = process.env.COVERAGE_REPORT;
77
+ const linesCoverage = process.env.LINES_COVERAGE;
78
+ const functionsCoverage = process.env.FUNCTIONS_COVERAGE;
79
+ const branchesCoverage = process.env.BRANCHES_COVERAGE;
80
+
81
+ const body = `## 📊 Coverage Report
82
+
83
+ \`\`\`
84
+ ${coverageReport}
85
+ \`\`\`
86
+
87
+ ### Summary
88
+ - **Lines:** ${linesCoverage}
89
+ - **Functions:** ${functionsCoverage}
90
+ - **Branches:** ${branchesCoverage}
91
+
92
+ [Coverage Report](https://s3.us-east-1.amazonaws.com/dev.temba.io/coverage/temba-components/pr-${context.payload.number}/index.html)
93
+ `;
94
+
95
+ // Find existing coverage comment
96
+ const comments = await github.rest.issues.listComments({
97
+ owner: context.repo.owner,
98
+ repo: context.repo.repo,
99
+ issue_number: context.payload.number,
100
+ });
101
+
102
+ const existingComment = comments.data.find(comment =>
103
+ comment.user.login === 'github-actions[bot]' &&
104
+ comment.body.includes('📊 Coverage Report')
105
+ );
106
+
107
+ if (existingComment) {
108
+ // Update existing comment
109
+ await github.rest.issues.updateComment({
110
+ owner: context.repo.owner,
111
+ repo: context.repo.repo,
112
+ comment_id: existingComment.id,
113
+ body: body
114
+ });
115
+ } else {
116
+ // Create new comment
117
+ await github.rest.issues.createComment({
118
+ owner: context.repo.owner,
119
+ repo: context.repo.repo,
120
+ issue_number: context.payload.number,
121
+ body: body
122
+ });
123
+ }
124
+
125
+ - name: Configure AWS credentials
126
+ if: always()
127
+ uses: aws-actions/configure-aws-credentials@v4
128
+ with:
129
+ aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
130
+ aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
131
+ aws-region: us-east-1
132
+
133
+ - name: Upload coverage report to S3
134
+ if: always()
135
+ run: |
136
+ # Check if coverage directory exists
137
+ if [ -d "coverage/lcov-report" ]; then
138
+ echo "Uploading coverage report to S3..."
139
+
140
+ if [ "${{ github.event_name }}" == "pull_request" ]; then
141
+ # For PRs, upload to a PR-specific folder
142
+ S3_PATH="s3://dev.temba.io/coverage/temba-components/pr-${{ github.event.number }}/"
143
+ else
144
+ # For main branch, upload to main folder
145
+ S3_PATH="s3://dev.temba.io/coverage/temba-components/main/"
146
+ fi
147
+
148
+ aws s3 sync coverage/lcov-report/ "$S3_PATH" --delete
149
+ echo "Coverage report uploaded to: $S3_PATH"
150
+ else
151
+ echo "No coverage report found to upload"
152
+ fi
153
+
154
+ - name: Check validation result
155
+ run: |
156
+ if [ "${{ steps.validate.outcome }}" != "success" ]; then
157
+ echo "❌ Validation failed"
158
+ exit 1
159
+ else
160
+ echo "✅ Validation passed"
161
+ fi
162
+
30
163
  - name: Upload artifacts
31
164
  if: failure()
32
165
  uses: actions/upload-artifact@v4
33
166
  with:
34
167
  name: screenshots
35
168
  path: screenshots/
36
-
package/CHANGELOG.md CHANGED
@@ -4,8 +4,27 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ #### [v0.129.5](https://github.com/nyaruka/temba-components/compare/v0.129.3...v0.129.5)
8
+
9
+ - Don't trigger ref change on internal values change for Select [`#648`](https://github.com/nyaruka/temba-components/pull/648)
10
+ - Cleanup unused chat event types and remove some unused properties on other types [`#647`](https://github.com/nyaruka/temba-components/pull/647)
11
+ - Nestable form layouts [`#644`](https://github.com/nyaruka/temba-components/pull/644)
12
+ - Add KeyValueEditor and field config abstraction [`#643`](https://github.com/nyaruka/temba-components/pull/643)
13
+ - Add send_email test [`#642`](https://github.com/nyaruka/temba-components/pull/642)
14
+ - Add better action tests [`#641`](https://github.com/nyaruka/temba-components/pull/641)
15
+ - Change coverage user and path [`#640`](https://github.com/nyaruka/temba-components/pull/640)
16
+ - Update coverage storage for build [`#639`](https://github.com/nyaruka/temba-components/pull/639)
17
+ - Add NodeConfig [`#638`](https://github.com/nyaruka/temba-components/pull/638)
18
+ - Simplify ActionEditor form configuration by removing properties support and renaming transformations [`#637`](https://github.com/nyaruka/temba-components/pull/637)
19
+ - Action editor [`#635`](https://github.com/nyaruka/temba-components/pull/635)
20
+ - Introduce NodeConfig to complement ActionConfig [`3144a8b`](https://github.com/nyaruka/temba-components/commit/3144a8ba2ece77c35fe1610cc6b2fd2378874845)
21
+ - Reorg flow config [`cb64d1f`](https://github.com/nyaruka/temba-components/commit/cb64d1fc24d8502442f854e612cf7d3b8723e5e8)
22
+ - Add KeyValueEditor [`a138f41`](https://github.com/nyaruka/temba-components/commit/a138f41d9d62de3df79e82b0907cefac1997c0cf)
23
+
7
24
  #### [v0.129.3](https://github.com/nyaruka/temba-components/compare/v0.129.2...v0.129.3)
8
25
 
26
+ > 29 July 2025
27
+
9
28
  - Don't attempt to show select items if loading [`#634`](https://github.com/nyaruka/temba-components/pull/634)
10
29
  - Fix sticky selection intersection [`#633`](https://github.com/nyaruka/temba-components/pull/633)
11
30
  - Flow Editor: Add missing action descriptions for flow rendering [`#632`](https://github.com/nyaruka/temba-components/pull/632)
@@ -16,9 +16,9 @@
16
16
  "text": "What is your favorite color?",
17
17
  "type": "send_msg",
18
18
  "quick_replies": [
19
- "red",
20
- "green",
21
- "blue"
19
+ "Red",
20
+ "Green",
21
+ "Blue"
22
22
  ],
23
23
  "uuid": "3d56e4cf-1e88-499a-b0b4-ff48385fc9a5"
24
24
  }
@@ -75,7 +75,7 @@
75
75
  },
76
76
  {
77
77
  "uuid": "ee972b45-3bfe-4e93-9d4e-e9c8f8ffc587",
78
- "name": "Blue",
78
+ "name": "Blue but longer so it hits the max width for categories in nodes",
79
79
  "exit_uuid": "3dfd68c4-0184-49d8-b2a4-0bbb62425f33"
80
80
  },
81
81
  {
@@ -127,13 +127,15 @@
127
127
  "actions": [
128
128
  {
129
129
  "uuid": "cb497975-a8fb-4d28-a662-277eb7a699f9",
130
- "headers": {
131
- "Accept": "application/json"
132
- },
133
130
  "type": "call_webhook",
134
131
  "url": "http://google.com",
135
- "body": "",
136
- "method": "GET"
132
+ "method": "POST",
133
+ "headers": {
134
+ "Accepts": "application/json",
135
+ "Content-Type": "application/json",
136
+ "Authorization": "Bearer token here"
137
+ },
138
+ "body": "@(json(object(\n \"contact\", object(\n \"uuid\", contact.uuid, \n \"name\", contact.name, \n \"urn\", contact.urn\n ),\n \"flow\", object(\n \"uuid\", run.flow.uuid, \n \"name\", run.flow.name\n ),\n \"results\", foreach_value(results, extract_object, \"value\", \"category\")\n)))"
137
139
  }
138
140
  ],
139
141
  "router": {
@@ -152,14 +154,14 @@
152
154
  ],
153
155
  "categories": [
154
156
  {
155
- "uuid": "0bb08076-45e2-4ca1-b321-1506f1779198",
157
+ "uuid": "1b9100a4-f3f0-410e-8b6f-d339bf58a13a",
156
158
  "name": "Success",
157
- "exit_uuid": "4f1f8e3b-887c-42f5-bf59-fa59c5245dc2"
159
+ "exit_uuid": "e6d66511-f532-44c5-acbe-bede3963e677"
158
160
  },
159
161
  {
160
- "uuid": "67fc0e41-eeb2-4f54-9f71-abdd64c097f4",
162
+ "uuid": "13915377-5eb1-46c5-8955-78646b75b8ef",
161
163
  "name": "Failure",
162
- "exit_uuid": "4929ff2a-35cf-43a5-8353-dfede604add7"
164
+ "exit_uuid": "8087c747-eebc-4f35-8032-33490ba390d6"
163
165
  }
164
166
  ],
165
167
  "default_category_uuid": "67fc0e41-eeb2-4f54-9f71-abdd64c097f4",
@@ -167,12 +169,12 @@
167
169
  },
168
170
  "exits": [
169
171
  {
170
- "uuid": "4f1f8e3b-887c-42f5-bf59-fa59c5245dc2",
172
+ "uuid": "e6d66511-f532-44c5-acbe-bede3963e677",
171
173
  "destination_uuid": "b85000c4-1990-4d86-807a-1318ea512708"
172
174
  },
173
175
  {
174
- "uuid": "4929ff2a-35cf-43a5-8353-dfede604add7",
175
- "destination_uuid": "8ecec688-f154-4b80-a0b3-3cbff0fac892"
176
+ "uuid": "8087c747-eebc-4f35-8032-33490ba390d6",
177
+ "destination_uuid": "b85000c4-1990-4d86-807a-1318ea512708"
176
178
  }
177
179
  ]
178
180
  },
@@ -180,42 +182,71 @@
180
182
  "uuid": "4efc49e0-ebfe-454d-a1a0-900a911dd5ef",
181
183
  "actions": [
182
184
  {
183
- "attachments": [],
184
- "text": "Excellent choice!",
185
+ "uuid": "9963160a-a007-4c7b-8c9e-7325e1b69ed8",
185
186
  "type": "send_msg",
186
- "quick_replies": [],
187
- "uuid": "9963160a-a007-4c7b-8c9e-7325e1b69ed8"
187
+ "text": "Excellent choices.",
188
+ "quick_replies": [
189
+ "blooooop",
190
+ "bleep"
191
+ ]
188
192
  },
189
193
  {
190
- "type": "add_contact_groups",
194
+ "uuid": "ffe1c2d3-4e5f-6a7b-8c9d-e0f1a2b3c4d5",
195
+ "type": "remove_contact_groups",
191
196
  "groups": [
192
197
  {
193
- "uuid": "269e8abf-e81b-404c-82ce-45ff42d13769",
194
- "name": "Empty",
198
+ "uuid": "f80ed7b6-5e6a-49eb-94b6-4631a9677cd8",
199
+ "name": "Reporters",
195
200
  "query": null,
196
201
  "status": "ready",
197
- "system": false,
198
202
  "count": 0
199
203
  },
200
204
  {
201
- "uuid": "58a6a3cd-20c0-4791-82da-ce9f319ab91b",
202
- "name": "Farmers",
205
+ "uuid": "a3f2990b-4096-452e-a586-dc06a9434dde",
206
+ "name": "Empty",
203
207
  "query": null,
204
208
  "status": "ready",
205
- "system": false,
206
- "count": 2414
209
+ "count": 0
210
+ },
211
+ {
212
+ "uuid": "76e7a094-22ea-441d-91c4-283d8168e8e3",
213
+ "name": "Some Really Long Group Name",
214
+ "count": 2028
215
+ },
216
+ {
217
+ "uuid": "66e7a094-22ea-441d-91c4-283d8168e8e4",
218
+ "name": "The Poots",
219
+ "query": "name ~ \"poots\" OR name ~ \"dave\"",
220
+ "status": "ready",
221
+ "count": 1028
222
+ },
223
+ {
224
+ "uuid": "94e3ff12-9206-4ce8-87ab-934a864a1819",
225
+ "name": "Youth",
226
+ "query": "age <= 18",
227
+ "status": "ready",
228
+ "count": 174
207
229
  }
208
230
  ],
209
- "uuid": "d1ca86da-f321-4e09-8bb2-981de03f5a90"
231
+ "all_groups": false
210
232
  },
211
233
  {
212
- "addresses": [
213
- "name@domain.com"
214
- ],
215
- "subject": "Did you get this?",
216
- "body": "I hope it arrived!",
217
- "type": "send_email",
218
- "uuid": "a0f3f1f2-1869-4ad6-9fb0-e610a3e00ae7"
234
+ "uuid": "d1ca86da-f321-4e09-8bb2-981de03f5a90",
235
+ "type": "add_contact_groups",
236
+ "groups": [
237
+ {
238
+ "uuid": "a3f2990b-4096-452e-a586-dc06a9434dde",
239
+ "name": "Empty",
240
+ "query": null,
241
+ "status": "ready",
242
+ "count": 0
243
+ },
244
+ {
245
+ "uuid": "76e7a094-22ea-441d-91c4-283d8168e8e3",
246
+ "name": "Some Really Long Group Name",
247
+ "count": 2028
248
+ }
249
+ ]
219
250
  },
220
251
  {
221
252
  "type": "set_run_result",
@@ -249,39 +280,31 @@
249
280
  "language": "eng"
250
281
  },
251
282
  {
252
- "type": "remove_contact_groups",
253
- "groups": [
283
+ "uuid": "773fa48f-7341-4f57-bf74-2afed2e4b763",
284
+ "actions": [
254
285
  {
255
- "uuid": "269e8abf-e81b-404c-82ce-45ff42d13769",
256
- "name": "Empty"
257
- },
258
- {
259
- "uuid": "2f81d414-47b7-446d-b8c7-6662f611cb3d",
260
- "name": "Testers"
261
- },
262
- {
263
- "uuid": "90c0dc52-ddd8-466d-8333-a96fdd67195a",
264
- "name": "Teachers"
265
- },
266
- {
267
- "uuid": "58a6a3cd-20c0-4791-82da-ce9f319ab91b",
268
- "name": "Farmers"
269
- },
270
- {
271
- "uuid": "3b9caef9-e701-4475-a0c3-ef346704f71e",
272
- "name": "Reporters"
273
- },
274
- {
275
- "uuid": "f4f46e03-3d7c-4840-8ed3-8c6c5677a2f2",
276
- "name": "Doctors"
277
- },
286
+ "type": "remove_contact_groups",
287
+ "groups": [],
288
+ "all_groups": true,
289
+ "uuid": "4f6a8bbb-5563-4bdb-8b53-e23490596fcd"
290
+ }
291
+ ],
292
+ "exits": [
278
293
  {
279
- "uuid": "4b4ad0a2-0be6-4edd-8d6f-f6fa40ce695c",
280
- "name": "Drivers"
294
+ "uuid": "f2265a88-4568-4105-8a0c-c698d32ff18f",
295
+ "destination_uuid": null
281
296
  }
297
+ ]
298
+ },
299
+ {
300
+ "uuid": "a0f3f1f2-1869-4ad6-9fb0-e610a3e00ae7",
301
+ "type": "send_email",
302
+ "addresses": [
303
+ "mistermeowface@whiskers.com",
304
+ "name@domain.com"
282
305
  ],
283
- "all_groups": false,
284
- "uuid": "6ec87721-6ec2-43fa-b7d2-930bf1f0574d"
306
+ "subject": "Did you get this?",
307
+ "body": "I hope it arrived! But this message is a bit longer."
285
308
  },
286
309
  {
287
310
  "type": "add_contact_urn",
@@ -515,7 +538,7 @@
515
538
  },
516
539
  {
517
540
  "uuid": "5ef3425c-f015-46a5-9975-046879eba986",
518
- "destination_uuid": "e780a7ef-9dad-45a3-abda-11200a9afbf4"
541
+ "destination_uuid": "8ecec688-f154-4b80-a0b3-3cbff0fac892"
519
542
  }
520
543
  ]
521
544
  },
@@ -775,7 +798,7 @@
775
798
  "nodes": {
776
799
  "a229fa3c-16bb-440b-9ae8-b7ee7a723f44": {
777
800
  "position": {
778
- "left": 280,
801
+ "left": 260,
779
802
  "top": 0
780
803
  },
781
804
  "type": "execute_actions"
@@ -793,30 +816,30 @@
793
816
  "e1f22e97-a170-44b4-a79b-98ab916f4c34": {
794
817
  "type": "split_by_webhook",
795
818
  "position": {
796
- "left": 1020,
797
- "top": 100
819
+ "left": 800,
820
+ "top": 0
798
821
  },
799
822
  "config": {}
800
823
  },
801
824
  "4efc49e0-ebfe-454d-a1a0-900a911dd5ef": {
802
825
  "position": {
803
826
  "left": 240,
804
- "top": 380
827
+ "top": 340
805
828
  },
806
829
  "type": "execute_actions"
807
830
  },
808
831
  "2c60c381-487d-42cd-80be-a31f44c36fd9": {
809
832
  "type": "split_by_subflow",
810
833
  "position": {
811
- "left": 580,
812
- "top": 600
834
+ "left": 520,
835
+ "top": 680
813
836
  },
814
837
  "config": {}
815
838
  },
816
839
  "f115fdb0-d92d-47a2-96f3-e03e36767b14": {
817
840
  "type": "split_by_contact_field",
818
841
  "position": {
819
- "left": 800,
842
+ "left": 1020,
820
843
  "top": 220
821
844
  },
822
845
  "config": {
@@ -831,8 +854,8 @@
831
854
  "b85000c4-1990-4d86-807a-1318ea512708": {
832
855
  "type": "split_by_expression",
833
856
  "position": {
834
- "left": 1020,
835
- "top": 440
857
+ "left": 720,
858
+ "top": 240
836
859
  },
837
860
  "config": {
838
861
  "cases": {}
@@ -841,16 +864,16 @@
841
864
  "8ecec688-f154-4b80-a0b3-3cbff0fac892": {
842
865
  "type": "split_by_random",
843
866
  "position": {
844
- "left": 780,
845
- "top": 380
867
+ "left": 940,
868
+ "top": 360
846
869
  },
847
870
  "config": null
848
871
  },
849
872
  "66171418-2368-44b9-95db-fdf7cd5cf4fe": {
850
873
  "type": "split_by_run_result",
851
874
  "position": {
852
- "left": 900,
853
- "top": 560
875
+ "left": 800,
876
+ "top": 600
854
877
  },
855
878
  "config": {
856
879
  "operand": {
@@ -865,7 +888,7 @@
865
888
  "type": "split_by_groups",
866
889
  "position": {
867
890
  "left": 500,
868
- "top": 340
891
+ "top": 360
869
892
  },
870
893
  "config": {
871
894
  "cases": {}
@@ -874,8 +897,8 @@
874
897
  "e780a7ef-9dad-45a3-abda-11200a9afbf4": {
875
898
  "type": "split_by_scheme",
876
899
  "position": {
877
- "left": 580,
878
- "top": 480
900
+ "left": 480,
901
+ "top": 560
879
902
  },
880
903
  "config": {
881
904
  "cases": {}
@@ -885,22 +908,22 @@
885
908
  "type": "split_by_llm",
886
909
  "position": {
887
910
  "left": 580,
888
- "top": 880
911
+ "top": 1040
889
912
  },
890
913
  "config": {}
891
914
  },
892
915
  "425c4757-bead-440f-92aa-a1cc3fcd7d35": {
893
916
  "position": {
894
- "left": 900,
895
- "top": 740
917
+ "left": 620,
918
+ "top": 840
896
919
  },
897
920
  "type": "execute_actions"
898
921
  },
899
922
  "21ff86c2-5276-4448-afb6-54d1f832ba0c": {
900
923
  "type": "split_by_ticket",
901
924
  "position": {
902
- "left": 900,
903
- "top": 860
925
+ "left": 920,
926
+ "top": 900
904
927
  },
905
928
  "config": {}
906
929
  }