@nyaruka/temba-components 0.131.1 → 0.131.3
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 +75 -1
- package/demo/components/floating-tabs/example.html +400 -0
- package/demo/components/flow/index.html +1 -1
- package/demo/data/flows/food-order.json +2 -2
- package/demo/data/flows/sample-flow.json +113 -125
- package/demo/data/flows/voicemail.json +613 -0
- package/demo/index.html +6 -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/static/svg/index.svg +1 -1
- package/dist/temba-components.js +1773 -662
- 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/display/FloatingTab.js +167 -0
- package/out-tsc/src/display/FloatingTab.js.map +1 -0
- package/out-tsc/src/display/ProgressBar.js +22 -2
- package/out-tsc/src/display/ProgressBar.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 +489 -47
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +1417 -67
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/NodeEditor.js +479 -112
- package/out-tsc/src/flow/NodeEditor.js.map +1 -1
- package/out-tsc/src/flow/NodeTypeSelector.js +540 -0
- package/out-tsc/src/flow/NodeTypeSelector.js.map +1 -0
- package/out-tsc/src/flow/StickyNote.js +12 -3
- package/out-tsc/src/flow/StickyNote.js.map +1 -1
- package/out-tsc/src/flow/actions/add_contact_groups.js +4 -3
- package/out-tsc/src/flow/actions/add_contact_groups.js.map +1 -1
- package/out-tsc/src/flow/actions/add_contact_urn.js +63 -4
- package/out-tsc/src/flow/actions/add_contact_urn.js.map +1 -1
- package/out-tsc/src/flow/actions/add_input_labels.js +4 -3
- package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -1
- package/out-tsc/src/flow/actions/play_audio.js +3 -2
- package/out-tsc/src/flow/actions/play_audio.js.map +1 -1
- package/out-tsc/src/flow/actions/remove_contact_groups.js +7 -5
- package/out-tsc/src/flow/actions/remove_contact_groups.js.map +1 -1
- package/out-tsc/src/flow/actions/request_optin.js +3 -2
- package/out-tsc/src/flow/actions/request_optin.js.map +1 -1
- package/out-tsc/src/flow/actions/say_msg.js +3 -2
- package/out-tsc/src/flow/actions/say_msg.js.map +1 -1
- package/out-tsc/src/flow/actions/send_broadcast.js +77 -23
- package/out-tsc/src/flow/actions/send_broadcast.js.map +1 -1
- package/out-tsc/src/flow/actions/send_email.js +5 -5
- package/out-tsc/src/flow/actions/send_email.js.map +1 -1
- package/out-tsc/src/flow/actions/send_msg.js +101 -21
- package/out-tsc/src/flow/actions/send_msg.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_channel.js +6 -9
- package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_field.js +20 -20
- package/out-tsc/src/flow/actions/set_contact_field.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_language.js +3 -2
- package/out-tsc/src/flow/actions/set_contact_language.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_name.js +3 -12
- package/out-tsc/src/flow/actions/set_contact_name.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_status.js +3 -2
- package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -1
- package/out-tsc/src/flow/actions/set_run_result.js +4 -3
- package/out-tsc/src/flow/actions/set_run_result.js.map +1 -1
- package/out-tsc/src/flow/actions/start_session.js +181 -6
- package/out-tsc/src/flow/actions/start_session.js.map +1 -1
- package/out-tsc/src/flow/config.js +11 -23
- 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 +71 -0
- package/out-tsc/src/flow/nodes/shared.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_airtime.js +211 -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 +152 -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 +73 -2
- package/out-tsc/src/flow/nodes/split_by_expression.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_groups.js +18 -10
- package/out-tsc/src/flow/nodes/split_by_groups.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_intent.js +8 -0
- package/out-tsc/src/flow/nodes/split_by_intent.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_llm.js +11 -3
- package/out-tsc/src/flow/nodes/split_by_llm.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +10 -3
- package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_random.js +10 -4
- package/out-tsc/src/flow/nodes/split_by_random.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_resthook.js +113 -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 +211 -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 +158 -2
- package/out-tsc/src/flow/nodes/split_by_scheme.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_subflow.js +13 -5
- package/out-tsc/src/flow/nodes/split_by_subflow.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_ticket.js +10 -3
- package/out-tsc/src/flow/nodes/split_by_ticket.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_webhook.js +10 -3
- package/out-tsc/src/flow/nodes/split_by_webhook.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_digits.js +3 -2
- package/out-tsc/src/flow/nodes/wait_for_digits.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_menu.js +3 -2
- package/out-tsc/src/flow/nodes/wait_for_menu.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_response.js +38 -568
- package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
- package/out-tsc/src/flow/types.js +86 -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/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/layout/FloatingWindow.js +346 -0
- package/out-tsc/src/layout/FloatingWindow.js.map +1 -0
- 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 +6 -25
- package/out-tsc/src/live/ContactChat.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/store/AppState.js +120 -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 +8 -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-floating-tab.test.js +91 -0
- package/out-tsc/test/temba-floating-tab.test.js.map +1 -0
- package/out-tsc/test/temba-floating-window.test.js +301 -0
- package/out-tsc/test/temba-floating-window.test.js.map +1 -0
- package/out-tsc/test/temba-flow-editor-node.test.js +202 -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-localization.test.js +471 -0
- package/out-tsc/test/temba-localization.test.js.map +1 -0
- 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 +265 -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 +20 -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/floating-tab/default.png +0 -0
- package/screenshots/truth/floating-tab/gray.png +0 -0
- package/screenshots/truth/floating-tab/green.png +0 -0
- package/screenshots/truth/floating-tab/hidden.png +0 -0
- package/screenshots/truth/floating-tab/hover.png +0 -0
- package/screenshots/truth/floating-tab/purple.png +0 -0
- package/screenshots/truth/floating-window/chromeless.png +0 -0
- package/screenshots/truth/floating-window/custom-size.png +0 -0
- package/screenshots/truth/floating-window/default.png +0 -0
- package/screenshots/truth/floating-window/with-header.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/display/FloatingTab.ts +174 -0
- package/src/display/ProgressBar.ts +22 -2
- package/src/events.ts +2 -8
- package/src/flow/CanvasMenu.ts +217 -0
- package/src/flow/CanvasNode.ts +596 -40
- package/src/flow/Editor.ts +1721 -45
- package/src/flow/NodeEditor.ts +621 -144
- package/src/flow/NodeTypeSelector.ts +636 -0
- package/src/flow/StickyNote.ts +12 -3
- package/src/flow/actions/add_contact_groups.ts +5 -4
- package/src/flow/actions/add_contact_urn.ts +78 -4
- package/src/flow/actions/add_input_labels.ts +5 -4
- package/src/flow/actions/play_audio.ts +3 -2
- package/src/flow/actions/remove_contact_groups.ts +16 -6
- package/src/flow/actions/request_optin.ts +3 -2
- package/src/flow/actions/say_msg.ts +3 -2
- package/src/flow/actions/send_broadcast.ts +86 -23
- package/src/flow/actions/send_email.ts +12 -6
- package/src/flow/actions/send_msg.ts +155 -34
- package/src/flow/actions/set_contact_channel.ts +6 -11
- package/src/flow/actions/set_contact_field.ts +21 -25
- package/src/flow/actions/set_contact_language.ts +11 -4
- package/src/flow/actions/set_contact_name.ts +4 -15
- package/src/flow/actions/set_contact_status.ts +4 -3
- package/src/flow/actions/set_run_result.ts +5 -4
- package/src/flow/actions/start_session.ts +210 -6
- package/src/flow/config.ts +11 -23
- package/src/flow/currencies.ts +51 -0
- package/src/flow/nodes/shared-rules.ts +301 -0
- package/src/flow/nodes/shared.ts +87 -0
- package/src/flow/nodes/split_by_airtime.ts +255 -5
- package/src/flow/nodes/split_by_contact_field.ts +195 -3
- package/src/flow/nodes/split_by_expression.ts +104 -2
- package/src/flow/nodes/split_by_groups.ts +26 -11
- package/src/flow/nodes/split_by_intent.ts +8 -0
- package/src/flow/nodes/split_by_llm.ts +22 -4
- package/src/flow/nodes/split_by_llm_categorize.ts +22 -5
- package/src/flow/nodes/split_by_random.ts +16 -6
- package/src/flow/nodes/split_by_resthook.ts +140 -0
- package/src/flow/nodes/split_by_run_result.ts +259 -3
- package/src/flow/nodes/split_by_scheme.ts +202 -2
- package/src/flow/nodes/split_by_subflow.ts +17 -5
- package/src/flow/nodes/split_by_ticket.ts +15 -4
- package/src/flow/nodes/split_by_webhook.ts +17 -6
- package/src/flow/nodes/wait_for_digits.ts +3 -2
- package/src/flow/nodes/wait_for_menu.ts +3 -2
- package/src/flow/nodes/wait_for_response.ts +59 -680
- package/src/flow/types.ts +156 -23
- package/src/flow/utils.ts +108 -14
- package/src/form/FieldRenderer.ts +2 -4
- package/src/interfaces.ts +3 -0
- package/src/layout/FloatingWindow.ts +386 -0
- package/src/list/SortableList.ts +109 -34
- package/src/live/ContactChat.ts +7 -25
- 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/store/AppState.ts +173 -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/llms.json +18 -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 +8 -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-floating-tab.test.ts +110 -0
- package/test/temba-floating-window.test.ts +477 -0
- package/test/temba-flow-editor-node.test.ts +246 -2
- package/test/temba-flow-editor.test.ts +7 -8
- package/test/temba-localization.test.ts +611 -0
- package/test/temba-node-editor.test.ts +3 -1
- package/test/temba-node-type-selector.test.ts +355 -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 +22 -0
- package/test-assets/contacts/history.json +14 -21
- package/test-assets/select/llms.json +2 -2
- package/web-dev-server.config.mjs +49 -1
- package/web-test-runner.config.mjs +0 -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/out-tsc/src/flow/nodes/wait_for_audio.js +0 -7
- package/out-tsc/src/flow/nodes/wait_for_audio.js.map +0 -1
- package/out-tsc/src/flow/nodes/wait_for_image.js +0 -7
- package/out-tsc/src/flow/nodes/wait_for_image.js.map +0 -1
- package/out-tsc/src/flow/nodes/wait_for_location.js +0 -7
- package/out-tsc/src/flow/nodes/wait_for_location.js.map +0 -1
- package/out-tsc/src/flow/nodes/wait_for_video.js +0 -7
- package/out-tsc/src/flow/nodes/wait_for_video.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
- package/src/flow/nodes/wait_for_audio.ts +0 -7
- package/src/flow/nodes/wait_for_image.ts +0 -7
- package/src/flow/nodes/wait_for_location.ts +0 -7
- package/src/flow/nodes/wait_for_video.ts +0 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FieldRenderer.js","sourceRoot":"","sources":["../../../src/form/FieldRenderer.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, TemplateResult } from 'lit';\nimport {\n FieldConfig,\n TextFieldConfig,\n TextareaFieldConfig,\n SelectFieldConfig,\n CheckboxFieldConfig,\n MessageEditorFieldConfig,\n KeyValueFieldConfig,\n ArrayFieldConfig\n} from '../flow/types';\n\n/**\n * FieldRenderer provides a consistent way to render field configurations\n * into web components across different contexts (NodeEditor, ArrayEditor, etc.)\n */\nexport class FieldRenderer {\n /**\n * Renders a field based on its configuration\n * @param fieldName - The name of the field\n * @param config - The field configuration\n * @param value - The current value of the field\n * @param context - Additional context for rendering\n * @returns A TemplateResult for the rendered field\n */\n static renderField(\n fieldName: string,\n config: FieldConfig,\n value: any,\n context: FieldRenderContext = {}\n ): TemplateResult {\n /*const {\n errors = [],\n onChange,\n showLabel = true,\n flavor,\n extraClasses = '',\n style = ''\n } = context;*/\n switch (config.type) {\n case 'text':\n return FieldRenderer.renderTextInput(fieldName, config, value, context);\n\n case 'textarea':\n return FieldRenderer.renderTextarea(\n fieldName,\n config as TextareaFieldConfig,\n value,\n context\n );\n\n case 'select':\n return FieldRenderer.renderSelect(\n fieldName,\n config as SelectFieldConfig,\n value,\n context\n );\n\n case 'checkbox':\n return FieldRenderer.renderCheckbox(\n fieldName,\n config as CheckboxFieldConfig,\n value,\n context\n );\n\n case 'key-value':\n return FieldRenderer.renderKeyValue(\n fieldName,\n config as KeyValueFieldConfig,\n value,\n context\n );\n\n case 'array':\n return FieldRenderer.renderArray(\n fieldName,\n config as ArrayFieldConfig,\n value,\n context\n );\n\n case 'message-editor':\n return FieldRenderer.renderMessageEditor(\n fieldName,\n config as MessageEditorFieldConfig,\n value,\n context\n );\n\n default:\n return html`<div>Unsupported field type: ${(config as any).type}</div>`;\n }\n }\n\n private static renderTextInput(\n fieldName: string,\n config: TextFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n // If field supports expression evaluation, use temba-completion\n if (config.evaluated) {\n return html`<temba-completion\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n expressions=\"session\"\n .helpText=\"${config.helpText || ''}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-completion>`;\n }\n\n return html`<temba-textinput\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n .helpText=\"${config.helpText || ''}\"\n flavor=\"${config.flavor || 'default'}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-textinput>`;\n }\n\n private static renderTextarea(\n fieldName: string,\n config: TextareaFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n const minHeightStyle = config.minHeight\n ? `--textarea-min-height: ${config.minHeight}px;`\n : '';\n const combinedStyle = `${minHeightStyle}${style}`;\n\n // If field supports expression evaluation, use temba-completion\n if (config.evaluated) {\n return html`<temba-completion\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n textarea\n expressions=\"session\"\n .helpText=\"${config.helpText || ''}\"\n class=\"${extraClasses}\"\n style=\"${combinedStyle}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-completion>`;\n }\n\n return html`<temba-textinput\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n textarea\n .rows=\"${config.rows || 3}\"\n .helpText=\"${config.helpText || ''}\"\n class=\"${extraClasses}\"\n style=\"${combinedStyle}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-textinput>`;\n }\n\n private static renderSelect(\n fieldName: string,\n config: SelectFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n flavor,\n extraClasses,\n style\n } = context;\n\n // Get options - use dynamic options if available, otherwise use static options\n const optionsToRender = config.getDynamicOptions\n ? config.getDynamicOptions()\n : config.options;\n\n return html`<temba-select\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .values=${value}\n ?multi=\"${config.multi}\"\n ?searchable=\"${config.searchable}\"\n ?tags=\"${config.tags}\"\n ?emails=\"${config.emails}\"\n ?clearable=\"${config.clearable || false}\"\n placeholder=\"${config.placeholder || ''}\"\n maxItems=\"${config.maxItems || 0}\"\n valueKey=\"${config.valueKey || 'value'}\"\n nameKey=\"${config.nameKey || 'name'}\"\n endpoint=\"${config.endpoint || ''}\"\n .helpText=\"${config.helpText || ''}\"\n flavor=\"${flavor || config.flavor || 'small'}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n .getName=${config.getName}\n .createArbitraryOption=${config.createArbitraryOption}\n ?allowCreate=\"${config.allowCreate || false}\"\n @change=\"${onChange || (() => {})}\"\n >\n ${optionsToRender?.map((option: any) => {\n if (typeof option === 'string') {\n return html`<temba-option\n name=\"${option}\"\n value=\"${option}\"\n ></temba-option>`;\n } else {\n return html`<temba-option\n name=\"${option.label || option.name}\"\n value=\"${option.value}\"\n ></temba-option>`;\n }\n })}\n </temba-select>`;\n }\n\n private static renderCheckbox(\n fieldName: string,\n config: CheckboxFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n extraClasses,\n style,\n formData = {}\n } = context;\n\n // Handle dynamic labels\n const label =\n typeof config.label === 'function'\n ? config.label(formData)\n : config.label;\n\n // Build custom style including labelPadding\n const customStyle = config.labelPadding\n ? `--checkbox-padding: ${config.labelPadding}; ${style || ''}`\n : style || '';\n\n return html`<div class=\"form-field\">\n <temba-checkbox\n name=\"${fieldName}\"\n label=\"${label}\"\n .helpText=\"${config.helpText || ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n ?checked=\"${value || false}\"\n size=\"${config.size || 1.2}\"\n animateChange=\"${config.animateChange || 'pulse'}\"\n class=\"${extraClasses}\"\n style=\"${customStyle}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-checkbox>\n ${errors.length\n ? html`<div class=\"field-errors\">${errors.join(', ')}</div>`\n : ''}\n </div>`;\n }\n\n private static renderKeyValue(\n fieldName: string,\n config: KeyValueFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n return html`<div class=\"form-field\">\n ${showLabel ? html`<label>${config.label}</label>` : ''}\n <temba-key-value-editor\n name=\"${fieldName}\"\n .value=\"${value || []}\"\n .sortable=\"${config.sortable}\"\n .keyPlaceholder=\"${config.keyPlaceholder || 'Key'}\"\n .valuePlaceholder=\"${config.valuePlaceholder || 'Value'}\"\n .minRows=\"${config.minRows || 0}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-key-value-editor>\n ${errors.length\n ? html`<div class=\"field-errors\">${errors.join(', ')}</div>`\n : ''}\n </div>`;\n }\n\n private static renderArray(\n fieldName: string,\n config: ArrayFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n return html`<div class=\"form-field\">\n <temba-array-editor\n name=\"${fieldName}\"\n .label=\"${showLabel ? config.label : ''}\"\n .value=\"${value || []}\"\n .itemConfig=\"${config.itemConfig}\"\n .sortable=\"${config.sortable}\"\n .itemLabel=\"${config.itemLabel || 'Item'}\"\n .minItems=\"${config.minItems || 0}\"\n .maxItems=\"${config.maxItems || 0}\"\n ?maintainEmptyItem=\"${config.maintainEmptyItem !== false}\"\n .onItemChange=\"${config.onItemChange}\"\n .isEmptyItemFn=\"${config.isEmptyItem}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-array-editor>\n ${errors.length\n ? html`<div class=\"field-errors\">${errors.join(', ')}</div>`\n : ''}\n </div>`;\n }\n\n private static renderMessageEditor(\n fieldName: string,\n config: MessageEditorFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style,\n additionalData = {}\n } = context;\n\n return html`<temba-message-editor\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n .attachments=\"${additionalData.attachments || []}\"\n placeholder=\"${config.placeholder || ''}\"\n .helpText=\"${config.helpText || ''}\"\n ?autogrow=\"${config.autogrow}\"\n ?gsm=\"${config.gsm}\"\n ?disableCompletion=\"${config.disableCompletion}\"\n counter=\"${config.counter || ''}\"\n accept=\"${config.accept || ''}\"\n endpoint=\"${config.endpoint || ''}\"\n max-attachments=\"${config.maxAttachments || 3}\"\n minHeight=\"${config.minHeight || 60}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-message-editor>`;\n }\n}\n\nexport interface FieldRenderContext {\n /** Array of error messages for the field */\n errors?: string[];\n /** Change event handler */\n onChange?: (event: Event) => void;\n /** Whether to show the field label */\n showLabel?: boolean;\n /** Flavor for components that support it (like temba-select) */\n flavor?: string;\n /** Additional CSS classes to apply */\n extraClasses?: string;\n /** Additional CSS styles to apply */\n style?: string;\n /** Additional data needed for specific field types */\n additionalData?: Record<string, any>;\n /** Form data for dynamic field configurations */\n formData?: Record<string, any>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"FieldRenderer.js","sourceRoot":"","sources":["../../../src/form/FieldRenderer.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, TemplateResult } from 'lit';\nimport { spread } from '@open-wc/lit-helpers';\nimport {\n FieldConfig,\n TextFieldConfig,\n TextareaFieldConfig,\n SelectFieldConfig,\n CheckboxFieldConfig,\n MessageEditorFieldConfig,\n KeyValueFieldConfig,\n ArrayFieldConfig\n} from '../flow/types';\n\n/**\n * FieldRenderer provides a consistent way to render field configurations\n * into web components across different contexts (NodeEditor, ArrayEditor, etc.)\n */\nexport class FieldRenderer {\n /**\n * Renders a field based on its configuration\n * @param fieldName - The name of the field\n * @param config - The field configuration\n * @param value - The current value of the field\n * @param context - Additional context for rendering\n * @returns A TemplateResult for the rendered field\n */\n static renderField(\n fieldName: string,\n config: FieldConfig,\n value: any,\n context: FieldRenderContext = {}\n ): TemplateResult {\n /*const {\n errors = [],\n onChange,\n showLabel = true,\n flavor,\n extraClasses = '',\n style = ''\n } = context;*/\n switch (config.type) {\n case 'text':\n return FieldRenderer.renderTextInput(fieldName, config, value, context);\n\n case 'textarea':\n return FieldRenderer.renderTextarea(\n fieldName,\n config as TextareaFieldConfig,\n value,\n context\n );\n\n case 'select':\n return FieldRenderer.renderSelect(\n fieldName,\n config as SelectFieldConfig,\n value,\n context\n );\n\n case 'checkbox':\n return FieldRenderer.renderCheckbox(\n fieldName,\n config as CheckboxFieldConfig,\n value,\n context\n );\n\n case 'key-value':\n return FieldRenderer.renderKeyValue(\n fieldName,\n config as KeyValueFieldConfig,\n value,\n context\n );\n\n case 'array':\n return FieldRenderer.renderArray(\n fieldName,\n config as ArrayFieldConfig,\n value,\n context\n );\n\n case 'message-editor':\n return FieldRenderer.renderMessageEditor(\n fieldName,\n config as MessageEditorFieldConfig,\n value,\n context\n );\n\n default:\n return html`<div>Unsupported field type: ${(config as any).type}</div>`;\n }\n }\n\n private static renderTextInput(\n fieldName: string,\n config: TextFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n // If field supports expression evaluation, use temba-completion\n if (config.evaluated) {\n return html`<temba-completion\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n expressions=\"session\"\n .helpText=\"${config.helpText || ''}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-completion>`;\n }\n\n return html`<temba-textinput\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n .helpText=\"${config.helpText || ''}\"\n flavor=\"${config.flavor || 'default'}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-textinput>`;\n }\n\n private static renderTextarea(\n fieldName: string,\n config: TextareaFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n const minHeightStyle = config.minHeight\n ? `--textarea-min-height: ${config.minHeight}px;`\n : '';\n const combinedStyle = `${minHeightStyle}${style}`;\n\n // If field supports expression evaluation, use temba-completion\n if (config.evaluated) {\n return html`<temba-completion\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n textarea\n expressions=\"session\"\n .helpText=\"${config.helpText || ''}\"\n class=\"${extraClasses}\"\n style=\"${combinedStyle}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-completion>`;\n }\n\n return html`<temba-textinput\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n textarea\n .rows=\"${config.rows || 3}\"\n .helpText=\"${config.helpText || ''}\"\n class=\"${extraClasses}\"\n style=\"${combinedStyle}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-textinput>`;\n }\n\n private static renderSelect(\n fieldName: string,\n config: SelectFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n flavor,\n extraClasses,\n style\n } = context;\n\n // Get options - use dynamic options if available, otherwise use static options\n const optionsToRender = config.getDynamicOptions\n ? config.getDynamicOptions()\n : config.options;\n\n return html`<temba-select\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .values=${value}\n ?multi=\"${config.multi}\"\n ?searchable=\"${config.searchable}\"\n ?tags=\"${config.tags}\"\n ?emails=\"${config.emails}\"\n ?clearable=\"${config.clearable || false}\"\n placeholder=\"${config.placeholder || ''}\"\n maxItems=\"${config.maxItems || 0}\"\n valueKey=\"${config.valueKey || 'value'}\"\n nameKey=\"${config.nameKey || 'name'}\"\n endpoint=\"${config.endpoint || ''}\"\n .helpText=\"${config.helpText || ''}\"\n flavor=\"${flavor || config.flavor || 'small'}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n .getName=${config.getName}\n .createArbitraryOption=${config.createArbitraryOption}\n ?allowCreate=\"${config.allowCreate || false}\"\n @change=\"${onChange || (() => {})}\"\n >\n ${optionsToRender?.map((option: any) => {\n if (typeof option === 'string') {\n return html`<temba-option\n name=\"${option}\"\n value=\"${option}\"\n ></temba-option>`;\n } else {\n return html`<temba-option ${spread(option)}></temba-option>`;\n }\n })}\n </temba-select>`;\n }\n\n private static renderCheckbox(\n fieldName: string,\n config: CheckboxFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n extraClasses,\n style,\n formData = {}\n } = context;\n\n // Handle dynamic labels\n const label =\n typeof config.label === 'function'\n ? config.label(formData)\n : config.label;\n\n // Build custom style including labelPadding\n const customStyle = config.labelPadding\n ? `--checkbox-padding: ${config.labelPadding}; ${style || ''}`\n : style || '';\n\n return html`<div class=\"form-field\">\n <temba-checkbox\n name=\"${fieldName}\"\n label=\"${label}\"\n .helpText=\"${config.helpText || ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n ?checked=\"${value || false}\"\n size=\"${config.size || 1.2}\"\n animateChange=\"${config.animateChange || 'pulse'}\"\n class=\"${extraClasses}\"\n style=\"${customStyle}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-checkbox>\n ${errors.length\n ? html`<div class=\"field-errors\">${errors.join(', ')}</div>`\n : ''}\n </div>`;\n }\n\n private static renderKeyValue(\n fieldName: string,\n config: KeyValueFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n return html`<div class=\"form-field\">\n ${showLabel ? html`<label>${config.label}</label>` : ''}\n <temba-key-value-editor\n name=\"${fieldName}\"\n .value=\"${value || []}\"\n .sortable=\"${config.sortable}\"\n .keyPlaceholder=\"${config.keyPlaceholder || 'Key'}\"\n .valuePlaceholder=\"${config.valuePlaceholder || 'Value'}\"\n .minRows=\"${config.minRows || 0}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-key-value-editor>\n ${errors.length\n ? html`<div class=\"field-errors\">${errors.join(', ')}</div>`\n : ''}\n </div>`;\n }\n\n private static renderArray(\n fieldName: string,\n config: ArrayFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n return html`<div class=\"form-field\">\n <temba-array-editor\n name=\"${fieldName}\"\n .label=\"${showLabel ? config.label : ''}\"\n .value=\"${value || []}\"\n .itemConfig=\"${config.itemConfig}\"\n .sortable=\"${config.sortable}\"\n .itemLabel=\"${config.itemLabel || 'Item'}\"\n .minItems=\"${config.minItems || 0}\"\n .maxItems=\"${config.maxItems || 0}\"\n ?maintainEmptyItem=\"${config.maintainEmptyItem !== false}\"\n .onItemChange=\"${config.onItemChange}\"\n .isEmptyItemFn=\"${config.isEmptyItem}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-array-editor>\n ${errors.length\n ? html`<div class=\"field-errors\">${errors.join(', ')}</div>`\n : ''}\n </div>`;\n }\n\n private static renderMessageEditor(\n fieldName: string,\n config: MessageEditorFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style,\n additionalData = {}\n } = context;\n\n return html`<temba-message-editor\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n .attachments=\"${additionalData.attachments || []}\"\n placeholder=\"${config.placeholder || ''}\"\n .helpText=\"${config.helpText || ''}\"\n ?autogrow=\"${config.autogrow}\"\n ?gsm=\"${config.gsm}\"\n ?disableCompletion=\"${config.disableCompletion}\"\n counter=\"${config.counter || ''}\"\n accept=\"${config.accept || ''}\"\n endpoint=\"${config.endpoint || ''}\"\n max-attachments=\"${config.maxAttachments || 3}\"\n minHeight=\"${config.minHeight || 60}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-message-editor>`;\n }\n}\n\nexport interface FieldRenderContext {\n /** Array of error messages for the field */\n errors?: string[];\n /** Change event handler */\n onChange?: (event: Event) => void;\n /** Whether to show the field label */\n showLabel?: boolean;\n /** Flavor for components that support it (like temba-select) */\n flavor?: string;\n /** Additional CSS classes to apply */\n extraClasses?: string;\n /** Additional CSS styles to apply */\n style?: string;\n /** Additional data needed for specific field types */\n additionalData?: Record<string, any>;\n /** Form data for dynamic field configurations */\n formData?: Record<string, any>;\n}\n"]}
|
|
@@ -38,6 +38,8 @@ export var CustomEventType;
|
|
|
38
38
|
CustomEventType["OrderChanged"] = "temba-order-changed";
|
|
39
39
|
CustomEventType["DragStart"] = "temba-drag-start";
|
|
40
40
|
CustomEventType["DragStop"] = "temba-drag-stop";
|
|
41
|
+
CustomEventType["DragExternal"] = "temba-drag-external";
|
|
42
|
+
CustomEventType["DragInternal"] = "temba-drag-internal";
|
|
41
43
|
CustomEventType["Resized"] = "temba-resized";
|
|
42
44
|
CustomEventType["DetailsChanged"] = "temba-details-changed";
|
|
43
45
|
CustomEventType["Error"] = "temba-error";
|
|
@@ -48,6 +50,7 @@ export var CustomEventType;
|
|
|
48
50
|
CustomEventType["DateRangeChanged"] = "temba-date-range-changed";
|
|
49
51
|
CustomEventType["NodeDeleted"] = "temba-node-deleted";
|
|
50
52
|
CustomEventType["ActionEditRequested"] = "temba-action-edit-requested";
|
|
53
|
+
CustomEventType["AddActionRequested"] = "temba-add-action-requested";
|
|
51
54
|
CustomEventType["ActionSaved"] = "temba-action-saved";
|
|
52
55
|
CustomEventType["ActionEditCanceled"] = "temba-action-edit-canceled";
|
|
53
56
|
CustomEventType["NodeEditRequested"] = "temba-node-edit-requested";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../src/interfaces.ts"],"names":[],"mappings":"AAwBA,MAAM,CAAN,IAAY,SAIX;AAJD,WAAY,SAAS;IACnB,mCAAsB,CAAA;IACtB,uCAA0B,CAAA;IAC1B,qCAAwB,CAAA;AAC1B,CAAC,EAJW,SAAS,KAAT,SAAS,QAIpB;AAED,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,sDAAgC,CAAA;IAChC,gEAA0C,CAAA;IAC1C,4DAAsC,CAAA;AACxC,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B;AAED,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,6BAAa,CAAA;IACb,iCAAiB,CAAA;AACnB,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB;AA2ND,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../src/interfaces.ts"],"names":[],"mappings":"AAwBA,MAAM,CAAN,IAAY,SAIX;AAJD,WAAY,SAAS;IACnB,mCAAsB,CAAA;IACtB,uCAA0B,CAAA;IAC1B,qCAAwB,CAAA;AAC1B,CAAC,EAJW,SAAS,KAAT,SAAS,QAIpB;AAED,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,sDAAgC,CAAA;IAChC,gEAA0C,CAAA;IAC1C,4DAAsC,CAAA;AACxC,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B;AAED,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,6BAAa,CAAA;IACb,iCAAiB,CAAA;AACnB,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB;AA2ND,MAAM,CAAN,IAAY,eAwCX;AAxCD,WAAY,eAAe;IACzB,0CAAuB,CAAA;IACvB,4CAAyB,CAAA;IACzB,8CAA2B,CAAA;IAC3B,yDAAsC,CAAA;IACtC,gDAA6B,CAAA;IAC7B,gDAA6B,CAAA;IAC7B,yDAAsC,CAAA;IACtC,uDAAoC,CAAA;IACpC,6DAA0C,CAAA;IAC1C,2DAAwC,CAAA;IACxC,2DAAwC,CAAA;IACxC,yDAAsC,CAAA;IACtC,qDAAkC,CAAA;IAClC,gDAA6B,CAAA;IAC7B,kDAA+B,CAAA;IAC/B,2CAAwB,CAAA;IACxB,uDAAoC,CAAA;IACpC,wCAAqB,CAAA;IACrB,uDAAoC,CAAA;IACpC,iDAA8B,CAAA;IAC9B,+CAA4B,CAAA;IAC5B,uDAAoC,CAAA;IACpC,uDAAoC,CAAA;IACpC,4CAAyB,CAAA;IACzB,2DAAwC,CAAA;IACxC,wCAAqB,CAAA;IACrB,gDAA6B,CAAA;IAC7B,0CAAuB,CAAA;IACvB,yDAAsC,CAAA;IACtC,wCAAqB,CAAA;IACrB,gEAA6C,CAAA;IAC7C,qDAAkC,CAAA;IAClC,sEAAmD,CAAA;IACnD,oEAAiD,CAAA;IACjD,qDAAkC,CAAA;IAClC,oEAAiD,CAAA;IACjD,kEAA+C,CAAA;IAC/C,iDAA8B,CAAA;IAC9B,kEAA+C,CAAA;AACjD,CAAC,EAxCW,eAAe,KAAf,eAAe,QAwC1B","sourcesContent":["export interface Workspace {\n uuid: string;\n name: string;\n country: string;\n languages: string[];\n timezone: string;\n date_style: DateStyle;\n anon: boolean;\n}\n\nexport interface Language {\n iso: string;\n name: string;\n}\n\nexport interface Attachment {\n uuid: string;\n content_type: string;\n url: string;\n filename: string;\n size: number;\n error: string;\n}\n\nexport enum DateStyle {\n DayFirst = 'day_first',\n MonthFirst = 'month_first',\n YearFirst = 'year_first'\n}\n\nexport enum ScheduledEventType {\n CampaignEvent = 'campaign_event',\n ScheduledBroadcast = 'scheduled_broadcast',\n ScheduledTrigger = 'scheduled_trigger'\n}\n\nexport enum TicketStatus {\n Open = 'open',\n Closed = 'closed'\n}\n\nexport interface ScheduledEvent {\n type: ScheduledEventType;\n scheduled: string;\n repeat_period: string;\n campaign?: ObjectReference;\n flow?: ObjectReference;\n message?: string;\n}\n\nexport interface NamedUser extends User {\n name: string;\n}\n\nexport interface User {\n id?: number;\n first_name?: string;\n last_name?: string;\n name?: string;\n email?: string;\n role?: string;\n created_on?: string;\n avatar?: string;\n}\n\nexport interface Ticket {\n uuid: string;\n subject: string;\n body?: string;\n closed_on: string;\n opened_on: string;\n status: string;\n contact: ObjectReference;\n topic: ObjectReference;\n assignee?: { email: string; name: string; avatar?: string };\n}\n\nexport interface FlowResult {\n key: string;\n name: string;\n categories: string[];\n node_uuids: string[];\n}\n\nexport interface FlowDetails {\n name: string;\n results: FlowResult[];\n modified_on: string;\n runs: {\n active: number;\n completed: number;\n expired: number;\n interrupted: number;\n };\n}\n\nexport interface Msg {\n text: string;\n status: string;\n channel: ObjectReference;\n quick_replies: string[];\n urn: string;\n direction: string;\n type: string;\n attachments: string[];\n}\n\nexport interface ObjectReference {\n uuid: string;\n name: string;\n}\n\nexport interface Shortcut {\n uuid: string;\n name: string;\n text: string;\n modified_on: string;\n}\n\nexport interface ContactField {\n key: string;\n label: string;\n value_type: string;\n featured: boolean;\n priority: number;\n agent_access: string;\n type: string;\n usages: { campaign_events: number; flows: number; groups: number };\n}\n\nexport interface ContactGroup {\n uuid: string;\n count: number;\n name: string;\n query?: string;\n status: string;\n}\n\nexport interface URN {\n scheme: string;\n path: string;\n}\n\nexport interface Group {\n name: string;\n uuid: string;\n is_dynamic?: boolean;\n}\n\nexport interface ContactNote {\n text: string;\n created_on: string;\n created_by: NamedUser;\n}\n\nexport interface ContactTicket {\n name: string;\n uuid: string;\n status: string;\n\n contact: {\n uuid: string;\n name: string;\n created_on: Date;\n last_seen_on: Date;\n };\n}\n\nexport interface Contact {\n name: string;\n uuid: string;\n stopped: boolean;\n blocked: boolean;\n urns: string[];\n language?: string;\n fields: { [key: string]: string };\n groups: Group[];\n notes: ContactNote[];\n modified_on: string;\n created_on: string;\n last_seen_on: string;\n status: string;\n\n ref?: string; // only returned for anon workspaces\n flow?: ObjectReference;\n last_msg?: Msg;\n direction?: string;\n ticket: {\n uuid: string;\n subject: string;\n closed_on?: string;\n last_activity_on: string;\n assignee?: User;\n topic?: ObjectReference;\n };\n}\n\nexport interface FeatureProperties {\n name: string;\n osm_id: string;\n level: number;\n children?: FeatureProperties[];\n has_children?: boolean;\n aliases?: string;\n parent_osm_id?: string;\n id?: number;\n path?: string;\n}\n\nexport interface Position {\n top: number;\n left: number;\n}\n\nexport interface FunctionExample {\n template: string;\n output: string;\n}\n\nexport interface CompletionOption {\n name?: string;\n summary: string;\n\n // functions\n signature?: string;\n detail?: string;\n examples?: FunctionExample[];\n}\n\nexport interface CompletionResult {\n anchorPosition: Position;\n query: string;\n options: CompletionOption[];\n currentFunction: CompletionOption;\n}\n\nexport interface CompletionProperty {\n key: string;\n help: string;\n type: string;\n}\n\nexport interface CompletionType {\n name: string;\n\n key_source?: string;\n property_template?: CompletionProperty;\n properties?: CompletionProperty[];\n}\n\nexport interface CompletionSchema {\n types: CompletionType[];\n root: CompletionProperty[];\n root_no_session: CompletionProperty[];\n}\n\nexport type KeyedAssets = { [assetType: string]: string[] };\n\nexport enum CustomEventType {\n Loaded = 'temba-loaded',\n Loading = 'temba-loading',\n Canceled = 'temba-canceled',\n CursorChanged = 'temba-cursor-changed',\n Refreshed = 'temba-refreshed',\n Selection = 'temba-selection',\n ButtonClicked = 'temba-button-clicked',\n DialogHidden = 'temba-dialog-hidden',\n ScrollThreshold = 'temba-scroll-threshold',\n ContentChanged = 'temba-content-changed',\n ContextChanged = 'temba-context-changed',\n FetchComplete = 'temba-fetch-complete',\n MessageSent = 'temba-message-sent',\n Submitted = 'temba-submitted',\n Redirected = 'temba-redirected',\n NoPath = 'temba-no-path',\n StoreUpdated = 'temba-store-updated',\n Ready = 'temba-ready',\n OrderChanged = 'temba-order-changed',\n DragStart = 'temba-drag-start',\n DragStop = 'temba-drag-stop',\n DragExternal = 'temba-drag-external',\n DragInternal = 'temba-drag-internal',\n Resized = 'temba-resized',\n DetailsChanged = 'temba-details-changed',\n Error = 'temba-error',\n Interrupt = 'temba-interrupt',\n Opened = 'temba-opened',\n TicketUpdated = 'temba-ticket-updated',\n Moved = 'temba-moved',\n DateRangeChanged = 'temba-date-range-changed',\n NodeDeleted = 'temba-node-deleted',\n ActionEditRequested = 'temba-action-edit-requested',\n AddActionRequested = 'temba-add-action-requested',\n ActionSaved = 'temba-action-saved',\n ActionEditCanceled = 'temba-action-edit-canceled',\n NodeEditRequested = 'temba-node-edit-requested',\n NodeSaved = 'temba-node-saved',\n NodeEditCancelled = 'temba-node-edit-cancelled'\n}\n"]}
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { css, html } from 'lit';
|
|
3
|
+
import { property } from 'lit/decorators.js';
|
|
4
|
+
import { RapidElement } from '../RapidElement';
|
|
5
|
+
import { CustomEventType } from '../interfaces';
|
|
6
|
+
import { getClasses } from '../utils';
|
|
7
|
+
import { FloatingTab } from '../display/FloatingTab';
|
|
8
|
+
export class FloatingWindow extends RapidElement {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
this.header = '';
|
|
12
|
+
this.width = 500;
|
|
13
|
+
this.minHeight = 200;
|
|
14
|
+
this.maxHeight = 800;
|
|
15
|
+
this.top = 100;
|
|
16
|
+
this.left = -1; // -1 means calculate from right side
|
|
17
|
+
this.hidden = true;
|
|
18
|
+
this.dragging = false;
|
|
19
|
+
this.chromeless = false;
|
|
20
|
+
this.color = '#6B7280';
|
|
21
|
+
this.dragStartX = 0;
|
|
22
|
+
this.dragStartY = 0;
|
|
23
|
+
this.dragOffsetX = 0;
|
|
24
|
+
this.dragOffsetY = 0;
|
|
25
|
+
this.positionFromRight = false;
|
|
26
|
+
this.defaultTop = 100;
|
|
27
|
+
this.defaultLeft = -1;
|
|
28
|
+
this.handleSlotMouseDown = (event) => {
|
|
29
|
+
// check if the target or any parent has the drag-handle class
|
|
30
|
+
const target = event.target;
|
|
31
|
+
const dragHandle = target.closest('.drag-handle');
|
|
32
|
+
if (!dragHandle) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
this.dragging = true;
|
|
36
|
+
this.dragStartX = event.clientX;
|
|
37
|
+
this.dragStartY = event.clientY;
|
|
38
|
+
this.dragOffsetX = this.left;
|
|
39
|
+
this.dragOffsetY = this.top;
|
|
40
|
+
document.addEventListener('mousemove', this.handleMouseMove);
|
|
41
|
+
document.addEventListener('mouseup', this.handleMouseUp);
|
|
42
|
+
event.preventDefault();
|
|
43
|
+
};
|
|
44
|
+
this.handleMouseMove = (event) => {
|
|
45
|
+
var _a;
|
|
46
|
+
if (!this.dragging)
|
|
47
|
+
return;
|
|
48
|
+
const deltaX = event.clientX - this.dragStartX;
|
|
49
|
+
const deltaY = event.clientY - this.dragStartY;
|
|
50
|
+
this.left = this.dragOffsetX + deltaX;
|
|
51
|
+
this.top = this.dragOffsetY + deltaY;
|
|
52
|
+
// keep window within viewport bounds with 20px padding
|
|
53
|
+
const padding = 20;
|
|
54
|
+
this.left = Math.max(padding, Math.min(this.left, window.innerWidth - this.width - padding));
|
|
55
|
+
// get the actual rendered height of the window element
|
|
56
|
+
const windowElement = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.window');
|
|
57
|
+
const currentHeight = (windowElement === null || windowElement === void 0 ? void 0 : windowElement.offsetHeight) || this.maxHeight || window.innerHeight;
|
|
58
|
+
const maxTop = Math.max(padding, window.innerHeight - currentHeight - padding);
|
|
59
|
+
this.top = Math.max(padding, Math.min(this.top, maxTop));
|
|
60
|
+
};
|
|
61
|
+
this.handleMouseUp = () => {
|
|
62
|
+
this.dragging = false;
|
|
63
|
+
document.removeEventListener('mousemove', this.handleMouseMove);
|
|
64
|
+
document.removeEventListener('mouseup', this.handleMouseUp);
|
|
65
|
+
// once user drags the window, stop auto-positioning from right
|
|
66
|
+
this.positionFromRight = false;
|
|
67
|
+
};
|
|
68
|
+
this.handleResize = () => {
|
|
69
|
+
var _a;
|
|
70
|
+
// only constrain position if window is visible
|
|
71
|
+
if (this.hidden)
|
|
72
|
+
return;
|
|
73
|
+
const padding = 20;
|
|
74
|
+
const windowElement = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.window');
|
|
75
|
+
const currentHeight = (windowElement === null || windowElement === void 0 ? void 0 : windowElement.offsetHeight) || this.maxHeight || window.innerHeight;
|
|
76
|
+
// if positioned from right, always recalculate from right edge
|
|
77
|
+
if (this.positionFromRight) {
|
|
78
|
+
this.left = window.innerWidth - this.width - padding;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
// only adjust left if out of bounds
|
|
82
|
+
const minLeft = padding;
|
|
83
|
+
const maxLeft = window.innerWidth - this.width - padding;
|
|
84
|
+
if (this.left < minLeft) {
|
|
85
|
+
this.left = minLeft;
|
|
86
|
+
}
|
|
87
|
+
else if (this.left > maxLeft) {
|
|
88
|
+
this.left = maxLeft;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// only adjust top if out of bounds
|
|
92
|
+
const minTop = padding;
|
|
93
|
+
const maxTop = Math.max(padding, window.innerHeight - currentHeight - padding);
|
|
94
|
+
if (this.top < minTop) {
|
|
95
|
+
this.top = minTop;
|
|
96
|
+
}
|
|
97
|
+
else if (this.top > maxTop) {
|
|
98
|
+
this.top = maxTop;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
static get styles() {
|
|
103
|
+
return css `
|
|
104
|
+
.window.hidden {
|
|
105
|
+
transform: translateX(100%);
|
|
106
|
+
opacity: 0;
|
|
107
|
+
pointer-events: none;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.window {
|
|
111
|
+
transition: transform var(--transition-duration, 300ms) ease-in-out,
|
|
112
|
+
opacity var(--transition-duration, 300ms) ease-in-out;
|
|
113
|
+
position: fixed;
|
|
114
|
+
z-index: 9999;
|
|
115
|
+
top: 100px;
|
|
116
|
+
background: white;
|
|
117
|
+
border-radius: 8px;
|
|
118
|
+
box-shadow: -4px 4px 20px rgba(0, 0, 0, 0.3);
|
|
119
|
+
display: flex;
|
|
120
|
+
flex-direction: column;
|
|
121
|
+
overflow: hidden;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.window.chromeless {
|
|
125
|
+
background: transparent;
|
|
126
|
+
border-radius: 0;
|
|
127
|
+
box-shadow: none;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.window.dragging {
|
|
131
|
+
user-select: none;
|
|
132
|
+
cursor: move;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.header {
|
|
136
|
+
display: flex;
|
|
137
|
+
align-items: center;
|
|
138
|
+
justify-content: space-between;
|
|
139
|
+
padding: 6px 6px;
|
|
140
|
+
background: var(--header-color, var(--color-primary-light, #f3f4f6));
|
|
141
|
+
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
|
142
|
+
cursor: move;
|
|
143
|
+
user-select: none;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.title {
|
|
147
|
+
font-weight: 600;
|
|
148
|
+
font-size: 16px;
|
|
149
|
+
color: white;
|
|
150
|
+
padding-left: 8px;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.close-button {
|
|
154
|
+
background: none;
|
|
155
|
+
border: none;
|
|
156
|
+
cursor: pointer;
|
|
157
|
+
padding: 4px;
|
|
158
|
+
display: flex;
|
|
159
|
+
align-items: center;
|
|
160
|
+
justify-content: center;
|
|
161
|
+
border-radius: 4px;
|
|
162
|
+
transition: background-color calc(var(--transition-duration, 150ms) / 2)
|
|
163
|
+
ease-in-out;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.close-button:hover {
|
|
167
|
+
background-color: rgba(255, 255, 255, 0.2);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.close-button temba-icon {
|
|
171
|
+
--icon-color: white;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.body {
|
|
175
|
+
flex: 1;
|
|
176
|
+
overflow-y: auto;
|
|
177
|
+
padding: 16px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.window.chromeless .body {
|
|
181
|
+
padding: 0;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
::slotted(.drag-handle) {
|
|
185
|
+
cursor: move;
|
|
186
|
+
user-select: none;
|
|
187
|
+
border: 1px solid red;
|
|
188
|
+
}
|
|
189
|
+
`;
|
|
190
|
+
}
|
|
191
|
+
firstUpdated(changes) {
|
|
192
|
+
super.firstUpdated(changes);
|
|
193
|
+
// store the default position from properties
|
|
194
|
+
this.defaultTop = this.top;
|
|
195
|
+
this.defaultLeft = this.left;
|
|
196
|
+
// determine if we should position from right side
|
|
197
|
+
if (this.left === -1) {
|
|
198
|
+
this.positionFromRight = true;
|
|
199
|
+
}
|
|
200
|
+
// set up drag handle listeners for chromeless windows
|
|
201
|
+
if (this.chromeless) {
|
|
202
|
+
this.setupDragHandles();
|
|
203
|
+
}
|
|
204
|
+
// listen for window resize to keep window in bounds
|
|
205
|
+
window.addEventListener('resize', this.handleResize);
|
|
206
|
+
}
|
|
207
|
+
disconnectedCallback() {
|
|
208
|
+
super.disconnectedCallback();
|
|
209
|
+
window.removeEventListener('resize', this.handleResize);
|
|
210
|
+
}
|
|
211
|
+
setupDragHandles() {
|
|
212
|
+
// listen for mousedown on slotted content
|
|
213
|
+
this.addEventListener('mousedown', this.handleSlotMouseDown);
|
|
214
|
+
}
|
|
215
|
+
updated(changes) {
|
|
216
|
+
super.updated(changes);
|
|
217
|
+
if (changes.has('hidden')) {
|
|
218
|
+
this.classList.toggle('hidden', this.hidden);
|
|
219
|
+
// when hiding, reset positioning behavior to original
|
|
220
|
+
if (this.hidden && !changes.get('hidden')) {
|
|
221
|
+
if (this.defaultLeft === -1) {
|
|
222
|
+
this.positionFromRight = true;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// reset to default position when showing
|
|
226
|
+
if (!this.hidden && changes.get('hidden')) {
|
|
227
|
+
// reset top to default
|
|
228
|
+
this.top = this.defaultTop;
|
|
229
|
+
// if positioned from right, recalculate based on current viewport
|
|
230
|
+
if (this.positionFromRight) {
|
|
231
|
+
this.left = window.innerWidth - this.width - 20;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
// reset left to default
|
|
235
|
+
this.left = this.defaultLeft;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// setup drag handles if chromeless changed to true
|
|
240
|
+
if (changes.has('chromeless') && this.chromeless) {
|
|
241
|
+
this.setupDragHandles();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
handleClose() {
|
|
245
|
+
this.hidden = true;
|
|
246
|
+
// show all tabs when window is closed
|
|
247
|
+
FloatingTab.showAllTabs();
|
|
248
|
+
this.fireCustomEvent(CustomEventType.DialogHidden);
|
|
249
|
+
}
|
|
250
|
+
handleHeaderMouseDown(event) {
|
|
251
|
+
// don't start drag if clicking on close button
|
|
252
|
+
if (event.target.closest('.close-button')) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
this.dragging = true;
|
|
256
|
+
this.dragStartX = event.clientX;
|
|
257
|
+
this.dragStartY = event.clientY;
|
|
258
|
+
this.dragOffsetX = this.left;
|
|
259
|
+
this.dragOffsetY = this.top;
|
|
260
|
+
document.addEventListener('mousemove', this.handleMouseMove);
|
|
261
|
+
document.addEventListener('mouseup', this.handleMouseUp);
|
|
262
|
+
event.preventDefault();
|
|
263
|
+
}
|
|
264
|
+
show() {
|
|
265
|
+
this.hidden = false;
|
|
266
|
+
}
|
|
267
|
+
hide() {
|
|
268
|
+
this.hidden = true;
|
|
269
|
+
}
|
|
270
|
+
close() {
|
|
271
|
+
this.hidden = true;
|
|
272
|
+
// show all tabs when window is closed
|
|
273
|
+
FloatingTab.showAllTabs();
|
|
274
|
+
this.fireCustomEvent(CustomEventType.DialogHidden);
|
|
275
|
+
}
|
|
276
|
+
render() {
|
|
277
|
+
const minHeightStyle = this.minHeight
|
|
278
|
+
? `min-height: ${this.minHeight}px;`
|
|
279
|
+
: '';
|
|
280
|
+
const maxHeightStyle = this.maxHeight
|
|
281
|
+
? `max-height: ${this.maxHeight}px;`
|
|
282
|
+
: '';
|
|
283
|
+
const windowStyle = `
|
|
284
|
+
width: ${this.width}px;
|
|
285
|
+
${minHeightStyle}
|
|
286
|
+
${maxHeightStyle}
|
|
287
|
+
top: ${this.top}px;
|
|
288
|
+
left: ${this.left}px;
|
|
289
|
+
--header-color: ${this.color};
|
|
290
|
+
`;
|
|
291
|
+
const windowClasses = getClasses({
|
|
292
|
+
window: true,
|
|
293
|
+
dragging: this.dragging,
|
|
294
|
+
hidden: this.hidden,
|
|
295
|
+
chromeless: this.chromeless
|
|
296
|
+
});
|
|
297
|
+
return html `
|
|
298
|
+
<div class="${windowClasses}" style="${windowStyle}">
|
|
299
|
+
${!this.chromeless
|
|
300
|
+
? html `
|
|
301
|
+
<div class="header" @mousedown=${this.handleHeaderMouseDown}>
|
|
302
|
+
<div class="title">${this.header}</div>
|
|
303
|
+
<button class="close-button" @click=${this.handleClose}>
|
|
304
|
+
<temba-icon name="close" size="1.5"></temba-icon>
|
|
305
|
+
</button>
|
|
306
|
+
</div>
|
|
307
|
+
`
|
|
308
|
+
: ''}
|
|
309
|
+
<div class="body">
|
|
310
|
+
<slot></slot>
|
|
311
|
+
</div>
|
|
312
|
+
</div>
|
|
313
|
+
`;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
__decorate([
|
|
317
|
+
property({ type: String })
|
|
318
|
+
], FloatingWindow.prototype, "header", void 0);
|
|
319
|
+
__decorate([
|
|
320
|
+
property({ type: Number })
|
|
321
|
+
], FloatingWindow.prototype, "width", void 0);
|
|
322
|
+
__decorate([
|
|
323
|
+
property({ type: Number })
|
|
324
|
+
], FloatingWindow.prototype, "minHeight", void 0);
|
|
325
|
+
__decorate([
|
|
326
|
+
property({ type: Number })
|
|
327
|
+
], FloatingWindow.prototype, "maxHeight", void 0);
|
|
328
|
+
__decorate([
|
|
329
|
+
property({ type: Number })
|
|
330
|
+
], FloatingWindow.prototype, "top", void 0);
|
|
331
|
+
__decorate([
|
|
332
|
+
property({ type: Number })
|
|
333
|
+
], FloatingWindow.prototype, "left", void 0);
|
|
334
|
+
__decorate([
|
|
335
|
+
property({ type: Boolean })
|
|
336
|
+
], FloatingWindow.prototype, "hidden", void 0);
|
|
337
|
+
__decorate([
|
|
338
|
+
property({ type: Boolean })
|
|
339
|
+
], FloatingWindow.prototype, "dragging", void 0);
|
|
340
|
+
__decorate([
|
|
341
|
+
property({ type: Boolean })
|
|
342
|
+
], FloatingWindow.prototype, "chromeless", void 0);
|
|
343
|
+
__decorate([
|
|
344
|
+
property({ type: String })
|
|
345
|
+
], FloatingWindow.prototype, "color", void 0);
|
|
346
|
+
//# sourceMappingURL=FloatingWindow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FloatingWindow.js","sourceRoot":"","sources":["../../../src/layout/FloatingWindow.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { RapidElement } from '../RapidElement';\nimport { CustomEventType } from '../interfaces';\nimport { getClasses } from '../utils';\nimport { FloatingTab } from '../display/FloatingTab';\n\nexport class FloatingWindow extends RapidElement {\n static get styles() {\n return css`\n .window.hidden {\n transform: translateX(100%);\n opacity: 0;\n pointer-events: none;\n }\n\n .window {\n transition: transform var(--transition-duration, 300ms) ease-in-out,\n opacity var(--transition-duration, 300ms) ease-in-out;\n position: fixed;\n z-index: 9999;\n top: 100px;\n background: white;\n border-radius: 8px;\n box-shadow: -4px 4px 20px rgba(0, 0, 0, 0.3);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n .window.chromeless {\n background: transparent;\n border-radius: 0;\n box-shadow: none;\n }\n\n .window.dragging {\n user-select: none;\n cursor: move;\n }\n\n .header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 6px;\n background: var(--header-color, var(--color-primary-light, #f3f4f6));\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n cursor: move;\n user-select: none;\n }\n\n .title {\n font-weight: 600;\n font-size: 16px;\n color: white;\n padding-left: 8px;\n }\n\n .close-button {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n transition: background-color calc(var(--transition-duration, 150ms) / 2)\n ease-in-out;\n }\n\n .close-button:hover {\n background-color: rgba(255, 255, 255, 0.2);\n }\n\n .close-button temba-icon {\n --icon-color: white;\n }\n\n .body {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n }\n\n .window.chromeless .body {\n padding: 0;\n }\n\n ::slotted(.drag-handle) {\n cursor: move;\n user-select: none;\n border: 1px solid red;\n }\n `;\n }\n\n @property({ type: String })\n header = '';\n\n @property({ type: Number })\n width = 500;\n\n @property({ type: Number })\n minHeight = 200;\n\n @property({ type: Number })\n maxHeight = 800;\n\n @property({ type: Number })\n top = 100;\n\n @property({ type: Number })\n left = -1; // -1 means calculate from right side\n\n @property({ type: Boolean })\n hidden = true;\n\n @property({ type: Boolean })\n dragging = false;\n\n @property({ type: Boolean })\n chromeless = false;\n\n @property({ type: String })\n color = '#6B7280';\n\n private dragStartX = 0;\n private dragStartY = 0;\n private dragOffsetX = 0;\n private dragOffsetY = 0;\n private positionFromRight = false;\n private defaultTop = 100;\n private defaultLeft = -1;\n\n public firstUpdated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(changes);\n\n // store the default position from properties\n this.defaultTop = this.top;\n this.defaultLeft = this.left;\n\n // determine if we should position from right side\n if (this.left === -1) {\n this.positionFromRight = true;\n }\n\n // set up drag handle listeners for chromeless windows\n if (this.chromeless) {\n this.setupDragHandles();\n }\n\n // listen for window resize to keep window in bounds\n window.addEventListener('resize', this.handleResize);\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n window.removeEventListener('resize', this.handleResize);\n }\n\n private setupDragHandles() {\n // listen for mousedown on slotted content\n this.addEventListener('mousedown', this.handleSlotMouseDown);\n }\n\n private handleSlotMouseDown = (event: MouseEvent) => {\n // check if the target or any parent has the drag-handle class\n const target = event.target as HTMLElement;\n const dragHandle = target.closest('.drag-handle');\n\n if (!dragHandle) {\n return;\n }\n\n this.dragging = true;\n this.dragStartX = event.clientX;\n this.dragStartY = event.clientY;\n this.dragOffsetX = this.left;\n this.dragOffsetY = this.top;\n\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('mouseup', this.handleMouseUp);\n\n event.preventDefault();\n };\n\n public updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('hidden')) {\n this.classList.toggle('hidden', this.hidden);\n\n // when hiding, reset positioning behavior to original\n if (this.hidden && !changes.get('hidden')) {\n if (this.defaultLeft === -1) {\n this.positionFromRight = true;\n }\n }\n\n // reset to default position when showing\n if (!this.hidden && changes.get('hidden')) {\n // reset top to default\n this.top = this.defaultTop;\n\n // if positioned from right, recalculate based on current viewport\n if (this.positionFromRight) {\n this.left = window.innerWidth - this.width - 20;\n } else {\n // reset left to default\n this.left = this.defaultLeft;\n }\n }\n }\n\n // setup drag handles if chromeless changed to true\n if (changes.has('chromeless') && this.chromeless) {\n this.setupDragHandles();\n }\n }\n\n private handleClose() {\n this.hidden = true;\n // show all tabs when window is closed\n FloatingTab.showAllTabs();\n this.fireCustomEvent(CustomEventType.DialogHidden);\n }\n\n private handleHeaderMouseDown(event: MouseEvent) {\n // don't start drag if clicking on close button\n if ((event.target as HTMLElement).closest('.close-button')) {\n return;\n }\n\n this.dragging = true;\n this.dragStartX = event.clientX;\n this.dragStartY = event.clientY;\n this.dragOffsetX = this.left;\n this.dragOffsetY = this.top;\n\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('mouseup', this.handleMouseUp);\n\n event.preventDefault();\n }\n\n private handleMouseMove = (event: MouseEvent) => {\n if (!this.dragging) return;\n\n const deltaX = event.clientX - this.dragStartX;\n const deltaY = event.clientY - this.dragStartY;\n\n this.left = this.dragOffsetX + deltaX;\n this.top = this.dragOffsetY + deltaY;\n\n // keep window within viewport bounds with 20px padding\n const padding = 20;\n this.left = Math.max(\n padding,\n Math.min(this.left, window.innerWidth - this.width - padding)\n );\n\n // get the actual rendered height of the window element\n const windowElement = this.shadowRoot?.querySelector(\n '.window'\n ) as HTMLElement;\n const currentHeight =\n windowElement?.offsetHeight || this.maxHeight || window.innerHeight;\n const maxTop = Math.max(\n padding,\n window.innerHeight - currentHeight - padding\n );\n this.top = Math.max(padding, Math.min(this.top, maxTop));\n };\n\n private handleMouseUp = () => {\n this.dragging = false;\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('mouseup', this.handleMouseUp);\n\n // once user drags the window, stop auto-positioning from right\n this.positionFromRight = false;\n };\n\n private handleResize = () => {\n // only constrain position if window is visible\n if (this.hidden) return;\n\n const padding = 20;\n const windowElement = this.shadowRoot?.querySelector(\n '.window'\n ) as HTMLElement;\n const currentHeight =\n windowElement?.offsetHeight || this.maxHeight || window.innerHeight;\n\n // if positioned from right, always recalculate from right edge\n if (this.positionFromRight) {\n this.left = window.innerWidth - this.width - padding;\n } else {\n // only adjust left if out of bounds\n const minLeft = padding;\n const maxLeft = window.innerWidth - this.width - padding;\n\n if (this.left < minLeft) {\n this.left = minLeft;\n } else if (this.left > maxLeft) {\n this.left = maxLeft;\n }\n }\n\n // only adjust top if out of bounds\n const minTop = padding;\n const maxTop = Math.max(\n padding,\n window.innerHeight - currentHeight - padding\n );\n\n if (this.top < minTop) {\n this.top = minTop;\n } else if (this.top > maxTop) {\n this.top = maxTop;\n }\n };\n\n public show() {\n this.hidden = false;\n }\n\n public hide() {\n this.hidden = true;\n }\n\n public close() {\n this.hidden = true;\n // show all tabs when window is closed\n FloatingTab.showAllTabs();\n this.fireCustomEvent(CustomEventType.DialogHidden);\n }\n\n public render(): TemplateResult {\n const minHeightStyle = this.minHeight\n ? `min-height: ${this.minHeight}px;`\n : '';\n const maxHeightStyle = this.maxHeight\n ? `max-height: ${this.maxHeight}px;`\n : '';\n\n const windowStyle = `\n width: ${this.width}px;\n ${minHeightStyle}\n ${maxHeightStyle}\n top: ${this.top}px;\n left: ${this.left}px;\n --header-color: ${this.color};\n `;\n\n const windowClasses = getClasses({\n window: true,\n dragging: this.dragging,\n hidden: this.hidden,\n chromeless: this.chromeless\n });\n\n return html`\n <div class=\"${windowClasses}\" style=\"${windowStyle}\">\n ${!this.chromeless\n ? html`\n <div class=\"header\" @mousedown=${this.handleHeaderMouseDown}>\n <div class=\"title\">${this.header}</div>\n <button class=\"close-button\" @click=${this.handleClose}>\n <temba-icon name=\"close\" size=\"1.5\"></temba-icon>\n </button>\n </div>\n `\n : ''}\n <div class=\"body\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n}\n"]}
|