@nyaruka/temba-components 0.131.0 → 0.131.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.
- package/.github/workflows/publish.yml +4 -1
- package/CHANGELOG.md +67 -1
- package/demo/data/flows/food-order.json +2 -2
- package/demo/data/flows/sample-flow.json +74 -125
- package/dist/static/svg/index.svg +1 -1
- package/dist/temba-components.js +1156 -619
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/Icons.js +4 -1
- package/out-tsc/src/Icons.js.map +1 -1
- package/out-tsc/src/events.js.map +1 -1
- package/out-tsc/src/flow/CanvasMenu.js +200 -0
- package/out-tsc/src/flow/CanvasMenu.js.map +1 -0
- package/out-tsc/src/flow/CanvasNode.js +327 -19
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +562 -66
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/NodeEditor.js +240 -93
- package/out-tsc/src/flow/NodeEditor.js.map +1 -1
- package/out-tsc/src/flow/NodeTypeSelector.js +499 -0
- package/out-tsc/src/flow/NodeTypeSelector.js.map +1 -0
- package/out-tsc/src/flow/actions/add_contact_groups.js +3 -3
- package/out-tsc/src/flow/actions/add_contact_groups.js.map +1 -1
- package/out-tsc/src/flow/actions/add_contact_urn.js +62 -4
- package/out-tsc/src/flow/actions/add_contact_urn.js.map +1 -1
- package/out-tsc/src/flow/actions/add_input_labels.js +3 -3
- package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -1
- package/out-tsc/src/flow/actions/play_audio.js +2 -2
- package/out-tsc/src/flow/actions/play_audio.js.map +1 -1
- package/out-tsc/src/flow/actions/remove_contact_groups.js +6 -5
- package/out-tsc/src/flow/actions/remove_contact_groups.js.map +1 -1
- package/out-tsc/src/flow/actions/request_optin.js +2 -2
- package/out-tsc/src/flow/actions/request_optin.js.map +1 -1
- package/out-tsc/src/flow/actions/say_msg.js +2 -2
- package/out-tsc/src/flow/actions/say_msg.js.map +1 -1
- package/out-tsc/src/flow/actions/send_broadcast.js +76 -23
- package/out-tsc/src/flow/actions/send_broadcast.js.map +1 -1
- package/out-tsc/src/flow/actions/send_email.js +4 -5
- package/out-tsc/src/flow/actions/send_email.js.map +1 -1
- package/out-tsc/src/flow/actions/send_msg.js +9 -19
- package/out-tsc/src/flow/actions/send_msg.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_channel.js +5 -9
- package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_field.js +19 -20
- package/out-tsc/src/flow/actions/set_contact_field.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_language.js +2 -2
- package/out-tsc/src/flow/actions/set_contact_language.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_name.js +2 -12
- package/out-tsc/src/flow/actions/set_contact_name.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_status.js +2 -2
- package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -1
- package/out-tsc/src/flow/actions/set_run_result.js +3 -3
- package/out-tsc/src/flow/actions/set_run_result.js.map +1 -1
- package/out-tsc/src/flow/actions/start_session.js +180 -6
- package/out-tsc/src/flow/actions/start_session.js.map +1 -1
- package/out-tsc/src/flow/config.js +11 -15
- package/out-tsc/src/flow/config.js.map +1 -1
- package/out-tsc/src/flow/currencies.js +45 -0
- package/out-tsc/src/flow/currencies.js.map +1 -0
- package/out-tsc/src/flow/nodes/shared-rules.js +257 -0
- package/out-tsc/src/flow/nodes/shared-rules.js.map +1 -0
- package/out-tsc/src/flow/nodes/shared.js +17 -0
- package/out-tsc/src/flow/nodes/shared.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_airtime.js +205 -5
- package/out-tsc/src/flow/nodes/split_by_airtime.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_contact_field.js +147 -3
- package/out-tsc/src/flow/nodes/split_by_contact_field.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_expression.js +68 -2
- package/out-tsc/src/flow/nodes/split_by_expression.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_groups.js +12 -9
- package/out-tsc/src/flow/nodes/split_by_groups.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_intent.js +7 -0
- package/out-tsc/src/flow/nodes/split_by_intent.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_llm.js +3 -2
- package/out-tsc/src/flow/nodes/split_by_llm.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +2 -2
- package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_random.js +3 -3
- package/out-tsc/src/flow/nodes/split_by_random.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_resthook.js +108 -0
- package/out-tsc/src/flow/nodes/split_by_resthook.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_run_result.js +206 -3
- package/out-tsc/src/flow/nodes/split_by_run_result.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_scheme.js +153 -2
- package/out-tsc/src/flow/nodes/split_by_scheme.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_subflow.js +6 -4
- package/out-tsc/src/flow/nodes/split_by_subflow.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_ticket.js +3 -2
- package/out-tsc/src/flow/nodes/split_by_ticket.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_webhook.js +3 -2
- package/out-tsc/src/flow/nodes/split_by_webhook.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_audio.js +2 -2
- package/out-tsc/src/flow/nodes/wait_for_audio.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_digits.js +2 -2
- package/out-tsc/src/flow/nodes/wait_for_digits.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_image.js +2 -2
- package/out-tsc/src/flow/nodes/wait_for_image.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_location.js +2 -2
- package/out-tsc/src/flow/nodes/wait_for_location.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_menu.js +2 -2
- package/out-tsc/src/flow/nodes/wait_for_menu.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_response.js +32 -567
- package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_video.js +2 -2
- package/out-tsc/src/flow/nodes/wait_for_video.js.map +1 -1
- package/out-tsc/src/flow/types.js +71 -12
- package/out-tsc/src/flow/types.js.map +1 -1
- package/out-tsc/src/flow/utils.js +101 -14
- package/out-tsc/src/flow/utils.js.map +1 -1
- package/out-tsc/src/form/ContactSearch.js +1 -1
- package/out-tsc/src/form/ContactSearch.js.map +1 -1
- package/out-tsc/src/form/FieldRenderer.js +2 -4
- package/out-tsc/src/form/FieldRenderer.js.map +1 -1
- package/out-tsc/src/interfaces.js +3 -0
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/list/SortableList.js +98 -33
- package/out-tsc/src/list/SortableList.js.map +1 -1
- package/out-tsc/src/live/ContactChat.js +15 -18
- package/out-tsc/src/live/ContactChat.js.map +1 -1
- package/out-tsc/src/store/AppState.js +53 -0
- package/out-tsc/src/store/AppState.js.map +1 -1
- package/out-tsc/src/utils.js +254 -13
- package/out-tsc/src/utils.js.map +1 -1
- package/out-tsc/temba-modules.js +4 -0
- package/out-tsc/temba-modules.js.map +1 -1
- package/out-tsc/test/ActionHelper.js +3 -3
- package/out-tsc/test/ActionHelper.js.map +1 -1
- package/out-tsc/test/NodeHelper.js +6 -3
- package/out-tsc/test/NodeHelper.js.map +1 -1
- package/out-tsc/test/actions/add_contact_urn.test.js +202 -0
- package/out-tsc/test/actions/add_contact_urn.test.js.map +1 -0
- package/out-tsc/test/actions/send_broadcast.test.js +148 -0
- package/out-tsc/test/actions/send_broadcast.test.js.map +1 -0
- package/out-tsc/test/actions/send_email.test.js +17 -23
- package/out-tsc/test/actions/send_email.test.js.map +1 -1
- package/out-tsc/test/actions/send_msg.test.js +33 -15
- package/out-tsc/test/actions/send_msg.test.js.map +1 -1
- package/out-tsc/test/actions/start_session.test.js +116 -0
- package/out-tsc/test/actions/start_session.test.js.map +1 -0
- package/out-tsc/test/nodes/split_by_airtime.test.js +604 -0
- package/out-tsc/test/nodes/split_by_airtime.test.js.map +1 -0
- package/out-tsc/test/nodes/split_by_contact_field.test.js +387 -0
- package/out-tsc/test/nodes/split_by_contact_field.test.js.map +1 -0
- package/out-tsc/test/nodes/split_by_expression.test.js +614 -0
- package/out-tsc/test/nodes/split_by_expression.test.js.map +1 -0
- package/out-tsc/test/nodes/split_by_random.test.js +3 -3
- package/out-tsc/test/nodes/split_by_random.test.js.map +1 -1
- package/out-tsc/test/nodes/split_by_resthook.test.js +337 -0
- package/out-tsc/test/nodes/split_by_resthook.test.js.map +1 -0
- package/out-tsc/test/nodes/split_by_run_result.test.js +920 -0
- package/out-tsc/test/nodes/split_by_run_result.test.js.map +1 -0
- package/out-tsc/test/nodes/split_by_scheme.test.js +399 -0
- package/out-tsc/test/nodes/split_by_scheme.test.js.map +1 -0
- package/out-tsc/test/nodes/split_by_subflow.test.js +333 -0
- package/out-tsc/test/nodes/split_by_subflow.test.js.map +1 -0
- package/out-tsc/test/nodes/wait_for_digits.test.js +2 -2
- package/out-tsc/test/nodes/wait_for_digits.test.js.map +1 -1
- package/out-tsc/test/nodes/wait_for_response.test.js +2 -1
- package/out-tsc/test/nodes/wait_for_response.test.js.map +1 -1
- package/out-tsc/test/temba-action-drag-between-nodes.test.js +252 -0
- package/out-tsc/test/temba-action-drag-between-nodes.test.js.map +1 -0
- package/out-tsc/test/temba-canvas-menu.test.js +122 -0
- package/out-tsc/test/temba-canvas-menu.test.js.map +1 -0
- package/out-tsc/test/temba-flow-editor-node.test.js +85 -2
- package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
- package/out-tsc/test/temba-flow-editor.test.js +7 -8
- package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
- package/out-tsc/test/temba-node-editor.test.js +3 -1
- package/out-tsc/test/temba-node-editor.test.js.map +1 -1
- package/out-tsc/test/temba-node-type-selector.test.js +115 -0
- package/out-tsc/test/temba-node-type-selector.test.js.map +1 -0
- package/out-tsc/test/temba-omnibox.test.js +2 -1
- package/out-tsc/test/temba-omnibox.test.js.map +1 -1
- package/out-tsc/test/temba-sortable-list.test.js +51 -0
- package/out-tsc/test/temba-sortable-list.test.js.map +1 -1
- package/out-tsc/test/temba-utils-index.test.js +1 -27
- package/out-tsc/test/temba-utils-index.test.js.map +1 -1
- package/out-tsc/test/utils.test.js +2 -0
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +2 -1
- package/screenshots/truth/actions/add_contact_groups/editor/descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/editor/long-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/editor/many-groups.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/editor/multiple-groups.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/editor/single-group.png +0 -0
- 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/editor/expression-facebook.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/expression-phone.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/facebook-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/instagram-handle.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/line-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/phone-number.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/telegram-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/viber-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/wechat-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/whatsapp.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/remove_contact_groups/editor/cleanup-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/long-descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/many-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/multiple-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/remove-from-all-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/single-group.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/send_broadcast/editor/contacts-only.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/groups-and-contacts.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/groups-only.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/many-groups.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/multiline-text.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/with-attachments.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_broadcast/render/with-attachments.png +0 -0
- package/screenshots/truth/actions/send_email/editor/complex-business-email.png +0 -0
- package/screenshots/truth/actions/send_email/editor/empty-body.png +0 -0
- package/screenshots/truth/actions/send_email/editor/empty-subject.png +0 -0
- package/screenshots/truth/actions/send_email/editor/long-subject.png +0 -0
- package/screenshots/truth/actions/send_email/editor/multiline-body.png +0 -0
- package/screenshots/truth/actions/send_email/editor/multiple-recipients.png +0 -0
- package/screenshots/truth/actions/send_email/editor/simple-email.png +0 -0
- package/screenshots/truth/actions/send_email/editor/with-expressions.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/editor/long-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/multiline-text-with-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/simple-text.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-with-linebreaks.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-with-many-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-with-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-without-quick-replies.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/start_session/editor/contact-query.png +0 -0
- package/screenshots/truth/actions/start_session/editor/contacts-only.png +0 -0
- package/screenshots/truth/actions/start_session/editor/create-contact.png +0 -0
- package/screenshots/truth/actions/start_session/editor/groups-and-contacts.png +0 -0
- package/screenshots/truth/actions/start_session/editor/groups-only.png +0 -0
- package/screenshots/truth/actions/start_session/editor/many-recipients.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/canvas-menu/open.png +0 -0
- package/screenshots/truth/editor/router.png +0 -0
- package/screenshots/truth/editor/wait.png +0 -0
- package/screenshots/truth/list/fields-dragging.png +0 -0
- package/screenshots/truth/list/sortable-dragging.png +0 -0
- package/screenshots/truth/node-type-selector/action-mode.png +0 -0
- package/screenshots/truth/node-type-selector/split-mode.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/editor/information-extraction.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/editor/sentiment-analysis.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/editor/summarization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/editor/translation-task.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_digits/editor/basic-digits-wait.png +0 -0
- 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/basic-digits-wait.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
- 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/Icons.ts +4 -1
- package/src/events.ts +2 -6
- package/src/flow/CanvasMenu.ts +217 -0
- package/src/flow/CanvasNode.ts +408 -10
- package/src/flow/Editor.ts +683 -44
- package/src/flow/NodeEditor.ts +304 -125
- package/src/flow/NodeTypeSelector.ts +592 -0
- package/src/flow/actions/add_contact_groups.ts +4 -4
- package/src/flow/actions/add_contact_urn.ts +76 -4
- package/src/flow/actions/add_input_labels.ts +4 -4
- package/src/flow/actions/play_audio.ts +2 -2
- package/src/flow/actions/remove_contact_groups.ts +14 -6
- package/src/flow/actions/request_optin.ts +2 -2
- package/src/flow/actions/say_msg.ts +2 -2
- package/src/flow/actions/send_broadcast.ts +85 -23
- package/src/flow/actions/send_email.ts +10 -6
- package/src/flow/actions/send_msg.ts +22 -32
- package/src/flow/actions/set_contact_channel.ts +5 -11
- package/src/flow/actions/set_contact_field.ts +20 -25
- package/src/flow/actions/set_contact_language.ts +9 -4
- package/src/flow/actions/set_contact_name.ts +3 -15
- package/src/flow/actions/set_contact_status.ts +3 -3
- package/src/flow/actions/set_run_result.ts +4 -4
- package/src/flow/actions/start_session.ts +208 -6
- package/src/flow/config.ts +13 -15
- package/src/flow/currencies.ts +51 -0
- package/src/flow/nodes/shared-rules.ts +301 -0
- package/src/flow/nodes/shared.ts +18 -0
- package/src/flow/nodes/split_by_airtime.ts +238 -5
- package/src/flow/nodes/split_by_contact_field.ts +185 -3
- package/src/flow/nodes/split_by_expression.ts +94 -2
- package/src/flow/nodes/split_by_groups.ts +15 -10
- package/src/flow/nodes/split_by_intent.ts +7 -0
- package/src/flow/nodes/split_by_llm.ts +4 -3
- package/src/flow/nodes/split_by_llm_categorize.ts +4 -4
- package/src/flow/nodes/split_by_random.ts +5 -5
- package/src/flow/nodes/split_by_resthook.ts +130 -0
- package/src/flow/nodes/split_by_run_result.ts +249 -3
- package/src/flow/nodes/split_by_scheme.ts +192 -2
- package/src/flow/nodes/split_by_subflow.ts +6 -4
- package/src/flow/nodes/split_by_ticket.ts +4 -3
- package/src/flow/nodes/split_by_webhook.ts +6 -5
- package/src/flow/nodes/wait_for_audio.ts +2 -2
- package/src/flow/nodes/wait_for_digits.ts +2 -2
- package/src/flow/nodes/wait_for_image.ts +2 -2
- package/src/flow/nodes/wait_for_location.ts +2 -2
- package/src/flow/nodes/wait_for_menu.ts +2 -2
- package/src/flow/nodes/wait_for_response.ts +48 -679
- package/src/flow/nodes/wait_for_video.ts +2 -2
- package/src/flow/types.ts +109 -23
- package/src/flow/utils.ts +108 -14
- package/src/form/ContactSearch.ts +1 -1
- package/src/form/FieldRenderer.ts +2 -4
- package/src/interfaces.ts +3 -0
- package/src/list/SortableList.ts +109 -34
- package/src/live/ContactChat.ts +15 -18
- package/src/store/AppState.ts +69 -0
- package/src/store/flow-definition.d.ts +2 -5
- package/src/utils.ts +332 -12
- package/static/api/channels.json +46 -0
- package/static/api/resthooks.json +31 -0
- package/static/svg/index.svg +1 -1
- package/static/svg/work/traced/lightning-02.svg +1 -0
- package/static/svg/work/used/lightning-02.svg +3 -0
- package/temba-modules.ts +4 -0
- package/test/ActionHelper.ts +3 -3
- package/test/NodeHelper.ts +6 -3
- package/test/actions/add_contact_urn.test.ts +287 -0
- package/test/actions/send_broadcast.test.ts +190 -0
- package/test/actions/send_email.test.ts +17 -23
- package/test/actions/send_msg.test.ts +39 -15
- package/test/actions/start_session.test.ts +151 -0
- package/test/nodes/split_by_airtime.test.ts +673 -0
- package/test/nodes/split_by_contact_field.test.ts +451 -0
- package/test/nodes/split_by_expression.test.ts +751 -0
- package/test/nodes/split_by_random.test.ts +3 -3
- package/test/nodes/split_by_resthook.test.ts +398 -0
- package/test/nodes/split_by_run_result.test.ts +1109 -0
- package/test/nodes/split_by_scheme.test.ts +486 -0
- package/test/nodes/split_by_subflow.test.ts +381 -0
- package/test/nodes/wait_for_digits.test.ts +2 -2
- package/test/nodes/wait_for_response.test.ts +2 -1
- package/test/temba-action-drag-between-nodes.test.ts +301 -0
- package/test/temba-canvas-menu.test.ts +156 -0
- package/test/temba-flow-editor-node.test.ts +102 -2
- package/test/temba-flow-editor.test.ts +7 -8
- package/test/temba-node-editor.test.ts +3 -1
- package/test/temba-node-type-selector.test.ts +152 -0
- package/test/temba-omnibox.test.ts +2 -1
- package/test/temba-sortable-list.test.ts +69 -0
- package/test/temba-utils-index.test.ts +0 -35
- package/test/utils.test.ts +2 -0
- package/test-assets/contacts/history.json +14 -20
- package/web-dev-server.config.mjs +3 -1
- package/out-tsc/src/flow/actions/call_classifier.js +0 -11
- package/out-tsc/src/flow/actions/call_classifier.js.map +0 -1
- package/out-tsc/src/flow/actions/call_resthook.js +0 -11
- package/out-tsc/src/flow/actions/call_resthook.js.map +0 -1
- package/out-tsc/src/flow/actions/split_by_expression_example.js +0 -77
- package/out-tsc/src/flow/actions/split_by_expression_example.js.map +0 -1
- package/out-tsc/src/flow/actions/transfer_airtime.js +0 -11
- package/out-tsc/src/flow/actions/transfer_airtime.js.map +0 -1
- package/src/flow/actions/call_classifier.ts +0 -12
- package/src/flow/actions/call_resthook.ts +0 -12
- package/src/flow/actions/split_by_expression_example.ts +0 -88
- package/src/flow/actions/transfer_airtime.ts +0 -12
|
@@ -3,6 +3,7 @@ import { html, css } from 'lit';
|
|
|
3
3
|
import { property, state } from 'lit/decorators.js';
|
|
4
4
|
import { RapidElement } from '../RapidElement';
|
|
5
5
|
import { NODE_CONFIG, ACTION_CONFIG } from './config';
|
|
6
|
+
import { ACTION_GROUP_METADATA, SPLIT_GROUP_METADATA } from './types';
|
|
6
7
|
import { CustomEventType } from '../interfaces';
|
|
7
8
|
import { generateUUID } from '../utils';
|
|
8
9
|
import { FieldRenderer } from '../form/FieldRenderer';
|
|
@@ -16,6 +17,7 @@ export class NodeEditor extends RapidElement {
|
|
|
16
17
|
this.errors = {};
|
|
17
18
|
this.groupCollapseState = {};
|
|
18
19
|
this.groupHoverState = {};
|
|
20
|
+
this.revealedOptionalFields = new Set();
|
|
19
21
|
}
|
|
20
22
|
static get styles() {
|
|
21
23
|
return css `
|
|
@@ -25,7 +27,6 @@ export class NodeEditor extends RapidElement {
|
|
|
25
27
|
flex-direction: column;
|
|
26
28
|
gap: 15px;
|
|
27
29
|
min-width: 400px;
|
|
28
|
-
padding-bottom: 40px;
|
|
29
30
|
|
|
30
31
|
--color-bubble-bg: rgba(var(--primary-rgb), 0.7);
|
|
31
32
|
--color-bubble-border: rgba(0, 0, 0, 0.2);
|
|
@@ -88,6 +89,28 @@ export class NodeEditor extends RapidElement {
|
|
|
88
89
|
align-items: center;
|
|
89
90
|
}
|
|
90
91
|
|
|
92
|
+
.form-row-wrapper {
|
|
93
|
+
display: flex;
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.form-row-label {
|
|
98
|
+
margin-bottom: 5px;
|
|
99
|
+
margin-left: 4px;
|
|
100
|
+
display: block;
|
|
101
|
+
font-weight: 400;
|
|
102
|
+
font-size: var(--label-size);
|
|
103
|
+
letter-spacing: 0.05em;
|
|
104
|
+
line-height: normal;
|
|
105
|
+
color: var(--color-label, #777);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.form-row-help {
|
|
109
|
+
font-size: 12px;
|
|
110
|
+
color: #666;
|
|
111
|
+
margin-top: 6px;
|
|
112
|
+
}
|
|
113
|
+
|
|
91
114
|
.form-group {
|
|
92
115
|
border: 1px solid #e0e0e0;
|
|
93
116
|
border-radius: 6px;
|
|
@@ -276,6 +299,21 @@ export class NodeEditor extends RapidElement {
|
|
|
276
299
|
.gutter-fields temba-select {
|
|
277
300
|
min-width: 120px;
|
|
278
301
|
}
|
|
302
|
+
|
|
303
|
+
.optional-field-link {
|
|
304
|
+
margin: 10px 0;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.optional-field-link a {
|
|
308
|
+
color: var(--color-link-primary, #0066cc);
|
|
309
|
+
text-decoration: none;
|
|
310
|
+
font-size: 13px;
|
|
311
|
+
cursor: pointer;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.optional-field-link a:hover {
|
|
315
|
+
text-decoration: underline;
|
|
316
|
+
}
|
|
279
317
|
`;
|
|
280
318
|
}
|
|
281
319
|
connectedCallback() {
|
|
@@ -326,7 +364,7 @@ export class NodeEditor extends RapidElement {
|
|
|
326
364
|
// Node editing mode - use node config
|
|
327
365
|
const nodeConfig = this.getNodeConfig();
|
|
328
366
|
if (nodeConfig === null || nodeConfig === void 0 ? void 0 : nodeConfig.toFormData) {
|
|
329
|
-
this.formData = nodeConfig.toFormData(this.node);
|
|
367
|
+
this.formData = nodeConfig.toFormData(this.node, this.nodeUI);
|
|
330
368
|
}
|
|
331
369
|
else {
|
|
332
370
|
this.formData = { ...this.node };
|
|
@@ -433,8 +471,12 @@ export class NodeEditor extends RapidElement {
|
|
|
433
471
|
return this.nodeUI.type ? NODE_CONFIG[this.nodeUI.type] : null;
|
|
434
472
|
}
|
|
435
473
|
getHeaderColor() {
|
|
474
|
+
var _a, _b;
|
|
436
475
|
const config = this.getConfig();
|
|
437
|
-
return (config === null || config === void 0 ? void 0 : config.
|
|
476
|
+
return (config === null || config === void 0 ? void 0 : config.group)
|
|
477
|
+
? ((_a = ACTION_GROUP_METADATA[config.group]) === null || _a === void 0 ? void 0 : _a.color) ||
|
|
478
|
+
((_b = SPLIT_GROUP_METADATA[config.group]) === null || _b === void 0 ? void 0 : _b.color)
|
|
479
|
+
: '#aaaaaa';
|
|
438
480
|
}
|
|
439
481
|
handleDialogButtonClick(event) {
|
|
440
482
|
const button = event.detail.button;
|
|
@@ -462,8 +504,14 @@ export class NodeEditor extends RapidElement {
|
|
|
462
504
|
if (this.node && this.node.router) {
|
|
463
505
|
// Node editing mode with router - use formDataToNode
|
|
464
506
|
const updatedNode = this.formDataToNode(processedFormData);
|
|
507
|
+
// Generate UI config if the node config provides a toUIConfig function
|
|
508
|
+
const nodeConfig = this.getNodeConfig();
|
|
509
|
+
const uiConfig = (nodeConfig === null || nodeConfig === void 0 ? void 0 : nodeConfig.toUIConfig)
|
|
510
|
+
? nodeConfig.toUIConfig(processedFormData)
|
|
511
|
+
: undefined;
|
|
465
512
|
this.fireCustomEvent(CustomEventType.NodeSaved, {
|
|
466
|
-
node: updatedNode
|
|
513
|
+
node: updatedNode,
|
|
514
|
+
uiConfig
|
|
467
515
|
});
|
|
468
516
|
}
|
|
469
517
|
else if (this.action) {
|
|
@@ -476,8 +524,14 @@ export class NodeEditor extends RapidElement {
|
|
|
476
524
|
else if (this.node) {
|
|
477
525
|
// Node editing mode without router
|
|
478
526
|
const updatedNode = this.formDataToNode(processedFormData);
|
|
527
|
+
// Generate UI config if the node config provides a toUIConfig function
|
|
528
|
+
const nodeConfig = this.getNodeConfig();
|
|
529
|
+
const uiConfig = (nodeConfig === null || nodeConfig === void 0 ? void 0 : nodeConfig.toUIConfig)
|
|
530
|
+
? nodeConfig.toUIConfig(processedFormData)
|
|
531
|
+
: undefined;
|
|
479
532
|
this.fireCustomEvent(CustomEventType.NodeSaved, {
|
|
480
|
-
node: updatedNode
|
|
533
|
+
node: updatedNode,
|
|
534
|
+
uiConfig
|
|
481
535
|
});
|
|
482
536
|
}
|
|
483
537
|
}
|
|
@@ -642,8 +696,14 @@ export class NodeEditor extends RapidElement {
|
|
|
642
696
|
if (!this.node)
|
|
643
697
|
throw new Error('No node to update');
|
|
644
698
|
let updatedNode = { ...this.node };
|
|
699
|
+
// Check if node config has fromFormData - if so, it handles the entire transformation
|
|
700
|
+
const nodeConfig = this.getNodeConfig();
|
|
701
|
+
const nodeHasFromFormData = (nodeConfig === null || nodeConfig === void 0 ? void 0 : nodeConfig.fromFormData) !== undefined;
|
|
645
702
|
// Handle actions using action config transformations if available
|
|
646
|
-
if
|
|
703
|
+
// Skip this if the node has its own fromFormData (which handles actions itself)
|
|
704
|
+
if (!nodeHasFromFormData &&
|
|
705
|
+
this.node.actions &&
|
|
706
|
+
this.node.actions.length > 0) {
|
|
647
707
|
updatedNode.actions = this.node.actions.map((action) => {
|
|
648
708
|
// If we're editing a specific action, only transform that one
|
|
649
709
|
if (this.action && action.uuid === this.action.uuid) {
|
|
@@ -664,53 +724,83 @@ export class NodeEditor extends RapidElement {
|
|
|
664
724
|
});
|
|
665
725
|
}
|
|
666
726
|
// Handle router configuration using node config
|
|
667
|
-
if (
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
727
|
+
if (nodeHasFromFormData) {
|
|
728
|
+
// Use node-specific form data transformation
|
|
729
|
+
// When a node has fromFormData, it's responsible for creating the entire
|
|
730
|
+
// node structure including actions and router (regardless of whether router exists yet)
|
|
731
|
+
updatedNode = nodeConfig.fromFormData(formData, updatedNode);
|
|
732
|
+
}
|
|
733
|
+
else if (this.node.router) {
|
|
734
|
+
// Default router handling when no nodeConfig.fromFormData
|
|
735
|
+
updatedNode.router = { ...this.node.router };
|
|
736
|
+
// Apply form data to router fields if they exist
|
|
737
|
+
if (formData.result_name !== undefined) {
|
|
738
|
+
updatedNode.router.result_name = formData.result_name;
|
|
672
739
|
}
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
//
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
740
|
+
// Handle preconfigured rules from node config
|
|
741
|
+
if ((_a = nodeConfig === null || nodeConfig === void 0 ? void 0 : nodeConfig.router) === null || _a === void 0 ? void 0 : _a.rules) {
|
|
742
|
+
// Build a complete new set of categories and exits based on node config
|
|
743
|
+
const existingCategories = updatedNode.router.categories || [];
|
|
744
|
+
const existingExits = updatedNode.exits || [];
|
|
745
|
+
const newCategories = [];
|
|
746
|
+
const newExits = [];
|
|
747
|
+
// Group rules by category name to handle multiple rules pointing to the same category
|
|
748
|
+
const categoryNameToRules = new Map();
|
|
749
|
+
nodeConfig.router.rules.forEach((rule) => {
|
|
750
|
+
if (!categoryNameToRules.has(rule.categoryName)) {
|
|
751
|
+
categoryNameToRules.set(rule.categoryName, []);
|
|
752
|
+
}
|
|
753
|
+
categoryNameToRules.get(rule.categoryName).push(rule);
|
|
754
|
+
});
|
|
755
|
+
// Create categories for all unique category names
|
|
756
|
+
categoryNameToRules.forEach((rules, categoryName) => {
|
|
757
|
+
// Check if category already exists to preserve its UUID and exit_uuid
|
|
758
|
+
const existingCategory = existingCategories.find((cat) => cat.name === categoryName);
|
|
759
|
+
if (existingCategory) {
|
|
760
|
+
// Preserve existing category and its associated exit
|
|
761
|
+
newCategories.push(existingCategory);
|
|
762
|
+
const associatedExit = existingExits.find((exit) => exit.uuid === existingCategory.exit_uuid);
|
|
763
|
+
if (associatedExit) {
|
|
764
|
+
newExits.push(associatedExit);
|
|
692
765
|
}
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
766
|
+
}
|
|
767
|
+
else {
|
|
768
|
+
// Create new category and exit
|
|
769
|
+
const categoryUuid = generateUUID();
|
|
770
|
+
const exitUuid = generateUUID();
|
|
771
|
+
newCategories.push({
|
|
772
|
+
uuid: categoryUuid,
|
|
773
|
+
name: categoryName,
|
|
774
|
+
exit_uuid: exitUuid
|
|
775
|
+
});
|
|
776
|
+
newExits.push({
|
|
777
|
+
uuid: exitUuid,
|
|
778
|
+
destination_uuid: null
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
});
|
|
782
|
+
// Add default category if specified
|
|
783
|
+
if (nodeConfig.router.defaultCategory) {
|
|
784
|
+
// Check if default category already exists in our new list
|
|
785
|
+
const existingDefault = newCategories.find((cat) => cat.name === nodeConfig.router.defaultCategory);
|
|
786
|
+
if (!existingDefault) {
|
|
787
|
+
// Check if it exists in the original categories
|
|
788
|
+
const originalDefault = existingCategories.find((cat) => cat.name === nodeConfig.router.defaultCategory);
|
|
789
|
+
if (originalDefault) {
|
|
790
|
+
// Preserve existing default category and its exit
|
|
791
|
+
newCategories.push(originalDefault);
|
|
792
|
+
const associatedExit = existingExits.find((exit) => exit.uuid === originalDefault.exit_uuid);
|
|
703
793
|
if (associatedExit) {
|
|
704
794
|
newExits.push(associatedExit);
|
|
705
795
|
}
|
|
706
796
|
}
|
|
707
797
|
else {
|
|
708
|
-
// Create new category and exit
|
|
798
|
+
// Create new default category and exit
|
|
709
799
|
const categoryUuid = generateUUID();
|
|
710
800
|
const exitUuid = generateUUID();
|
|
711
801
|
newCategories.push({
|
|
712
802
|
uuid: categoryUuid,
|
|
713
|
-
name:
|
|
803
|
+
name: nodeConfig.router.defaultCategory,
|
|
714
804
|
exit_uuid: exitUuid
|
|
715
805
|
});
|
|
716
806
|
newExits.push({
|
|
@@ -718,42 +808,11 @@ export class NodeEditor extends RapidElement {
|
|
|
718
808
|
destination_uuid: null
|
|
719
809
|
});
|
|
720
810
|
}
|
|
721
|
-
});
|
|
722
|
-
// Add default category if specified
|
|
723
|
-
if (nodeConfig.router.defaultCategory) {
|
|
724
|
-
// Check if default category already exists in our new list
|
|
725
|
-
const existingDefault = newCategories.find((cat) => cat.name === nodeConfig.router.defaultCategory);
|
|
726
|
-
if (!existingDefault) {
|
|
727
|
-
// Check if it exists in the original categories
|
|
728
|
-
const originalDefault = existingCategories.find((cat) => cat.name === nodeConfig.router.defaultCategory);
|
|
729
|
-
if (originalDefault) {
|
|
730
|
-
// Preserve existing default category and its exit
|
|
731
|
-
newCategories.push(originalDefault);
|
|
732
|
-
const associatedExit = existingExits.find((exit) => exit.uuid === originalDefault.exit_uuid);
|
|
733
|
-
if (associatedExit) {
|
|
734
|
-
newExits.push(associatedExit);
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
else {
|
|
738
|
-
// Create new default category and exit
|
|
739
|
-
const categoryUuid = generateUUID();
|
|
740
|
-
const exitUuid = generateUUID();
|
|
741
|
-
newCategories.push({
|
|
742
|
-
uuid: categoryUuid,
|
|
743
|
-
name: nodeConfig.router.defaultCategory,
|
|
744
|
-
exit_uuid: exitUuid
|
|
745
|
-
});
|
|
746
|
-
newExits.push({
|
|
747
|
-
uuid: exitUuid,
|
|
748
|
-
destination_uuid: null
|
|
749
|
-
});
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
811
|
}
|
|
753
|
-
// Replace the entire categories and exits lists with our complete new sets
|
|
754
|
-
updatedNode.router.categories = newCategories;
|
|
755
|
-
updatedNode.exits = newExits;
|
|
756
812
|
}
|
|
813
|
+
// Replace the entire categories and exits lists with our complete new sets
|
|
814
|
+
updatedNode.router.categories = newCategories;
|
|
815
|
+
updatedNode.exits = newExits;
|
|
757
816
|
}
|
|
758
817
|
}
|
|
759
818
|
else {
|
|
@@ -862,21 +921,28 @@ export class NodeEditor extends RapidElement {
|
|
|
862
921
|
}
|
|
863
922
|
});
|
|
864
923
|
}
|
|
865
|
-
|
|
924
|
+
/**
|
|
925
|
+
* Helper method to check if a field is visible based on its conditions
|
|
926
|
+
*/
|
|
927
|
+
isFieldVisible(fieldName, config) {
|
|
866
928
|
var _a;
|
|
867
|
-
// Check visibility condition
|
|
868
929
|
if ((_a = config.conditions) === null || _a === void 0 ? void 0 : _a.visible) {
|
|
869
930
|
try {
|
|
870
|
-
|
|
871
|
-
if (!isVisible) {
|
|
872
|
-
return html ``;
|
|
873
|
-
}
|
|
931
|
+
return config.conditions.visible(this.formData);
|
|
874
932
|
}
|
|
875
933
|
catch (error) {
|
|
876
934
|
console.error(`Error checking visibility for ${fieldName}:`, error);
|
|
877
935
|
// If there's an error, show the field by default
|
|
936
|
+
return true;
|
|
878
937
|
}
|
|
879
938
|
}
|
|
939
|
+
return true;
|
|
940
|
+
}
|
|
941
|
+
renderNewField(fieldName, config, value) {
|
|
942
|
+
// Check visibility condition
|
|
943
|
+
if (!this.isFieldVisible(fieldName, config)) {
|
|
944
|
+
return html ``;
|
|
945
|
+
}
|
|
880
946
|
const errors = this.errors[fieldName] ? [this.errors[fieldName]] : [];
|
|
881
947
|
// Build container style with maxWidth if specified
|
|
882
948
|
const containerStyle = config.maxWidth
|
|
@@ -889,6 +955,35 @@ export class NodeEditor extends RapidElement {
|
|
|
889
955
|
}
|
|
890
956
|
return fieldContent;
|
|
891
957
|
}
|
|
958
|
+
renderOptionalField(fieldName, config, value) {
|
|
959
|
+
// If the field has a value or has been revealed, show it
|
|
960
|
+
const hasValue = value && value.toString().trim() !== '';
|
|
961
|
+
const isRevealed = this.revealedOptionalFields.has(fieldName);
|
|
962
|
+
if (hasValue || isRevealed) {
|
|
963
|
+
// Render the field normally
|
|
964
|
+
return this.renderNewField(fieldName, config, value);
|
|
965
|
+
}
|
|
966
|
+
// Show the "Save as..." link
|
|
967
|
+
return html `
|
|
968
|
+
<div class="optional-field-link">
|
|
969
|
+
<a
|
|
970
|
+
href="#"
|
|
971
|
+
@click="${(e) => {
|
|
972
|
+
e.preventDefault();
|
|
973
|
+
this.revealOptionalField(fieldName);
|
|
974
|
+
}}"
|
|
975
|
+
>
|
|
976
|
+
${config.optionalLink}
|
|
977
|
+
</a>
|
|
978
|
+
</div>
|
|
979
|
+
`;
|
|
980
|
+
}
|
|
981
|
+
revealOptionalField(fieldName) {
|
|
982
|
+
this.revealedOptionalFields = new Set([
|
|
983
|
+
...this.revealedOptionalFields,
|
|
984
|
+
fieldName
|
|
985
|
+
]);
|
|
986
|
+
}
|
|
892
987
|
renderFieldContent(fieldName, config, value, errors) {
|
|
893
988
|
// Use FieldRenderer for consistent field rendering
|
|
894
989
|
return FieldRenderer.renderField(fieldName, config, value, {
|
|
@@ -977,7 +1072,12 @@ export class NodeEditor extends RapidElement {
|
|
|
977
1072
|
case 'field':
|
|
978
1073
|
if (config.form[item.field] && !renderedFields.has(item.field)) {
|
|
979
1074
|
renderedFields.add(item.field);
|
|
980
|
-
|
|
1075
|
+
const fieldConfig = config.form[item.field];
|
|
1076
|
+
// Handle optional link fields
|
|
1077
|
+
if (fieldConfig.optionalLink) {
|
|
1078
|
+
return this.renderOptionalField(item.field, fieldConfig, this.formData[item.field]);
|
|
1079
|
+
}
|
|
1080
|
+
return this.renderNewField(item.field, fieldConfig, this.formData[item.field]);
|
|
981
1081
|
}
|
|
982
1082
|
return html ``;
|
|
983
1083
|
case 'row':
|
|
@@ -989,24 +1089,68 @@ export class NodeEditor extends RapidElement {
|
|
|
989
1089
|
}
|
|
990
1090
|
}
|
|
991
1091
|
renderRow(rowConfig, config, renderedFields) {
|
|
992
|
-
const { items, gap = '1rem' } = rowConfig;
|
|
1092
|
+
const { items, gap = '1rem', label, helpText } = rowConfig;
|
|
993
1093
|
// Collect all fields from this row for width calculations
|
|
994
1094
|
const fieldsInRow = this.collectFieldsFromItems(items);
|
|
995
1095
|
const validFields = fieldsInRow.filter((fieldName) => { var _a; return (_a = config.form) === null || _a === void 0 ? void 0 : _a[fieldName]; });
|
|
996
|
-
|
|
1096
|
+
// Filter for visible fields only to handle conditional visibility
|
|
1097
|
+
const visibleFields = validFields.filter((fieldName) => {
|
|
1098
|
+
const fieldConfig = config.form[fieldName];
|
|
1099
|
+
return this.isFieldVisible(fieldName, fieldConfig);
|
|
1100
|
+
});
|
|
1101
|
+
if (visibleFields.length === 0) {
|
|
997
1102
|
return html ``;
|
|
998
1103
|
}
|
|
999
|
-
//
|
|
1000
|
-
|
|
1104
|
+
// Build a map of field flex styles
|
|
1105
|
+
// Fields with maxWidth get flex: 0 0 {maxWidth} (fixed)
|
|
1106
|
+
// Fields without maxWidth get flex: 1 1 0 (grow to fill space)
|
|
1107
|
+
const fieldFlexStyles = new Map();
|
|
1108
|
+
visibleFields.forEach((fieldName) => {
|
|
1001
1109
|
const fieldConfig = config.form[fieldName];
|
|
1002
|
-
|
|
1110
|
+
if (fieldConfig.maxWidth) {
|
|
1111
|
+
// Fixed width field: no grow, no shrink, basis = maxWidth
|
|
1112
|
+
fieldFlexStyles.set(fieldName, `flex: 0 0 ${fieldConfig.maxWidth};`);
|
|
1113
|
+
}
|
|
1114
|
+
else {
|
|
1115
|
+
// Flexible field: grow to fill remaining space
|
|
1116
|
+
fieldFlexStyles.set(fieldName, `flex: 1 1 0;`);
|
|
1117
|
+
}
|
|
1003
1118
|
});
|
|
1119
|
+
const rowContent = html `
|
|
1120
|
+
<div class="form-row" style="display: flex; gap: ${gap};">
|
|
1121
|
+
${items.map((item) => {
|
|
1122
|
+
// Get the field name from the item
|
|
1123
|
+
const fieldName = typeof item === 'string'
|
|
1124
|
+
? item
|
|
1125
|
+
: item.type === 'field'
|
|
1126
|
+
? item.field
|
|
1127
|
+
: null;
|
|
1128
|
+
// Get flex style for this field if it's a visible field
|
|
1129
|
+
const flexStyle = fieldName && fieldFlexStyles.has(fieldName)
|
|
1130
|
+
? fieldFlexStyles.get(fieldName)
|
|
1131
|
+
: '';
|
|
1132
|
+
const itemContent = this.renderLayoutItem(item, config, renderedFields);
|
|
1133
|
+
// Wrap in a div with flex style if we have a flex style
|
|
1134
|
+
return flexStyle
|
|
1135
|
+
? html `<div style="${flexStyle}">${itemContent}</div>`
|
|
1136
|
+
: itemContent;
|
|
1137
|
+
})}
|
|
1138
|
+
</div>
|
|
1139
|
+
`;
|
|
1140
|
+
// If no label or helpText, return just the row content
|
|
1141
|
+
if (!label && !helpText) {
|
|
1142
|
+
return rowContent;
|
|
1143
|
+
}
|
|
1144
|
+
// Otherwise, wrap with label on top, content, then helpText below (matching field pattern)
|
|
1004
1145
|
return html `
|
|
1005
|
-
<div
|
|
1006
|
-
class="form-row"
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1146
|
+
<div class="form-row-wrapper">
|
|
1147
|
+
${label ? html `<label class="form-row-label">${label}</label>` : ''}
|
|
1148
|
+
${rowContent}
|
|
1149
|
+
${helpText
|
|
1150
|
+
? html `<div class="form-row-help">
|
|
1151
|
+
${renderMarkdownInline(helpText)}
|
|
1152
|
+
</div>`
|
|
1153
|
+
: ''}
|
|
1010
1154
|
</div>
|
|
1011
1155
|
`;
|
|
1012
1156
|
}
|
|
@@ -1351,4 +1495,7 @@ __decorate([
|
|
|
1351
1495
|
__decorate([
|
|
1352
1496
|
state()
|
|
1353
1497
|
], NodeEditor.prototype, "groupHoverState", void 0);
|
|
1498
|
+
__decorate([
|
|
1499
|
+
state()
|
|
1500
|
+
], NodeEditor.prototype, "revealedOptionalFields", void 0);
|
|
1354
1501
|
//# sourceMappingURL=NodeEditor.js.map
|