@nyaruka/temba-components 0.139.0 → 0.141.0
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.
- package/.github/workflows/cla.yml +1 -1
- package/.github/workflows/copilot-setup-steps.yml +6 -1
- package/.lintstagedrc.js +10 -0
- package/CHANGELOG.md +32 -0
- package/demo/data/flows/sample-flow.json +24 -0
- package/dist/locales/es.js +5 -5
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/fr.js +5 -5
- package/dist/locales/fr.js.map +1 -1
- package/dist/locales/locale-codes.js +11 -2
- package/dist/locales/locale-codes.js.map +1 -1
- package/dist/locales/pt.js +5 -5
- package/dist/locales/pt.js.map +1 -1
- package/dist/temba-components.js +702 -338
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/display/Chat.js +10 -7
- package/out-tsc/src/display/Chat.js.map +1 -1
- package/out-tsc/src/display/Dropdown.js +3 -1
- package/out-tsc/src/display/Dropdown.js.map +1 -1
- package/out-tsc/src/display/FloatingTab.js +4 -4
- package/out-tsc/src/display/FloatingTab.js.map +1 -1
- package/out-tsc/src/display/Thumbnail.js +163 -5
- package/out-tsc/src/display/Thumbnail.js.map +1 -1
- package/out-tsc/src/flow/CanvasNode.js +65 -23
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +369 -49
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/NodeEditor.js +118 -10
- package/out-tsc/src/flow/NodeEditor.js.map +1 -1
- package/out-tsc/src/flow/Plumber.js +61 -14
- package/out-tsc/src/flow/Plumber.js.map +1 -1
- package/out-tsc/src/flow/StickyNote.js +13 -4
- package/out-tsc/src/flow/StickyNote.js.map +1 -1
- package/out-tsc/src/flow/actions/add_contact_groups.js +4 -1
- package/out-tsc/src/flow/actions/add_contact_groups.js.map +1 -1
- package/out-tsc/src/flow/actions/add_input_labels.js +4 -1
- package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -1
- package/out-tsc/src/flow/actions/audio-player.js +112 -0
- package/out-tsc/src/flow/actions/audio-player.js.map +1 -0
- package/out-tsc/src/flow/actions/enter_flow.js +43 -0
- package/out-tsc/src/flow/actions/enter_flow.js.map +1 -0
- package/out-tsc/src/flow/actions/play_audio.js +57 -4
- package/out-tsc/src/flow/actions/play_audio.js.map +1 -1
- package/out-tsc/src/flow/actions/remove_contact_groups.js +6 -1
- package/out-tsc/src/flow/actions/remove_contact_groups.js.map +1 -1
- package/out-tsc/src/flow/actions/say_msg.js +86 -3
- package/out-tsc/src/flow/actions/say_msg.js.map +1 -1
- package/out-tsc/src/flow/actions/send_broadcast.js +6 -2
- package/out-tsc/src/flow/actions/send_broadcast.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_channel.js +13 -0
- package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_status.js +7 -5
- package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -1
- package/out-tsc/src/flow/actions/start_session.js +10 -3
- package/out-tsc/src/flow/actions/start_session.js.map +1 -1
- package/out-tsc/src/flow/config.js +11 -3
- package/out-tsc/src/flow/config.js.map +1 -1
- package/out-tsc/src/flow/nodes/shared-rules.js +1 -1
- package/out-tsc/src/flow/nodes/shared-rules.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_contact_field.js +18 -5
- package/out-tsc/src/flow/nodes/split_by_contact_field.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_expression.js +1 -1
- package/out-tsc/src/flow/nodes/split_by_expression.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +0 -1
- package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_random.js +0 -1
- package/out-tsc/src/flow/nodes/split_by_random.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_run_result.js +10 -4
- package/out-tsc/src/flow/nodes/split_by_run_result.js.map +1 -1
- package/out-tsc/src/flow/nodes/terminal.js +7 -0
- package/out-tsc/src/flow/nodes/terminal.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_audio.js +77 -0
- package/out-tsc/src/flow/nodes/wait_for_audio.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_dial.js +151 -0
- package/out-tsc/src/flow/nodes/wait_for_dial.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_digits.js +61 -1
- package/out-tsc/src/flow/nodes/wait_for_digits.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_menu.js +173 -2
- package/out-tsc/src/flow/nodes/wait_for_menu.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_response.js +1 -1
- package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
- package/out-tsc/src/flow/operators.js +21 -5
- package/out-tsc/src/flow/operators.js.map +1 -1
- package/out-tsc/src/flow/types.js.map +1 -1
- package/out-tsc/src/flow/utils.js +79 -3
- package/out-tsc/src/flow/utils.js.map +1 -1
- package/out-tsc/src/form/ArrayEditor.js +4 -2
- package/out-tsc/src/form/ArrayEditor.js.map +1 -1
- package/out-tsc/src/form/FieldRenderer.js +56 -0
- package/out-tsc/src/form/FieldRenderer.js.map +1 -1
- package/out-tsc/src/interfaces.js +1 -0
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/layout/Dialog.js +51 -7
- package/out-tsc/src/layout/Dialog.js.map +1 -1
- package/out-tsc/src/layout/Modax.js +20 -2
- package/out-tsc/src/layout/Modax.js.map +1 -1
- package/out-tsc/src/list/ContentMenu.js +14 -1
- package/out-tsc/src/list/ContentMenu.js.map +1 -1
- package/out-tsc/src/locales/es.js +5 -5
- package/out-tsc/src/locales/es.js.map +1 -1
- package/out-tsc/src/locales/fr.js +5 -5
- package/out-tsc/src/locales/fr.js.map +1 -1
- package/out-tsc/src/locales/locale-codes.js +11 -2
- package/out-tsc/src/locales/locale-codes.js.map +1 -1
- package/out-tsc/src/locales/pt.js +5 -5
- package/out-tsc/src/locales/pt.js.map +1 -1
- package/out-tsc/src/simulator/Simulator.js +21 -4
- package/out-tsc/src/simulator/Simulator.js.map +1 -1
- package/out-tsc/src/store/AppState.js +102 -3
- package/out-tsc/src/store/AppState.js.map +1 -1
- package/out-tsc/test/actions/add_contact_groups.test.js +35 -0
- package/out-tsc/test/actions/add_contact_groups.test.js.map +1 -1
- package/out-tsc/test/actions/add_input_labels.test.js +53 -0
- package/out-tsc/test/actions/add_input_labels.test.js.map +1 -0
- package/out-tsc/test/actions/enter_flow.test.js +71 -0
- package/out-tsc/test/actions/enter_flow.test.js.map +1 -0
- package/out-tsc/test/actions/play_audio.test.js +118 -0
- package/out-tsc/test/actions/play_audio.test.js.map +1 -0
- package/out-tsc/test/actions/remove_contact_groups.test.js +24 -0
- package/out-tsc/test/actions/remove_contact_groups.test.js.map +1 -1
- package/out-tsc/test/actions/say_msg.test.js +158 -0
- package/out-tsc/test/actions/say_msg.test.js.map +1 -0
- package/out-tsc/test/actions/send_broadcast.test.js +41 -0
- package/out-tsc/test/actions/send_broadcast.test.js.map +1 -1
- package/out-tsc/test/actions/set_contact_channel.test.js +67 -0
- package/out-tsc/test/actions/set_contact_channel.test.js.map +1 -0
- package/out-tsc/test/actions/set_contact_field.test.js +52 -0
- package/out-tsc/test/actions/set_contact_field.test.js.map +1 -0
- package/out-tsc/test/actions/set_contact_language.test.js +39 -0
- package/out-tsc/test/actions/set_contact_language.test.js.map +1 -0
- package/out-tsc/test/actions/set_contact_name.test.js +28 -0
- package/out-tsc/test/actions/set_contact_name.test.js.map +1 -0
- package/out-tsc/test/actions/set_contact_status.test.js +44 -0
- package/out-tsc/test/actions/set_contact_status.test.js.map +1 -0
- package/out-tsc/test/actions/set_run_result.test.js +47 -0
- package/out-tsc/test/actions/set_run_result.test.js.map +1 -0
- package/out-tsc/test/actions/start_session.test.js +76 -0
- package/out-tsc/test/actions/start_session.test.js.map +1 -1
- package/out-tsc/test/nodes/split_by_contact_field.test.js +50 -0
- package/out-tsc/test/nodes/split_by_contact_field.test.js.map +1 -1
- package/out-tsc/test/nodes/split_by_run_result.test.js +82 -0
- package/out-tsc/test/nodes/split_by_run_result.test.js.map +1 -1
- package/out-tsc/test/nodes/split_by_ticket.test.js +139 -0
- package/out-tsc/test/nodes/split_by_ticket.test.js.map +1 -0
- package/out-tsc/test/nodes/split_by_webhook.test.js +111 -0
- package/out-tsc/test/nodes/split_by_webhook.test.js.map +1 -0
- package/out-tsc/test/nodes/wait_for_audio.test.js +156 -0
- package/out-tsc/test/nodes/wait_for_audio.test.js.map +1 -0
- package/out-tsc/test/nodes/wait_for_dial.test.js +336 -0
- package/out-tsc/test/nodes/wait_for_dial.test.js.map +1 -0
- package/out-tsc/test/nodes/wait_for_digits.test.js +198 -84
- package/out-tsc/test/nodes/wait_for_digits.test.js.map +1 -1
- package/out-tsc/test/nodes/wait_for_menu.test.js +340 -0
- package/out-tsc/test/nodes/wait_for_menu.test.js.map +1 -0
- package/out-tsc/test/temba-flow-collision.test.js +261 -6
- package/out-tsc/test/temba-flow-collision.test.js.map +1 -1
- package/out-tsc/test/temba-flow-editor.test.js +187 -0
- package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
- package/out-tsc/test/temba-flow-plumber.test.js +19 -0
- package/out-tsc/test/temba-flow-plumber.test.js.map +1 -1
- package/out-tsc/test/temba-node-type-selector.test.js +6 -6
- package/out-tsc/test/temba-node-type-selector.test.js.map +1 -1
- package/out-tsc/test/temba-select.test.js +4 -1
- package/out-tsc/test/temba-select.test.js.map +1 -1
- package/out-tsc/test/utils.test.js +4 -2
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +3 -9
- package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/expression-facebook.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/expression-phone.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/facebook-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/instagram-handle.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/line-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/phone-number.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/telegram-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/viber-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/wechat-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/whatsapp.png +0 -0
- package/screenshots/truth/actions/add_input_labels/editor/multiple-labels.png +0 -0
- package/screenshots/truth/actions/add_input_labels/editor/single-label.png +0 -0
- package/screenshots/truth/actions/add_input_labels/render/multiple-labels.png +0 -0
- package/screenshots/truth/actions/add_input_labels/render/single-label.png +0 -0
- package/screenshots/truth/actions/enter_flow/editor/basic-flow.png +0 -0
- package/screenshots/truth/actions/enter_flow/editor/long-flow-name.png +0 -0
- package/screenshots/truth/actions/enter_flow/render/basic-flow.png +0 -0
- package/screenshots/truth/actions/enter_flow/render/long-flow-name.png +0 -0
- package/screenshots/truth/actions/play_audio/editor/expression-url.png +0 -0
- package/screenshots/truth/actions/play_audio/editor/static-url.png +0 -0
- package/screenshots/truth/actions/play_audio/render/expression-url.png +0 -0
- package/screenshots/truth/actions/play_audio/render/static-url.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
- package/screenshots/truth/actions/say_msg/editor/multiline-text.png +0 -0
- package/screenshots/truth/actions/say_msg/editor/simple-text.png +0 -0
- package/screenshots/truth/actions/say_msg/editor/text-with-audio-url.png +0 -0
- package/screenshots/truth/actions/say_msg/render/multiline-text.png +0 -0
- package/screenshots/truth/actions/say_msg/render/simple-text.png +0 -0
- package/screenshots/truth/actions/say_msg/render/text-with-audio-url.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/contacts-only.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/groups-and-contacts.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/groups-only.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/many-groups.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/multiline-text.png +0 -0
- package/screenshots/truth/actions/send_email/render/complex-business-email.png +0 -0
- package/screenshots/truth/actions/send_email/render/empty-body.png +0 -0
- package/screenshots/truth/actions/send_email/render/empty-subject.png +0 -0
- package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
- package/screenshots/truth/actions/send_email/render/multiline-body.png +0 -0
- package/screenshots/truth/actions/send_email/render/multiple-recipients.png +0 -0
- package/screenshots/truth/actions/send_email/render/simple-email.png +0 -0
- package/screenshots/truth/actions/send_email/render/with-expressions.png +0 -0
- package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/simple-text.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-with-linebreaks.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-without-quick-replies.png +0 -0
- package/screenshots/truth/actions/set_contact_channel/editor/sms-channel.png +0 -0
- package/screenshots/truth/actions/set_contact_channel/editor/whatsapp-channel.png +0 -0
- package/screenshots/truth/actions/set_contact_channel/render/sms-channel.png +0 -0
- package/screenshots/truth/actions/set_contact_channel/render/whatsapp-channel.png +0 -0
- package/screenshots/truth/actions/set_contact_field/editor/clear-value.png +0 -0
- package/screenshots/truth/actions/set_contact_field/editor/set-value.png +0 -0
- package/screenshots/truth/actions/set_contact_field/render/clear-value.png +0 -0
- package/screenshots/truth/actions/set_contact_field/render/set-value.png +0 -0
- package/screenshots/truth/actions/set_contact_language/editor/english.png +0 -0
- package/screenshots/truth/actions/set_contact_language/editor/french.png +0 -0
- package/screenshots/truth/actions/set_contact_language/render/english.png +0 -0
- package/screenshots/truth/actions/set_contact_language/render/french.png +0 -0
- package/screenshots/truth/actions/set_contact_name/editor/expression-name.png +0 -0
- package/screenshots/truth/actions/set_contact_name/editor/static-name.png +0 -0
- package/screenshots/truth/actions/set_contact_name/render/expression-name.png +0 -0
- package/screenshots/truth/actions/set_contact_name/render/static-name.png +0 -0
- package/screenshots/truth/actions/set_contact_status/editor/active.png +0 -0
- package/screenshots/truth/actions/set_contact_status/editor/archived.png +0 -0
- package/screenshots/truth/actions/set_contact_status/editor/blocked.png +0 -0
- package/screenshots/truth/actions/set_contact_status/render/active.png +0 -0
- package/screenshots/truth/actions/set_contact_status/render/archived.png +0 -0
- package/screenshots/truth/actions/set_contact_status/render/blocked.png +0 -0
- package/screenshots/truth/actions/set_run_result/editor/expression-value.png +0 -0
- package/screenshots/truth/actions/set_run_result/editor/with-category.png +0 -0
- package/screenshots/truth/actions/set_run_result/render/expression-value.png +0 -0
- package/screenshots/truth/actions/set_run_result/render/with-category.png +0 -0
- package/screenshots/truth/actions/start_session/render/contact-query.png +0 -0
- package/screenshots/truth/actions/start_session/render/contacts-only.png +0 -0
- package/screenshots/truth/actions/start_session/render/create-contact.png +0 -0
- package/screenshots/truth/actions/start_session/render/groups-and-contacts.png +0 -0
- package/screenshots/truth/actions/start_session/render/groups-only.png +0 -0
- package/screenshots/truth/actions/start_session/render/many-recipients.png +0 -0
- package/screenshots/truth/editor/router.png +0 -0
- package/screenshots/truth/editor/wait.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/information-extraction.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/sentiment-analysis.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/summarization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/translation-task.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/basic-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/custom-input-and-result-name.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/many-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/minimal-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/basic-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/minimal-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_random/editor/ab-test-multiple-variants.png +0 -0
- package/screenshots/truth/nodes/split_by_random/editor/sampling-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/editor/three-way-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/editor/two-bucket-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/ab-test-multiple-variants.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.png +0 -0
- package/screenshots/truth/nodes/wait_for_audio/editor/basic-audio-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_audio/render/basic-audio-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_dial/editor/basic-dial.png +0 -0
- package/screenshots/truth/nodes/wait_for_dial/editor/dial-with-limits.png +0 -0
- package/screenshots/truth/nodes/wait_for_dial/render/basic-dial.png +0 -0
- package/screenshots/truth/nodes/wait_for_dial/render/dial-with-limits.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/basic-digits-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/digits-with-rules.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/digits-with-rules.png +0 -0
- package/screenshots/truth/nodes/wait_for_menu/editor/menu-with-digits.png +0 -0
- package/screenshots/truth/nodes/wait_for_menu/render/menu-with-digits.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/basic-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/custom-result-name.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/no-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/short-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
- package/src/display/Chat.ts +13 -7
- package/src/display/Dropdown.ts +3 -1
- package/src/display/FloatingTab.ts +4 -4
- package/src/display/Thumbnail.ts +162 -2
- package/src/flow/CanvasNode.ts +70 -24
- package/src/flow/Editor.ts +440 -99
- package/src/flow/NodeEditor.ts +137 -9
- package/src/flow/Plumber.ts +89 -14
- package/src/flow/StickyNote.ts +14 -4
- package/src/flow/actions/add_contact_groups.ts +4 -1
- package/src/flow/actions/add_input_labels.ts +4 -1
- package/src/flow/actions/audio-player.ts +127 -0
- package/src/flow/actions/enter_flow.ts +44 -0
- package/src/flow/actions/play_audio.ts +64 -5
- package/src/flow/actions/remove_contact_groups.ts +6 -1
- package/src/flow/actions/say_msg.ts +94 -4
- package/src/flow/actions/send_broadcast.ts +6 -2
- package/src/flow/actions/set_contact_channel.ts +13 -1
- package/src/flow/actions/set_contact_status.ts +7 -5
- package/src/flow/actions/start_session.ts +10 -3
- package/src/flow/config.ts +11 -3
- package/src/flow/nodes/shared-rules.ts +1 -1
- package/src/flow/nodes/split_by_contact_field.ts +16 -5
- package/src/flow/nodes/split_by_expression.ts +1 -1
- package/src/flow/nodes/split_by_llm_categorize.ts +0 -1
- package/src/flow/nodes/split_by_random.ts +0 -1
- package/src/flow/nodes/split_by_run_result.ts +10 -4
- package/src/flow/nodes/terminal.ts +9 -0
- package/src/flow/nodes/wait_for_audio.ts +88 -0
- package/src/flow/nodes/wait_for_dial.ts +176 -0
- package/src/flow/nodes/wait_for_digits.ts +87 -2
- package/src/flow/nodes/wait_for_menu.ts +209 -3
- package/src/flow/nodes/wait_for_response.ts +1 -1
- package/src/flow/operators.ts +23 -5
- package/src/flow/types.ts +23 -1
- package/src/flow/utils.ts +82 -3
- package/src/form/ArrayEditor.ts +4 -2
- package/src/form/FieldRenderer.ts +71 -1
- package/src/interfaces.ts +2 -1
- package/src/layout/Dialog.ts +52 -7
- package/src/layout/Modax.ts +19 -2
- package/src/list/ContentMenu.ts +15 -1
- package/src/locales/es.ts +18 -13
- package/src/locales/fr.ts +18 -13
- package/src/locales/locale-codes.ts +11 -2
- package/src/locales/pt.ts +18 -13
- package/src/simulator/Simulator.ts +25 -4
- package/src/store/AppState.ts +120 -1
- package/src/store/flow-definition.d.ts +2 -0
- package/test/actions/add_contact_groups.test.ts +38 -0
- package/test/actions/add_input_labels.test.ts +67 -0
- package/test/actions/enter_flow.test.ts +88 -0
- package/test/actions/play_audio.test.ts +155 -0
- package/test/actions/remove_contact_groups.test.ts +29 -0
- package/test/actions/say_msg.test.ts +196 -0
- package/test/actions/send_broadcast.test.ts +44 -0
- package/test/actions/set_contact_channel.test.ts +88 -0
- package/test/actions/set_contact_field.test.ts +68 -0
- package/test/actions/set_contact_language.test.ts +55 -0
- package/test/actions/set_contact_name.test.ts +39 -0
- package/test/actions/set_contact_status.test.ts +64 -0
- package/test/actions/set_run_result.test.ts +61 -0
- package/test/actions/start_session.test.ts +82 -0
- package/test/nodes/split_by_contact_field.test.ts +59 -0
- package/test/nodes/split_by_run_result.test.ts +100 -0
- package/test/nodes/split_by_ticket.test.ts +157 -0
- package/test/nodes/split_by_webhook.test.ts +131 -0
- package/test/nodes/wait_for_audio.test.ts +182 -0
- package/test/nodes/wait_for_dial.test.ts +382 -0
- package/test/nodes/wait_for_digits.test.ts +233 -109
- package/test/nodes/wait_for_menu.test.ts +383 -0
- package/test/temba-flow-collision.test.ts +286 -6
- package/test/temba-flow-editor.test.ts +240 -0
- package/test/temba-flow-plumber.test.ts +62 -0
- package/test/temba-node-type-selector.test.ts +6 -6
- package/test/temba-select.test.ts +6 -1
- package/test/utils.test.ts +4 -2
- package/screenshots/truth/nodes/wait_for_digits/editor/phone-number-collection.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/single-digit-with-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/verification-code.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/phone-number-collection.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/single-digit-with-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/verification-code.png +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"split_by_random.js","sourceRoot":"","sources":["../../../../src/flow/nodes/split_by_random.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAwB,SAAS,EAAE,MAAM,UAAU,CAAC;AAEzE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,gCAAgC,EAChC,gCAAgC,EACjC,MAAM,UAAU,CAAC;AAElB,4DAA4D;AAC5D,MAAM,kBAAkB,GAAG,CACzB,cAAwB,EACxB,qBAAiC,EAAE,EACnC,gBAAwB,EAAE,EAC1B,EAAE;IACF,MAAM,UAAU,GAAe,EAAE,CAAC;IAClC,MAAM,KAAK,GAAW,EAAE,CAAC;IAEzB,uDAAuD;IACvD,cAAc,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE;QACtC,wCAAwC;QACxC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,IAAI,CAC9C,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,YAAY,CACnC,CAAC;QACF,MAAM,YAAY,GAAG,gBAAgB;YACnC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,gBAAgB,CAAC,SAAS,CAAC;YACxE,CAAC,CAAC,IAAI,CAAC;QAET,MAAM,QAAQ,GAAG,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,IAAI,KAAI,YAAY,EAAE,CAAC;QACtD,MAAM,YAAY,GAAG,CAAA,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,CAAE,IAAI,KAAI,YAAY,EAAE,CAAC;QAE9D,UAAU,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,YAAY;YAClB,SAAS,EAAE,QAAQ;SACpB,CAAC,CAAC;QAEH,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,QAAQ;YACd,gBAAgB,EAAE,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,gBAAgB,KAAI,IAAI;SACzD,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,MAAM,EAAE;YACN,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE,UAAU;SACvB;QACD,KAAK,EAAE,KAAK;KACb,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAe;IACzC,IAAI,EAAE,iBAAiB;IACvB,IAAI,EAAE,cAAc;IACpB,KAAK,EAAE,YAAY,CAAC,KAAK;IACzB,SAAS,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC;IACrE,IAAI,EAAE;QACJ,UAAU,EAAE;YACV,IAAI,EAAE,OAAO;YACb,
|
|
1
|
+
{"version":3,"file":"split_by_random.js","sourceRoot":"","sources":["../../../../src/flow/nodes/split_by_random.ts"],"names":[],"mappings":"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","sourcesContent":["import { SPLIT_GROUPS, FormData, NodeConfig, FlowTypes } from '../types';\nimport { Node, Category, Exit } from '../../store/flow-definition.d';\nimport { generateUUID } from '../../utils';\nimport {\n categoriesToLocalizationFormData,\n localizationFormDataToCategories\n} from './shared';\n\n// Helper function to create a random router with categories\nconst createRandomRouter = (\n userCategories: string[],\n existingCategories: Category[] = [],\n existingExits: Exit[] = []\n) => {\n const categories: Category[] = [];\n const exits: Exit[] = [];\n\n // Create categories and exits for user-defined buckets\n userCategories.forEach((categoryName) => {\n // Try to find existing category by name\n const existingCategory = existingCategories.find(\n (cat) => cat.name === categoryName\n );\n const existingExit = existingCategory\n ? existingExits.find((exit) => exit.uuid === existingCategory.exit_uuid)\n : null;\n\n const exitUuid = existingExit?.uuid || generateUUID();\n const categoryUuid = existingCategory?.uuid || generateUUID();\n\n categories.push({\n uuid: categoryUuid,\n name: categoryName,\n exit_uuid: exitUuid\n });\n\n exits.push({\n uuid: exitUuid,\n destination_uuid: existingExit?.destination_uuid || null\n });\n });\n\n return {\n router: {\n type: 'random' as const,\n categories: categories\n },\n exits: exits\n };\n};\n\nexport const split_by_random: NodeConfig = {\n type: 'split_by_random',\n name: 'Random Split',\n group: SPLIT_GROUPS.split,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n form: {\n categories: {\n type: 'array',\n helpText: 'Define the buckets to randomly split contacts into',\n required: true,\n itemLabel: 'Bucket',\n sortable: true,\n minItems: 2,\n maxItems: 10,\n isEmptyItem: (item: any) => {\n return !item.name || item.name.trim() === '';\n },\n itemConfig: {\n name: {\n type: 'text',\n placeholder: 'Bucket name',\n required: true\n }\n }\n }\n },\n layout: ['categories'],\n validate: (formData: FormData) => {\n const errors: { [key: string]: string } = {};\n\n // Check for duplicate category names\n if (formData.categories && Array.isArray(formData.categories)) {\n const categories = formData.categories.filter(\n (item: any) => item?.name && item.name.trim() !== ''\n );\n\n // Ensure minimum buckets\n if (categories.length < 2) {\n errors.categories = 'At least 2 buckets are required for random split';\n }\n\n // Find all categories that have duplicates (case-insensitive)\n const duplicateCategories = [];\n const lowerCaseMap = new Map();\n\n // First pass: map lowercase names to all original cases\n categories.forEach((category) => {\n const lowerName = category.name.trim().toLowerCase();\n if (!lowerCaseMap.has(lowerName)) {\n lowerCaseMap.set(lowerName, []);\n }\n lowerCaseMap.get(lowerName).push(category.name.trim());\n });\n\n // Second pass: collect all names that appear more than once\n lowerCaseMap.forEach((originalNames) => {\n if (originalNames.length > 1) {\n duplicateCategories.push(...originalNames);\n }\n });\n\n if (duplicateCategories.length > 0) {\n const uniqueDuplicates = [...new Set(duplicateCategories)];\n errors.categories = `Duplicate bucket names found: ${uniqueDuplicates.join(\n ', '\n )}`;\n }\n }\n\n return {\n valid: Object.keys(errors).length === 0,\n errors\n };\n },\n toFormData: (node: Node) => {\n // Extract categories from the existing node structure\n const categories =\n node.router?.categories?.map((cat) => ({ name: cat.name })) || [];\n\n return {\n uuid: node.uuid,\n categories: categories\n };\n },\n fromFormData: (formData: FormData, originalNode: Node): Node => {\n // Get user categories\n const userCategories = (formData.categories || [])\n .filter((item: any) => item?.name?.trim())\n .map((item: any) => item.name.trim());\n\n // Create router and exits using existing data when possible\n const existingCategories = originalNode.router?.categories || [];\n const existingExits = originalNode.exits || [];\n\n const { router, exits } = createRandomRouter(\n userCategories,\n existingCategories,\n existingExits\n );\n\n // Return the complete node\n return {\n uuid: originalNode.uuid,\n actions: originalNode.actions || [],\n router: router,\n exits: exits\n };\n },\n router: {\n type: 'random'\n },\n\n // Localization support for categories\n localizable: 'categories',\n toLocalizationFormData: categoriesToLocalizationFormData,\n fromLocalizationFormData: localizationFormDataToCategories\n};\n"]}
|
|
@@ -87,7 +87,7 @@ export const split_by_run_result = {
|
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
},
|
|
90
|
-
rules: createRulesArrayConfig(operatorsToSelectOptions(getWaitForResponseOperators()), '
|
|
90
|
+
rules: createRulesArrayConfig(operatorsToSelectOptions(getWaitForResponseOperators()), ''),
|
|
91
91
|
result_name: resultNameField
|
|
92
92
|
},
|
|
93
93
|
layout: [
|
|
@@ -114,7 +114,12 @@ export const split_by_run_result = {
|
|
|
114
114
|
toFormData: (node, nodeUI) => {
|
|
115
115
|
var _a, _b, _c;
|
|
116
116
|
// Get the result from the UI config operand (source of truth)
|
|
117
|
-
|
|
117
|
+
// Normalize: toUIConfig saves { id, name, type } but the Select component
|
|
118
|
+
// (valueKey: 'value') and fromFormData expect a 'value' property.
|
|
119
|
+
const savedOperand = (_a = nodeUI === null || nodeUI === void 0 ? void 0 : nodeUI.config) === null || _a === void 0 ? void 0 : _a.operand;
|
|
120
|
+
const result = savedOperand
|
|
121
|
+
? { ...savedOperand, value: savedOperand.value || savedOperand.id }
|
|
122
|
+
: null;
|
|
118
123
|
// Extract rules from router cases using shared function
|
|
119
124
|
const rules = casesToFormRules(node);
|
|
120
125
|
// Extract delimiter configuration by checking the actual operand string
|
|
@@ -150,17 +155,18 @@ export const split_by_run_result = {
|
|
|
150
155
|
}
|
|
151
156
|
// Build operand based on whether delimiter is selected
|
|
152
157
|
let operand;
|
|
158
|
+
const resultKey = selectedResult.value || selectedResult.id;
|
|
153
159
|
const delimitBy = (_c = (_b = formData.delimit_by) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.value;
|
|
154
160
|
const hasDelimiter = delimitBy !== undefined && delimitBy !== '';
|
|
155
161
|
if (hasDelimiter) {
|
|
156
162
|
// Get delimiter configuration
|
|
157
163
|
const delimitIndex = (_f = (_e = (_d = formData.delimit_index) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.value) !== null && _f !== void 0 ? _f : '0';
|
|
158
164
|
// Build operand with field() function
|
|
159
|
-
operand = `@(field(results.${
|
|
165
|
+
operand = `@(field(results.${resultKey}, ${delimitIndex}, "${delimitBy}"))`;
|
|
160
166
|
}
|
|
161
167
|
else {
|
|
162
168
|
// Standard operand without delimiter
|
|
163
|
-
operand = `@results.${
|
|
169
|
+
operand = `@results.${resultKey}`;
|
|
164
170
|
}
|
|
165
171
|
// Get user rules using shared extraction function
|
|
166
172
|
const userRules = extractUserRules(formData);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"split_by_run_result.js","sourceRoot":"","sources":["../../../../src/flow/nodes/split_by_run_result.ts"],"names":[],"mappings":"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","sourcesContent":["import { SPLIT_GROUPS, FormData, NodeConfig, FlowTypes } from '../types';\nimport { Node } from '../../store/flow-definition';\nimport { createRulesRouter } from '../../utils';\nimport {\n getWaitForResponseOperators,\n operatorsToSelectOptions,\n getOperatorConfig\n} from '../operators';\nimport {\n resultNameField,\n categoriesToLocalizationFormData,\n localizationFormDataToCategories\n} from './shared';\nimport {\n createRulesArrayConfig,\n extractUserRules,\n casesToFormRules\n} from './shared-rules';\nimport { getStore } from '../../store/Store';\n\n// delimit index options (first through 20th)\nconst DELIMIT_INDEX_OPTIONS = [\n { value: '0', name: 'first result' },\n { value: '1', name: 'second result' },\n { value: '2', name: 'third result' },\n { value: '3', name: 'fourth result' },\n { value: '4', name: 'fifth result' },\n { value: '5', name: 'sixth result' },\n { value: '6', name: 'seventh result' },\n { value: '7', name: 'eighth result' },\n { value: '8', name: 'ninth result' },\n { value: '9', name: 'tenth result' },\n { value: '10', name: '11th result' },\n { value: '11', name: '12th result' },\n { value: '12', name: '13th result' },\n { value: '13', name: '14th result' },\n { value: '14', name: '15th result' },\n { value: '15', name: '16th result' },\n { value: '16', name: '17th result' },\n { value: '17', name: '18th result' },\n { value: '18', name: '19th result' },\n { value: '19', name: '20th result' }\n];\n\n// delimit by options - includes \"don't delimit\" and delimiter characters\nconst DELIMIT_BY_OPTIONS = [\n { value: '', name: \"Don't delimit result\" },\n { value: ' ', name: 'Delimited by spaces' },\n { value: '.', name: 'Delimited by periods' },\n { value: '+', name: 'Delimited by plusses' }\n];\n\nexport const split_by_run_result: NodeConfig = {\n type: 'split_by_run_result',\n name: 'Split by Result',\n aliases: ['split_by_run_result_delimited'], // backwards compatibility with old flow editor\n group: SPLIT_GROUPS.split,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n dialogSize: 'large',\n form: {\n result: {\n type: 'select',\n\n required: true,\n searchable: false,\n clearable: false,\n placeholder: 'Select a result...',\n getDynamicOptions: () => {\n const store = getStore();\n return store\n ? store\n .getState()\n .getFlowResults()\n .map((r) => ({ value: r.key, name: r.name }))\n : [];\n },\n valueKey: 'value',\n nameKey: 'name'\n },\n delimit_by: {\n type: 'select',\n required: false,\n searchable: false,\n clearable: false,\n options: DELIMIT_BY_OPTIONS,\n valueKey: 'value',\n nameKey: 'name',\n maxWidth: '180px'\n },\n delimit_index: {\n type: 'select',\n required: false,\n searchable: false,\n clearable: false,\n options: DELIMIT_INDEX_OPTIONS,\n valueKey: 'value',\n nameKey: 'name',\n maxWidth: '140px',\n conditions: {\n visible: (formData: FormData) => {\n const delimitBy = formData.delimit_by?.[0]?.value;\n return delimitBy !== undefined && delimitBy !== '';\n }\n }\n },\n rules: createRulesArrayConfig(\n operatorsToSelectOptions(getWaitForResponseOperators()),\n 'Define rules to categorize the result'\n ),\n result_name: resultNameField\n },\n layout: [\n {\n type: 'row',\n label: 'Flow Result',\n helpText:\n 'Select a flow result and optionally delimit it to split on a specific part',\n items: ['result', 'delimit_by', 'delimit_index']\n },\n 'rules',\n 'result_name'\n ],\n validate: (formData: FormData) => {\n const errors: { [key: string]: string } = {};\n\n // Validate result is provided\n if (!formData.result || formData.result.length === 0) {\n errors.result = 'A flow result is required';\n }\n\n return {\n valid: Object.keys(errors).length === 0,\n errors\n };\n },\n toFormData: (node: Node, nodeUI?: any) => {\n // Get the result from the UI config operand (source of truth)\n const result = nodeUI?.config?.operand;\n\n // Extract rules from router cases using shared function\n const rules = casesToFormRules(node);\n\n // Extract delimiter configuration by checking the actual operand string\n // If operand contains field() function, we have a delimiter\n const operand = node.router?.operand || '';\n const fieldFunctionMatch = operand.match(\n /field\\(results\\.[\\w]+,\\s*(\\d+),\\s*\"(.+?)\"\\)/\n );\n\n const hasDelimiter = fieldFunctionMatch !== null;\n const delimitIndex = hasDelimiter\n ? parseInt(fieldFunctionMatch![1], 10)\n : 0;\n const delimiter = hasDelimiter ? fieldFunctionMatch![2] : '';\n\n return {\n uuid: node.uuid,\n result: result ? [result] : [],\n delimit_by: hasDelimiter\n ? [DELIMIT_BY_OPTIONS.find((opt) => opt.value === delimiter)]\n : [DELIMIT_BY_OPTIONS[0]],\n delimit_index: hasDelimiter\n ? [\n DELIMIT_INDEX_OPTIONS.find(\n (opt) => opt.value === String(delimitIndex)\n )\n ]\n : [DELIMIT_INDEX_OPTIONS[0]],\n rules: rules,\n result_name: node.router?.result_name || ''\n };\n },\n fromFormData: (formData: FormData, originalNode: Node): Node => {\n // Get selected result (it's an array from the select component)\n const selectedResult = formData.result?.[0];\n\n if (!selectedResult) {\n return originalNode;\n }\n\n // Build operand based on whether delimiter is selected\n let operand: string;\n const delimitBy = formData.delimit_by?.[0]?.value;\n const hasDelimiter = delimitBy !== undefined && delimitBy !== '';\n\n if (hasDelimiter) {\n // Get delimiter configuration\n const delimitIndex = formData.delimit_index?.[0]?.value ?? '0';\n\n // Build operand with field() function\n operand = `@(field(results.${selectedResult.value}, ${delimitIndex}, \"${delimitBy}\"))`;\n } else {\n // Standard operand without delimiter\n operand = `@results.${selectedResult.value}`;\n }\n\n // Get user rules using shared extraction function\n const userRules = extractUserRules(formData);\n\n // Get existing router data for preservation\n const existingCategories = originalNode.router?.categories || [];\n const existingExits = originalNode.exits || [];\n const existingCases = originalNode.router?.cases || [];\n\n // Create router and exits using existing data when possible\n const { router, exits } = createRulesRouter(\n operand,\n userRules,\n getOperatorConfig,\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 {\n ...originalNode,\n router: finalRouter,\n exits: exits\n };\n },\n toUIConfig: (formData: FormData) => {\n // Get selected result (it's an array from the select component)\n const selectedResult = formData.result?.[0];\n\n if (!selectedResult) {\n return {};\n }\n\n // Build UI config with operand information\n const config: any = {\n operand: {\n id: selectedResult.value,\n name: selectedResult.name,\n type: 'result'\n }\n };\n\n // Add delimiter configuration if selected\n const delimitBy = formData.delimit_by?.[0]?.value;\n const hasDelimiter = delimitBy !== undefined && delimitBy !== '';\n\n if (hasDelimiter) {\n config.index = parseInt(formData.delimit_index?.[0]?.value ?? '0', 10);\n config.delimiter = delimitBy;\n }\n\n // Set the type based on whether delimiter is configured\n // Use split_by_run_result_delimited for backward compatibility with old editor\n config.type = hasDelimiter\n ? 'split_by_run_result_delimited'\n : 'split_by_run_result';\n\n return config;\n },\n\n // Localization support for categories\n localizable: 'categories',\n toLocalizationFormData: categoriesToLocalizationFormData,\n fromLocalizationFormData: localizationFormDataToCategories\n};\n"]}
|
|
1
|
+
{"version":3,"file":"split_by_run_result.js","sourceRoot":"","sources":["../../../../src/flow/nodes/split_by_run_result.ts"],"names":[],"mappings":"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","sourcesContent":["import { SPLIT_GROUPS, FormData, NodeConfig, FlowTypes } from '../types';\nimport { Node } from '../../store/flow-definition';\nimport { createRulesRouter } from '../../utils';\nimport {\n getWaitForResponseOperators,\n operatorsToSelectOptions,\n getOperatorConfig\n} from '../operators';\nimport {\n resultNameField,\n categoriesToLocalizationFormData,\n localizationFormDataToCategories\n} from './shared';\nimport {\n createRulesArrayConfig,\n extractUserRules,\n casesToFormRules\n} from './shared-rules';\nimport { getStore } from '../../store/Store';\n\n// delimit index options (first through 20th)\nconst DELIMIT_INDEX_OPTIONS = [\n { value: '0', name: 'first result' },\n { value: '1', name: 'second result' },\n { value: '2', name: 'third result' },\n { value: '3', name: 'fourth result' },\n { value: '4', name: 'fifth result' },\n { value: '5', name: 'sixth result' },\n { value: '6', name: 'seventh result' },\n { value: '7', name: 'eighth result' },\n { value: '8', name: 'ninth result' },\n { value: '9', name: 'tenth result' },\n { value: '10', name: '11th result' },\n { value: '11', name: '12th result' },\n { value: '12', name: '13th result' },\n { value: '13', name: '14th result' },\n { value: '14', name: '15th result' },\n { value: '15', name: '16th result' },\n { value: '16', name: '17th result' },\n { value: '17', name: '18th result' },\n { value: '18', name: '19th result' },\n { value: '19', name: '20th result' }\n];\n\n// delimit by options - includes \"don't delimit\" and delimiter characters\nconst DELIMIT_BY_OPTIONS = [\n { value: '', name: \"Don't delimit result\" },\n { value: ' ', name: 'Delimited by spaces' },\n { value: '.', name: 'Delimited by periods' },\n { value: '+', name: 'Delimited by plusses' }\n];\n\nexport const split_by_run_result: NodeConfig = {\n type: 'split_by_run_result',\n name: 'Split by Result',\n aliases: ['split_by_run_result_delimited'], // backwards compatibility with old flow editor\n group: SPLIT_GROUPS.split,\n flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],\n dialogSize: 'large',\n form: {\n result: {\n type: 'select',\n\n required: true,\n searchable: false,\n clearable: false,\n placeholder: 'Select a result...',\n getDynamicOptions: () => {\n const store = getStore();\n return store\n ? store\n .getState()\n .getFlowResults()\n .map((r) => ({ value: r.key, name: r.name }))\n : [];\n },\n valueKey: 'value',\n nameKey: 'name'\n },\n delimit_by: {\n type: 'select',\n required: false,\n searchable: false,\n clearable: false,\n options: DELIMIT_BY_OPTIONS,\n valueKey: 'value',\n nameKey: 'name',\n maxWidth: '180px'\n },\n delimit_index: {\n type: 'select',\n required: false,\n searchable: false,\n clearable: false,\n options: DELIMIT_INDEX_OPTIONS,\n valueKey: 'value',\n nameKey: 'name',\n maxWidth: '140px',\n conditions: {\n visible: (formData: FormData) => {\n const delimitBy = formData.delimit_by?.[0]?.value;\n return delimitBy !== undefined && delimitBy !== '';\n }\n }\n },\n rules: createRulesArrayConfig(\n operatorsToSelectOptions(getWaitForResponseOperators()),\n ''\n ),\n result_name: resultNameField\n },\n layout: [\n {\n type: 'row',\n label: 'Flow Result',\n helpText:\n 'Select a flow result and optionally delimit it to split on a specific part',\n items: ['result', 'delimit_by', 'delimit_index']\n },\n 'rules',\n 'result_name'\n ],\n validate: (formData: FormData) => {\n const errors: { [key: string]: string } = {};\n\n // Validate result is provided\n if (!formData.result || formData.result.length === 0) {\n errors.result = 'A flow result is required';\n }\n\n return {\n valid: Object.keys(errors).length === 0,\n errors\n };\n },\n toFormData: (node: Node, nodeUI?: any) => {\n // Get the result from the UI config operand (source of truth)\n // Normalize: toUIConfig saves { id, name, type } but the Select component\n // (valueKey: 'value') and fromFormData expect a 'value' property.\n const savedOperand = nodeUI?.config?.operand;\n const result = savedOperand\n ? { ...savedOperand, value: savedOperand.value || savedOperand.id }\n : null;\n\n // Extract rules from router cases using shared function\n const rules = casesToFormRules(node);\n\n // Extract delimiter configuration by checking the actual operand string\n // If operand contains field() function, we have a delimiter\n const operand = node.router?.operand || '';\n const fieldFunctionMatch = operand.match(\n /field\\(results\\.[\\w]+,\\s*(\\d+),\\s*\"(.+?)\"\\)/\n );\n\n const hasDelimiter = fieldFunctionMatch !== null;\n const delimitIndex = hasDelimiter\n ? parseInt(fieldFunctionMatch![1], 10)\n : 0;\n const delimiter = hasDelimiter ? fieldFunctionMatch![2] : '';\n\n return {\n uuid: node.uuid,\n result: result ? [result] : [],\n delimit_by: hasDelimiter\n ? [DELIMIT_BY_OPTIONS.find((opt) => opt.value === delimiter)]\n : [DELIMIT_BY_OPTIONS[0]],\n delimit_index: hasDelimiter\n ? [\n DELIMIT_INDEX_OPTIONS.find(\n (opt) => opt.value === String(delimitIndex)\n )\n ]\n : [DELIMIT_INDEX_OPTIONS[0]],\n rules: rules,\n result_name: node.router?.result_name || ''\n };\n },\n fromFormData: (formData: FormData, originalNode: Node): Node => {\n // Get selected result (it's an array from the select component)\n const selectedResult = formData.result?.[0];\n\n if (!selectedResult) {\n return originalNode;\n }\n\n // Build operand based on whether delimiter is selected\n let operand: string;\n const resultKey = selectedResult.value || selectedResult.id;\n const delimitBy = formData.delimit_by?.[0]?.value;\n const hasDelimiter = delimitBy !== undefined && delimitBy !== '';\n\n if (hasDelimiter) {\n // Get delimiter configuration\n const delimitIndex = formData.delimit_index?.[0]?.value ?? '0';\n\n // Build operand with field() function\n operand = `@(field(results.${resultKey}, ${delimitIndex}, \"${delimitBy}\"))`;\n } else {\n // Standard operand without delimiter\n operand = `@results.${resultKey}`;\n }\n\n // Get user rules using shared extraction function\n const userRules = extractUserRules(formData);\n\n // Get existing router data for preservation\n const existingCategories = originalNode.router?.categories || [];\n const existingExits = originalNode.exits || [];\n const existingCases = originalNode.router?.cases || [];\n\n // Create router and exits using existing data when possible\n const { router, exits } = createRulesRouter(\n operand,\n userRules,\n getOperatorConfig,\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 {\n ...originalNode,\n router: finalRouter,\n exits: exits\n };\n },\n toUIConfig: (formData: FormData) => {\n // Get selected result (it's an array from the select component)\n const selectedResult = formData.result?.[0];\n\n if (!selectedResult) {\n return {};\n }\n\n // Build UI config with operand information\n const config: any = {\n operand: {\n id: selectedResult.value,\n name: selectedResult.name,\n type: 'result'\n }\n };\n\n // Add delimiter configuration if selected\n const delimitBy = formData.delimit_by?.[0]?.value;\n const hasDelimiter = delimitBy !== undefined && delimitBy !== '';\n\n if (hasDelimiter) {\n config.index = parseInt(formData.delimit_index?.[0]?.value ?? '0', 10);\n config.delimiter = delimitBy;\n }\n\n // Set the type based on whether delimiter is configured\n // Use split_by_run_result_delimited for backward compatibility with old editor\n config.type = hasDelimiter\n ? 'split_by_run_result_delimited'\n : 'split_by_run_result';\n\n return config;\n },\n\n // Localization support for categories\n localizable: 'categories',\n toLocalizationFormData: categoriesToLocalizationFormData,\n fromLocalizationFormData: localizationFormDataToCategories\n};\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Temporary: Legacy support for terminal nodes (nodes with a terminal action
|
|
2
|
+
// like enter_flow with terminal: true). This node type and its reclassification
|
|
3
|
+
// logic in AppState.ts can be removed once we stop supporting terminal nodes.
|
|
4
|
+
export const terminal = {
|
|
5
|
+
type: 'terminal'
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=terminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../../../src/flow/nodes/terminal.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,gFAAgF;AAChF,8EAA8E;AAI9E,MAAM,CAAC,MAAM,QAAQ,GAAe;IAClC,IAAI,EAAE,UAAU;CACjB,CAAC","sourcesContent":["// Temporary: Legacy support for terminal nodes (nodes with a terminal action\n// like enter_flow with terminal: true). This node type and its reclassification\n// logic in AppState.ts can be removed once we stop supporting terminal nodes.\n\nimport { NodeConfig } from '../types';\n\nexport const terminal: NodeConfig = {\n type: 'terminal'\n};\n"]}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { SPLIT_GROUPS, FlowTypes } from '../types';
|
|
2
|
+
import { generateUUID } from '../../utils';
|
|
3
|
+
import { categoriesToLocalizationFormData, localizationFormDataToCategories } from './shared';
|
|
4
|
+
export const wait_for_audio = {
|
|
5
|
+
type: 'wait_for_audio',
|
|
6
|
+
name: 'Make Recording',
|
|
7
|
+
group: SPLIT_GROUPS.wait,
|
|
8
|
+
flowTypes: [FlowTypes.VOICE],
|
|
9
|
+
form: {
|
|
10
|
+
result_name: {
|
|
11
|
+
type: 'text',
|
|
12
|
+
label: 'Result Name',
|
|
13
|
+
required: false,
|
|
14
|
+
placeholder: '(optional)',
|
|
15
|
+
helpText: 'The name to use to reference this result in the flow'
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
layout: ['result_name'],
|
|
19
|
+
toFormData: (node) => {
|
|
20
|
+
var _a;
|
|
21
|
+
return {
|
|
22
|
+
uuid: node.uuid,
|
|
23
|
+
result_name: ((_a = node.router) === null || _a === void 0 ? void 0 : _a.result_name) || ''
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
fromFormData: (formData, originalNode) => {
|
|
27
|
+
var _a;
|
|
28
|
+
// Preserve or create "All Responses" category
|
|
29
|
+
const existingCategories = ((_a = originalNode.router) === null || _a === void 0 ? void 0 : _a.categories) || [];
|
|
30
|
+
const existingExits = originalNode.exits || [];
|
|
31
|
+
let allResponsesCategory = existingCategories.find((cat) => cat.name === 'All Responses');
|
|
32
|
+
let allResponsesExit;
|
|
33
|
+
if (allResponsesCategory) {
|
|
34
|
+
allResponsesExit = existingExits.find((exit) => exit.uuid === allResponsesCategory.exit_uuid) || {
|
|
35
|
+
uuid: allResponsesCategory.exit_uuid,
|
|
36
|
+
destination_uuid: null
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
const exitUuid = generateUUID();
|
|
41
|
+
allResponsesCategory = {
|
|
42
|
+
uuid: generateUUID(),
|
|
43
|
+
name: 'All Responses',
|
|
44
|
+
exit_uuid: exitUuid
|
|
45
|
+
};
|
|
46
|
+
allResponsesExit = {
|
|
47
|
+
uuid: exitUuid,
|
|
48
|
+
destination_uuid: null
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const router = {
|
|
52
|
+
type: 'switch',
|
|
53
|
+
operand: '@input',
|
|
54
|
+
default_category_uuid: allResponsesCategory.uuid,
|
|
55
|
+
cases: [],
|
|
56
|
+
categories: [allResponsesCategory],
|
|
57
|
+
wait: {
|
|
58
|
+
type: 'msg',
|
|
59
|
+
hint: {
|
|
60
|
+
type: 'audio'
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
if (formData.result_name && formData.result_name.trim() !== '') {
|
|
65
|
+
router.result_name = formData.result_name.trim();
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
...originalNode,
|
|
69
|
+
router,
|
|
70
|
+
exits: [allResponsesExit]
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
localizable: 'categories',
|
|
74
|
+
toLocalizationFormData: categoriesToLocalizationFormData,
|
|
75
|
+
fromLocalizationFormData: localizationFormDataToCategories
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=wait_for_audio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait_for_audio.js","sourceRoot":"","sources":["../../../../src/flow/nodes/wait_for_audio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAwB,SAAS,EAAE,MAAM,UAAU,CAAC;AAEzE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,gCAAgC,EAChC,gCAAgC,EACjC,MAAM,UAAU,CAAC;AAElB,MAAM,CAAC,MAAM,cAAc,GAAe;IACxC,IAAI,EAAE,gBAAgB;IACtB,IAAI,EAAE,gBAAgB;IACtB,KAAK,EAAE,YAAY,CAAC,IAAI;IACxB,SAAS,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC;IAC5B,IAAI,EAAE;QACJ,WAAW,EAAE;YACX,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,aAAa;YACpB,QAAQ,EAAE,KAAK;YACf,WAAW,EAAE,YAAY;YACzB,QAAQ,EAAE,sDAAsD;SACjE;KACF;IACD,MAAM,EAAE,CAAC,aAAa,CAAC;IACvB,UAAU,EAAE,CAAC,IAAU,EAAE,EAAE;;QACzB,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,CAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,WAAW,KAAI,EAAE;SAC5C,CAAC;IACJ,CAAC;IACD,YAAY,EAAE,CAAC,QAAkB,EAAE,YAAkB,EAAQ,EAAE;;QAC7D,8CAA8C;QAC9C,MAAM,kBAAkB,GAAG,CAAA,MAAA,YAAY,CAAC,MAAM,0CAAE,UAAU,KAAI,EAAE,CAAC;QACjE,MAAM,aAAa,GAAG,YAAY,CAAC,KAAK,IAAI,EAAE,CAAC;QAE/C,IAAI,oBAAoB,GAAG,kBAAkB,CAAC,IAAI,CAChD,CAAC,GAAa,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,eAAe,CAChD,CAAC;QAEF,IAAI,gBAAsB,CAAC;QAE3B,IAAI,oBAAoB,EAAE,CAAC;YACzB,gBAAgB,GAAG,aAAa,CAAC,IAAI,CACnC,CAAC,IAAU,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,oBAAqB,CAAC,SAAS,CAC9D,IAAI;gBACH,IAAI,EAAE,oBAAoB,CAAC,SAAS;gBACpC,gBAAgB,EAAE,IAAI;aACvB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;YAChC,oBAAoB,GAAG;gBACrB,IAAI,EAAE,YAAY,EAAE;gBACpB,IAAI,EAAE,eAAe;gBACrB,SAAS,EAAE,QAAQ;aACpB,CAAC;YACF,gBAAgB,GAAG;gBACjB,IAAI,EAAE,QAAQ;gBACd,gBAAgB,EAAE,IAAI;aACvB,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAQ;YAClB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,QAAQ;YACjB,qBAAqB,EAAE,oBAAoB,CAAC,IAAI;YAChD,KAAK,EAAE,EAAE;YACT,UAAU,EAAE,CAAC,oBAAoB,CAAC;YAClC,IAAI,EAAE;gBACJ,IAAI,EAAE,KAAK;gBACX,IAAI,EAAE;oBACJ,IAAI,EAAE,OAAO;iBACd;aACF;SACF,CAAC;QAEF,IAAI,QAAQ,CAAC,WAAW,IAAI,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC/D,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QACnD,CAAC;QAED,OAAO;YACL,GAAG,YAAY;YACf,MAAM;YACN,KAAK,EAAE,CAAC,gBAAgB,CAAC;SAC1B,CAAC;IACJ,CAAC;IACD,WAAW,EAAE,YAAY;IACzB,sBAAsB,EAAE,gCAAgC;IACxD,wBAAwB,EAAE,gCAAgC;CAC3D,CAAC","sourcesContent":["import { SPLIT_GROUPS, FormData, NodeConfig, FlowTypes } from '../types';\nimport { Node, Category, Exit } from '../../store/flow-definition';\nimport { generateUUID } from '../../utils';\nimport {\n categoriesToLocalizationFormData,\n localizationFormDataToCategories\n} from './shared';\n\nexport const wait_for_audio: NodeConfig = {\n type: 'wait_for_audio',\n name: 'Make Recording',\n group: SPLIT_GROUPS.wait,\n flowTypes: [FlowTypes.VOICE],\n form: {\n result_name: {\n type: 'text',\n label: 'Result Name',\n required: false,\n placeholder: '(optional)',\n helpText: 'The name to use to reference this result in the flow'\n }\n },\n layout: ['result_name'],\n toFormData: (node: Node) => {\n return {\n uuid: node.uuid,\n result_name: node.router?.result_name || ''\n };\n },\n fromFormData: (formData: FormData, originalNode: Node): Node => {\n // Preserve or create \"All Responses\" category\n const existingCategories = originalNode.router?.categories || [];\n const existingExits = originalNode.exits || [];\n\n let allResponsesCategory = existingCategories.find(\n (cat: Category) => cat.name === 'All Responses'\n );\n\n let allResponsesExit: Exit;\n\n if (allResponsesCategory) {\n allResponsesExit = existingExits.find(\n (exit: Exit) => exit.uuid === allResponsesCategory!.exit_uuid\n ) || {\n uuid: allResponsesCategory.exit_uuid,\n destination_uuid: null\n };\n } else {\n const exitUuid = generateUUID();\n allResponsesCategory = {\n uuid: generateUUID(),\n name: 'All Responses',\n exit_uuid: exitUuid\n };\n allResponsesExit = {\n uuid: exitUuid,\n destination_uuid: null\n };\n }\n\n const router: any = {\n type: 'switch',\n operand: '@input',\n default_category_uuid: allResponsesCategory.uuid,\n cases: [],\n categories: [allResponsesCategory],\n wait: {\n type: 'msg',\n hint: {\n type: 'audio'\n }\n }\n };\n\n if (formData.result_name && formData.result_name.trim() !== '') {\n router.result_name = formData.result_name.trim();\n }\n\n return {\n ...originalNode,\n router,\n exits: [allResponsesExit]\n };\n },\n localizable: 'categories',\n toLocalizationFormData: categoriesToLocalizationFormData,\n fromLocalizationFormData: localizationFormDataToCategories\n};\n"]}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { SPLIT_GROUPS, FlowTypes } from '../types';
|
|
2
|
+
import { generateUUID } from '../../utils';
|
|
3
|
+
import { resultNameField, categoriesToLocalizationFormData, localizationFormDataToCategories } from './shared';
|
|
4
|
+
const DIAL_CATEGORIES = ['Answered', 'No Answer', 'Busy', 'Failed'];
|
|
5
|
+
const DIAL_CASES = [
|
|
6
|
+
{ type: 'has_only_text', arguments: ['answered'], categoryName: 'Answered' },
|
|
7
|
+
{
|
|
8
|
+
type: 'has_only_text',
|
|
9
|
+
arguments: ['no_answer'],
|
|
10
|
+
categoryName: 'No Answer'
|
|
11
|
+
},
|
|
12
|
+
{ type: 'has_only_text', arguments: ['busy'], categoryName: 'Busy' }
|
|
13
|
+
];
|
|
14
|
+
export const wait_for_dial = {
|
|
15
|
+
type: 'wait_for_dial',
|
|
16
|
+
name: 'Redirect Call',
|
|
17
|
+
group: SPLIT_GROUPS.wait,
|
|
18
|
+
flowTypes: [FlowTypes.VOICE],
|
|
19
|
+
router: {
|
|
20
|
+
type: 'switch',
|
|
21
|
+
defaultCategory: 'Failed',
|
|
22
|
+
rules: DIAL_CASES.map((c) => ({
|
|
23
|
+
type: c.type,
|
|
24
|
+
arguments: c.arguments,
|
|
25
|
+
categoryName: c.categoryName
|
|
26
|
+
}))
|
|
27
|
+
},
|
|
28
|
+
form: {
|
|
29
|
+
phone: {
|
|
30
|
+
type: 'text',
|
|
31
|
+
label: 'Phone Number',
|
|
32
|
+
required: true,
|
|
33
|
+
evaluated: true,
|
|
34
|
+
placeholder: 'Phone number or expression'
|
|
35
|
+
},
|
|
36
|
+
dial_limit_seconds: {
|
|
37
|
+
type: 'text',
|
|
38
|
+
label: 'Dial Limit (seconds)',
|
|
39
|
+
required: false,
|
|
40
|
+
placeholder: '60'
|
|
41
|
+
},
|
|
42
|
+
call_limit_seconds: {
|
|
43
|
+
type: 'text',
|
|
44
|
+
label: 'Call Limit (seconds)',
|
|
45
|
+
required: false,
|
|
46
|
+
placeholder: '7200'
|
|
47
|
+
},
|
|
48
|
+
result_name: resultNameField
|
|
49
|
+
},
|
|
50
|
+
layout: [
|
|
51
|
+
'phone',
|
|
52
|
+
{
|
|
53
|
+
type: 'row',
|
|
54
|
+
items: ['dial_limit_seconds', 'call_limit_seconds']
|
|
55
|
+
},
|
|
56
|
+
'result_name'
|
|
57
|
+
],
|
|
58
|
+
toFormData: (node) => {
|
|
59
|
+
var _a, _b;
|
|
60
|
+
const wait = (_a = node.router) === null || _a === void 0 ? void 0 : _a.wait;
|
|
61
|
+
return {
|
|
62
|
+
uuid: node.uuid,
|
|
63
|
+
phone: (wait === null || wait === void 0 ? void 0 : wait.phone) || '',
|
|
64
|
+
dial_limit_seconds: (wait === null || wait === void 0 ? void 0 : wait.dial_limit_seconds)
|
|
65
|
+
? String(wait.dial_limit_seconds)
|
|
66
|
+
: '',
|
|
67
|
+
call_limit_seconds: (wait === null || wait === void 0 ? void 0 : wait.call_limit_seconds)
|
|
68
|
+
? String(wait.call_limit_seconds)
|
|
69
|
+
: '',
|
|
70
|
+
result_name: ((_b = node.router) === null || _b === void 0 ? void 0 : _b.result_name) || ''
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
fromFormData: (formData, originalNode) => {
|
|
74
|
+
var _a, _b;
|
|
75
|
+
const existingCategories = ((_a = originalNode.router) === null || _a === void 0 ? void 0 : _a.categories) || [];
|
|
76
|
+
const existingExits = originalNode.exits || [];
|
|
77
|
+
const existingCases = ((_b = originalNode.router) === null || _b === void 0 ? void 0 : _b.cases) || [];
|
|
78
|
+
const categories = [];
|
|
79
|
+
const exits = [];
|
|
80
|
+
const cases = [];
|
|
81
|
+
// Build categories and cases for each dial outcome
|
|
82
|
+
for (const catName of DIAL_CATEGORIES) {
|
|
83
|
+
const existing = existingCategories.find((c) => c.name === catName);
|
|
84
|
+
if (existing) {
|
|
85
|
+
categories.push(existing);
|
|
86
|
+
const existingExit = existingExits.find((e) => e.uuid === existing.exit_uuid);
|
|
87
|
+
exits.push(existingExit || {
|
|
88
|
+
uuid: existing.exit_uuid,
|
|
89
|
+
destination_uuid: null
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const exitUuid = generateUUID();
|
|
94
|
+
categories.push({
|
|
95
|
+
uuid: generateUUID(),
|
|
96
|
+
name: catName,
|
|
97
|
+
exit_uuid: exitUuid
|
|
98
|
+
});
|
|
99
|
+
exits.push({ uuid: exitUuid, destination_uuid: null });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Build cases for non-default categories
|
|
103
|
+
for (const dialCase of DIAL_CASES) {
|
|
104
|
+
const category = categories.find((c) => c.name === dialCase.categoryName);
|
|
105
|
+
if (!category)
|
|
106
|
+
continue;
|
|
107
|
+
const existingCase = existingCases.find((c) => { var _a; return c.type === dialCase.type && ((_a = c.arguments) === null || _a === void 0 ? void 0 : _a[0]) === dialCase.arguments[0]; });
|
|
108
|
+
cases.push({
|
|
109
|
+
uuid: (existingCase === null || existingCase === void 0 ? void 0 : existingCase.uuid) || generateUUID(),
|
|
110
|
+
type: dialCase.type,
|
|
111
|
+
arguments: dialCase.arguments,
|
|
112
|
+
category_uuid: category.uuid
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
const failedCategory = categories.find((c) => c.name === 'Failed');
|
|
116
|
+
// Build wait config
|
|
117
|
+
const phone = (formData.phone || '').trim();
|
|
118
|
+
const dialLimit = parseInt(formData.dial_limit_seconds, 10);
|
|
119
|
+
const callLimit = parseInt(formData.call_limit_seconds, 10);
|
|
120
|
+
const waitConfig = {
|
|
121
|
+
type: 'dial',
|
|
122
|
+
phone
|
|
123
|
+
};
|
|
124
|
+
if (!isNaN(dialLimit) && dialLimit > 0) {
|
|
125
|
+
waitConfig.dial_limit_seconds = dialLimit;
|
|
126
|
+
}
|
|
127
|
+
if (!isNaN(callLimit) && callLimit > 0) {
|
|
128
|
+
waitConfig.call_limit_seconds = callLimit;
|
|
129
|
+
}
|
|
130
|
+
const router = {
|
|
131
|
+
type: 'switch',
|
|
132
|
+
operand: '@(default(resume.dial.status, ""))',
|
|
133
|
+
default_category_uuid: failedCategory === null || failedCategory === void 0 ? void 0 : failedCategory.uuid,
|
|
134
|
+
cases,
|
|
135
|
+
categories,
|
|
136
|
+
wait: waitConfig
|
|
137
|
+
};
|
|
138
|
+
if (formData.result_name && formData.result_name.trim() !== '') {
|
|
139
|
+
router.result_name = formData.result_name.trim();
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
...originalNode,
|
|
143
|
+
router,
|
|
144
|
+
exits
|
|
145
|
+
};
|
|
146
|
+
},
|
|
147
|
+
localizable: 'categories',
|
|
148
|
+
toLocalizationFormData: categoriesToLocalizationFormData,
|
|
149
|
+
fromLocalizationFormData: localizationFormDataToCategories
|
|
150
|
+
};
|
|
151
|
+
//# sourceMappingURL=wait_for_dial.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait_for_dial.js","sourceRoot":"","sources":["../../../../src/flow/nodes/wait_for_dial.ts"],"names":[],"mappings":"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","sourcesContent":["import { SPLIT_GROUPS, FormData, NodeConfig, FlowTypes } from '../types';\nimport { Node, Category, Exit } from '../../store/flow-definition';\nimport { generateUUID } from '../../utils';\nimport {\n resultNameField,\n categoriesToLocalizationFormData,\n localizationFormDataToCategories\n} from './shared';\n\nconst DIAL_CATEGORIES = ['Answered', 'No Answer', 'Busy', 'Failed'];\nconst DIAL_CASES = [\n { type: 'has_only_text', arguments: ['answered'], categoryName: 'Answered' },\n {\n type: 'has_only_text',\n arguments: ['no_answer'],\n categoryName: 'No Answer'\n },\n { type: 'has_only_text', arguments: ['busy'], categoryName: 'Busy' }\n];\n\nexport const wait_for_dial: NodeConfig = {\n type: 'wait_for_dial',\n name: 'Redirect Call',\n group: SPLIT_GROUPS.wait,\n flowTypes: [FlowTypes.VOICE],\n router: {\n type: 'switch',\n defaultCategory: 'Failed',\n rules: DIAL_CASES.map((c) => ({\n type: c.type as any,\n arguments: c.arguments,\n categoryName: c.categoryName\n }))\n },\n form: {\n phone: {\n type: 'text',\n label: 'Phone Number',\n required: true,\n evaluated: true,\n placeholder: 'Phone number or expression'\n },\n dial_limit_seconds: {\n type: 'text',\n label: 'Dial Limit (seconds)',\n required: false,\n placeholder: '60'\n },\n call_limit_seconds: {\n type: 'text',\n label: 'Call Limit (seconds)',\n required: false,\n placeholder: '7200'\n },\n result_name: resultNameField\n },\n layout: [\n 'phone',\n {\n type: 'row',\n items: ['dial_limit_seconds', 'call_limit_seconds']\n },\n 'result_name'\n ],\n toFormData: (node: Node) => {\n const wait = node.router?.wait;\n return {\n uuid: node.uuid,\n phone: wait?.phone || '',\n dial_limit_seconds: wait?.dial_limit_seconds\n ? String(wait.dial_limit_seconds)\n : '',\n call_limit_seconds: wait?.call_limit_seconds\n ? String(wait.call_limit_seconds)\n : '',\n result_name: node.router?.result_name || ''\n };\n },\n fromFormData: (formData: FormData, originalNode: Node): Node => {\n const existingCategories = originalNode.router?.categories || [];\n const existingExits = originalNode.exits || [];\n const existingCases = originalNode.router?.cases || [];\n\n const categories: Category[] = [];\n const exits: Exit[] = [];\n const cases: any[] = [];\n\n // Build categories and cases for each dial outcome\n for (const catName of DIAL_CATEGORIES) {\n const existing = existingCategories.find(\n (c: Category) => c.name === catName\n );\n\n if (existing) {\n categories.push(existing);\n const existingExit = existingExits.find(\n (e: Exit) => e.uuid === existing.exit_uuid\n );\n exits.push(\n existingExit || {\n uuid: existing.exit_uuid,\n destination_uuid: null\n }\n );\n } else {\n const exitUuid = generateUUID();\n categories.push({\n uuid: generateUUID(),\n name: catName,\n exit_uuid: exitUuid\n });\n exits.push({ uuid: exitUuid, destination_uuid: null });\n }\n }\n\n // Build cases for non-default categories\n for (const dialCase of DIAL_CASES) {\n const category = categories.find((c) => c.name === dialCase.categoryName);\n if (!category) continue;\n\n const existingCase = existingCases.find(\n (c: any) =>\n c.type === dialCase.type && c.arguments?.[0] === dialCase.arguments[0]\n );\n\n cases.push({\n uuid: existingCase?.uuid || generateUUID(),\n type: dialCase.type,\n arguments: dialCase.arguments,\n category_uuid: category.uuid\n });\n }\n\n const failedCategory = categories.find((c) => c.name === 'Failed');\n\n // Build wait config\n const phone = (formData.phone || '').trim();\n const dialLimit = parseInt(formData.dial_limit_seconds, 10);\n const callLimit = parseInt(formData.call_limit_seconds, 10);\n\n const waitConfig: any = {\n type: 'dial',\n phone\n };\n\n if (!isNaN(dialLimit) && dialLimit > 0) {\n waitConfig.dial_limit_seconds = dialLimit;\n }\n\n if (!isNaN(callLimit) && callLimit > 0) {\n waitConfig.call_limit_seconds = callLimit;\n }\n\n const router: any = {\n type: 'switch',\n operand: '@(default(resume.dial.status, \"\"))',\n default_category_uuid: failedCategory?.uuid,\n cases,\n categories,\n wait: waitConfig\n };\n\n if (formData.result_name && formData.result_name.trim() !== '') {\n router.result_name = formData.result_name.trim();\n }\n\n return {\n ...originalNode,\n router,\n exits\n };\n },\n localizable: 'categories',\n toLocalizationFormData: categoriesToLocalizationFormData,\n fromLocalizationFormData: localizationFormDataToCategories\n};\n"]}
|
|
@@ -1,8 +1,68 @@
|
|
|
1
1
|
import { SPLIT_GROUPS, FlowTypes } from '../types';
|
|
2
|
+
import { createRulesRouter } from '../../utils';
|
|
3
|
+
import { getDigitOperators, operatorsToSelectOptions, getOperatorConfig } from '../operators';
|
|
4
|
+
import { resultNameField, categoriesToLocalizationFormData, localizationFormDataToCategories } from './shared';
|
|
5
|
+
import { createRulesArrayConfig, extractUserRules, casesToFormRules } from './shared-rules';
|
|
2
6
|
export const wait_for_digits = {
|
|
3
7
|
type: 'wait_for_digits',
|
|
4
8
|
name: 'Wait for Digits',
|
|
5
9
|
group: SPLIT_GROUPS.wait,
|
|
6
|
-
flowTypes: [FlowTypes.VOICE]
|
|
10
|
+
flowTypes: [FlowTypes.VOICE],
|
|
11
|
+
dialogSize: 'large',
|
|
12
|
+
form: {
|
|
13
|
+
rules: createRulesArrayConfig(operatorsToSelectOptions(getDigitOperators()), ''),
|
|
14
|
+
result_name: resultNameField
|
|
15
|
+
},
|
|
16
|
+
layout: [
|
|
17
|
+
{
|
|
18
|
+
type: 'text',
|
|
19
|
+
text: 'Rules match against all digits pressed by the caller followed by the # sign.'
|
|
20
|
+
},
|
|
21
|
+
'rules',
|
|
22
|
+
'result_name'
|
|
23
|
+
],
|
|
24
|
+
validate: (_formData) => {
|
|
25
|
+
return {
|
|
26
|
+
valid: true,
|
|
27
|
+
errors: {}
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
toFormData: (node) => {
|
|
31
|
+
var _a;
|
|
32
|
+
const rules = casesToFormRules(node);
|
|
33
|
+
return {
|
|
34
|
+
uuid: node.uuid,
|
|
35
|
+
rules,
|
|
36
|
+
result_name: ((_a = node.router) === null || _a === void 0 ? void 0 : _a.result_name) || ''
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
fromFormData: (formData, originalNode) => {
|
|
40
|
+
var _a, _b;
|
|
41
|
+
const userRules = extractUserRules(formData);
|
|
42
|
+
const existingCategories = ((_a = originalNode.router) === null || _a === void 0 ? void 0 : _a.categories) || [];
|
|
43
|
+
const existingExits = originalNode.exits || [];
|
|
44
|
+
const existingCases = ((_b = originalNode.router) === null || _b === void 0 ? void 0 : _b.cases) || [];
|
|
45
|
+
const { router, exits } = createRulesRouter('@input.text', userRules, getOperatorConfig, existingCategories, existingExits, existingCases);
|
|
46
|
+
const finalRouter = {
|
|
47
|
+
...router,
|
|
48
|
+
wait: {
|
|
49
|
+
type: 'msg',
|
|
50
|
+
hint: {
|
|
51
|
+
type: 'digits'
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
if (formData.result_name && formData.result_name.trim() !== '') {
|
|
56
|
+
finalRouter.result_name = formData.result_name.trim();
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
...originalNode,
|
|
60
|
+
router: finalRouter,
|
|
61
|
+
exits
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
localizable: 'categories',
|
|
65
|
+
toLocalizationFormData: categoriesToLocalizationFormData,
|
|
66
|
+
fromLocalizationFormData: localizationFormDataToCategories
|
|
7
67
|
};
|
|
8
68
|
//# sourceMappingURL=wait_for_digits.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wait_for_digits.js","sourceRoot":"","sources":["../../../../src/flow/nodes/wait_for_digits.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"wait_for_digits.js","sourceRoot":"","sources":["../../../../src/flow/nodes/wait_for_digits.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAwB,SAAS,EAAE,MAAM,UAAU,CAAC;AAEzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,iBAAiB,EAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,eAAe,EACf,gCAAgC,EAChC,gCAAgC,EACjC,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AAExB,MAAM,CAAC,MAAM,eAAe,GAAe;IACzC,IAAI,EAAE,iBAAiB;IACvB,IAAI,EAAE,iBAAiB;IACvB,KAAK,EAAE,YAAY,CAAC,IAAI;IACxB,SAAS,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC;IAC5B,UAAU,EAAE,OAAO;IACnB,IAAI,EAAE;QACJ,KAAK,EAAE,sBAAsB,CAC3B,wBAAwB,CAAC,iBAAiB,EAAE,CAAC,EAC7C,EAAE,CACH;QACD,WAAW,EAAE,eAAe;KAC7B;IACD,MAAM,EAAE;QACN;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,8EAA8E;SACrF;QACD,OAAO;QACP,aAAa;KACd;IACD,QAAQ,EAAE,CAAC,SAAmB,EAAE,EAAE;QAChC,OAAO;YACL,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,EAAE;SACX,CAAC;IACJ,CAAC;IACD,UAAU,EAAE,CAAC,IAAU,EAAE,EAAE;;QACzB,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACrC,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK;YACL,WAAW,EAAE,CAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,WAAW,KAAI,EAAE;SAC5C,CAAC;IACJ,CAAC;IACD,YAAY,EAAE,CAAC,QAAkB,EAAE,YAAkB,EAAQ,EAAE;;QAC7D,MAAM,SAAS,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAC7C,MAAM,kBAAkB,GAAG,CAAA,MAAA,YAAY,CAAC,MAAM,0CAAE,UAAU,KAAI,EAAE,CAAC;QACjE,MAAM,aAAa,GAAG,YAAY,CAAC,KAAK,IAAI,EAAE,CAAC;QAC/C,MAAM,aAAa,GAAG,CAAA,MAAA,YAAY,CAAC,MAAM,0CAAE,KAAK,KAAI,EAAE,CAAC;QAEvD,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,iBAAiB,CACzC,aAAa,EACb,SAAS,EACT,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,aAAa,CACd,CAAC;QAEF,MAAM,WAAW,GAAQ;YACvB,GAAG,MAAM;YACT,IAAI,EAAE;gBACJ,IAAI,EAAE,KAAK;gBACX,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;iBACf;aACF;SACF,CAAC;QAEF,IAAI,QAAQ,CAAC,WAAW,IAAI,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC/D,WAAW,CAAC,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QACxD,CAAC;QAED,OAAO;YACL,GAAG,YAAY;YACf,MAAM,EAAE,WAAW;YACnB,KAAK;SACN,CAAC;IACJ,CAAC;IACD,WAAW,EAAE,YAAY;IACzB,sBAAsB,EAAE,gCAAgC;IACxD,wBAAwB,EAAE,gCAAgC;CAC3D,CAAC","sourcesContent":["import { SPLIT_GROUPS, FormData, NodeConfig, FlowTypes } from '../types';\nimport { Node } from '../../store/flow-definition';\nimport { createRulesRouter } from '../../utils';\nimport {\n getDigitOperators,\n operatorsToSelectOptions,\n getOperatorConfig\n} from '../operators';\nimport {\n resultNameField,\n categoriesToLocalizationFormData,\n localizationFormDataToCategories\n} from './shared';\nimport {\n createRulesArrayConfig,\n extractUserRules,\n casesToFormRules\n} from './shared-rules';\n\nexport const wait_for_digits: NodeConfig = {\n type: 'wait_for_digits',\n name: 'Wait for Digits',\n group: SPLIT_GROUPS.wait,\n flowTypes: [FlowTypes.VOICE],\n dialogSize: 'large',\n form: {\n rules: createRulesArrayConfig(\n operatorsToSelectOptions(getDigitOperators()),\n ''\n ),\n result_name: resultNameField\n },\n layout: [\n {\n type: 'text',\n text: 'Rules match against all digits pressed by the caller followed by the # sign.'\n },\n 'rules',\n 'result_name'\n ],\n validate: (_formData: FormData) => {\n return {\n valid: true,\n errors: {}\n };\n },\n toFormData: (node: Node) => {\n const rules = casesToFormRules(node);\n return {\n uuid: node.uuid,\n rules,\n result_name: node.router?.result_name || ''\n };\n },\n fromFormData: (formData: FormData, originalNode: Node): Node => {\n const userRules = extractUserRules(formData);\n const existingCategories = originalNode.router?.categories || [];\n const existingExits = originalNode.exits || [];\n const existingCases = originalNode.router?.cases || [];\n\n const { router, exits } = createRulesRouter(\n '@input.text',\n userRules,\n getOperatorConfig,\n existingCategories,\n existingExits,\n existingCases\n );\n\n const finalRouter: any = {\n ...router,\n wait: {\n type: 'msg',\n hint: {\n type: 'digits'\n }\n }\n };\n\n if (formData.result_name && formData.result_name.trim() !== '') {\n finalRouter.result_name = formData.result_name.trim();\n }\n\n return {\n ...originalNode,\n router: finalRouter,\n exits\n };\n },\n localizable: 'categories',\n toLocalizationFormData: categoriesToLocalizationFormData,\n fromLocalizationFormData: localizationFormDataToCategories\n};\n"]}
|