@nyaruka/temba-components 0.129.8 → 0.129.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/CHANGELOG.md +37 -3
  2. package/demo/data/flows/sample-flow.json +186 -96
  3. package/demo/test-colorpicker.html +30 -0
  4. package/dist/temba-components.js +1126 -1111
  5. package/dist/temba-components.js.map +1 -1
  6. package/out-tsc/src/events.js.map +1 -1
  7. package/out-tsc/src/excellent/helpers.js +2 -2
  8. package/out-tsc/src/excellent/helpers.js.map +1 -1
  9. package/out-tsc/src/flow/CanvasNode.js +25 -7
  10. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  11. package/out-tsc/src/flow/Editor.js +11 -1
  12. package/out-tsc/src/flow/Editor.js.map +1 -1
  13. package/out-tsc/src/flow/NodeEditor.js +133 -290
  14. package/out-tsc/src/flow/NodeEditor.js.map +1 -1
  15. package/out-tsc/src/flow/actions/add_input_labels.js +40 -0
  16. package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -1
  17. package/out-tsc/src/flow/actions/call_llm.js +56 -3
  18. package/out-tsc/src/flow/actions/call_llm.js.map +1 -1
  19. package/out-tsc/src/flow/actions/call_webhook.js +1 -1
  20. package/out-tsc/src/flow/actions/call_webhook.js.map +1 -1
  21. package/out-tsc/src/flow/actions/open_ticket.js +65 -3
  22. package/out-tsc/src/flow/actions/open_ticket.js.map +1 -1
  23. package/out-tsc/src/flow/actions/set_run_result.js +75 -0
  24. package/out-tsc/src/flow/actions/set_run_result.js.map +1 -1
  25. package/out-tsc/src/flow/config.js +4 -0
  26. package/out-tsc/src/flow/config.js.map +1 -1
  27. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +227 -0
  28. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -0
  29. package/out-tsc/src/flow/nodes/split_by_ticket.js +18 -0
  30. package/out-tsc/src/flow/nodes/split_by_ticket.js.map +1 -0
  31. package/out-tsc/src/flow/nodes/wait_for_response.js +27 -1
  32. package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
  33. package/out-tsc/src/flow/types.js +0 -65
  34. package/out-tsc/src/flow/types.js.map +1 -1
  35. package/out-tsc/src/form/ArrayEditor.js +63 -117
  36. package/out-tsc/src/form/ArrayEditor.js.map +1 -1
  37. package/out-tsc/src/form/BaseListEditor.js +4 -3
  38. package/out-tsc/src/form/BaseListEditor.js.map +1 -1
  39. package/out-tsc/src/form/Checkbox.js +77 -24
  40. package/out-tsc/src/form/Checkbox.js.map +1 -1
  41. package/out-tsc/src/form/ColorPicker.js +28 -40
  42. package/out-tsc/src/form/ColorPicker.js.map +1 -1
  43. package/out-tsc/src/form/Completion.js +44 -53
  44. package/out-tsc/src/form/Completion.js.map +1 -1
  45. package/out-tsc/src/form/Compose.js +7 -8
  46. package/out-tsc/src/form/Compose.js.map +1 -1
  47. package/out-tsc/src/form/ContactSearch.js +3 -4
  48. package/out-tsc/src/form/ContactSearch.js.map +1 -1
  49. package/out-tsc/src/form/DatePicker.js +29 -36
  50. package/out-tsc/src/form/DatePicker.js.map +1 -1
  51. package/out-tsc/src/form/{FormField.js → FieldElement.js} +81 -53
  52. package/out-tsc/src/form/FieldElement.js.map +1 -0
  53. package/out-tsc/src/form/FieldRenderer.js +306 -0
  54. package/out-tsc/src/form/FieldRenderer.js.map +1 -0
  55. package/out-tsc/src/form/ImagePicker.js +122 -126
  56. package/out-tsc/src/form/ImagePicker.js.map +1 -1
  57. package/out-tsc/src/form/KeyValueEditor.js +41 -37
  58. package/out-tsc/src/form/KeyValueEditor.js.map +1 -1
  59. package/out-tsc/src/form/MessageEditor.js +55 -63
  60. package/out-tsc/src/form/MessageEditor.js.map +1 -1
  61. package/out-tsc/src/form/TembaSlider.js +3 -3
  62. package/out-tsc/src/form/TembaSlider.js.map +1 -1
  63. package/out-tsc/src/form/TemplateEditor.js +3 -3
  64. package/out-tsc/src/form/TemplateEditor.js.map +1 -1
  65. package/out-tsc/src/form/TextInput.js +23 -27
  66. package/out-tsc/src/form/TextInput.js.map +1 -1
  67. package/out-tsc/src/form/select/Select.js +57 -35
  68. package/out-tsc/src/form/select/Select.js.map +1 -1
  69. package/out-tsc/src/form/select/UserSelect.js +8 -9
  70. package/out-tsc/src/form/select/UserSelect.js.map +1 -1
  71. package/out-tsc/src/form/select/WorkspaceSelect.js +7 -8
  72. package/out-tsc/src/form/select/WorkspaceSelect.js.map +1 -1
  73. package/out-tsc/src/live/ContactChat.js +62 -44
  74. package/out-tsc/src/live/ContactChat.js.map +1 -1
  75. package/out-tsc/src/live/ContactFieldEditor.js.map +1 -1
  76. package/out-tsc/src/markdown.js +13 -11
  77. package/out-tsc/src/markdown.js.map +1 -1
  78. package/out-tsc/temba-modules.js +3 -2
  79. package/out-tsc/temba-modules.js.map +1 -1
  80. package/out-tsc/test/ActionHelper.js +2 -0
  81. package/out-tsc/test/ActionHelper.js.map +1 -1
  82. package/out-tsc/test/NodeHelper.js +148 -0
  83. package/out-tsc/test/NodeHelper.js.map +1 -0
  84. package/out-tsc/test/actions/call_llm.test.js +103 -0
  85. package/out-tsc/test/actions/call_llm.test.js.map +1 -0
  86. package/out-tsc/test/nodes/split_by_llm_categorize.test.js +532 -0
  87. package/out-tsc/test/nodes/split_by_llm_categorize.test.js.map +1 -0
  88. package/out-tsc/test/nodes/split_by_random.test.js +150 -0
  89. package/out-tsc/test/nodes/split_by_random.test.js.map +1 -0
  90. package/out-tsc/test/nodes/wait_for_digits.test.js +150 -0
  91. package/out-tsc/test/nodes/wait_for_digits.test.js.map +1 -0
  92. package/out-tsc/test/nodes/wait_for_response.test.js +171 -0
  93. package/out-tsc/test/nodes/wait_for_response.test.js.map +1 -0
  94. package/out-tsc/test/temba-add-input-labels.test.js +70 -0
  95. package/out-tsc/test/temba-add-input-labels.test.js.map +1 -0
  96. package/out-tsc/test/temba-checkbox.test.js +16 -0
  97. package/out-tsc/test/temba-checkbox.test.js.map +1 -1
  98. package/out-tsc/test/temba-field-renderer.test.js +296 -0
  99. package/out-tsc/test/temba-field-renderer.test.js.map +1 -0
  100. package/out-tsc/test/temba-integration-markdown.test.js +2 -4
  101. package/out-tsc/test/temba-integration-markdown.test.js.map +1 -1
  102. package/out-tsc/test/temba-markdown.test.js +1 -1
  103. package/out-tsc/test/temba-markdown.test.js.map +1 -1
  104. package/out-tsc/test/temba-node-editor.test.js +400 -0
  105. package/out-tsc/test/temba-node-editor.test.js.map +1 -1
  106. package/out-tsc/test/temba-select.test.js +6 -3
  107. package/out-tsc/test/temba-select.test.js.map +1 -1
  108. package/out-tsc/test/temba-slider.test.js +0 -1
  109. package/out-tsc/test/temba-slider.test.js.map +1 -1
  110. package/out-tsc/test/temba-webchat.test.js +1 -1
  111. package/out-tsc/test/temba-webchat.test.js.map +1 -1
  112. package/package.json +1 -1
  113. package/screenshots/truth/actions/add_contact_groups/editor/descriptive-group-names.png +0 -0
  114. package/screenshots/truth/actions/add_contact_groups/editor/long-group-names.png +0 -0
  115. package/screenshots/truth/actions/add_contact_groups/editor/many-groups.png +0 -0
  116. package/screenshots/truth/actions/call_llm/editor/information-extraction.png +0 -0
  117. package/screenshots/truth/actions/call_llm/editor/sentiment-analysis.png +0 -0
  118. package/screenshots/truth/actions/call_llm/editor/summarization.png +0 -0
  119. package/screenshots/truth/actions/call_llm/editor/translation-task.png +0 -0
  120. package/screenshots/truth/actions/call_llm/render/information-extraction.png +0 -0
  121. package/screenshots/truth/actions/call_llm/render/sentiment-analysis.png +0 -0
  122. package/screenshots/truth/actions/call_llm/render/summarization.png +0 -0
  123. package/screenshots/truth/actions/call_llm/render/translation-task.png +0 -0
  124. package/screenshots/truth/actions/remove_contact_groups/editor/cleanup-groups.png +0 -0
  125. package/screenshots/truth/actions/remove_contact_groups/editor/long-descriptive-group-names.png +0 -0
  126. package/screenshots/truth/actions/remove_contact_groups/editor/many-groups.png +0 -0
  127. package/screenshots/truth/actions/remove_contact_groups/editor/multiple-groups.png +0 -0
  128. package/screenshots/truth/actions/remove_contact_groups/editor/remove-from-all-groups.png +0 -0
  129. package/screenshots/truth/actions/remove_contact_groups/editor/single-group.png +0 -0
  130. package/screenshots/truth/actions/send_email/editor/complex-business-email.png +0 -0
  131. package/screenshots/truth/actions/send_email/editor/multiple-recipients.png +0 -0
  132. package/screenshots/truth/actions/send_msg/editor/long-quick-replies.png +0 -0
  133. package/screenshots/truth/actions/send_msg/editor/multiline-text-with-replies.png +0 -0
  134. package/screenshots/truth/actions/send_msg/editor/simple-text.png +0 -0
  135. package/screenshots/truth/actions/send_msg/editor/text-with-linebreaks.png +0 -0
  136. package/screenshots/truth/actions/send_msg/editor/text-with-many-quick-replies.png +0 -0
  137. package/screenshots/truth/actions/send_msg/editor/text-with-quick-replies.png +0 -0
  138. package/screenshots/truth/actions/send_msg/editor/text-without-quick-replies.png +0 -0
  139. package/screenshots/truth/checkbox/checkbox-label-background-hover.png +0 -0
  140. package/screenshots/truth/checkbox/checkbox-no-label-no-background-hover.png +0 -0
  141. package/screenshots/truth/checkbox/checkbox-with-help-text.png +0 -0
  142. package/screenshots/truth/checkbox/checked.png +0 -0
  143. package/screenshots/truth/checkbox/default.png +0 -0
  144. package/screenshots/truth/colorpicker/default.png +0 -0
  145. package/screenshots/truth/colorpicker/focused.png +0 -0
  146. package/screenshots/truth/colorpicker/initialized.png +0 -0
  147. package/screenshots/truth/colorpicker/selected.png +0 -0
  148. package/screenshots/truth/editor/router.png +0 -0
  149. package/screenshots/truth/editor/send_msg.png +0 -0
  150. package/screenshots/truth/editor/set_contact_language.png +0 -0
  151. package/screenshots/truth/editor/set_contact_name.png +0 -0
  152. package/screenshots/truth/editor/set_run_result.png +0 -0
  153. package/screenshots/truth/editor/wait.png +0 -0
  154. package/screenshots/truth/field-renderer/checkbox-checked.png +0 -0
  155. package/screenshots/truth/field-renderer/checkbox-unchecked.png +0 -0
  156. package/screenshots/truth/field-renderer/checkbox-with-errors.png +0 -0
  157. package/screenshots/truth/field-renderer/context-comparison.png +0 -0
  158. package/screenshots/truth/field-renderer/key-value-with-label.png +0 -0
  159. package/screenshots/truth/field-renderer/message-editor-with-label.png +0 -0
  160. package/screenshots/truth/field-renderer/select-multi.png +0 -0
  161. package/screenshots/truth/field-renderer/select-no-label.png +0 -0
  162. package/screenshots/truth/field-renderer/select-with-label.png +0 -0
  163. package/screenshots/truth/field-renderer/text-evaluated.png +0 -0
  164. package/screenshots/truth/field-renderer/text-no-label.png +0 -0
  165. package/screenshots/truth/field-renderer/text-with-errors.png +0 -0
  166. package/screenshots/truth/field-renderer/text-with-label.png +0 -0
  167. package/screenshots/truth/field-renderer/textarea-evaluated.png +0 -0
  168. package/screenshots/truth/field-renderer/textarea-with-label.png +0 -0
  169. package/screenshots/truth/integration/checkbox-markdown-errors.png +0 -0
  170. package/screenshots/truth/nodes/split_by_llm_categorize/editor/basic-categorization.png +0 -0
  171. package/screenshots/truth/nodes/split_by_llm_categorize/editor/custom-input-and-result-name.png +0 -0
  172. package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
  173. package/screenshots/truth/nodes/split_by_llm_categorize/editor/many-categories.png +0 -0
  174. package/screenshots/truth/nodes/split_by_llm_categorize/editor/minimal-categories.png +0 -0
  175. package/screenshots/truth/nodes/split_by_llm_categorize/render/basic-categorization.png +0 -0
  176. package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
  177. package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
  178. package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
  179. package/screenshots/truth/nodes/split_by_llm_categorize/render/minimal-categories.png +0 -0
  180. package/screenshots/truth/nodes/split_by_random/editor/ab-test-multiple-variants.png +0 -0
  181. package/screenshots/truth/nodes/split_by_random/editor/sampling-split.png +0 -0
  182. package/screenshots/truth/nodes/split_by_random/editor/three-way-split.png +0 -0
  183. package/screenshots/truth/nodes/split_by_random/editor/two-bucket-split.png +0 -0
  184. package/screenshots/truth/nodes/split_by_random/render/ab-test-multiple-variants.png +0 -0
  185. package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
  186. package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
  187. package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.png +0 -0
  188. package/screenshots/truth/nodes/wait_for_digits/editor/basic-digits-wait.png +0 -0
  189. package/screenshots/truth/nodes/wait_for_digits/editor/phone-number-collection.png +0 -0
  190. package/screenshots/truth/nodes/wait_for_digits/editor/single-digit-with-timeout.png +0 -0
  191. package/screenshots/truth/nodes/wait_for_digits/editor/verification-code.png +0 -0
  192. package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
  193. package/screenshots/truth/nodes/wait_for_digits/render/phone-number-collection.png +0 -0
  194. package/screenshots/truth/nodes/wait_for_digits/render/single-digit-with-timeout.png +0 -0
  195. package/screenshots/truth/nodes/wait_for_digits/render/verification-code.png +0 -0
  196. package/screenshots/truth/nodes/wait_for_response/editor/basic-wait.png +0 -0
  197. package/screenshots/truth/nodes/wait_for_response/editor/custom-result-name.png +0 -0
  198. package/screenshots/truth/nodes/wait_for_response/editor/no-timeout.png +0 -0
  199. package/screenshots/truth/nodes/wait_for_response/editor/short-timeout.png +0 -0
  200. package/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
  201. package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
  202. package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
  203. package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
  204. package/screenshots/truth/omnibox/selected.png +0 -0
  205. package/screenshots/truth/run-list/basic.png +0 -0
  206. package/screenshots/truth/select/functions.png +0 -0
  207. package/screenshots/truth/select/multi-with-endpoint.png +0 -0
  208. package/screenshots/truth/select/search-enabled.png +0 -0
  209. package/src/events.ts +12 -6
  210. package/src/excellent/helpers.ts +2 -2
  211. package/src/flow/CanvasNode.ts +22 -1
  212. package/src/flow/Editor.ts +12 -1
  213. package/src/flow/NodeEditor.ts +186 -374
  214. package/src/flow/actions/add_input_labels.ts +45 -0
  215. package/src/flow/actions/call_llm.ts +57 -3
  216. package/src/flow/actions/call_webhook.ts +1 -1
  217. package/src/flow/actions/open_ticket.ts +74 -3
  218. package/src/flow/actions/set_run_result.ts +83 -0
  219. package/src/flow/config.ts +4 -0
  220. package/src/flow/nodes/split_by_llm_categorize.ts +277 -0
  221. package/src/flow/nodes/split_by_ticket.ts +19 -0
  222. package/src/flow/nodes/wait_for_response.ts +28 -1
  223. package/src/flow/types.ts +26 -127
  224. package/src/form/ArrayEditor.ts +79 -139
  225. package/src/form/BaseListEditor.ts +4 -4
  226. package/src/form/Checkbox.ts +81 -24
  227. package/src/form/ColorPicker.ts +31 -43
  228. package/src/form/Completion.ts +49 -56
  229. package/src/form/Compose.ts +8 -8
  230. package/src/form/ContactSearch.ts +3 -4
  231. package/src/form/DatePicker.ts +32 -38
  232. package/src/form/{FormField.ts → FieldElement.ts} +108 -55
  233. package/src/form/FieldRenderer.ts +466 -0
  234. package/src/form/ImagePicker.ts +107 -110
  235. package/src/form/KeyValueEditor.ts +43 -39
  236. package/src/form/MessageEditor.ts +61 -67
  237. package/src/form/TembaSlider.ts +3 -3
  238. package/src/form/TemplateEditor.ts +3 -3
  239. package/src/form/TextInput.ts +26 -29
  240. package/src/form/select/Select.ts +63 -37
  241. package/src/form/select/UserSelect.ts +10 -11
  242. package/src/form/select/WorkspaceSelect.ts +9 -10
  243. package/src/live/ContactChat.ts +62 -47
  244. package/src/live/ContactFieldEditor.ts +2 -2
  245. package/src/markdown.ts +19 -11
  246. package/src/store/flow-definition.d.ts +5 -2
  247. package/static/api/labels.json +31 -0
  248. package/static/api/topics.json +24 -9
  249. package/static/api/users.json +35 -16
  250. package/static/css/temba-components.css +3 -3
  251. package/stress-test.js +18 -13
  252. package/temba-modules.ts +3 -2
  253. package/test/ActionHelper.ts +2 -0
  254. package/test/NodeHelper.ts +184 -0
  255. package/test/actions/call_llm.test.ts +137 -0
  256. package/test/nodes/README.md +78 -0
  257. package/test/nodes/split_by_llm_categorize.test.ts +698 -0
  258. package/test/nodes/split_by_random.test.ts +177 -0
  259. package/test/nodes/wait_for_digits.test.ts +176 -0
  260. package/test/nodes/wait_for_response.test.ts +206 -0
  261. package/test/temba-add-input-labels.test.ts +87 -0
  262. package/test/temba-checkbox.test.ts +26 -0
  263. package/test/temba-field-renderer.test.ts +482 -0
  264. package/test/temba-integration-markdown.test.ts +2 -4
  265. package/test/temba-markdown.test.ts +1 -1
  266. package/test/temba-node-editor.test.ts +496 -0
  267. package/test/temba-select.test.ts +6 -6
  268. package/test/temba-slider.test.ts +0 -1
  269. package/test/temba-webchat.test.ts +1 -1
  270. package/test-assets/contacts/history.json +7 -20
  271. package/test-assets/select/llms.json +18 -0
  272. package/web-dev-mock.mjs +96 -6
  273. package/web-dev-server.config.mjs +29 -7
  274. package/out-tsc/src/form/FormElement.js +0 -67
  275. package/out-tsc/src/form/FormElement.js.map +0 -1
  276. package/out-tsc/src/form/FormField.js.map +0 -1
  277. package/out-tsc/test/temba-formfield.test.js +0 -94
  278. package/out-tsc/test/temba-formfield.test.js.map +0 -1
  279. package/src/form/FormElement.ts +0 -69
  280. package/test/temba-flow-editor.test.ts.backup +0 -563
  281. package/test/temba-formfield.test.ts +0 -121
  282. package/test/temba-utils-index.test.ts.backup +0 -1737
@@ -3,31 +3,33 @@ import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
3
3
  import { directive, Directive, PartType } from 'lit/directive.js';
4
4
  import { Remarkable } from 'remarkable';
5
5
  export const markdown = new Remarkable();
6
- // Class-based directive API
7
- export class RenderMarkdown extends Directive {
8
- // State stored in class field
9
- // value: string | undefined;
6
+ // Base class for markdown rendering directives
7
+ class BaseMarkdownDirective extends Directive {
10
8
  constructor(partInfo) {
11
9
  super(partInfo);
12
10
  // When necessary, validate part in constructor using `part.type`
13
11
  if (partInfo.type !== PartType.CHILD) {
14
- throw new Error('renderMarkdown only supports child expressions');
12
+ throw new Error('markdown directives only support child expressions');
15
13
  }
16
14
  }
17
15
  // Optional: override update to perform any direct DOM manipulation
18
- // DirectiveParameters<this>
19
16
  update(part, [initialValue]) {
20
17
  /* Any imperative updates to DOM/parts would go here */
21
18
  return this.render(initialValue);
22
19
  }
23
- // Do SSR-compatible rendering (arguments are passed from call site)
20
+ }
21
+ // Class-based directive for block markdown rendering
22
+ export class RenderMarkdown extends BaseMarkdownDirective {
24
23
  render(initialValue) {
25
- // Previous state available on class field
26
- // if (this.value === undefined) {
27
- // this.value = initialValue;
28
- //}
29
24
  return html `${unsafeHTML(markdown.render(initialValue))}`;
30
25
  }
31
26
  }
27
+ // Class-based directive for inline markdown rendering
28
+ export class RenderMarkdownInline extends BaseMarkdownDirective {
29
+ render(initialValue) {
30
+ return html `${unsafeHTML(markdown.renderInline(initialValue))}`;
31
+ }
32
+ }
32
33
  export const renderMarkdown = directive(RenderMarkdown);
34
+ export const renderMarkdownInline = directive(RenderMarkdownInline);
33
35
  //# sourceMappingURL=markdown.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAChE,OAAO,EACL,SAAS,EACT,SAAS,EAGT,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,UAAU,EAAE,CAAC;AAEzC,4BAA4B;AAC5B,MAAM,OAAO,cAAe,SAAQ,SAAS;IAC3C,8BAA8B;IAC9B,6BAA6B;IAC7B,YAAY,QAAkB;QAC5B,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChB,iEAAiE;QACjE,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IACD,mEAAmE;IACnE,4BAA4B;IAC5B,MAAM,CAAC,IAAU,EAAE,CAAC,YAAY,CAAM;QACpC,uDAAuD;QACvD,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACnC,CAAC;IACD,oEAAoE;IACpE,MAAM,CAAC,YAAoB;QACzB,0CAA0C;QAC1C,mCAAmC;QACnC,6BAA6B;QAC7B,GAAG;QACH,OAAO,IAAI,CAAA,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;IAC5D,CAAC;CACF;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAC,cAAc,CAAC,CAAC","sourcesContent":["import { html } from 'lit';\nimport { unsafeHTML } from 'lit-html/directives/unsafe-html.js';\nimport {\n directive,\n Directive,\n Part,\n PartInfo,\n PartType\n} from 'lit/directive.js';\nimport { Remarkable } from 'remarkable';\n\nexport const markdown = new Remarkable();\n\n// Class-based directive API\nexport class RenderMarkdown extends Directive {\n // State stored in class field\n // value: string | undefined;\n constructor(partInfo: PartInfo) {\n super(partInfo);\n // When necessary, validate part in constructor using `part.type`\n if (partInfo.type !== PartType.CHILD) {\n throw new Error('renderMarkdown only supports child expressions');\n }\n }\n // Optional: override update to perform any direct DOM manipulation\n // DirectiveParameters<this>\n update(part: Part, [initialValue]: any) {\n /* Any imperative updates to DOM/parts would go here */\n return this.render(initialValue);\n }\n // Do SSR-compatible rendering (arguments are passed from call site)\n render(initialValue: string) {\n // Previous state available on class field\n // if (this.value === undefined) {\n // this.value = initialValue;\n //}\n return html`${unsafeHTML(markdown.render(initialValue))}`;\n }\n}\n\nexport const renderMarkdown = directive(RenderMarkdown);\n"]}
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAChE,OAAO,EACL,SAAS,EACT,SAAS,EAGT,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,UAAU,EAAE,CAAC;AAEzC,+CAA+C;AAC/C,MAAe,qBAAsB,SAAQ,SAAS;IACpD,YAAY,QAAkB;QAC5B,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChB,iEAAiE;QACjE,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,MAAM,CAAC,IAAU,EAAE,CAAC,YAAY,CAAM;QACpC,uDAAuD;QACvD,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACnC,CAAC;CAIF;AAED,qDAAqD;AACrD,MAAM,OAAO,cAAe,SAAQ,qBAAqB;IACvD,MAAM,CAAC,YAAoB;QACzB,OAAO,IAAI,CAAA,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;IAC5D,CAAC;CACF;AAED,sDAAsD;AACtD,MAAM,OAAO,oBAAqB,SAAQ,qBAAqB;IAC7D,MAAM,CAAC,YAAoB;QACzB,OAAO,IAAI,CAAA,GAAG,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;IAClE,CAAC;CACF;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAC,cAAc,CAAC,CAAC;AACxD,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAC,oBAAoB,CAAC,CAAC","sourcesContent":["import { html } from 'lit';\nimport { unsafeHTML } from 'lit-html/directives/unsafe-html.js';\nimport {\n directive,\n Directive,\n Part,\n PartInfo,\n PartType\n} from 'lit/directive.js';\nimport { Remarkable } from 'remarkable';\n\nexport const markdown = new Remarkable();\n\n// Base class for markdown rendering directives\nabstract class BaseMarkdownDirective extends Directive {\n constructor(partInfo: PartInfo) {\n super(partInfo);\n // When necessary, validate part in constructor using `part.type`\n if (partInfo.type !== PartType.CHILD) {\n throw new Error('markdown directives only support child expressions');\n }\n }\n\n // Optional: override update to perform any direct DOM manipulation\n update(part: Part, [initialValue]: any) {\n /* Any imperative updates to DOM/parts would go here */\n return this.render(initialValue);\n }\n\n // Abstract method to be implemented by subclasses\n abstract render(initialValue: string): any;\n}\n\n// Class-based directive for block markdown rendering\nexport class RenderMarkdown extends BaseMarkdownDirective {\n render(initialValue: string) {\n return html`${unsafeHTML(markdown.render(initialValue))}`;\n }\n}\n\n// Class-based directive for inline markdown rendering\nexport class RenderMarkdownInline extends BaseMarkdownDirective {\n render(initialValue: string) {\n return html`${unsafeHTML(markdown.renderInline(initialValue))}`;\n }\n}\n\nexport const renderMarkdown = directive(RenderMarkdown);\nexport const renderMarkdownInline = directive(RenderMarkdownInline);\n"]}
@@ -6,7 +6,7 @@ import { Completion } from './src/form/Completion';
6
6
  import { Modax } from './src/layout/Modax';
7
7
  import { Dialog } from './src/layout/Dialog';
8
8
  import { Button } from './src/display/Button';
9
- import { FormField } from './src/form/FormField';
9
+ import { FieldElement } from './src/form/FieldElement';
10
10
  import { Loading } from './src/display/Loading';
11
11
  import { CharCount } from './src/display/CharCount';
12
12
  import { Options } from './src/display/Options';
@@ -99,7 +99,8 @@ addCustomElement('temba-contact-fields', ContactFields);
99
99
  addCustomElement('temba-field-manager', FieldManager);
100
100
  addCustomElement('temba-urn', ContactUrn);
101
101
  addCustomElement('temba-content-menu', ContentMenu);
102
- addCustomElement('temba-field', FormField);
102
+ // Note: FieldElement is a base class and not directly instantiated as a custom element
103
+ export { FieldElement };
103
104
  addCustomElement('temba-dialog', Dialog);
104
105
  addCustomElement('temba-modax', Modax);
105
106
  addCustomElement('temba-charcount', CharCount);
@@ -1 +1 @@
1
- {"version":3,"file":"temba-modules.js","sourceRoot":"","sources":["../temba-modules.ts"],"names":[],"mappings":"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","sourcesContent":["import { Checkbox } from './src/form/Checkbox';\nimport { TextInput } from './src/form/TextInput';\nimport { Store } from './src/store/Store';\nimport { Select } from './src/form/select/Select';\nimport { Completion } from './src/form/Completion';\nimport { Modax } from './src/layout/Modax';\nimport { Dialog } from './src/layout/Dialog';\nimport { Button } from './src/display/Button';\nimport { FormField } from './src/form/FormField';\nimport { Loading } from './src/display/Loading';\nimport { CharCount } from './src/display/CharCount';\nimport { Options } from './src/display/Options';\nimport { ContactChat } from './src/live/ContactChat';\nimport { TicketList } from './src/list/TicketList';\nimport { ContactDetails } from './src/live/ContactDetails';\nimport { TembaList } from './src/list/TembaList';\nimport { ContactSearch } from './src/form/ContactSearch';\nimport { VectorIcon } from './src/display/Icon';\nimport { Alert } from './src/display/Alert';\nimport { Omnibox } from './src/form/select/Omnibox';\nimport { Tip } from './src/display/Tip';\nimport { TembaMenu } from './src/list/TembaMenu';\nimport { Anchor } from './src/display/Anchor';\nimport { Dropdown } from './src/display/Dropdown';\nimport { TabPane } from './src/layout/TabPane';\nimport { Tab } from './src/layout/Tab';\nimport Label from './src/display/Label';\nimport { ContactName } from './src/display/ContactName';\nimport { ContactUrn } from './src/display/ContactUrn';\nimport { ContactFields } from './src/live/ContactFields';\nimport { ContactFieldEditor } from './src/live/ContactFieldEditor';\n\nimport { ContactBadges } from './src/live/ContactBadges';\nimport { ContactPending } from './src/live/ContactPending';\nimport { TembaSlider } from './src/form/TembaSlider';\nimport { RunList } from './src/list/RunList';\nimport { FlowStoreElement } from './src/store/FlowStoreElement';\nimport { ContactNameFetch } from './src/live/ContactNameFetch';\nimport { DatePicker } from './src/form/DatePicker';\nimport { FieldManager } from './src/live/FieldManager';\nimport { SortableList } from './src/list/SortableList';\nimport { ContentMenu } from './src/list/ContentMenu';\nimport { TembaDate } from './src/display/TembaDate';\nimport { Compose } from './src/form/Compose';\nimport { Lightbox } from './src/display/Lightbox';\nimport { ColorPicker } from './src/form/ColorPicker';\nimport { Resizer } from './src/layout/Resizer';\nimport { Thumbnail } from './src/display/Thumbnail';\nimport { NotificationList } from './src/list/NotificationList';\nimport { WebChat } from './src/webchat/WebChat';\nimport { ImagePicker } from './src/form/ImagePicker';\nimport { Mask } from './src/layout/Mask';\nimport { TembaUser } from './src/display/TembaUser';\nimport { TemplateEditor } from './src/form/TemplateEditor';\nimport { Toast } from './src/display/Toast';\nimport { Chat } from './src/display/Chat';\nimport { MediaPicker } from './src/form/MediaPicker';\nimport { Editor } from './src/flow/Editor';\nimport { CanvasNode } from './src/flow/CanvasNode';\nimport { StickyNote } from './src/flow/StickyNote';\nimport { ContactNotepad } from './src/live/ContactNotepad';\nimport { ProgressBar } from './src/display/ProgressBar';\nimport { StartProgress } from './src/live/StartProgress';\nimport { ShortcutList } from './src/list/ShortcutList';\nimport { PopupSelect } from './src/form/select/PopupSelect';\nimport { UserSelect } from './src/form/select/UserSelect';\nimport { WorkspaceSelect } from './src/form/select/WorkspaceSelect';\nimport { TembaChart } from './src/live/TembaChart';\nimport { RangePicker } from './src/form/RangePicker';\nimport { NodeEditor } from './src/flow/NodeEditor';\nimport { KeyValueEditor } from './src/form/KeyValueEditor';\nimport { TembaArrayEditor } from './src/form/ArrayEditor';\nimport { MessageEditor } from './src/form/MessageEditor';\nimport './src/form/BaseListEditor'; // Import base class\n\nexport function addCustomElement(name: string, comp: any) {\n if (!window.customElements.get(name)) {\n window.customElements.define(name, comp);\n }\n}\n\naddCustomElement('temba-anchor', Anchor);\naddCustomElement('temba-alert', Alert);\naddCustomElement('temba-store', Store);\naddCustomElement('temba-textinput', TextInput);\naddCustomElement('temba-datepicker', DatePicker);\naddCustomElement('temba-range-picker', RangePicker);\naddCustomElement('temba-date', TembaDate);\naddCustomElement('temba-completion', Completion);\naddCustomElement('temba-checkbox', Checkbox);\naddCustomElement('temba-select', Select);\naddCustomElement('temba-options', Options);\naddCustomElement('temba-loading', Loading);\naddCustomElement('temba-lightbox', Lightbox);\naddCustomElement('temba-button', Button);\naddCustomElement('temba-omnibox', Omnibox);\naddCustomElement('temba-tip', Tip);\naddCustomElement('temba-contact-name', ContactName);\naddCustomElement('temba-contact-name-fetch', ContactNameFetch);\naddCustomElement('temba-contact-field', ContactFieldEditor);\naddCustomElement('temba-contact-fields', ContactFields);\naddCustomElement('temba-field-manager', FieldManager);\naddCustomElement('temba-urn', ContactUrn);\naddCustomElement('temba-content-menu', ContentMenu);\n\naddCustomElement('temba-field', FormField);\naddCustomElement('temba-dialog', Dialog);\naddCustomElement('temba-modax', Modax);\naddCustomElement('temba-charcount', CharCount);\naddCustomElement('temba-contact-chat', ContactChat);\naddCustomElement('temba-contact-details', ContactDetails);\naddCustomElement('temba-ticket-list', TicketList);\naddCustomElement('temba-notification-list', NotificationList);\naddCustomElement('temba-list', TembaList);\naddCustomElement('temba-sortable-list', SortableList);\naddCustomElement('temba-run-list', RunList);\naddCustomElement('temba-flow-details', FlowStoreElement);\naddCustomElement('temba-label', Label);\naddCustomElement('temba-menu', TembaMenu);\naddCustomElement('temba-contact-search', ContactSearch);\naddCustomElement('temba-icon', VectorIcon);\naddCustomElement('temba-dropdown', Dropdown);\naddCustomElement('temba-tabs', TabPane);\naddCustomElement('temba-tab', Tab);\naddCustomElement('temba-contact-badges', ContactBadges);\naddCustomElement('temba-contact-pending', ContactPending);\naddCustomElement('temba-slider', TembaSlider);\naddCustomElement('temba-content-menu', ContentMenu);\naddCustomElement('temba-compose', Compose);\naddCustomElement('temba-color-picker', ColorPicker);\naddCustomElement('temba-resizer', Resizer);\naddCustomElement('temba-thumbnail', Thumbnail);\naddCustomElement('temba-webchat', WebChat);\naddCustomElement('temba-image-picker', ImagePicker);\naddCustomElement('temba-mask', Mask);\naddCustomElement('temba-user', TembaUser);\naddCustomElement('temba-template-editor', TemplateEditor);\naddCustomElement('temba-toast', Toast);\naddCustomElement('temba-chat', Chat);\naddCustomElement('temba-media-picker', MediaPicker);\naddCustomElement('temba-flow-editor', Editor);\naddCustomElement('temba-node-editor', NodeEditor);\naddCustomElement('temba-flow-node', CanvasNode);\naddCustomElement('temba-sticky-note', StickyNote);\naddCustomElement('temba-contact-notepad', ContactNotepad);\naddCustomElement('temba-progress', ProgressBar);\naddCustomElement('temba-start-progress', StartProgress);\naddCustomElement('temba-shortcuts', ShortcutList);\naddCustomElement('temba-popup-select', PopupSelect);\naddCustomElement('temba-user-select', UserSelect);\naddCustomElement('temba-workspace-select', WorkspaceSelect);\naddCustomElement('temba-chart', TembaChart);\naddCustomElement('temba-key-value-editor', KeyValueEditor);\naddCustomElement('temba-array-editor', TembaArrayEditor);\naddCustomElement('temba-message-editor', MessageEditor);\n"]}
1
+ {"version":3,"file":"temba-modules.js","sourceRoot":"","sources":["../temba-modules.ts"],"names":[],"mappings":"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","sourcesContent":["import { Checkbox } from './src/form/Checkbox';\nimport { TextInput } from './src/form/TextInput';\nimport { Store } from './src/store/Store';\nimport { Select } from './src/form/select/Select';\nimport { Completion } from './src/form/Completion';\nimport { Modax } from './src/layout/Modax';\nimport { Dialog } from './src/layout/Dialog';\nimport { Button } from './src/display/Button';\nimport { FieldElement } from './src/form/FieldElement';\nimport { Loading } from './src/display/Loading';\nimport { CharCount } from './src/display/CharCount';\nimport { Options } from './src/display/Options';\nimport { ContactChat } from './src/live/ContactChat';\nimport { TicketList } from './src/list/TicketList';\nimport { ContactDetails } from './src/live/ContactDetails';\nimport { TembaList } from './src/list/TembaList';\nimport { ContactSearch } from './src/form/ContactSearch';\nimport { VectorIcon } from './src/display/Icon';\nimport { Alert } from './src/display/Alert';\nimport { Omnibox } from './src/form/select/Omnibox';\nimport { Tip } from './src/display/Tip';\nimport { TembaMenu } from './src/list/TembaMenu';\nimport { Anchor } from './src/display/Anchor';\nimport { Dropdown } from './src/display/Dropdown';\nimport { TabPane } from './src/layout/TabPane';\nimport { Tab } from './src/layout/Tab';\nimport Label from './src/display/Label';\nimport { ContactName } from './src/display/ContactName';\nimport { ContactUrn } from './src/display/ContactUrn';\nimport { ContactFields } from './src/live/ContactFields';\nimport { ContactFieldEditor } from './src/live/ContactFieldEditor';\n\nimport { ContactBadges } from './src/live/ContactBadges';\nimport { ContactPending } from './src/live/ContactPending';\nimport { TembaSlider } from './src/form/TembaSlider';\nimport { RunList } from './src/list/RunList';\nimport { FlowStoreElement } from './src/store/FlowStoreElement';\nimport { ContactNameFetch } from './src/live/ContactNameFetch';\nimport { DatePicker } from './src/form/DatePicker';\nimport { FieldManager } from './src/live/FieldManager';\nimport { SortableList } from './src/list/SortableList';\nimport { ContentMenu } from './src/list/ContentMenu';\nimport { TembaDate } from './src/display/TembaDate';\nimport { Compose } from './src/form/Compose';\nimport { Lightbox } from './src/display/Lightbox';\nimport { ColorPicker } from './src/form/ColorPicker';\nimport { Resizer } from './src/layout/Resizer';\nimport { Thumbnail } from './src/display/Thumbnail';\nimport { NotificationList } from './src/list/NotificationList';\nimport { WebChat } from './src/webchat/WebChat';\nimport { ImagePicker } from './src/form/ImagePicker';\nimport { Mask } from './src/layout/Mask';\nimport { TembaUser } from './src/display/TembaUser';\nimport { TemplateEditor } from './src/form/TemplateEditor';\nimport { Toast } from './src/display/Toast';\nimport { Chat } from './src/display/Chat';\nimport { MediaPicker } from './src/form/MediaPicker';\nimport { Editor } from './src/flow/Editor';\nimport { CanvasNode } from './src/flow/CanvasNode';\nimport { StickyNote } from './src/flow/StickyNote';\nimport { ContactNotepad } from './src/live/ContactNotepad';\nimport { ProgressBar } from './src/display/ProgressBar';\nimport { StartProgress } from './src/live/StartProgress';\nimport { ShortcutList } from './src/list/ShortcutList';\nimport { PopupSelect } from './src/form/select/PopupSelect';\nimport { UserSelect } from './src/form/select/UserSelect';\nimport { WorkspaceSelect } from './src/form/select/WorkspaceSelect';\nimport { TembaChart } from './src/live/TembaChart';\nimport { RangePicker } from './src/form/RangePicker';\nimport { NodeEditor } from './src/flow/NodeEditor';\nimport { KeyValueEditor } from './src/form/KeyValueEditor';\nimport { TembaArrayEditor } from './src/form/ArrayEditor';\nimport { MessageEditor } from './src/form/MessageEditor';\nimport './src/form/BaseListEditor'; // Import base class\n\nexport function addCustomElement(name: string, comp: any) {\n if (!window.customElements.get(name)) {\n window.customElements.define(name, comp);\n }\n}\n\naddCustomElement('temba-anchor', Anchor);\naddCustomElement('temba-alert', Alert);\naddCustomElement('temba-store', Store);\naddCustomElement('temba-textinput', TextInput);\naddCustomElement('temba-datepicker', DatePicker);\naddCustomElement('temba-range-picker', RangePicker);\naddCustomElement('temba-date', TembaDate);\naddCustomElement('temba-completion', Completion);\naddCustomElement('temba-checkbox', Checkbox);\naddCustomElement('temba-select', Select);\naddCustomElement('temba-options', Options);\naddCustomElement('temba-loading', Loading);\naddCustomElement('temba-lightbox', Lightbox);\naddCustomElement('temba-button', Button);\naddCustomElement('temba-omnibox', Omnibox);\naddCustomElement('temba-tip', Tip);\naddCustomElement('temba-contact-name', ContactName);\naddCustomElement('temba-contact-name-fetch', ContactNameFetch);\naddCustomElement('temba-contact-field', ContactFieldEditor);\naddCustomElement('temba-contact-fields', ContactFields);\naddCustomElement('temba-field-manager', FieldManager);\naddCustomElement('temba-urn', ContactUrn);\naddCustomElement('temba-content-menu', ContentMenu);\n\n// Note: FieldElement is a base class and not directly instantiated as a custom element\nexport { FieldElement };\naddCustomElement('temba-dialog', Dialog);\naddCustomElement('temba-modax', Modax);\naddCustomElement('temba-charcount', CharCount);\naddCustomElement('temba-contact-chat', ContactChat);\naddCustomElement('temba-contact-details', ContactDetails);\naddCustomElement('temba-ticket-list', TicketList);\naddCustomElement('temba-notification-list', NotificationList);\naddCustomElement('temba-list', TembaList);\naddCustomElement('temba-sortable-list', SortableList);\naddCustomElement('temba-run-list', RunList);\naddCustomElement('temba-flow-details', FlowStoreElement);\naddCustomElement('temba-label', Label);\naddCustomElement('temba-menu', TembaMenu);\naddCustomElement('temba-contact-search', ContactSearch);\naddCustomElement('temba-icon', VectorIcon);\naddCustomElement('temba-dropdown', Dropdown);\naddCustomElement('temba-tabs', TabPane);\naddCustomElement('temba-tab', Tab);\naddCustomElement('temba-contact-badges', ContactBadges);\naddCustomElement('temba-contact-pending', ContactPending);\naddCustomElement('temba-slider', TembaSlider);\naddCustomElement('temba-content-menu', ContentMenu);\naddCustomElement('temba-compose', Compose);\naddCustomElement('temba-color-picker', ColorPicker);\naddCustomElement('temba-resizer', Resizer);\naddCustomElement('temba-thumbnail', Thumbnail);\naddCustomElement('temba-webchat', WebChat);\naddCustomElement('temba-image-picker', ImagePicker);\naddCustomElement('temba-mask', Mask);\naddCustomElement('temba-user', TembaUser);\naddCustomElement('temba-template-editor', TemplateEditor);\naddCustomElement('temba-toast', Toast);\naddCustomElement('temba-chat', Chat);\naddCustomElement('temba-media-picker', MediaPicker);\naddCustomElement('temba-flow-editor', Editor);\naddCustomElement('temba-node-editor', NodeEditor);\naddCustomElement('temba-flow-node', CanvasNode);\naddCustomElement('temba-sticky-note', StickyNote);\naddCustomElement('temba-contact-notepad', ContactNotepad);\naddCustomElement('temba-progress', ProgressBar);\naddCustomElement('temba-start-progress', StartProgress);\naddCustomElement('temba-shortcuts', ShortcutList);\naddCustomElement('temba-popup-select', PopupSelect);\naddCustomElement('temba-user-select', UserSelect);\naddCustomElement('temba-workspace-select', WorkspaceSelect);\naddCustomElement('temba-chart', TembaChart);\naddCustomElement('temba-key-value-editor', KeyValueEditor);\naddCustomElement('temba-array-editor', TembaArrayEditor);\naddCustomElement('temba-message-editor', MessageEditor);\n"]}
@@ -5,6 +5,8 @@ import '../temba-modules';
5
5
  /**
6
6
  * Generic action test framework
7
7
  * Tests the complete action lifecycle: render → edit → save → validate
8
+ *
9
+ * For node configuration testing, see NodeHelper.ts
8
10
  */
9
11
  export class ActionTest {
10
12
  constructor(actionConfig, actionName) {
@@ -1 +1 @@
1
- {"version":3,"file":"ActionHelper.js","sourceRoot":"","sources":["../../test/ActionHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import { fixture, expect } from '@open-wc/testing';\nimport { html } from 'lit';\nimport { Action, Node } from '../src/store/flow-definition';\nimport { assertScreenshot, getClip } from './utils.test';\nimport { Editor } from '../src/flow/Editor';\nimport '../temba-modules';\n\n/**\n * Generic action test framework\n * Tests the complete action lifecycle: render → edit → save → validate\n */\nexport class ActionTest<T extends Action> {\n constructor(private actionConfig: any, private actionName: string) {}\n\n /**\n * Renders an action in the flow editor and returns the flow node\n */\n private async renderAction(action: T): Promise<HTMLElement> {\n const node: Node = {\n uuid: 'test-node',\n actions: [action],\n exits: []\n };\n\n const mockDefinition = {\n nodes: [node],\n _ui: {\n nodes: {\n [node.uuid]: {\n type: 'execute_actions',\n position: { left: 50, top: 50 }\n }\n }\n }\n };\n\n const editor = (await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `)) as Editor;\n\n (editor as any).definition = mockDefinition;\n (editor as any).canvasSize = { width: 400, height: 300 };\n await editor.updateComplete;\n\n const flowNode = editor.querySelector('temba-flow-node') as HTMLElement;\n expect(flowNode).to.exist;\n\n return flowNode;\n }\n\n /**\n * Opens the node editor for an action and returns the editor element\n */\n private async openNodeEditor(action: T): Promise<HTMLElement> {\n const nodeEditor = (await fixture(html`\n <temba-node-editor .action=${action} .isOpen=${true}></temba-node-editor>\n `)) as HTMLElement;\n\n await (nodeEditor as any).updateComplete;\n expect(nodeEditor).to.exist;\n\n return nodeEditor;\n }\n\n /**\n * Takes a screenshot of the dialog container within a node editor\n */\n private async assertDialogScreenshot(\n el: HTMLElement,\n screenshotName: string\n ) {\n const dialog = el.shadowRoot\n .querySelector('temba-dialog')\n .shadowRoot.querySelector('.dialog-container') as HTMLElement;\n await assertScreenshot(screenshotName, getClip(dialog));\n }\n\n /**\n * Complete test for an action configuration\n * 1. Renders the action in a flow node (with screenshot)\n * 2. Opens the node editor (with screenshot)\n * 3. Simulates save and validates round-trip conversion\n */\n async testAction(action: T, testName: string) {\n it(`${testName}`, async () => {\n // Step 1: Render action in flow node\n const flowNode = await this.renderAction(action);\n expect(flowNode.querySelector('.body')).to.exist;\n await assertScreenshot(\n `actions/${this.actionName}/render/${testName}`,\n getClip(flowNode)\n );\n\n // Step 2: Open node editor\n const nodeEditor = await this.openNodeEditor(action);\n await this.assertDialogScreenshot(\n nodeEditor,\n `actions/${this.actionName}/editor/${testName}`\n );\n\n // Step 3: Test round-trip conversion (simulates save workflow)\n if (this.actionConfig.toFormData && this.actionConfig.fromFormData) {\n const formData = this.actionConfig.toFormData(action);\n const convertedAction = this.actionConfig.fromFormData(formData) as T;\n\n // Validate the round trip worked\n expect(convertedAction.uuid).to.equal(action.uuid);\n expect(convertedAction.type).to.equal(action.type);\n\n // Validate the converted action\n if (this.actionConfig.validate) {\n const validation = this.actionConfig.validate(convertedAction);\n expect(validation.valid).to.be.true;\n }\n }\n });\n }\n\n /**\n * Run basic property tests\n */\n testBasicProperties() {\n it('has correct basic properties', () => {\n expect(this.actionConfig.name).to.be.a('string');\n expect(this.actionConfig.color).to.exist;\n\n // toFormData and fromFormData are optional - only needed for complex data transformations\n if (this.actionConfig.toFormData) {\n expect(this.actionConfig.toFormData).to.be.a('function');\n }\n if (this.actionConfig.fromFormData) {\n expect(this.actionConfig.fromFormData).to.be.a('function');\n }\n\n if (this.actionConfig.validate) {\n expect(this.actionConfig.validate).to.be.a('function');\n }\n });\n }\n}\n"]}
1
+ {"version":3,"file":"ActionHelper.js","sourceRoot":"","sources":["../../test/ActionHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import { fixture, expect } from '@open-wc/testing';\nimport { html } from 'lit';\nimport { Action, Node } from '../src/store/flow-definition';\nimport { assertScreenshot, getClip } from './utils.test';\nimport { Editor } from '../src/flow/Editor';\nimport '../temba-modules';\n\n/**\n * Generic action test framework\n * Tests the complete action lifecycle: render → edit → save → validate\n *\n * For node configuration testing, see NodeHelper.ts\n */\nexport class ActionTest<T extends Action> {\n constructor(private actionConfig: any, private actionName: string) {}\n\n /**\n * Renders an action in the flow editor and returns the flow node\n */\n private async renderAction(action: T): Promise<HTMLElement> {\n const node: Node = {\n uuid: 'test-node',\n actions: [action],\n exits: []\n };\n\n const mockDefinition = {\n nodes: [node],\n _ui: {\n nodes: {\n [node.uuid]: {\n type: 'execute_actions',\n position: { left: 50, top: 50 }\n }\n }\n }\n };\n\n const editor = (await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `)) as Editor;\n\n (editor as any).definition = mockDefinition;\n (editor as any).canvasSize = { width: 400, height: 300 };\n await editor.updateComplete;\n\n const flowNode = editor.querySelector('temba-flow-node') as HTMLElement;\n expect(flowNode).to.exist;\n\n return flowNode;\n }\n\n /**\n * Opens the node editor for an action and returns the editor element\n */\n private async openNodeEditor(action: T): Promise<HTMLElement> {\n const nodeEditor = (await fixture(html`\n <temba-node-editor .action=${action} .isOpen=${true}></temba-node-editor>\n `)) as HTMLElement;\n\n await (nodeEditor as any).updateComplete;\n expect(nodeEditor).to.exist;\n\n return nodeEditor;\n }\n\n /**\n * Takes a screenshot of the dialog container within a node editor\n */\n private async assertDialogScreenshot(\n el: HTMLElement,\n screenshotName: string\n ) {\n const dialog = el.shadowRoot\n .querySelector('temba-dialog')\n .shadowRoot.querySelector('.dialog-container') as HTMLElement;\n await assertScreenshot(screenshotName, getClip(dialog));\n }\n\n /**\n * Complete test for an action configuration\n * 1. Renders the action in a flow node (with screenshot)\n * 2. Opens the node editor (with screenshot)\n * 3. Simulates save and validates round-trip conversion\n */\n async testAction(action: T, testName: string) {\n it(`${testName}`, async () => {\n // Step 1: Render action in flow node\n const flowNode = await this.renderAction(action);\n expect(flowNode.querySelector('.body')).to.exist;\n await assertScreenshot(\n `actions/${this.actionName}/render/${testName}`,\n getClip(flowNode)\n );\n\n // Step 2: Open node editor\n const nodeEditor = await this.openNodeEditor(action);\n await this.assertDialogScreenshot(\n nodeEditor,\n `actions/${this.actionName}/editor/${testName}`\n );\n\n // Step 3: Test round-trip conversion (simulates save workflow)\n if (this.actionConfig.toFormData && this.actionConfig.fromFormData) {\n const formData = this.actionConfig.toFormData(action);\n const convertedAction = this.actionConfig.fromFormData(formData) as T;\n\n // Validate the round trip worked\n expect(convertedAction.uuid).to.equal(action.uuid);\n expect(convertedAction.type).to.equal(action.type);\n\n // Validate the converted action\n if (this.actionConfig.validate) {\n const validation = this.actionConfig.validate(convertedAction);\n expect(validation.valid).to.be.true;\n }\n }\n });\n }\n\n /**\n * Run basic property tests\n */\n testBasicProperties() {\n it('has correct basic properties', () => {\n expect(this.actionConfig.name).to.be.a('string');\n expect(this.actionConfig.color).to.exist;\n\n // toFormData and fromFormData are optional - only needed for complex data transformations\n if (this.actionConfig.toFormData) {\n expect(this.actionConfig.toFormData).to.be.a('function');\n }\n if (this.actionConfig.fromFormData) {\n expect(this.actionConfig.fromFormData).to.be.a('function');\n }\n\n if (this.actionConfig.validate) {\n expect(this.actionConfig.validate).to.be.a('function');\n }\n });\n }\n}\n"]}
@@ -0,0 +1,148 @@
1
+ import { fixture, expect } from '@open-wc/testing';
2
+ import { html } from 'lit';
3
+ import { assertScreenshot, getClip } from './utils.test';
4
+ import '../temba-modules';
5
+ /**
6
+ * Generic node test framework
7
+ * Tests the complete node lifecycle: render → edit → save → validate
8
+ *
9
+ * This is the node configuration equivalent of ActionHelper.ts for action configurations.
10
+ * It provides uniform testing for all types of nodes: simple wait nodes, router-based
11
+ * split nodes, and complex form-configured nodes.
12
+ */
13
+ export class NodeTest {
14
+ constructor(nodeConfig, nodeName) {
15
+ this.nodeConfig = nodeConfig;
16
+ this.nodeName = nodeName;
17
+ }
18
+ /**
19
+ * Renders a node in the flow editor and returns the flow node
20
+ */
21
+ async renderNode(node, nodeUI) {
22
+ const mockDefinition = {
23
+ nodes: [node],
24
+ _ui: {
25
+ nodes: {
26
+ [node.uuid]: {
27
+ type: nodeUI.type,
28
+ position: { left: 50, top: 50 },
29
+ ...nodeUI
30
+ }
31
+ }
32
+ }
33
+ };
34
+ const editor = (await fixture(html `
35
+ <temba-flow-editor>
36
+ <div id="canvas"></div>
37
+ </temba-flow-editor>
38
+ `));
39
+ editor.definition = mockDefinition;
40
+ editor.canvasSize = { width: 400, height: 300 };
41
+ await editor.updateComplete;
42
+ const flowNode = editor.querySelector('temba-flow-node');
43
+ expect(flowNode).to.exist;
44
+ return flowNode;
45
+ }
46
+ /**
47
+ * Opens the node editor for a node and returns the editor element
48
+ */
49
+ async openNodeEditor(node, nodeUI) {
50
+ const nodeEditor = (await fixture(html `
51
+ <temba-node-editor
52
+ .node=${node}
53
+ .nodeUI=${nodeUI}
54
+ .isOpen=${true}
55
+ ></temba-node-editor>
56
+ `));
57
+ await nodeEditor.updateComplete;
58
+ // Wait for form data initialization if needed
59
+ await new Promise((resolve) => setTimeout(resolve, 200));
60
+ await nodeEditor.updateComplete;
61
+ expect(nodeEditor).to.exist;
62
+ return nodeEditor;
63
+ }
64
+ /**
65
+ * Takes a screenshot of the dialog container within a node editor
66
+ */
67
+ async assertDialogScreenshot(el, screenshotName) {
68
+ var _a, _b, _c;
69
+ const dialog = (_c = (_b = (_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('temba-dialog')) === null || _b === void 0 ? void 0 : _b.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector('.dialog-container');
70
+ await assertScreenshot(screenshotName, getClip(dialog));
71
+ }
72
+ /**
73
+ * Complete test for a node configuration
74
+ * 1. Renders the node in a flow node (with screenshot)
75
+ * 2. Opens the node editor (with screenshot)
76
+ * 3. Simulates save and validates round-trip conversion
77
+ */
78
+ async testNode(node, nodeUI, testName) {
79
+ it(`${testName}`, async () => {
80
+ var _a;
81
+ // Step 1: Render node in flow node
82
+ const flowNode = await this.renderNode(node, nodeUI);
83
+ // For execute_actions nodes, check for .body, for router nodes check for .router or .categories
84
+ const hasContent = flowNode.querySelector('.body') ||
85
+ flowNode.querySelector('.router') ||
86
+ flowNode.querySelector('.categories') ||
87
+ flowNode.querySelector('.action') ||
88
+ ((_a = flowNode.textContent) === null || _a === void 0 ? void 0 : _a.trim());
89
+ expect(hasContent).to.exist;
90
+ await assertScreenshot(`nodes/${this.nodeName}/render/${testName}`, getClip(flowNode));
91
+ // Step 2: Open node editor
92
+ const nodeEditor = await this.openNodeEditor(node, nodeUI);
93
+ await this.assertDialogScreenshot(nodeEditor, `nodes/${this.nodeName}/editor/${testName}`);
94
+ // Step 3: Test round-trip conversion (simulates save workflow)
95
+ if (this.nodeConfig.toFormData && this.nodeConfig.fromFormData) {
96
+ const formData = this.nodeConfig.toFormData(node);
97
+ const convertedNode = this.nodeConfig.fromFormData(formData, node);
98
+ // Validate the round trip worked
99
+ expect(convertedNode.uuid).to.equal(node.uuid);
100
+ // Validate the converted node has expected structure
101
+ expect(convertedNode).to.have.property('actions');
102
+ expect(convertedNode).to.have.property('exits');
103
+ expect(convertedNode).to.deep.equal(node);
104
+ }
105
+ });
106
+ }
107
+ /**
108
+ * Run basic property tests
109
+ */
110
+ testBasicProperties() {
111
+ it('has correct basic properties', () => {
112
+ expect(this.nodeConfig.type).to.be.a('string');
113
+ // Name is optional - only some node configs have it
114
+ if (this.nodeConfig.name) {
115
+ expect(this.nodeConfig.name).to.be.a('string');
116
+ }
117
+ // Color is optional
118
+ if (this.nodeConfig.color) {
119
+ expect(this.nodeConfig.color).to.be.a('string');
120
+ }
121
+ // toFormData and fromFormData are optional - only needed for complex data transformations
122
+ if (this.nodeConfig.toFormData) {
123
+ expect(this.nodeConfig.toFormData).to.be.a('function');
124
+ }
125
+ if (this.nodeConfig.fromFormData) {
126
+ expect(this.nodeConfig.fromFormData).to.be.a('function');
127
+ }
128
+ // Form configuration is optional
129
+ if (this.nodeConfig.form) {
130
+ expect(this.nodeConfig.form).to.be.an('object');
131
+ }
132
+ // Layout is optional
133
+ if (this.nodeConfig.layout) {
134
+ expect(this.nodeConfig.layout).to.be.an('array');
135
+ }
136
+ // Router config is optional
137
+ if (this.nodeConfig.router) {
138
+ expect(this.nodeConfig.router).to.be.an('object');
139
+ expect(this.nodeConfig.router.type).to.exist;
140
+ }
141
+ // Render function is optional
142
+ if (this.nodeConfig.render) {
143
+ expect(this.nodeConfig.render).to.be.a('function');
144
+ }
145
+ });
146
+ }
147
+ }
148
+ //# sourceMappingURL=NodeHelper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeHelper.js","sourceRoot":"","sources":["../../test/NodeHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import { fixture, expect } from '@open-wc/testing';\nimport { html } from 'lit';\nimport { Node } from '../src/store/flow-definition';\nimport { assertScreenshot, getClip } from './utils.test';\nimport { Editor } from '../src/flow/Editor';\nimport '../temba-modules';\n\n/**\n * Generic node test framework\n * Tests the complete node lifecycle: render → edit → save → validate\n *\n * This is the node configuration equivalent of ActionHelper.ts for action configurations.\n * It provides uniform testing for all types of nodes: simple wait nodes, router-based\n * split nodes, and complex form-configured nodes.\n */\nexport class NodeTest<T extends Node> {\n constructor(private nodeConfig: any, private nodeName: string) {}\n\n /**\n * Renders a node in the flow editor and returns the flow node\n */\n private async renderNode(node: T, nodeUI: any): Promise<HTMLElement> {\n const mockDefinition = {\n nodes: [node],\n _ui: {\n nodes: {\n [node.uuid]: {\n type: nodeUI.type,\n position: { left: 50, top: 50 },\n ...nodeUI\n }\n }\n }\n };\n\n const editor = (await fixture(html`\n <temba-flow-editor>\n <div id=\"canvas\"></div>\n </temba-flow-editor>\n `)) as Editor;\n\n (editor as any).definition = mockDefinition;\n (editor as any).canvasSize = { width: 400, height: 300 };\n await editor.updateComplete;\n\n const flowNode = editor.querySelector('temba-flow-node') as HTMLElement;\n expect(flowNode).to.exist;\n\n return flowNode;\n }\n\n /**\n * Opens the node editor for a node and returns the editor element\n */\n private async openNodeEditor(node: T, nodeUI: any): Promise<HTMLElement> {\n const nodeEditor = (await fixture(html`\n <temba-node-editor\n .node=${node}\n .nodeUI=${nodeUI}\n .isOpen=${true}\n ></temba-node-editor>\n `)) as HTMLElement;\n\n await (nodeEditor as any).updateComplete;\n\n // Wait for form data initialization if needed\n await new Promise((resolve) => setTimeout(resolve, 200));\n await (nodeEditor as any).updateComplete;\n\n expect(nodeEditor).to.exist;\n\n return nodeEditor;\n }\n\n /**\n * Takes a screenshot of the dialog container within a node editor\n */\n private async assertDialogScreenshot(\n el: HTMLElement,\n screenshotName: string\n ) {\n const dialog = el.shadowRoot\n ?.querySelector('temba-dialog')\n ?.shadowRoot?.querySelector('.dialog-container') as HTMLElement;\n await assertScreenshot(screenshotName, getClip(dialog));\n }\n\n /**\n * Complete test for a node configuration\n * 1. Renders the node in a flow node (with screenshot)\n * 2. Opens the node editor (with screenshot)\n * 3. Simulates save and validates round-trip conversion\n */\n async testNode(node: T, nodeUI: any, testName: string) {\n it(`${testName}`, async () => {\n // Step 1: Render node in flow node\n const flowNode = await this.renderNode(node, nodeUI);\n\n // For execute_actions nodes, check for .body, for router nodes check for .router or .categories\n const hasContent =\n flowNode.querySelector('.body') ||\n flowNode.querySelector('.router') ||\n flowNode.querySelector('.categories') ||\n flowNode.querySelector('.action') ||\n flowNode.textContent?.trim();\n\n expect(hasContent).to.exist;\n await assertScreenshot(\n `nodes/${this.nodeName}/render/${testName}`,\n getClip(flowNode)\n );\n\n // Step 2: Open node editor\n const nodeEditor = await this.openNodeEditor(node, nodeUI);\n await this.assertDialogScreenshot(\n nodeEditor,\n `nodes/${this.nodeName}/editor/${testName}`\n );\n\n // Step 3: Test round-trip conversion (simulates save workflow)\n if (this.nodeConfig.toFormData && this.nodeConfig.fromFormData) {\n const formData = this.nodeConfig.toFormData(node);\n const convertedNode = this.nodeConfig.fromFormData(formData, node) as T;\n\n // Validate the round trip worked\n expect(convertedNode.uuid).to.equal(node.uuid);\n\n // Validate the converted node has expected structure\n expect(convertedNode).to.have.property('actions');\n expect(convertedNode).to.have.property('exits');\n\n expect(convertedNode).to.deep.equal(node);\n }\n });\n }\n\n /**\n * Run basic property tests\n */\n testBasicProperties() {\n it('has correct basic properties', () => {\n expect(this.nodeConfig.type).to.be.a('string');\n\n // Name is optional - only some node configs have it\n if (this.nodeConfig.name) {\n expect(this.nodeConfig.name).to.be.a('string');\n }\n\n // Color is optional\n if (this.nodeConfig.color) {\n expect(this.nodeConfig.color).to.be.a('string');\n }\n\n // toFormData and fromFormData are optional - only needed for complex data transformations\n if (this.nodeConfig.toFormData) {\n expect(this.nodeConfig.toFormData).to.be.a('function');\n }\n if (this.nodeConfig.fromFormData) {\n expect(this.nodeConfig.fromFormData).to.be.a('function');\n }\n\n // Form configuration is optional\n if (this.nodeConfig.form) {\n expect(this.nodeConfig.form).to.be.an('object');\n }\n\n // Layout is optional\n if (this.nodeConfig.layout) {\n expect(this.nodeConfig.layout).to.be.an('array');\n }\n\n // Router config is optional\n if (this.nodeConfig.router) {\n expect(this.nodeConfig.router).to.be.an('object');\n expect(this.nodeConfig.router.type).to.exist;\n }\n\n // Render function is optional\n if (this.nodeConfig.render) {\n expect(this.nodeConfig.render).to.be.a('function');\n }\n });\n }\n}\n"]}
@@ -0,0 +1,103 @@
1
+ import { expect } from '@open-wc/testing';
2
+ import { call_llm } from '../../src/flow/actions/call_llm';
3
+ import { ActionTest } from '../ActionHelper';
4
+ /**
5
+ * Test suite for the call_llm action configuration.
6
+ */
7
+ describe('call_llm action config', () => {
8
+ const helper = new ActionTest(call_llm, 'call_llm');
9
+ describe('basic properties', () => {
10
+ helper.testBasicProperties();
11
+ it('has correct name', () => {
12
+ expect(call_llm.name).to.equal('Call AI');
13
+ });
14
+ it('has form configuration', () => {
15
+ expect(call_llm.form).to.exist;
16
+ expect(call_llm.form.llm).to.exist;
17
+ expect(call_llm.form.instructions).to.exist;
18
+ expect(call_llm.form.input).to.exist;
19
+ });
20
+ it('has layout configuration', () => {
21
+ expect(call_llm.layout).to.exist;
22
+ expect(call_llm.layout).to.deep.equal(['llm', 'input', 'instructions']);
23
+ });
24
+ it('has data transformation functions', () => {
25
+ expect(call_llm.toFormData).to.be.a('function');
26
+ expect(call_llm.fromFormData).to.be.a('function');
27
+ });
28
+ });
29
+ describe('data transformations', () => {
30
+ it('converts action to form data correctly', () => {
31
+ const action = {
32
+ uuid: 'test-llm-1',
33
+ type: 'call_llm',
34
+ input: '@input',
35
+ llm: { uuid: 'gpt-4', name: 'GPT 4.1' },
36
+ instructions: 'Translate to French',
37
+ result_name: 'translated_text'
38
+ };
39
+ const formData = call_llm.toFormData(action);
40
+ expect(formData.uuid).to.equal('test-llm-1');
41
+ expect(formData.llm).to.deep.equal([{ value: 'gpt-4', name: 'GPT 4.1' }]);
42
+ expect(formData.instructions).to.equal('Translate to French');
43
+ expect(formData.input).to.equal('@input');
44
+ });
45
+ it('converts form data to action correctly', () => {
46
+ const formData = {
47
+ uuid: 'test-llm-2',
48
+ llm: [{ value: 'gpt-5', name: 'GPT 5' }],
49
+ instructions: 'Summarize the following text',
50
+ input: '@input'
51
+ };
52
+ const action = call_llm.fromFormData(formData);
53
+ expect(action.uuid).to.equal('test-llm-2');
54
+ expect(action.type).to.equal('call_llm');
55
+ expect(action.llm).to.deep.equal({ uuid: 'gpt-5', name: 'GPT 5' });
56
+ expect(action.instructions).to.equal('Summarize the following text');
57
+ expect(action.input).to.equal('@input');
58
+ });
59
+ it('handles empty form data', () => {
60
+ const formData = {
61
+ uuid: 'test-llm-3',
62
+ llm: [],
63
+ instructions: '',
64
+ input: ''
65
+ };
66
+ const action = call_llm.fromFormData(formData);
67
+ expect(action.llm).to.deep.equal({ uuid: '', name: '' });
68
+ expect(action.instructions).to.equal('');
69
+ expect(action.input).to.equal('@input');
70
+ });
71
+ });
72
+ describe('action scenarios', () => {
73
+ helper.testAction({
74
+ uuid: 'test-action-1',
75
+ type: 'call_llm',
76
+ llm: { uuid: 'gpt-4', name: 'GPT 4.1' },
77
+ instructions: 'Translate to French',
78
+ input: '@input'
79
+ }, 'translation-task');
80
+ helper.testAction({
81
+ uuid: 'test-action-2',
82
+ type: 'call_llm',
83
+ llm: { uuid: 'gpt-5', name: 'GPT 5' },
84
+ instructions: 'Analyze the sentiment of the following message and classify it as positive, negative, or neutral. Provide a brief explanation for your classification.',
85
+ input: '@input'
86
+ }, 'sentiment-analysis');
87
+ helper.testAction({
88
+ uuid: 'test-action-3',
89
+ type: 'call_llm',
90
+ llm: { uuid: 'gpt-4', name: 'GPT 4.1' },
91
+ instructions: 'Summarize the key points from the conversation above in bullet format.',
92
+ input: '@input'
93
+ }, 'summarization');
94
+ helper.testAction({
95
+ uuid: 'test-action-4',
96
+ type: 'call_llm',
97
+ llm: { uuid: 'gpt-5', name: 'GPT 5' },
98
+ instructions: 'Extract any contact information (phone numbers, email addresses) from the text and format them as a JSON object.',
99
+ input: '@input'
100
+ }, 'information-extraction');
101
+ });
102
+ });
103
+ //# sourceMappingURL=call_llm.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call_llm.test.js","sourceRoot":"","sources":["../../../test/actions/call_llm.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { call_llm } from '../../src/flow/actions/call_llm';\nimport { CallLLM } from '../../src/store/flow-definition';\nimport { ActionTest } from '../ActionHelper';\n\n/**\n * Test suite for the call_llm action configuration.\n */\ndescribe('call_llm action config', () => {\n const helper = new ActionTest(call_llm, 'call_llm');\n\n describe('basic properties', () => {\n helper.testBasicProperties();\n\n it('has correct name', () => {\n expect(call_llm.name).to.equal('Call AI');\n });\n\n it('has form configuration', () => {\n expect(call_llm.form).to.exist;\n expect(call_llm.form.llm).to.exist;\n expect(call_llm.form.instructions).to.exist;\n expect(call_llm.form.input).to.exist;\n });\n\n it('has layout configuration', () => {\n expect(call_llm.layout).to.exist;\n expect(call_llm.layout).to.deep.equal(['llm', 'input', 'instructions']);\n });\n\n it('has data transformation functions', () => {\n expect(call_llm.toFormData).to.be.a('function');\n expect(call_llm.fromFormData).to.be.a('function');\n });\n });\n\n describe('data transformations', () => {\n it('converts action to form data correctly', () => {\n const action: CallLLM = {\n uuid: 'test-llm-1',\n type: 'call_llm',\n input: '@input',\n llm: { uuid: 'gpt-4', name: 'GPT 4.1' },\n instructions: 'Translate to French',\n result_name: 'translated_text'\n };\n\n const formData = call_llm.toFormData(action);\n\n expect(formData.uuid).to.equal('test-llm-1');\n expect(formData.llm).to.deep.equal([{ value: 'gpt-4', name: 'GPT 4.1' }]);\n expect(formData.instructions).to.equal('Translate to French');\n expect(formData.input).to.equal('@input');\n });\n\n it('converts form data to action correctly', () => {\n const formData = {\n uuid: 'test-llm-2',\n llm: [{ value: 'gpt-5', name: 'GPT 5' }],\n instructions: 'Summarize the following text',\n input: '@input'\n };\n\n const action = call_llm.fromFormData(formData) as CallLLM;\n\n expect(action.uuid).to.equal('test-llm-2');\n expect(action.type).to.equal('call_llm');\n expect(action.llm).to.deep.equal({ uuid: 'gpt-5', name: 'GPT 5' });\n expect(action.instructions).to.equal('Summarize the following text');\n expect(action.input).to.equal('@input');\n });\n\n it('handles empty form data', () => {\n const formData = {\n uuid: 'test-llm-3',\n llm: [],\n instructions: '',\n input: ''\n };\n\n const action = call_llm.fromFormData(formData) as CallLLM;\n\n expect(action.llm).to.deep.equal({ uuid: '', name: '' });\n expect(action.instructions).to.equal('');\n expect(action.input).to.equal('@input');\n });\n });\n\n describe('action scenarios', () => {\n helper.testAction(\n {\n uuid: 'test-action-1',\n type: 'call_llm',\n llm: { uuid: 'gpt-4', name: 'GPT 4.1' },\n instructions: 'Translate to French',\n input: '@input'\n } as CallLLM,\n 'translation-task'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-2',\n type: 'call_llm',\n llm: { uuid: 'gpt-5', name: 'GPT 5' },\n instructions:\n 'Analyze the sentiment of the following message and classify it as positive, negative, or neutral. Provide a brief explanation for your classification.',\n input: '@input'\n } as CallLLM,\n 'sentiment-analysis'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-3',\n type: 'call_llm',\n llm: { uuid: 'gpt-4', name: 'GPT 4.1' },\n instructions:\n 'Summarize the key points from the conversation above in bullet format.',\n input: '@input'\n } as CallLLM,\n 'summarization'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-4',\n type: 'call_llm',\n llm: { uuid: 'gpt-5', name: 'GPT 5' },\n instructions:\n 'Extract any contact information (phone numbers, email addresses) from the text and format them as a JSON object.',\n input: '@input'\n } as CallLLM,\n 'information-extraction'\n );\n });\n});\n"]}