@nyaruka/temba-components 0.142.0 → 0.142.2

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 (137) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/temba-components.js +825 -654
  3. package/dist/temba-components.js.map +1 -1
  4. package/out-tsc/src/Icons.js +1 -0
  5. package/out-tsc/src/Icons.js.map +1 -1
  6. package/out-tsc/src/flow/CanvasMenu.js +30 -35
  7. package/out-tsc/src/flow/CanvasMenu.js.map +1 -1
  8. package/out-tsc/src/flow/CanvasNode.js +13 -8
  9. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  10. package/out-tsc/src/flow/Editor.js +18 -5
  11. package/out-tsc/src/flow/Editor.js.map +1 -1
  12. package/out-tsc/src/flow/NodeEditor.js +346 -10
  13. package/out-tsc/src/flow/NodeEditor.js.map +1 -1
  14. package/out-tsc/src/flow/NodeTypeSelector.js +2 -0
  15. package/out-tsc/src/flow/NodeTypeSelector.js.map +1 -1
  16. package/out-tsc/src/flow/Plumber.js +3 -1
  17. package/out-tsc/src/flow/Plumber.js.map +1 -1
  18. package/out-tsc/src/flow/actions/add_contact_urn.js +2 -6
  19. package/out-tsc/src/flow/actions/add_contact_urn.js.map +1 -1
  20. package/out-tsc/src/flow/actions/enter_flow.js +2 -2
  21. package/out-tsc/src/flow/actions/enter_flow.js.map +1 -1
  22. package/out-tsc/src/flow/actions/say_msg.js +2 -1
  23. package/out-tsc/src/flow/actions/say_msg.js.map +1 -1
  24. package/out-tsc/src/flow/actions/send_broadcast.js +2 -6
  25. package/out-tsc/src/flow/actions/send_broadcast.js.map +1 -1
  26. package/out-tsc/src/flow/actions/send_email.js +2 -6
  27. package/out-tsc/src/flow/actions/send_email.js.map +1 -1
  28. package/out-tsc/src/flow/actions/send_msg.js +52 -35
  29. package/out-tsc/src/flow/actions/send_msg.js.map +1 -1
  30. package/out-tsc/src/flow/actions/set_contact_channel.js +2 -1
  31. package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -1
  32. package/out-tsc/src/flow/actions/set_contact_field.js +4 -5
  33. package/out-tsc/src/flow/actions/set_contact_field.js.map +1 -1
  34. package/out-tsc/src/flow/actions/set_contact_language.js +3 -3
  35. package/out-tsc/src/flow/actions/set_contact_language.js.map +1 -1
  36. package/out-tsc/src/flow/actions/set_contact_name.js +2 -1
  37. package/out-tsc/src/flow/actions/set_contact_name.js.map +1 -1
  38. package/out-tsc/src/flow/actions/set_contact_status.js +2 -1
  39. package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -1
  40. package/out-tsc/src/flow/actions/set_run_result.js +3 -3
  41. package/out-tsc/src/flow/actions/set_run_result.js.map +1 -1
  42. package/out-tsc/src/flow/actions/start_session.js +2 -2
  43. package/out-tsc/src/flow/actions/start_session.js.map +1 -1
  44. package/out-tsc/src/flow/nodes/split_by_llm.js +4 -5
  45. package/out-tsc/src/flow/nodes/split_by_llm.js.map +1 -1
  46. package/out-tsc/src/flow/nodes/split_by_resthook.js +3 -8
  47. package/out-tsc/src/flow/nodes/split_by_resthook.js.map +1 -1
  48. package/out-tsc/src/flow/nodes/split_by_subflow.js +2 -2
  49. package/out-tsc/src/flow/nodes/split_by_subflow.js.map +1 -1
  50. package/out-tsc/src/flow/nodes/split_by_webhook.js +25 -33
  51. package/out-tsc/src/flow/nodes/split_by_webhook.js.map +1 -1
  52. package/out-tsc/src/flow/nodes/wait_for_response.js +1 -0
  53. package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
  54. package/out-tsc/src/flow/types.js.map +1 -1
  55. package/out-tsc/src/flow/utils.js +68 -0
  56. package/out-tsc/src/flow/utils.js.map +1 -1
  57. package/out-tsc/src/form/FieldRenderer.js +17 -2
  58. package/out-tsc/src/form/FieldRenderer.js.map +1 -1
  59. package/out-tsc/src/interfaces.js +1 -0
  60. package/out-tsc/src/interfaces.js.map +1 -1
  61. package/out-tsc/src/simulator/Simulator.js +1 -1
  62. package/out-tsc/src/simulator/Simulator.js.map +1 -1
  63. package/out-tsc/src/utils.js +5 -12
  64. package/out-tsc/src/utils.js.map +1 -1
  65. package/out-tsc/test/nodes/split_by_run_result.test.js +1 -2
  66. package/out-tsc/test/nodes/split_by_run_result.test.js.map +1 -1
  67. package/out-tsc/test/temba-canvas-menu.test.js +13 -9
  68. package/out-tsc/test/temba-canvas-menu.test.js.map +1 -1
  69. package/out-tsc/test/temba-flow-reflow.test.js.map +1 -1
  70. package/out-tsc/test/temba-node-editor.test.js +9 -10
  71. package/out-tsc/test/temba-node-editor.test.js.map +1 -1
  72. package/out-tsc/test/temba-node-type-selector.test.js +3 -3
  73. package/out-tsc/test/temba-node-type-selector.test.js.map +1 -1
  74. package/out-tsc/test/temba-simulator.test.js +2 -2
  75. package/out-tsc/test/temba-simulator.test.js.map +1 -1
  76. package/package.json +2 -2
  77. package/screenshots/truth/actions/enter_flow/render/basic-flow.png +0 -0
  78. package/screenshots/truth/actions/enter_flow/render/long-flow-name.png +0 -0
  79. package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
  80. package/screenshots/truth/actions/send_msg/editor/long-quick-replies.png +0 -0
  81. package/screenshots/truth/actions/send_msg/editor/multiline-text-with-replies.png +0 -0
  82. package/screenshots/truth/actions/send_msg/editor/simple-text.png +0 -0
  83. package/screenshots/truth/actions/send_msg/editor/text-with-linebreaks.png +0 -0
  84. package/screenshots/truth/actions/send_msg/editor/text-with-many-quick-replies.png +0 -0
  85. package/screenshots/truth/actions/send_msg/editor/text-with-quick-replies.png +0 -0
  86. package/screenshots/truth/actions/send_msg/editor/text-without-quick-replies.png +0 -0
  87. package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
  88. package/screenshots/truth/actions/start_session/render/contact-query.png +0 -0
  89. package/screenshots/truth/actions/start_session/render/contacts-only.png +0 -0
  90. package/screenshots/truth/actions/start_session/render/create-contact.png +0 -0
  91. package/screenshots/truth/actions/start_session/render/groups-and-contacts.png +0 -0
  92. package/screenshots/truth/actions/start_session/render/groups-only.png +0 -0
  93. package/screenshots/truth/actions/start_session/render/many-recipients.png +0 -0
  94. package/screenshots/truth/canvas-menu/open.png +0 -0
  95. package/screenshots/truth/node-type-selector/action-mode.png +0 -0
  96. package/screenshots/truth/node-type-selector/split-mode.png +0 -0
  97. package/screenshots/truth/nodes/split_by_llm/render/information-extraction.png +0 -0
  98. package/screenshots/truth/nodes/split_by_llm/render/sentiment-analysis.png +0 -0
  99. package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
  100. package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
  101. package/src/Icons.ts +1 -0
  102. package/src/flow/CanvasMenu.ts +38 -39
  103. package/src/flow/CanvasNode.ts +16 -8
  104. package/src/flow/Editor.ts +33 -6
  105. package/src/flow/NodeEditor.ts +373 -10
  106. package/src/flow/NodeTypeSelector.ts +2 -0
  107. package/src/flow/Plumber.ts +3 -1
  108. package/src/flow/actions/add_contact_urn.ts +5 -6
  109. package/src/flow/actions/enter_flow.ts +2 -2
  110. package/src/flow/actions/say_msg.ts +2 -1
  111. package/src/flow/actions/send_broadcast.ts +2 -6
  112. package/src/flow/actions/send_email.ts +2 -6
  113. package/src/flow/actions/send_msg.ts +56 -38
  114. package/src/flow/actions/set_contact_channel.ts +5 -1
  115. package/src/flow/actions/set_contact_field.ts +10 -5
  116. package/src/flow/actions/set_contact_language.ts +6 -3
  117. package/src/flow/actions/set_contact_name.ts +5 -1
  118. package/src/flow/actions/set_contact_status.ts +5 -1
  119. package/src/flow/actions/set_run_result.ts +6 -3
  120. package/src/flow/actions/start_session.ts +2 -2
  121. package/src/flow/nodes/split_by_llm.ts +5 -5
  122. package/src/flow/nodes/split_by_resthook.ts +3 -8
  123. package/src/flow/nodes/split_by_subflow.ts +2 -2
  124. package/src/flow/nodes/split_by_webhook.ts +26 -34
  125. package/src/flow/nodes/wait_for_response.ts +1 -0
  126. package/src/flow/types.ts +25 -2
  127. package/src/flow/utils.ts +81 -1
  128. package/src/form/FieldRenderer.ts +32 -3
  129. package/src/interfaces.ts +1 -0
  130. package/src/simulator/Simulator.ts +1 -1
  131. package/src/utils.ts +5 -12
  132. package/test/nodes/split_by_run_result.test.ts +1 -2
  133. package/test/temba-canvas-menu.test.ts +13 -9
  134. package/test/temba-flow-reflow.test.ts +4 -2
  135. package/test/temba-node-editor.test.ts +9 -10
  136. package/test/temba-node-type-selector.test.ts +3 -3
  137. package/test/temba-simulator.test.ts +2 -2
@@ -1,11 +1,12 @@
1
1
  import { html } from 'lit-html';
2
2
  import { ACTION_GROUPS, FlowTypes } from '../types';
3
+ import { renderClamped } from '../utils';
3
4
  export const set_contact_name = {
4
5
  name: 'Update Name',
5
6
  group: ACTION_GROUPS.contacts,
6
7
  flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],
7
8
  render: (_node, action) => {
8
- return html `<div>Set to <strong>${action.name}</strong></div>`;
9
+ return renderClamped(html `Set to <strong>${action.name}</strong>`, `Set to ${action.name}`);
9
10
  },
10
11
  form: {
11
12
  name: {
@@ -1 +1 @@
1
- {"version":3,"file":"set_contact_name.js","sourceRoot":"","sources":["../../../../src/flow/actions/set_contact_name.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAgB,aAAa,EAAY,SAAS,EAAE,MAAM,UAAU,CAAC;AAG5E,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE,aAAa,CAAC,QAAQ;IAC7B,SAAS,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC;IACrE,MAAM,EAAE,CAAC,KAAW,EAAE,MAAsB,EAAE,EAAE;QAC9C,OAAO,IAAI,CAAA,uBAAuB,MAAM,CAAC,IAAI,iBAAiB,CAAC;IACjE,CAAC;IACD,IAAI,EAAE;QACJ,IAAI,EAAE;YACJ,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,MAAM;YACb,WAAW,EAAE,uBAAuB;YACpC,QAAQ,EAAE,IAAI;YACd,SAAS,EAAE,IAAI;YACf,QAAQ,EACN,0EAA0E;SAC7E;KACF;IACD,QAAQ,EAAE,CAAC,QAAkB,EAAQ,EAAE;QACrC,IAAI,QAAQ,CAAC,IAAI,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACvC,CAAC;IACH,CAAC;CACF,CAAC","sourcesContent":["import { html } from 'lit-html';\nimport { ActionConfig, ACTION_GROUPS, FormData, FlowTypes } from '../types';\nimport { Node, SetContactName } from '../../store/flow-definition';\n\nexport const set_contact_name: ActionConfig = {\n name: 'Update Name',\n group: ACTION_GROUPS.contacts,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n render: (_node: Node, action: SetContactName) => {\n return html`<div>Set to <strong>${action.name}</strong></div>`;\n },\n form: {\n name: {\n type: 'text',\n label: 'Name',\n placeholder: 'Enter contact name...',\n required: true,\n evaluated: true,\n helpText:\n 'The new name for the contact. You can use expressions like @contact.name'\n }\n },\n sanitize: (formData: FormData): void => {\n if (formData.name && typeof formData.name === 'string') {\n formData.name = formData.name.trim();\n }\n }\n};\n"]}
1
+ {"version":3,"file":"set_contact_name.js","sourceRoot":"","sources":["../../../../src/flow/actions/set_contact_name.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAgB,aAAa,EAAY,SAAS,EAAE,MAAM,UAAU,CAAC;AAE5E,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE,aAAa,CAAC,QAAQ;IAC7B,SAAS,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC;IACrE,MAAM,EAAE,CAAC,KAAW,EAAE,MAAsB,EAAE,EAAE;QAC9C,OAAO,aAAa,CAClB,IAAI,CAAA,kBAAkB,MAAM,CAAC,IAAI,WAAW,EAC5C,UAAU,MAAM,CAAC,IAAI,EAAE,CACxB,CAAC;IACJ,CAAC;IACD,IAAI,EAAE;QACJ,IAAI,EAAE;YACJ,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,MAAM;YACb,WAAW,EAAE,uBAAuB;YACpC,QAAQ,EAAE,IAAI;YACd,SAAS,EAAE,IAAI;YACf,QAAQ,EACN,0EAA0E;SAC7E;KACF;IACD,QAAQ,EAAE,CAAC,QAAkB,EAAQ,EAAE;QACrC,IAAI,QAAQ,CAAC,IAAI,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACvC,CAAC;IACH,CAAC;CACF,CAAC","sourcesContent":["import { html } from 'lit-html';\nimport { ActionConfig, ACTION_GROUPS, FormData, FlowTypes } from '../types';\nimport { Node, SetContactName } from '../../store/flow-definition';\nimport { renderClamped } from '../utils';\n\nexport const set_contact_name: ActionConfig = {\n name: 'Update Name',\n group: ACTION_GROUPS.contacts,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n render: (_node: Node, action: SetContactName) => {\n return renderClamped(\n html`Set to <strong>${action.name}</strong>`,\n `Set to ${action.name}`\n );\n },\n form: {\n name: {\n type: 'text',\n label: 'Name',\n placeholder: 'Enter contact name...',\n required: true,\n evaluated: true,\n helpText:\n 'The new name for the contact. You can use expressions like @contact.name'\n }\n },\n sanitize: (formData: FormData): void => {\n if (formData.name && typeof formData.name === 'string') {\n formData.name = formData.name.trim();\n }\n }\n};\n"]}
@@ -1,12 +1,13 @@
1
1
  import { html } from 'lit-html';
2
2
  import { ACTION_GROUPS, FlowTypes } from '../types';
3
3
  import { titleCase } from '../../utils';
4
+ import { renderClamped } from '../utils';
4
5
  export const set_contact_status = {
5
6
  name: 'Update Status',
6
7
  group: ACTION_GROUPS.contacts,
7
8
  flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],
8
9
  render: (_node, action) => {
9
- return html `<div>Set to <strong>${titleCase(action.status)}</strong></div>`;
10
+ return renderClamped(html `Set to <strong>${titleCase(action.status)}</strong>`, `Set to ${titleCase(action.status)}`);
10
11
  },
11
12
  toFormData: (action) => {
12
13
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"set_contact_status.js","sourceRoot":"","sources":["../../../../src/flow/actions/set_contact_status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAgB,aAAa,EAAY,SAAS,EAAE,MAAM,UAAU,CAAC;AAE5E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,CAAC,MAAM,kBAAkB,GAAiB;IAC9C,IAAI,EAAE,eAAe;IACrB,KAAK,EAAE,aAAa,CAAC,QAAQ;IAC7B,SAAS,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC;IACrE,MAAM,EAAE,CAAC,KAAW,EAAE,MAAwB,EAAE,EAAE;QAChD,OAAO,IAAI,CAAA,uBAAuB,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC;IAC9E,CAAC;IACD,UAAU,EAAE,CAAC,MAAwB,EAAE,EAAE;QACvC,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE;gBACN;oBACE,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,IAAI,QAAQ,CAAC;oBAC1C,KAAK,EAAE,MAAM,CAAC,MAAM,IAAI,QAAQ;iBACjC;aACF;SACF,CAAC;IACJ,CAAC;IACD,YAAY,EAAE,CAAC,QAAkB,EAAoB,EAAE;QACrD,OAAO;YACL,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;YAChC,IAAI,EAAE,oBAAoB;YAC1B,IAAI,EAAE,QAAQ,CAAC,IAAI;SACpB,CAAC;IACJ,CAAC;IACD,IAAI,EAAE;QACJ,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,IAAI;YACd,UAAU,EAAE,KAAK;YACjB,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACnC,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE;gBACvC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;gBACrC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;aACtC;YACD,QAAQ,EAAE,0CAA0C;SACrD;KACF;CACF,CAAC","sourcesContent":["import { html } from 'lit-html';\nimport { ActionConfig, ACTION_GROUPS, FormData, FlowTypes } from '../types';\nimport { Node, SetContactStatus } from '../../store/flow-definition';\nimport { titleCase } from '../../utils';\n\nexport const set_contact_status: ActionConfig = {\n name: 'Update Status',\n group: ACTION_GROUPS.contacts,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n render: (_node: Node, action: SetContactStatus) => {\n return html`<div>Set to <strong>${titleCase(action.status)}</strong></div>`;\n },\n toFormData: (action: SetContactStatus) => {\n return {\n uuid: action.uuid,\n status: [\n {\n name: titleCase(action.status || 'active'),\n value: action.status || 'active'\n }\n ]\n };\n },\n fromFormData: (formData: FormData): SetContactStatus => {\n return {\n status: formData.status[0].value,\n type: 'set_contact_status',\n uuid: formData.uuid\n };\n },\n form: {\n status: {\n type: 'select',\n label: 'Status',\n required: true,\n searchable: false,\n clearable: false,\n options: [\n { value: 'active', name: 'Active' },\n { value: 'archived', name: 'Archived' },\n { value: 'stopped', name: 'Stopped' },\n { value: 'blocked', name: 'Blocked' }\n ],\n helpText: 'Select the status to set for the contact'\n }\n }\n};\n"]}
1
+ {"version":3,"file":"set_contact_status.js","sourceRoot":"","sources":["../../../../src/flow/actions/set_contact_status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAgB,aAAa,EAAY,SAAS,EAAE,MAAM,UAAU,CAAC;AAE5E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,CAAC,MAAM,kBAAkB,GAAiB;IAC9C,IAAI,EAAE,eAAe;IACrB,KAAK,EAAE,aAAa,CAAC,QAAQ;IAC7B,SAAS,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC;IACrE,MAAM,EAAE,CAAC,KAAW,EAAE,MAAwB,EAAE,EAAE;QAChD,OAAO,aAAa,CAClB,IAAI,CAAA,kBAAkB,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,EACzD,UAAU,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CACrC,CAAC;IACJ,CAAC;IACD,UAAU,EAAE,CAAC,MAAwB,EAAE,EAAE;QACvC,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE;gBACN;oBACE,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,IAAI,QAAQ,CAAC;oBAC1C,KAAK,EAAE,MAAM,CAAC,MAAM,IAAI,QAAQ;iBACjC;aACF;SACF,CAAC;IACJ,CAAC;IACD,YAAY,EAAE,CAAC,QAAkB,EAAoB,EAAE;QACrD,OAAO;YACL,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;YAChC,IAAI,EAAE,oBAAoB;YAC1B,IAAI,EAAE,QAAQ,CAAC,IAAI;SACpB,CAAC;IACJ,CAAC;IACD,IAAI,EAAE;QACJ,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,IAAI;YACd,UAAU,EAAE,KAAK;YACjB,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACnC,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE;gBACvC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;gBACrC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;aACtC;YACD,QAAQ,EAAE,0CAA0C;SACrD;KACF;CACF,CAAC","sourcesContent":["import { html } from 'lit-html';\nimport { ActionConfig, ACTION_GROUPS, FormData, FlowTypes } from '../types';\nimport { Node, SetContactStatus } from '../../store/flow-definition';\nimport { titleCase } from '../../utils';\nimport { renderClamped } from '../utils';\n\nexport const set_contact_status: ActionConfig = {\n name: 'Update Status',\n group: ACTION_GROUPS.contacts,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n render: (_node: Node, action: SetContactStatus) => {\n return renderClamped(\n html`Set to <strong>${titleCase(action.status)}</strong>`,\n `Set to ${titleCase(action.status)}`\n );\n },\n toFormData: (action: SetContactStatus) => {\n return {\n uuid: action.uuid,\n status: [\n {\n name: titleCase(action.status || 'active'),\n value: action.status || 'active'\n }\n ]\n };\n },\n fromFormData: (formData: FormData): SetContactStatus => {\n return {\n status: formData.status[0].value,\n type: 'set_contact_status',\n uuid: formData.uuid\n };\n },\n form: {\n status: {\n type: 'select',\n label: 'Status',\n required: true,\n searchable: false,\n clearable: false,\n options: [\n { value: 'active', name: 'Active' },\n { value: 'archived', name: 'Archived' },\n { value: 'stopped', name: 'Stopped' },\n { value: 'blocked', name: 'Blocked' }\n ],\n helpText: 'Select the status to set for the contact'\n }\n }\n};\n"]}
@@ -1,14 +1,14 @@
1
1
  import { html } from 'lit-html';
2
2
  import { ACTION_GROUPS, FlowTypes } from '../types';
3
3
  import { getStore } from '../../store/Store';
4
+ import { renderClamped } from '../utils';
4
5
  export const set_run_result = {
5
6
  name: 'Save Flow Result',
6
7
  group: ACTION_GROUPS.save,
7
8
  flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],
8
9
  render: (_node, action) => {
9
- return html `<div>
10
- Save <strong>${action.value}</strong> as <strong>${action.name}</strong>
11
- </div>`;
10
+ return renderClamped(html `Save <strong>${action.value}</strong> as
11
+ <strong>${action.name}</strong>`, `Save ${action.value} as ${action.name}`);
12
12
  },
13
13
  form: {
14
14
  name: {
@@ -1 +1 @@
1
- {"version":3,"file":"set_run_result.js","sourceRoot":"","sources":["../../../../src/flow/actions/set_run_result.ts"],"names":[],"mappings":"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","sourcesContent":["import { html } from 'lit-html';\nimport { ActionConfig, ACTION_GROUPS, FormData, FlowTypes } from '../types';\nimport { Node, SetRunResult } from '../../store/flow-definition';\nimport { getStore } from '../../store/Store';\n\nexport const set_run_result: ActionConfig = {\n name: 'Save Flow Result',\n group: ACTION_GROUPS.save,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n render: (_node: Node, action: SetRunResult) => {\n return html`<div>\n Save <strong>${action.value}</strong> as <strong>${action.name}</strong>\n </div>`;\n },\n form: {\n name: {\n type: 'select',\n label: 'Result Name',\n helpText: 'Select an existing result name or type a new one',\n required: true,\n placeholder: 'Select or enter result name...',\n createArbitraryOption: (input, options) => {\n const exists = options.some(\n (option: any) =>\n option.value.toLowerCase() === input.toLowerCase() ||\n option.name.toLowerCase() === input.toLowerCase()\n );\n return !exists && input.trim().length > 0\n ? { value: input, name: input }\n : null;\n },\n searchable: true,\n clearable: false,\n getDynamicOptions: () => {\n const store = getStore();\n return store\n ? store\n .getState()\n .getFlowResults()\n .map((r) => ({ value: r.name, name: r.name }))\n : [];\n }\n },\n value: {\n type: 'text',\n label: 'Value',\n helpText: 'The value to save for this result (can use expressions)',\n required: false,\n evaluated: true,\n placeholder: 'Enter value...'\n },\n category: {\n type: 'text',\n label: 'Category',\n helpText: 'Optional category for this result',\n required: false,\n placeholder: 'Enter category...'\n }\n },\n layout: ['name', 'value', 'category'],\n toFormData: (action: SetRunResult) => {\n return {\n uuid: action.uuid,\n name: action.name ? [{ name: action.name, value: action.name }] : null,\n value: action.value || '',\n category: action.category || ''\n };\n },\n fromFormData: (formData: FormData): SetRunResult => {\n // Ensure name is a simple string, handling both direct values and select option objects\n let name = formData.name || '';\n if (Array.isArray(name) && name.length > 0) {\n // If it's an array (from multi-select), take the first item\n name = name[0];\n }\n if (typeof name === 'object' && name.value) {\n // If it's an option object, extract the value\n name = name.value;\n }\n if (typeof name === 'object' && name.name) {\n // If it's an option object with name property, extract it\n name = name.name;\n }\n\n return {\n uuid: formData.uuid,\n type: 'set_run_result',\n name: String(name), // Ensure it's always a string\n value: formData.value || '',\n category: formData.category || ''\n };\n }\n};\n"]}
1
+ {"version":3,"file":"set_run_result.js","sourceRoot":"","sources":["../../../../src/flow/actions/set_run_result.ts"],"names":[],"mappings":"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","sourcesContent":["import { html } from 'lit-html';\nimport { ActionConfig, ACTION_GROUPS, FormData, FlowTypes } from '../types';\nimport { Node, SetRunResult } from '../../store/flow-definition';\nimport { getStore } from '../../store/Store';\nimport { renderClamped } from '../utils';\n\nexport const set_run_result: ActionConfig = {\n name: 'Save Flow Result',\n group: ACTION_GROUPS.save,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n render: (_node: Node, action: SetRunResult) => {\n return renderClamped(\n html`Save <strong>${action.value}</strong> as\n <strong>${action.name}</strong>`,\n `Save ${action.value} as ${action.name}`\n );\n },\n form: {\n name: {\n type: 'select',\n label: 'Result Name',\n helpText: 'Select an existing result name or type a new one',\n required: true,\n placeholder: 'Select or enter result name...',\n createArbitraryOption: (input, options) => {\n const exists = options.some(\n (option: any) =>\n option.value.toLowerCase() === input.toLowerCase() ||\n option.name.toLowerCase() === input.toLowerCase()\n );\n return !exists && input.trim().length > 0\n ? { value: input, name: input }\n : null;\n },\n searchable: true,\n clearable: false,\n getDynamicOptions: () => {\n const store = getStore();\n return store\n ? store\n .getState()\n .getFlowResults()\n .map((r) => ({ value: r.name, name: r.name }))\n : [];\n }\n },\n value: {\n type: 'text',\n label: 'Value',\n helpText: 'The value to save for this result (can use expressions)',\n required: false,\n evaluated: true,\n placeholder: 'Enter value...'\n },\n category: {\n type: 'text',\n label: 'Category',\n helpText: 'Optional category for this result',\n required: false,\n placeholder: 'Enter category...'\n }\n },\n layout: ['name', 'value', 'category'],\n toFormData: (action: SetRunResult) => {\n return {\n uuid: action.uuid,\n name: action.name ? [{ name: action.name, value: action.name }] : null,\n value: action.value || '',\n category: action.category || ''\n };\n },\n fromFormData: (formData: FormData): SetRunResult => {\n // Ensure name is a simple string, handling both direct values and select option objects\n let name = formData.name || '';\n if (Array.isArray(name) && name.length > 0) {\n // If it's an array (from multi-select), take the first item\n name = name[0];\n }\n if (typeof name === 'object' && name.value) {\n // If it's an option object, extract the value\n name = name.value;\n }\n if (typeof name === 'object' && name.name) {\n // If it's an option object with name property, extract it\n name = name.name;\n }\n\n return {\n uuid: formData.uuid,\n type: 'set_run_result',\n name: String(name), // Ensure it's always a string\n value: formData.value || '',\n category: formData.category || ''\n };\n }\n};\n"]}
@@ -1,6 +1,6 @@
1
1
  import { html } from 'lit-html';
2
2
  import { ACTION_GROUPS, FlowTypes } from '../types';
3
- import { renderNamedObjects } from '../utils';
3
+ import { renderNamedObjects, renderFlowLinks } from '../utils';
4
4
  export const start_session = {
5
5
  name: 'Start Flow',
6
6
  group: ACTION_GROUPS.broadcast,
@@ -32,7 +32,7 @@ export const start_session = {
32
32
  ${recipientsDisplay}
33
33
  </div>
34
34
  <div style="padding: 0px 10px;">
35
- ${renderNamedObjects([action.flow], 'flow')}
35
+ ${renderFlowLinks([action.flow], 'flow')}
36
36
  </div>
37
37
  </div>
38
38
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"start_session.js","sourceRoot":"","sources":["../../../../src/flow/actions/start_session.ts"],"names":[],"mappings":"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","sourcesContent":["import { html } from 'lit-html';\nimport {\n ActionConfig,\n ACTION_GROUPS,\n FormData,\n ValidationResult,\n FlowTypes\n} from '../types';\nimport { Node, StartSession } from '../../store/flow-definition';\nimport { renderNamedObjects } from '../utils';\n\nexport const start_session: ActionConfig = {\n name: 'Start Flow',\n group: ACTION_GROUPS.broadcast,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n render: (_node: Node, action: StartSession) => {\n const hasGroups = action.groups && action.groups.length > 0;\n const hasContacts = action.contacts && action.contacts.length > 0;\n const hasRecipients = hasGroups || hasContacts;\n\n // Build the recipients display\n let recipientsDisplay = html``;\n if (action.create_contact) {\n recipientsDisplay = html`Create a new contact`;\n } else if ((action as any).contact_query) {\n recipientsDisplay = html`${(action as any).contact_query}`;\n } else if (hasRecipients) {\n const allRecipients = [\n ...(action.contacts || []),\n ...(action.groups || [])\n ];\n recipientsDisplay = html`${renderNamedObjects(\n allRecipients,\n hasGroups ? 'group' : 'contact'\n )}`;\n }\n\n return html`\n <div>\n <div\n style=\"padding: 3px 10px; background: #f5f5f5; padding-bottom: 0px; font-size: 11px; border-radius: var(--curvature); margin-bottom: 10px;\"\n >\n ${recipientsDisplay}\n </div>\n <div style=\"padding: 0px 10px;\">\n ${renderNamedObjects([action.flow], 'flow')}\n </div>\n </div>\n `;\n },\n\n toFormData: (action: StartSession) => {\n const extendedAction = action as StartSession & {\n contact_query?: string;\n exclusions?: { in_a_flow?: boolean };\n };\n\n // Determine start type based on action properties\n let startTypeValue = 'manual';\n if (action.create_contact) {\n startTypeValue = 'create';\n } else if (extendedAction.contact_query) {\n startTypeValue = 'query';\n }\n\n // Map value to full option object for proper display\n const startTypeOptions = [\n { value: 'manual', name: 'Select recipients manually' },\n { value: 'query', name: 'Select a contact with a query' },\n { value: 'create', name: 'Create a new contact' }\n ];\n const startType =\n startTypeOptions.find((opt) => opt.value === startTypeValue) ||\n startTypeOptions[0];\n\n return {\n flow: action.flow ? [action.flow] : null,\n recipients: [...(action.contacts || []), ...(action.groups || [])],\n startType: [startType],\n contactQuery: extendedAction.contact_query || '',\n skipContactsInFlow: extendedAction.exclusions?.in_a_flow || false,\n uuid: action.uuid\n };\n },\n\n form: {\n flow: {\n type: 'select',\n label: 'Flow',\n helpText: 'Select the flow to start',\n required: true,\n searchable: true,\n endpoint: '/api/v2/flows.json',\n valueKey: 'uuid',\n nameKey: 'name',\n placeholder: 'Select a flow...'\n },\n startType: {\n type: 'select',\n label: 'Start Type',\n helpText: 'How should contacts be selected?',\n required: true,\n options: [\n { value: 'manual', name: 'Select recipients manually' },\n { value: 'query', name: 'Select a contact with a query' },\n { value: 'create', name: 'Create a new contact' }\n ]\n },\n recipients: {\n type: 'select',\n label: 'Recipients',\n helpText: 'Select who should be started in the flow',\n options: [],\n multi: true,\n searchable: true,\n endpoint: '/api/v2/contacts.json',\n valueKey: 'uuid',\n nameKey: 'name',\n placeholder: 'Search for contacts or groups...',\n conditions: {\n visible: (formData: FormData) => {\n const startType = formData.startType?.[0]?.value;\n return startType === 'manual';\n }\n }\n },\n contactQuery: {\n type: 'text',\n evaluated: true,\n label: 'Contact Query',\n helpText: 'Only one matching contact will be started',\n placeholder: 'household_id = @fields.household_id',\n conditions: {\n visible: (formData: FormData) => {\n const startType = formData.startType?.[0]?.value;\n return startType === 'query';\n }\n }\n },\n skipContactsInFlow: {\n type: 'checkbox',\n label: 'Skip contacts currently in a flow',\n helpText: 'Avoid interrupting a contact who is already in a flow'\n }\n },\n\n layout: [\n 'flow',\n 'startType',\n 'recipients',\n 'contactQuery',\n 'skipContactsInFlow'\n ],\n\n validate: (formData: FormData): ValidationResult => {\n const errors: { [key: string]: string } = {};\n\n const startType = formData.startType?.[0]?.value;\n\n // Check if manual selection has recipients\n if (\n startType === 'manual' &&\n (!formData.recipients || formData.recipients.length === 0)\n ) {\n errors.recipients = 'At least one contact or group must be selected';\n }\n\n // Check if query has a query string\n if (\n startType === 'query' &&\n (!formData.contactQuery || !formData.contactQuery.trim())\n ) {\n errors.contactQuery = 'Contact query is required';\n }\n\n return {\n valid: Object.keys(errors).length === 0,\n errors\n };\n },\n\n fromFormData: (formData: FormData): StartSession => {\n const action: StartSession & {\n contact_query?: string;\n exclusions?: { in_a_flow: boolean };\n } = {\n uuid: formData.uuid,\n type: 'start_session',\n flow: {\n uuid: formData.flow[0].uuid || formData.flow[0].value,\n name: formData.flow[0].name\n },\n groups: [],\n contacts: []\n };\n\n // Get the start type value from array\n const startTypeValue = formData.startType[0].value;\n\n // Handle different start types\n if (startTypeValue === 'create') {\n action.create_contact = true;\n } else if (startTypeValue === 'query') {\n action.contact_query = formData.contactQuery || '';\n } else {\n // Manual selection - separate contacts and groups\n const recipients = formData.recipients || [];\n action.contacts = recipients\n .filter((r: any) => !r.group)\n .map((c: any) => ({ uuid: c.uuid, name: c.name }));\n action.groups = recipients\n .filter((r: any) => r.group)\n .map((g: any) => ({ uuid: g.uuid, name: g.name }));\n }\n\n // Add exclusions if set\n if (formData.skipContactsInFlow) {\n action.exclusions = { in_a_flow: true };\n }\n\n return action;\n }\n};\n"]}
1
+ {"version":3,"file":"start_session.js","sourceRoot":"","sources":["../../../../src/flow/actions/start_session.ts"],"names":[],"mappings":"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","sourcesContent":["import { html } from 'lit-html';\nimport {\n ActionConfig,\n ACTION_GROUPS,\n FormData,\n ValidationResult,\n FlowTypes\n} from '../types';\nimport { Node, StartSession } from '../../store/flow-definition';\nimport { renderNamedObjects, renderFlowLinks } from '../utils';\n\nexport const start_session: ActionConfig = {\n name: 'Start Flow',\n group: ACTION_GROUPS.broadcast,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n render: (_node: Node, action: StartSession) => {\n const hasGroups = action.groups && action.groups.length > 0;\n const hasContacts = action.contacts && action.contacts.length > 0;\n const hasRecipients = hasGroups || hasContacts;\n\n // Build the recipients display\n let recipientsDisplay = html``;\n if (action.create_contact) {\n recipientsDisplay = html`Create a new contact`;\n } else if ((action as any).contact_query) {\n recipientsDisplay = html`${(action as any).contact_query}`;\n } else if (hasRecipients) {\n const allRecipients = [\n ...(action.contacts || []),\n ...(action.groups || [])\n ];\n recipientsDisplay = html`${renderNamedObjects(\n allRecipients,\n hasGroups ? 'group' : 'contact'\n )}`;\n }\n\n return html`\n <div>\n <div\n style=\"padding: 3px 10px; background: #f5f5f5; padding-bottom: 0px; font-size: 11px; border-radius: var(--curvature); margin-bottom: 10px;\"\n >\n ${recipientsDisplay}\n </div>\n <div style=\"padding: 0px 10px;\">\n ${renderFlowLinks([action.flow], 'flow')}\n </div>\n </div>\n `;\n },\n\n toFormData: (action: StartSession) => {\n const extendedAction = action as StartSession & {\n contact_query?: string;\n exclusions?: { in_a_flow?: boolean };\n };\n\n // Determine start type based on action properties\n let startTypeValue = 'manual';\n if (action.create_contact) {\n startTypeValue = 'create';\n } else if (extendedAction.contact_query) {\n startTypeValue = 'query';\n }\n\n // Map value to full option object for proper display\n const startTypeOptions = [\n { value: 'manual', name: 'Select recipients manually' },\n { value: 'query', name: 'Select a contact with a query' },\n { value: 'create', name: 'Create a new contact' }\n ];\n const startType =\n startTypeOptions.find((opt) => opt.value === startTypeValue) ||\n startTypeOptions[0];\n\n return {\n flow: action.flow ? [action.flow] : null,\n recipients: [...(action.contacts || []), ...(action.groups || [])],\n startType: [startType],\n contactQuery: extendedAction.contact_query || '',\n skipContactsInFlow: extendedAction.exclusions?.in_a_flow || false,\n uuid: action.uuid\n };\n },\n\n form: {\n flow: {\n type: 'select',\n label: 'Flow',\n helpText: 'Select the flow to start',\n required: true,\n searchable: true,\n endpoint: '/api/v2/flows.json',\n valueKey: 'uuid',\n nameKey: 'name',\n placeholder: 'Select a flow...'\n },\n startType: {\n type: 'select',\n label: 'Start Type',\n helpText: 'How should contacts be selected?',\n required: true,\n options: [\n { value: 'manual', name: 'Select recipients manually' },\n { value: 'query', name: 'Select a contact with a query' },\n { value: 'create', name: 'Create a new contact' }\n ]\n },\n recipients: {\n type: 'select',\n label: 'Recipients',\n helpText: 'Select who should be started in the flow',\n options: [],\n multi: true,\n searchable: true,\n endpoint: '/api/v2/contacts.json',\n valueKey: 'uuid',\n nameKey: 'name',\n placeholder: 'Search for contacts or groups...',\n conditions: {\n visible: (formData: FormData) => {\n const startType = formData.startType?.[0]?.value;\n return startType === 'manual';\n }\n }\n },\n contactQuery: {\n type: 'text',\n evaluated: true,\n label: 'Contact Query',\n helpText: 'Only one matching contact will be started',\n placeholder: 'household_id = @fields.household_id',\n conditions: {\n visible: (formData: FormData) => {\n const startType = formData.startType?.[0]?.value;\n return startType === 'query';\n }\n }\n },\n skipContactsInFlow: {\n type: 'checkbox',\n label: 'Skip contacts currently in a flow',\n helpText: 'Avoid interrupting a contact who is already in a flow'\n }\n },\n\n layout: [\n 'flow',\n 'startType',\n 'recipients',\n 'contactQuery',\n 'skipContactsInFlow'\n ],\n\n validate: (formData: FormData): ValidationResult => {\n const errors: { [key: string]: string } = {};\n\n const startType = formData.startType?.[0]?.value;\n\n // Check if manual selection has recipients\n if (\n startType === 'manual' &&\n (!formData.recipients || formData.recipients.length === 0)\n ) {\n errors.recipients = 'At least one contact or group must be selected';\n }\n\n // Check if query has a query string\n if (\n startType === 'query' &&\n (!formData.contactQuery || !formData.contactQuery.trim())\n ) {\n errors.contactQuery = 'Contact query is required';\n }\n\n return {\n valid: Object.keys(errors).length === 0,\n errors\n };\n },\n\n fromFormData: (formData: FormData): StartSession => {\n const action: StartSession & {\n contact_query?: string;\n exclusions?: { in_a_flow: boolean };\n } = {\n uuid: formData.uuid,\n type: 'start_session',\n flow: {\n uuid: formData.flow[0].uuid || formData.flow[0].value,\n name: formData.flow[0].name\n },\n groups: [],\n contacts: []\n };\n\n // Get the start type value from array\n const startTypeValue = formData.startType[0].value;\n\n // Handle different start types\n if (startTypeValue === 'create') {\n action.create_contact = true;\n } else if (startTypeValue === 'query') {\n action.contact_query = formData.contactQuery || '';\n } else {\n // Manual selection - separate contacts and groups\n const recipients = formData.recipients || [];\n action.contacts = recipients\n .filter((r: any) => !r.group)\n .map((c: any) => ({ uuid: c.uuid, name: c.name }));\n action.groups = recipients\n .filter((r: any) => r.group)\n .map((g: any) => ({ uuid: g.uuid, name: g.name }));\n }\n\n // Add exclusions if set\n if (formData.skipContactsInFlow) {\n action.exclusions = { in_a_flow: true };\n }\n\n return action;\n }\n};\n"]}
@@ -2,6 +2,7 @@ import { ACTION_GROUPS, FlowTypes, Features } from '../types';
2
2
  import { generateUUID, createSuccessFailureRouter } from '../../utils';
3
3
  import { html } from 'lit';
4
4
  import { categoriesToLocalizationFormData, localizationFormDataToCategories } from './shared';
5
+ import { renderClamped } from '../utils';
5
6
  export const split_by_llm = {
6
7
  type: 'split_by_llm',
7
8
  name: 'Call AI',
@@ -12,12 +13,10 @@ export const split_by_llm = {
12
13
  render: (node) => {
13
14
  var _a;
14
15
  const callLlmAction = (_a = node.actions) === null || _a === void 0 ? void 0 : _a.find((action) => action.type === 'call_llm');
16
+ const instructions = (callLlmAction === null || callLlmAction === void 0 ? void 0 : callLlmAction.instructions) || 'Configure AI instructions';
15
17
  return html `
16
- <div
17
- class="body"
18
- style="word-wrap: break-word; overflow-wrap: break-word; hyphens: auto; max-width: 180px; max-height: 6.2em; margin-bottom:10px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical;"
19
- >
20
- ${(callLlmAction === null || callLlmAction === void 0 ? void 0 : callLlmAction.instructions) || 'Configure AI instructions'}
18
+ <div class="body" style="margin-bottom:10px;">
19
+ ${renderClamped(instructions, instructions)}
21
20
  </div>
22
21
  `;
23
22
  },
@@ -1 +1 @@
1
- {"version":3,"file":"split_by_llm.js","sourceRoot":"","sources":["../../../../src/flow/nodes/split_by_llm.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ACTION_GROUPS,\n FormData,\n NodeConfig,\n FlowTypes,\n Features\n} from '../types';\nimport { CallLLM, Node } from '../../store/flow-definition';\nimport { generateUUID, createSuccessFailureRouter } from '../../utils';\nimport { html } from 'lit';\nimport {\n categoriesToLocalizationFormData,\n localizationFormDataToCategories\n} from './shared';\n\nexport const split_by_llm: NodeConfig = {\n type: 'split_by_llm',\n name: 'Call AI',\n group: ACTION_GROUPS.services,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n features: [Features.AI],\n showAsAction: true,\n render: (node: Node) => {\n const callLlmAction = node.actions?.find(\n (action) => action.type === 'call_llm'\n ) as CallLLM;\n return html`\n <div\n class=\"body\"\n style=\"word-wrap: break-word; overflow-wrap: break-word; hyphens: auto; max-width: 180px; max-height: 6.2em; margin-bottom:10px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical;\"\n >\n ${callLlmAction?.instructions || 'Configure AI instructions'}\n </div>\n `;\n },\n\n form: {\n llm: {\n type: 'select',\n label: 'LLM',\n required: true,\n options: [],\n endpoint: '/test-assets/select/llms.json',\n searchable: true,\n valueKey: 'uuid',\n nameKey: 'name',\n placeholder: 'Select an LLM...'\n },\n input: {\n type: 'text',\n label: 'Input',\n helpText: 'The input the AI will process',\n required: true,\n evaluated: true,\n placeholder: '@input'\n },\n instructions: {\n type: 'textarea',\n label: 'Instructions',\n helpText:\n 'Tell the AI what to do with the input. The result can be referenced as **`@locals._llm_output`**',\n required: true,\n evaluated: true,\n placeholder: 'Enter instructions for the AI model...',\n minHeight: 130\n }\n },\n layout: ['llm', 'input', 'instructions'],\n toFormData: (node: Node) => {\n // Extract data from the existing node structure\n const callLlmAction = node.actions?.find(\n (action) => action.type === 'call_llm'\n ) as CallLLM;\n\n return {\n uuid: node.uuid,\n llm: callLlmAction?.llm\n ? [{ value: callLlmAction.llm.uuid, name: callLlmAction.llm.name }]\n : [],\n input: callLlmAction?.input || '@input',\n instructions: callLlmAction?.instructions || ''\n };\n },\n fromFormData: (formData: FormData, originalNode: Node): Node => {\n // Get LLM selection\n const llmSelection =\n Array.isArray(formData.llm) && formData.llm.length > 0\n ? formData.llm[0]\n : null;\n\n // Find existing call_llm action to preserve its UUID\n const existingCallLlmAction = originalNode.actions?.find(\n (action) => action.type === 'call_llm'\n );\n const callLlmUuid = existingCallLlmAction?.uuid || generateUUID();\n\n // Create call_llm action\n const callLlmAction: CallLLM = {\n type: 'call_llm',\n uuid: callLlmUuid,\n llm: llmSelection\n ? { uuid: llmSelection.value, name: llmSelection.name }\n : { uuid: '', name: '' },\n input: formData.input || '@input',\n instructions: formData.instructions || '',\n output_local: '_llm_output'\n };\n\n // Create categories and exits for Success and Failure\n const existingCategories = originalNode.router?.categories || [];\n const existingExits = originalNode.exits || [];\n const existingCases = originalNode.router?.cases || [];\n\n const { router, exits } = createSuccessFailureRouter(\n '@locals._llm_output',\n {\n type: 'has_text',\n arguments: []\n },\n existingCategories,\n existingExits,\n existingCases\n );\n\n // Return the complete node\n return {\n uuid: originalNode.uuid,\n actions: [callLlmAction],\n router: router,\n exits: exits\n };\n },\n\n // Localization support for categories\n localizable: 'categories',\n toLocalizationFormData: categoriesToLocalizationFormData,\n fromLocalizationFormData: localizationFormDataToCategories\n};\n"]}
1
+ {"version":3,"file":"split_by_llm.js","sourceRoot":"","sources":["../../../../src/flow/nodes/split_by_llm.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ACTION_GROUPS,\n FormData,\n NodeConfig,\n FlowTypes,\n Features\n} from '../types';\nimport { CallLLM, Node } from '../../store/flow-definition';\nimport { generateUUID, createSuccessFailureRouter } from '../../utils';\nimport { html } from 'lit';\nimport {\n categoriesToLocalizationFormData,\n localizationFormDataToCategories\n} from './shared';\nimport { renderClamped } from '../utils';\n\nexport const split_by_llm: NodeConfig = {\n type: 'split_by_llm',\n name: 'Call AI',\n group: ACTION_GROUPS.services,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n features: [Features.AI],\n showAsAction: true,\n render: (node: Node) => {\n const callLlmAction = node.actions?.find(\n (action) => action.type === 'call_llm'\n ) as CallLLM;\n const instructions =\n callLlmAction?.instructions || 'Configure AI instructions';\n return html`\n <div class=\"body\" style=\"margin-bottom:10px;\">\n ${renderClamped(instructions, instructions)}\n </div>\n `;\n },\n\n form: {\n llm: {\n type: 'select',\n label: 'LLM',\n required: true,\n options: [],\n endpoint: '/test-assets/select/llms.json',\n searchable: true,\n valueKey: 'uuid',\n nameKey: 'name',\n placeholder: 'Select an LLM...'\n },\n input: {\n type: 'text',\n label: 'Input',\n helpText: 'The input the AI will process',\n required: true,\n evaluated: true,\n placeholder: '@input'\n },\n instructions: {\n type: 'textarea',\n label: 'Instructions',\n helpText:\n 'Tell the AI what to do with the input. The result can be referenced as **`@locals._llm_output`**',\n required: true,\n evaluated: true,\n placeholder: 'Enter instructions for the AI model...',\n minHeight: 130\n }\n },\n layout: ['llm', 'input', 'instructions'],\n toFormData: (node: Node) => {\n // Extract data from the existing node structure\n const callLlmAction = node.actions?.find(\n (action) => action.type === 'call_llm'\n ) as CallLLM;\n\n return {\n uuid: node.uuid,\n llm: callLlmAction?.llm\n ? [{ value: callLlmAction.llm.uuid, name: callLlmAction.llm.name }]\n : [],\n input: callLlmAction?.input || '@input',\n instructions: callLlmAction?.instructions || ''\n };\n },\n fromFormData: (formData: FormData, originalNode: Node): Node => {\n // Get LLM selection\n const llmSelection =\n Array.isArray(formData.llm) && formData.llm.length > 0\n ? formData.llm[0]\n : null;\n\n // Find existing call_llm action to preserve its UUID\n const existingCallLlmAction = originalNode.actions?.find(\n (action) => action.type === 'call_llm'\n );\n const callLlmUuid = existingCallLlmAction?.uuid || generateUUID();\n\n // Create call_llm action\n const callLlmAction: CallLLM = {\n type: 'call_llm',\n uuid: callLlmUuid,\n llm: llmSelection\n ? { uuid: llmSelection.value, name: llmSelection.name }\n : { uuid: '', name: '' },\n input: formData.input || '@input',\n instructions: formData.instructions || '',\n output_local: '_llm_output'\n };\n\n // Create categories and exits for Success and Failure\n const existingCategories = originalNode.router?.categories || [];\n const existingExits = originalNode.exits || [];\n const existingCases = originalNode.router?.cases || [];\n\n const { router, exits } = createSuccessFailureRouter(\n '@locals._llm_output',\n {\n type: 'has_text',\n arguments: []\n },\n existingCategories,\n existingExits,\n existingCases\n );\n\n // Return the complete node\n return {\n uuid: originalNode.uuid,\n actions: [callLlmAction],\n router: router,\n exits: exits\n };\n },\n\n // Localization support for categories\n localizable: 'categories',\n toLocalizationFormData: categoriesToLocalizationFormData,\n fromLocalizationFormData: localizationFormDataToCategories\n};\n"]}
@@ -2,6 +2,7 @@ import { ACTION_GROUPS, FlowTypes } from '../types';
2
2
  import { generateUUID, createSuccessFailureRouter } from '../../utils';
3
3
  import { html } from 'lit';
4
4
  import { resultNameField, categoriesToLocalizationFormData, localizationFormDataToCategories } from './shared';
5
+ import { renderClamped } from '../utils';
5
6
  export const split_by_resthook = {
6
7
  type: 'split_by_resthook',
7
8
  name: 'Call Resthook',
@@ -38,14 +39,8 @@ export const split_by_resthook = {
38
39
  render: (node) => {
39
40
  var _a;
40
41
  const callResthookAction = (_a = node.actions) === null || _a === void 0 ? void 0 : _a.find((action) => action.type === 'call_resthook');
41
- return html `
42
- <div
43
- class="body"
44
- style="word-wrap: break-word; overflow-wrap: break-word; hyphens: auto;"
45
- >
46
- ${(callResthookAction === null || callResthookAction === void 0 ? void 0 : callResthookAction.resthook) || 'Configure resthook'}
47
- </div>
48
- `;
42
+ const resthook = (callResthookAction === null || callResthookAction === void 0 ? void 0 : callResthookAction.resthook) || 'Configure resthook';
43
+ return html ` <div class="body">${renderClamped(resthook, resthook)}</div> `;
49
44
  },
50
45
  toFormData: (node) => {
51
46
  var _a, _b;
@@ -1 +1 @@
1
- {"version":3,"file":"split_by_resthook.js","sourceRoot":"","sources":["../../../../src/flow/nodes/split_by_resthook.ts"],"names":[],"mappings":"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","sourcesContent":["import { ACTION_GROUPS, FormData, NodeConfig, FlowTypes } from '../types';\nimport { CallResthook, Node } from '../../store/flow-definition';\nimport { generateUUID, createSuccessFailureRouter } from '../../utils';\nimport { html } from 'lit';\nimport {\n resultNameField,\n categoriesToLocalizationFormData,\n localizationFormDataToCategories\n} from './shared';\n\nexport const split_by_resthook: NodeConfig = {\n type: 'split_by_resthook',\n name: 'Call Resthook',\n group: ACTION_GROUPS.services,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n showAsAction: true,\n form: {\n resthook: {\n type: 'select',\n label: 'Resthook',\n required: true,\n searchable: true,\n clearable: false,\n placeholder: 'Select a resthook...',\n endpoint: '/api/v2/resthooks.json',\n valueKey: 'resthook',\n nameKey: 'resthook',\n helpText: 'Select the resthook to call'\n },\n result_name: resultNameField\n },\n layout: ['resthook', 'result_name'],\n validate: (formData: FormData) => {\n const errors: { [key: string]: string } = {};\n\n // validate resthook is provided\n if (!formData.resthook || formData.resthook.length === 0) {\n errors.resthook = 'A resthook is required';\n }\n\n return {\n valid: Object.keys(errors).length === 0,\n errors\n };\n },\n render: (node: Node) => {\n const callResthookAction = node.actions?.find(\n (action) => action.type === 'call_resthook'\n ) as CallResthook;\n return html`\n <div\n class=\"body\"\n style=\"word-wrap: break-word; overflow-wrap: break-word; hyphens: auto;\"\n >\n ${callResthookAction?.resthook || 'Configure resthook'}\n </div>\n `;\n },\n toFormData: (node: Node) => {\n // extract data from the existing node structure\n const callResthookAction = node.actions?.find(\n (action) => action.type === 'call_resthook'\n ) as CallResthook;\n\n return {\n uuid: node.uuid,\n resthook: callResthookAction?.resthook\n ? [\n {\n resthook: callResthookAction.resthook\n }\n ]\n : [],\n result_name: node.router?.result_name || ''\n };\n },\n fromFormData: (formData: FormData, originalNode: Node): Node => {\n // get resthook selection\n const resthookSelection =\n Array.isArray(formData.resthook) && formData.resthook.length > 0\n ? formData.resthook[0]\n : null;\n\n if (!resthookSelection) {\n return originalNode;\n }\n\n // find existing call_resthook action to preserve its UUID\n const existingCallResthookAction = originalNode.actions?.find(\n (action) => action.type === 'call_resthook'\n );\n const callResthookUuid = existingCallResthookAction?.uuid || generateUUID();\n\n // create call_resthook action\n const callResthookAction: CallResthook = {\n type: 'call_resthook',\n uuid: callResthookUuid,\n resthook: resthookSelection.resthook\n };\n\n // create categories and exits for Success and Failure\n const existingCategories = originalNode.router?.categories || [];\n const existingExits = originalNode.exits || [];\n const existingCases = originalNode.router?.cases || [];\n\n const { router, exits } = createSuccessFailureRouter(\n '@webhook.json.status',\n {\n type: 'has_text',\n arguments: []\n },\n existingCategories,\n existingExits,\n existingCases\n );\n\n // Build final router with result_name\n const finalRouter: any = {\n ...router\n };\n\n // Only set result_name if provided\n if (formData.result_name && formData.result_name.trim() !== '') {\n finalRouter.result_name = formData.result_name.trim();\n }\n\n // return the complete node\n return {\n uuid: originalNode.uuid,\n actions: [callResthookAction],\n router: finalRouter,\n exits: exits\n };\n },\n\n // Localization support for categories\n localizable: 'categories',\n toLocalizationFormData: categoriesToLocalizationFormData,\n fromLocalizationFormData: localizationFormDataToCategories\n};\n"]}
1
+ {"version":3,"file":"split_by_resthook.js","sourceRoot":"","sources":["../../../../src/flow/nodes/split_by_resthook.ts"],"names":[],"mappings":"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","sourcesContent":["import { ACTION_GROUPS, FormData, NodeConfig, FlowTypes } from '../types';\nimport { CallResthook, Node } from '../../store/flow-definition';\nimport { generateUUID, createSuccessFailureRouter } from '../../utils';\nimport { html } from 'lit';\nimport {\n resultNameField,\n categoriesToLocalizationFormData,\n localizationFormDataToCategories\n} from './shared';\nimport { renderClamped } from '../utils';\n\nexport const split_by_resthook: NodeConfig = {\n type: 'split_by_resthook',\n name: 'Call Resthook',\n group: ACTION_GROUPS.services,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n showAsAction: true,\n form: {\n resthook: {\n type: 'select',\n label: 'Resthook',\n required: true,\n searchable: true,\n clearable: false,\n placeholder: 'Select a resthook...',\n endpoint: '/api/v2/resthooks.json',\n valueKey: 'resthook',\n nameKey: 'resthook',\n helpText: 'Select the resthook to call'\n },\n result_name: resultNameField\n },\n layout: ['resthook', 'result_name'],\n validate: (formData: FormData) => {\n const errors: { [key: string]: string } = {};\n\n // validate resthook is provided\n if (!formData.resthook || formData.resthook.length === 0) {\n errors.resthook = 'A resthook is required';\n }\n\n return {\n valid: Object.keys(errors).length === 0,\n errors\n };\n },\n render: (node: Node) => {\n const callResthookAction = node.actions?.find(\n (action) => action.type === 'call_resthook'\n ) as CallResthook;\n const resthook = callResthookAction?.resthook || 'Configure resthook';\n return html` <div class=\"body\">${renderClamped(resthook, resthook)}</div> `;\n },\n toFormData: (node: Node) => {\n // extract data from the existing node structure\n const callResthookAction = node.actions?.find(\n (action) => action.type === 'call_resthook'\n ) as CallResthook;\n\n return {\n uuid: node.uuid,\n resthook: callResthookAction?.resthook\n ? [\n {\n resthook: callResthookAction.resthook\n }\n ]\n : [],\n result_name: node.router?.result_name || ''\n };\n },\n fromFormData: (formData: FormData, originalNode: Node): Node => {\n // get resthook selection\n const resthookSelection =\n Array.isArray(formData.resthook) && formData.resthook.length > 0\n ? formData.resthook[0]\n : null;\n\n if (!resthookSelection) {\n return originalNode;\n }\n\n // find existing call_resthook action to preserve its UUID\n const existingCallResthookAction = originalNode.actions?.find(\n (action) => action.type === 'call_resthook'\n );\n const callResthookUuid = existingCallResthookAction?.uuid || generateUUID();\n\n // create call_resthook action\n const callResthookAction: CallResthook = {\n type: 'call_resthook',\n uuid: callResthookUuid,\n resthook: resthookSelection.resthook\n };\n\n // create categories and exits for Success and Failure\n const existingCategories = originalNode.router?.categories || [];\n const existingExits = originalNode.exits || [];\n const existingCases = originalNode.router?.cases || [];\n\n const { router, exits } = createSuccessFailureRouter(\n '@webhook.json.status',\n {\n type: 'has_text',\n arguments: []\n },\n existingCategories,\n existingExits,\n existingCases\n );\n\n // Build final router with result_name\n const finalRouter: any = {\n ...router\n };\n\n // Only set result_name if provided\n if (formData.result_name && formData.result_name.trim() !== '') {\n finalRouter.result_name = formData.result_name.trim();\n }\n\n // return the complete node\n return {\n uuid: originalNode.uuid,\n actions: [callResthookAction],\n router: finalRouter,\n exits: exits\n };\n },\n\n // Localization support for categories\n localizable: 'categories',\n toLocalizationFormData: categoriesToLocalizationFormData,\n fromLocalizationFormData: localizationFormDataToCategories\n};\n"]}
@@ -1,7 +1,7 @@
1
1
  import { ACTION_GROUPS, FlowTypes } from '../types';
2
2
  import { generateUUID } from '../../utils';
3
3
  import { html } from 'lit';
4
- import { renderNamedObjects } from '../utils';
4
+ import { renderFlowLinks } from '../utils';
5
5
  import { categoriesToLocalizationFormData, localizationFormDataToCategories } from './shared';
6
6
  export const split_by_subflow = {
7
7
  type: 'split_by_subflow',
@@ -26,7 +26,7 @@ export const split_by_subflow = {
26
26
  const enterFlowAction = (_a = node.actions) === null || _a === void 0 ? void 0 : _a.find((action) => action.type === 'enter_flow');
27
27
  return html `
28
28
  <div class="body">
29
- ${renderNamedObjects([enterFlowAction === null || enterFlowAction === void 0 ? void 0 : enterFlowAction.flow], 'flow')}
29
+ ${(enterFlowAction === null || enterFlowAction === void 0 ? void 0 : enterFlowAction.flow) ? renderFlowLinks([enterFlowAction.flow], 'flow') : null}
30
30
  </div>
31
31
  `;
32
32
  },
@@ -1 +1 @@
1
- {"version":3,"file":"split_by_subflow.js","sourceRoot":"","sources":["../../../../src/flow/nodes/split_by_subflow.ts"],"names":[],"mappings":"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","sourcesContent":["import { ACTION_GROUPS, FormData, NodeConfig, FlowTypes } from '../types';\nimport { Node } from '../../store/flow-definition';\nimport { generateUUID } from '../../utils';\nimport { html } from 'lit';\nimport { renderNamedObjects } from '../utils';\nimport {\n categoriesToLocalizationFormData,\n localizationFormDataToCategories\n} from './shared';\n\nexport const split_by_subflow: NodeConfig = {\n type: 'split_by_subflow',\n name: 'Enter a Flow',\n group: ACTION_GROUPS.trigger,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n showAsAction: true,\n form: {\n flow: {\n type: 'select',\n required: true,\n placeholder: 'Select a flow...',\n helpText:\n 'Once the subflow is complete or expires, the contact will return here',\n endpoint: '/api/v2/flows.json',\n valueKey: 'uuid',\n nameKey: 'name'\n }\n },\n layout: ['flow'],\n render: (node: Node) => {\n const enterFlowAction = node.actions?.find(\n (action) => action.type === 'enter_flow'\n ) as any;\n return html`\n <div class=\"body\">\n ${renderNamedObjects([enterFlowAction?.flow], 'flow')}\n </div>\n `;\n },\n toFormData: (node: Node) => {\n // Extract data from the existing node structure\n const enterFlowAction = node.actions?.find(\n (action) => action.type === 'enter_flow'\n ) as any;\n\n return {\n uuid: node.uuid,\n flow: enterFlowAction?.flow\n ? [{ uuid: enterFlowAction.flow.uuid, name: enterFlowAction.flow.name }]\n : []\n };\n },\n fromFormData: (formData: FormData, originalNode: Node): Node => {\n // Get flow selection\n const flowSelection =\n Array.isArray(formData.flow) && formData.flow.length > 0\n ? formData.flow[0]\n : null;\n\n // Find existing enter_flow action to preserve its UUID\n const existingEnterFlowAction = originalNode.actions?.find(\n (action) => action.type === 'enter_flow'\n );\n const enterFlowUuid = existingEnterFlowAction?.uuid || generateUUID();\n\n // Create enter_flow action\n const enterFlowAction: any = {\n type: 'enter_flow',\n uuid: enterFlowUuid,\n flow: flowSelection\n ? {\n uuid: flowSelection.uuid || flowSelection.value,\n name: flowSelection.name\n }\n : { uuid: '', name: '' }\n };\n\n // Create categories and exits for Complete and Expired\n const existingCategories = originalNode.router?.categories || [];\n const existingExits = originalNode.exits || [];\n const existingCases = originalNode.router?.cases || [];\n\n // Find existing Complete category\n const existingCompleteCategory = existingCategories.find(\n (cat) => cat.name === 'Complete'\n );\n const existingCompleteExit = existingCompleteCategory\n ? existingExits.find(\n (exit) => exit.uuid === existingCompleteCategory.exit_uuid\n )\n : null;\n const existingCompleteCase = existingCompleteCategory\n ? existingCases.find(\n (case_) => case_.category_uuid === existingCompleteCategory.uuid\n )\n : null;\n\n const completeCategoryUuid =\n existingCompleteCategory?.uuid || generateUUID();\n const completeExitUuid = existingCompleteExit?.uuid || generateUUID();\n const completeCaseUuid = existingCompleteCase?.uuid || generateUUID();\n\n // Find existing Expired category\n const existingExpiredCategory = existingCategories.find(\n (cat) => cat.name === 'Expired'\n );\n const existingExpiredExit = existingExpiredCategory\n ? existingExits.find(\n (exit) => exit.uuid === existingExpiredCategory.exit_uuid\n )\n : null;\n\n const expiredCategoryUuid = existingExpiredCategory?.uuid || generateUUID();\n const expiredExitUuid = existingExpiredExit?.uuid || generateUUID();\n\n const categories = [\n {\n uuid: completeCategoryUuid,\n name: 'Complete',\n exit_uuid: completeExitUuid\n },\n {\n uuid: expiredCategoryUuid,\n name: 'Expired',\n exit_uuid: expiredExitUuid\n }\n ];\n\n const exits = [\n {\n uuid: completeExitUuid,\n destination_uuid: existingCompleteExit?.destination_uuid || null\n },\n {\n uuid: expiredExitUuid,\n destination_uuid: existingExpiredExit?.destination_uuid || null\n }\n ];\n\n const cases = [\n {\n uuid: completeCaseUuid,\n type: 'has_only_text',\n arguments: ['completed'],\n category_uuid: completeCategoryUuid\n }\n ];\n\n // Create the router\n const router = {\n type: 'switch' as const,\n categories: categories,\n default_category_uuid: expiredCategoryUuid,\n operand: '@child.status',\n cases: cases\n };\n\n // Return the complete node\n return {\n uuid: originalNode.uuid,\n actions: [enterFlowAction],\n router: router,\n exits: exits\n };\n },\n\n // Localization support for categories\n localizable: 'categories',\n toLocalizationFormData: categoriesToLocalizationFormData,\n fromLocalizationFormData: localizationFormDataToCategories\n};\n"]}
1
+ {"version":3,"file":"split_by_subflow.js","sourceRoot":"","sources":["../../../../src/flow/nodes/split_by_subflow.ts"],"names":[],"mappings":"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","sourcesContent":["import { ACTION_GROUPS, FormData, NodeConfig, FlowTypes } from '../types';\nimport { Node } from '../../store/flow-definition';\nimport { generateUUID } from '../../utils';\nimport { html } from 'lit';\nimport { renderFlowLinks } from '../utils';\nimport {\n categoriesToLocalizationFormData,\n localizationFormDataToCategories\n} from './shared';\n\nexport const split_by_subflow: NodeConfig = {\n type: 'split_by_subflow',\n name: 'Enter a Flow',\n group: ACTION_GROUPS.trigger,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n showAsAction: true,\n form: {\n flow: {\n type: 'select',\n required: true,\n placeholder: 'Select a flow...',\n helpText:\n 'Once the subflow is complete or expires, the contact will return here',\n endpoint: '/api/v2/flows.json',\n valueKey: 'uuid',\n nameKey: 'name'\n }\n },\n layout: ['flow'],\n render: (node: Node) => {\n const enterFlowAction = node.actions?.find(\n (action) => action.type === 'enter_flow'\n ) as any;\n return html`\n <div class=\"body\">\n ${enterFlowAction?.flow ? renderFlowLinks([enterFlowAction.flow], 'flow') : null}\n </div>\n `;\n },\n toFormData: (node: Node) => {\n // Extract data from the existing node structure\n const enterFlowAction = node.actions?.find(\n (action) => action.type === 'enter_flow'\n ) as any;\n\n return {\n uuid: node.uuid,\n flow: enterFlowAction?.flow\n ? [{ uuid: enterFlowAction.flow.uuid, name: enterFlowAction.flow.name }]\n : []\n };\n },\n fromFormData: (formData: FormData, originalNode: Node): Node => {\n // Get flow selection\n const flowSelection =\n Array.isArray(formData.flow) && formData.flow.length > 0\n ? formData.flow[0]\n : null;\n\n // Find existing enter_flow action to preserve its UUID\n const existingEnterFlowAction = originalNode.actions?.find(\n (action) => action.type === 'enter_flow'\n );\n const enterFlowUuid = existingEnterFlowAction?.uuid || generateUUID();\n\n // Create enter_flow action\n const enterFlowAction: any = {\n type: 'enter_flow',\n uuid: enterFlowUuid,\n flow: flowSelection\n ? {\n uuid: flowSelection.uuid || flowSelection.value,\n name: flowSelection.name\n }\n : { uuid: '', name: '' }\n };\n\n // Create categories and exits for Complete and Expired\n const existingCategories = originalNode.router?.categories || [];\n const existingExits = originalNode.exits || [];\n const existingCases = originalNode.router?.cases || [];\n\n // Find existing Complete category\n const existingCompleteCategory = existingCategories.find(\n (cat) => cat.name === 'Complete'\n );\n const existingCompleteExit = existingCompleteCategory\n ? existingExits.find(\n (exit) => exit.uuid === existingCompleteCategory.exit_uuid\n )\n : null;\n const existingCompleteCase = existingCompleteCategory\n ? existingCases.find(\n (case_) => case_.category_uuid === existingCompleteCategory.uuid\n )\n : null;\n\n const completeCategoryUuid =\n existingCompleteCategory?.uuid || generateUUID();\n const completeExitUuid = existingCompleteExit?.uuid || generateUUID();\n const completeCaseUuid = existingCompleteCase?.uuid || generateUUID();\n\n // Find existing Expired category\n const existingExpiredCategory = existingCategories.find(\n (cat) => cat.name === 'Expired'\n );\n const existingExpiredExit = existingExpiredCategory\n ? existingExits.find(\n (exit) => exit.uuid === existingExpiredCategory.exit_uuid\n )\n : null;\n\n const expiredCategoryUuid = existingExpiredCategory?.uuid || generateUUID();\n const expiredExitUuid = existingExpiredExit?.uuid || generateUUID();\n\n const categories = [\n {\n uuid: completeCategoryUuid,\n name: 'Complete',\n exit_uuid: completeExitUuid\n },\n {\n uuid: expiredCategoryUuid,\n name: 'Expired',\n exit_uuid: expiredExitUuid\n }\n ];\n\n const exits = [\n {\n uuid: completeExitUuid,\n destination_uuid: existingCompleteExit?.destination_uuid || null\n },\n {\n uuid: expiredExitUuid,\n destination_uuid: existingExpiredExit?.destination_uuid || null\n }\n ];\n\n const cases = [\n {\n uuid: completeCaseUuid,\n type: 'has_only_text',\n arguments: ['completed'],\n category_uuid: completeCategoryUuid\n }\n ];\n\n // Create the router\n const router = {\n type: 'switch' as const,\n categories: categories,\n default_category_uuid: expiredCategoryUuid,\n operand: '@child.status',\n cases: cases\n };\n\n // Return the complete node\n return {\n uuid: originalNode.uuid,\n actions: [enterFlowAction],\n router: router,\n exits: exits\n };\n },\n\n // Localization support for categories\n localizable: 'categories',\n toLocalizationFormData: categoriesToLocalizationFormData,\n fromLocalizationFormData: localizationFormDataToCategories\n};\n"]}
@@ -2,6 +2,7 @@ import { ACTION_GROUPS, FlowTypes } from '../types';
2
2
  import { generateUUID, createSuccessFailureRouter } from '../../utils';
3
3
  import { html } from 'lit';
4
4
  import { categoriesToLocalizationFormData, localizationFormDataToCategories } from './shared';
5
+ import { renderClamped } from '../utils';
5
6
  const defaultPost = `@(json(object(
6
7
  "contact", object(
7
8
  "uuid", contact.uuid,
@@ -76,46 +77,37 @@ export const split_by_webhook = {
76
77
  }
77
78
  },
78
79
  layout: [
79
- // Row with method and URL side by side
80
80
  { type: 'row', items: ['method', 'url'] },
81
- // Advanced group with nested layouts
82
81
  {
83
- type: 'group',
84
- label: 'Headers',
85
- items: ['headers'],
86
- collapsible: true,
87
- collapsed: true,
88
- helpText: 'Configure authentication or custom headers',
89
- getGroupValueCount: (formData) => {
90
- var _a;
91
- return ((_a = formData.headers) === null || _a === void 0 ? void 0 : _a.length) || 0;
92
- }
93
- },
94
- {
95
- type: 'group',
96
- label: 'Body',
97
- items: ['body'],
98
- collapsible: true,
99
- collapsed: true,
100
- helpText: 'Configure the request payload',
101
- getGroupValueCount: (formData) => {
102
- return !!(formData.body &&
103
- formData.body.trim() !== '' &&
104
- formData.body !== defaultPost);
105
- }
82
+ type: 'accordion',
83
+ sections: [
84
+ {
85
+ label: 'Headers',
86
+ collapsed: true,
87
+ getValueCount: (formData) => {
88
+ var _a;
89
+ return ((_a = formData.headers) === null || _a === void 0 ? void 0 : _a.length) || 0;
90
+ },
91
+ items: ['headers']
92
+ },
93
+ {
94
+ label: 'Body',
95
+ collapsed: true,
96
+ getValueCount: (formData) => {
97
+ return !!(formData.body &&
98
+ formData.body.trim() !== '' &&
99
+ formData.body !== defaultPost);
100
+ },
101
+ items: ['body']
102
+ }
103
+ ]
106
104
  }
107
105
  ],
108
106
  render: (node) => {
109
107
  var _a;
110
108
  const callWebhookAction = (_a = node.actions) === null || _a === void 0 ? void 0 : _a.find((action) => action.type === 'call_webhook');
111
- return html `
112
- <div
113
- class="body"
114
- style="word-wrap: break-word; overflow-wrap: break-word; hyphens: auto;"
115
- >
116
- ${(callWebhookAction === null || callWebhookAction === void 0 ? void 0 : callWebhookAction.url) || 'Configure webhook'}
117
- </div>
118
- `;
109
+ const url = (callWebhookAction === null || callWebhookAction === void 0 ? void 0 : callWebhookAction.url) || 'Configure webhook';
110
+ return html ` <div class="body">${renderClamped(url, url)}</div> `;
119
111
  },
120
112
  toFormData: (node) => {
121
113
  var _a;
@@ -1 +1 @@
1
- {"version":3,"file":"split_by_webhook.js","sourceRoot":"","sources":["../../../../src/flow/nodes/split_by_webhook.ts"],"names":[],"mappings":"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","sourcesContent":["import { ACTION_GROUPS, FormData, NodeConfig, FlowTypes } from '../types';\nimport { CallWebhook, Node } from '../../store/flow-definition';\nimport { generateUUID, createSuccessFailureRouter } from '../../utils';\nimport { html } from 'lit';\nimport {\n categoriesToLocalizationFormData,\n localizationFormDataToCategories\n} from './shared';\n\nconst defaultPost = `@(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)))`;\n\nexport const split_by_webhook: NodeConfig = {\n type: 'split_by_webhook',\n name: 'Call Webhook',\n group: ACTION_GROUPS.services,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n showAsAction: true,\n form: {\n method: {\n type: 'select',\n required: true,\n options: ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'PATCH'],\n maxWidth: '120px',\n searchable: false\n },\n url: {\n type: 'text',\n required: true,\n evaluated: true,\n placeholder: 'https://example.com/webhook'\n },\n headers: {\n type: 'key-value',\n sortable: true,\n keyPlaceholder: 'Header name',\n valuePlaceholder: 'Header value',\n minRows: 0\n },\n body: {\n type: 'textarea',\n evaluated: true,\n placeholder: 'Request body content (JSON, XML, etc.)',\n minHeight: 200,\n dependsOn: ['method'],\n computeValue: (\n values: Record<string, any>,\n currentValue: any,\n originalValues?: Record<string, any>\n ) => {\n // Check if method is POST (handle both string and select object formats)\n const method =\n Array.isArray(values.method) && values.method.length > 0\n ? values.method[0].value || values.method[0].name\n : values.method;\n\n if (method === 'POST') {\n // For POST, provide the template if body is empty or was never set by user\n if (!currentValue || currentValue.trim() === '') {\n return defaultPost;\n }\n } else {\n // For non-POST methods, clear the body if it was auto-generated or empty\n // Check if the original body was empty (user never specified a body)\n const originalBody = originalValues?.body || '';\n const isOriginallyEmpty = !originalBody || originalBody.trim() === '';\n\n // Clear if: originally empty, contains default template, or is currently empty\n if (\n isOriginallyEmpty ||\n !currentValue ||\n currentValue.trim() === '' ||\n currentValue.trim() === defaultPost.trim()\n ) {\n return '';\n }\n }\n\n return currentValue; // Keep existing value if user has customized it\n }\n }\n },\n layout: [\n // Row with method and URL side by side\n { type: 'row', items: ['method', 'url'] },\n // Advanced group with nested layouts\n {\n type: 'group',\n label: 'Headers',\n items: ['headers'],\n collapsible: true,\n collapsed: true,\n helpText: 'Configure authentication or custom headers',\n getGroupValueCount: (formData: FormData) => {\n return formData.headers?.length || 0;\n }\n },\n {\n type: 'group',\n label: 'Body',\n items: ['body'],\n collapsible: true,\n collapsed: true,\n helpText: 'Configure the request payload',\n getGroupValueCount: (formData: FormData) => {\n return !!(\n formData.body &&\n formData.body.trim() !== '' &&\n formData.body !== defaultPost\n );\n }\n }\n ],\n render: (node: Node) => {\n const callWebhookAction = node.actions?.find(\n (action) => action.type === 'call_webhook'\n ) as CallWebhook;\n return html`\n <div\n class=\"body\"\n style=\"word-wrap: break-word; overflow-wrap: break-word; hyphens: auto;\"\n >\n ${callWebhookAction?.url || 'Configure webhook'}\n </div>\n `;\n },\n toFormData: (node: Node) => {\n // Extract data from the existing node structure\n const callWebhookAction = node.actions?.find(\n (action) => action.type === 'call_webhook'\n ) as any;\n\n return {\n uuid: node.uuid,\n method: callWebhookAction?.method || 'GET',\n url: callWebhookAction?.url || '',\n headers: callWebhookAction?.headers || [],\n body: callWebhookAction?.body || ''\n };\n },\n fromFormData: (formData: FormData, originalNode: Node): Node => {\n // Get method selection\n const methodSelection =\n Array.isArray(formData.method) && formData.method.length > 0\n ? formData.method[0]\n : { value: 'GET', name: 'GET' };\n\n // Find existing call_webhook action to preserve its UUID\n const existingCallWebhookAction = originalNode.actions?.find(\n (action) => action.type === 'call_webhook'\n );\n const callWebhookUuid = existingCallWebhookAction?.uuid || generateUUID();\n\n // Create call_webhook action\n const callWebhookAction: CallWebhook = {\n type: 'call_webhook',\n uuid: callWebhookUuid,\n method: methodSelection.value,\n url: formData.url || '',\n headers: formData.headers || [],\n body: formData.body || ''\n };\n\n // Create categories and exits for Success and Failure\n const existingCategories = originalNode.router?.categories || [];\n const existingExits = originalNode.exits || [];\n const existingCases = originalNode.router?.cases || [];\n\n const { router, exits } = createSuccessFailureRouter(\n '@webhook.status',\n {\n type: 'has_number_between',\n arguments: ['200', '299']\n },\n existingCategories,\n existingExits,\n existingCases\n );\n\n // Return the complete node\n return {\n uuid: originalNode.uuid,\n actions: [callWebhookAction],\n router: router,\n exits: exits\n };\n },\n\n // Localization support for categories\n localizable: 'categories',\n toLocalizationFormData: categoriesToLocalizationFormData,\n fromLocalizationFormData: localizationFormDataToCategories\n};\n"]}
1
+ {"version":3,"file":"split_by_webhook.js","sourceRoot":"","sources":["../../../../src/flow/nodes/split_by_webhook.ts"],"names":[],"mappings":"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","sourcesContent":["import { ACTION_GROUPS, FormData, NodeConfig, FlowTypes } from '../types';\nimport { CallWebhook, Node } from '../../store/flow-definition';\nimport { generateUUID, createSuccessFailureRouter } from '../../utils';\nimport { html } from 'lit';\nimport {\n categoriesToLocalizationFormData,\n localizationFormDataToCategories\n} from './shared';\nimport { renderClamped } from '../utils';\n\nconst defaultPost = `@(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)))`;\n\nexport const split_by_webhook: NodeConfig = {\n type: 'split_by_webhook',\n name: 'Call Webhook',\n group: ACTION_GROUPS.services,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n showAsAction: true,\n form: {\n method: {\n type: 'select',\n required: true,\n options: ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'PATCH'],\n maxWidth: '120px',\n searchable: false\n },\n url: {\n type: 'text',\n required: true,\n evaluated: true,\n placeholder: 'https://example.com/webhook'\n },\n headers: {\n type: 'key-value',\n sortable: true,\n keyPlaceholder: 'Header name',\n valuePlaceholder: 'Header value',\n minRows: 0\n },\n body: {\n type: 'textarea',\n evaluated: true,\n placeholder: 'Request body content (JSON, XML, etc.)',\n minHeight: 200,\n dependsOn: ['method'],\n computeValue: (\n values: Record<string, any>,\n currentValue: any,\n originalValues?: Record<string, any>\n ) => {\n // Check if method is POST (handle both string and select object formats)\n const method =\n Array.isArray(values.method) && values.method.length > 0\n ? values.method[0].value || values.method[0].name\n : values.method;\n\n if (method === 'POST') {\n // For POST, provide the template if body is empty or was never set by user\n if (!currentValue || currentValue.trim() === '') {\n return defaultPost;\n }\n } else {\n // For non-POST methods, clear the body if it was auto-generated or empty\n // Check if the original body was empty (user never specified a body)\n const originalBody = originalValues?.body || '';\n const isOriginallyEmpty = !originalBody || originalBody.trim() === '';\n\n // Clear if: originally empty, contains default template, or is currently empty\n if (\n isOriginallyEmpty ||\n !currentValue ||\n currentValue.trim() === '' ||\n currentValue.trim() === defaultPost.trim()\n ) {\n return '';\n }\n }\n\n return currentValue; // Keep existing value if user has customized it\n }\n }\n },\n layout: [\n { type: 'row', items: ['method', 'url'] },\n {\n type: 'accordion',\n sections: [\n {\n label: 'Headers',\n collapsed: true,\n getValueCount: (formData: FormData) => {\n return formData.headers?.length || 0;\n },\n items: ['headers']\n },\n {\n label: 'Body',\n collapsed: true,\n getValueCount: (formData: FormData) => {\n return !!(\n formData.body &&\n formData.body.trim() !== '' &&\n formData.body !== defaultPost\n );\n },\n items: ['body']\n }\n ]\n }\n ],\n render: (node: Node) => {\n const callWebhookAction = node.actions?.find(\n (action) => action.type === 'call_webhook'\n ) as CallWebhook;\n const url = callWebhookAction?.url || 'Configure webhook';\n return html` <div class=\"body\">${renderClamped(url, url)}</div> `;\n },\n toFormData: (node: Node) => {\n // Extract data from the existing node structure\n const callWebhookAction = node.actions?.find(\n (action) => action.type === 'call_webhook'\n ) as any;\n\n return {\n uuid: node.uuid,\n method: callWebhookAction?.method || 'GET',\n url: callWebhookAction?.url || '',\n headers: callWebhookAction?.headers || [],\n body: callWebhookAction?.body || ''\n };\n },\n fromFormData: (formData: FormData, originalNode: Node): Node => {\n // Get method selection\n const methodSelection =\n Array.isArray(formData.method) && formData.method.length > 0\n ? formData.method[0]\n : { value: 'GET', name: 'GET' };\n\n // Find existing call_webhook action to preserve its UUID\n const existingCallWebhookAction = originalNode.actions?.find(\n (action) => action.type === 'call_webhook'\n );\n const callWebhookUuid = existingCallWebhookAction?.uuid || generateUUID();\n\n // Create call_webhook action\n const callWebhookAction: CallWebhook = {\n type: 'call_webhook',\n uuid: callWebhookUuid,\n method: methodSelection.value,\n url: formData.url || '',\n headers: formData.headers || [],\n body: formData.body || ''\n };\n\n // Create categories and exits for Success and Failure\n const existingCategories = originalNode.router?.categories || [];\n const existingExits = originalNode.exits || [];\n const existingCases = originalNode.router?.cases || [];\n\n const { router, exits } = createSuccessFailureRouter(\n '@webhook.status',\n {\n type: 'has_number_between',\n arguments: ['200', '299']\n },\n existingCategories,\n existingExits,\n existingCases\n );\n\n // Return the complete node\n return {\n uuid: originalNode.uuid,\n actions: [callWebhookAction],\n router: router,\n exits: exits\n };\n },\n\n // Localization support for categories\n localizable: 'categories',\n toLocalizationFormData: categoriesToLocalizationFormData,\n fromLocalizationFormData: localizationFormDataToCategories\n};\n"]}
@@ -46,6 +46,7 @@ export const wait_for_response = {
46
46
  name: 'Wait for Response',
47
47
  group: SPLIT_GROUPS.wait,
48
48
  flowTypes: [FlowTypes.MESSAGE],
49
+ hideFromSplits: true,
49
50
  dialogSize: 'large',
50
51
  form: {
51
52
  rules: createRulesArrayConfig(operatorsToSelectOptions(getWaitForResponseOperators()), 'If the message from the contact...'),