@nyaruka/temba-components 0.129.3 → 0.129.4
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/.eslintrc.js +1 -0
- package/.github/workflows/build.yml +135 -3
- package/CHANGELOG.md +18 -0
- package/demo/data/flows/sample-flow.json +110 -87
- package/demo/field-config-demo.html +135 -0
- package/dist/temba-components.js +1257 -675
- package/dist/temba-components.js.map +1 -1
- package/docs/ActionEditor-Migration.md +118 -0
- package/out-tsc/src/events.js.map +1 -1
- package/out-tsc/src/flow/{EditorNode.js → CanvasNode.js} +345 -42
- package/out-tsc/src/flow/CanvasNode.js.map +1 -0
- package/out-tsc/src/flow/Editor.js +107 -3
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/NodeEditor.js +1200 -0
- package/out-tsc/src/flow/NodeEditor.js.map +1 -0
- package/out-tsc/src/flow/Plumber.js +0 -6
- package/out-tsc/src/flow/Plumber.js.map +1 -1
- package/out-tsc/src/flow/actions/add_contact_groups.js +40 -0
- package/out-tsc/src/flow/actions/add_contact_groups.js.map +1 -0
- package/out-tsc/src/flow/actions/add_contact_urn.js +16 -0
- package/out-tsc/src/flow/actions/add_contact_urn.js.map +1 -0
- package/out-tsc/src/flow/actions/add_input_labels.js +11 -0
- package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -0
- package/out-tsc/src/flow/actions/call_classifier.js +11 -0
- package/out-tsc/src/flow/actions/call_classifier.js.map +1 -0
- package/out-tsc/src/flow/actions/call_llm.js +11 -0
- package/out-tsc/src/flow/actions/call_llm.js.map +1 -0
- package/out-tsc/src/flow/actions/call_resthook.js +11 -0
- package/out-tsc/src/flow/actions/call_resthook.js.map +1 -0
- package/out-tsc/src/flow/actions/call_webhook.js +122 -0
- package/out-tsc/src/flow/actions/call_webhook.js.map +1 -0
- package/out-tsc/src/flow/actions/enter_flow.js +14 -0
- package/out-tsc/src/flow/actions/enter_flow.js.map +1 -0
- package/out-tsc/src/flow/actions/open_ticket.js +11 -0
- package/out-tsc/src/flow/actions/open_ticket.js.map +1 -0
- package/out-tsc/src/flow/actions/play_audio.js +11 -0
- package/out-tsc/src/flow/actions/play_audio.js.map +1 -0
- package/out-tsc/src/flow/actions/remove_contact_groups.js +62 -0
- package/out-tsc/src/flow/actions/remove_contact_groups.js.map +1 -0
- package/out-tsc/src/flow/actions/request_optin.js +11 -0
- package/out-tsc/src/flow/actions/request_optin.js.map +1 -0
- package/out-tsc/src/flow/actions/say_msg.js +11 -0
- package/out-tsc/src/flow/actions/say_msg.js.map +1 -0
- package/out-tsc/src/flow/actions/send_broadcast.js +33 -0
- package/out-tsc/src/flow/actions/send_broadcast.js.map +1 -0
- package/out-tsc/src/flow/actions/send_email.js +56 -0
- package/out-tsc/src/flow/actions/send_email.js.map +1 -0
- package/out-tsc/src/flow/actions/send_msg.js +55 -0
- package/out-tsc/src/flow/actions/send_msg.js.map +1 -0
- package/out-tsc/src/flow/actions/set_contact_channel.js +12 -0
- package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -0
- package/out-tsc/src/flow/actions/set_contact_field.js +12 -0
- package/out-tsc/src/flow/actions/set_contact_field.js.map +1 -0
- package/out-tsc/src/flow/actions/set_contact_language.js +10 -0
- package/out-tsc/src/flow/actions/set_contact_language.js.map +1 -0
- package/out-tsc/src/flow/actions/set_contact_name.js +10 -0
- package/out-tsc/src/flow/actions/set_contact_name.js.map +1 -0
- package/out-tsc/src/flow/actions/set_contact_status.js +10 -0
- package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -0
- package/out-tsc/src/flow/actions/set_run_result.js +10 -0
- package/out-tsc/src/flow/actions/set_run_result.js.map +1 -0
- package/out-tsc/src/flow/actions/split_by_expression_example.js +77 -0
- package/out-tsc/src/flow/actions/split_by_expression_example.js.map +1 -0
- package/out-tsc/src/flow/actions/start_session.js +11 -0
- package/out-tsc/src/flow/actions/start_session.js.map +1 -0
- package/out-tsc/src/flow/actions/transfer_airtime.js +11 -0
- package/out-tsc/src/flow/actions/transfer_airtime.js.map +1 -0
- package/out-tsc/src/flow/config.js +88 -193
- package/out-tsc/src/flow/config.js.map +1 -1
- package/out-tsc/src/flow/nodes/execute_actions.js +4 -0
- package/out-tsc/src/flow/nodes/execute_actions.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_airtime.js +9 -0
- package/out-tsc/src/flow/nodes/split_by_airtime.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_contact_field.js +7 -0
- package/out-tsc/src/flow/nodes/split_by_contact_field.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_expression.js +7 -0
- package/out-tsc/src/flow/nodes/split_by_expression.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_groups.js +7 -0
- package/out-tsc/src/flow/nodes/split_by_groups.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_random.js +10 -0
- package/out-tsc/src/flow/nodes/split_by_random.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_run_result.js +7 -0
- package/out-tsc/src/flow/nodes/split_by_run_result.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_scheme.js +7 -0
- package/out-tsc/src/flow/nodes/split_by_scheme.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_subflow.js +9 -0
- package/out-tsc/src/flow/nodes/split_by_subflow.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_webhook.js +18 -0
- package/out-tsc/src/flow/nodes/split_by_webhook.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_audio.js +7 -0
- package/out-tsc/src/flow/nodes/wait_for_audio.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_digits.js +7 -0
- package/out-tsc/src/flow/nodes/wait_for_digits.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_image.js +7 -0
- package/out-tsc/src/flow/nodes/wait_for_image.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_location.js +7 -0
- package/out-tsc/src/flow/nodes/wait_for_location.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_menu.js +7 -0
- package/out-tsc/src/flow/nodes/wait_for_menu.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_response.js +7 -0
- package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_video.js +7 -0
- package/out-tsc/src/flow/nodes/wait_for_video.js.map +1 -0
- package/out-tsc/src/flow/types.js +79 -0
- package/out-tsc/src/flow/types.js.map +1 -0
- package/out-tsc/src/flow/utils.js +65 -0
- package/out-tsc/src/flow/utils.js.map +1 -0
- package/out-tsc/src/form/ArrayEditor.js +199 -0
- package/out-tsc/src/form/ArrayEditor.js.map +1 -0
- package/out-tsc/src/form/BaseListEditor.js +128 -0
- package/out-tsc/src/form/BaseListEditor.js.map +1 -0
- package/out-tsc/src/form/Checkbox.js +17 -2
- package/out-tsc/src/form/Checkbox.js.map +1 -1
- package/out-tsc/src/form/Completion.js +6 -0
- package/out-tsc/src/form/Completion.js.map +1 -1
- package/out-tsc/src/form/FormField.js +110 -11
- package/out-tsc/src/form/FormField.js.map +1 -1
- package/out-tsc/src/form/KeyValueEditor.js +223 -0
- package/out-tsc/src/form/KeyValueEditor.js.map +1 -0
- package/out-tsc/src/form/select/Select.js +77 -32
- package/out-tsc/src/form/select/Select.js.map +1 -1
- package/out-tsc/src/interfaces.js +6 -0
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/live/ContactChat.js +2 -76
- package/out-tsc/src/live/ContactChat.js.map +1 -1
- package/out-tsc/temba-modules.js +9 -2
- package/out-tsc/temba-modules.js.map +1 -1
- package/out-tsc/test/ActionHelper.js +116 -0
- package/out-tsc/test/ActionHelper.js.map +1 -0
- package/out-tsc/test/actions/add_contact_groups.test.js +66 -0
- package/out-tsc/test/actions/add_contact_groups.test.js.map +1 -0
- package/out-tsc/test/actions/remove_contact_groups.test.js +226 -0
- package/out-tsc/test/actions/remove_contact_groups.test.js.map +1 -0
- package/out-tsc/test/actions/send_email.test.js +160 -0
- package/out-tsc/test/actions/send_email.test.js.map +1 -0
- package/out-tsc/test/actions/send_msg.test.js +95 -0
- package/out-tsc/test/actions/send_msg.test.js.map +1 -0
- package/out-tsc/test/temba-action-editing-integration.test.js +183 -0
- package/out-tsc/test/temba-action-editing-integration.test.js.map +1 -0
- package/out-tsc/test/temba-checkbox.test.js +1 -1
- package/out-tsc/test/temba-checkbox.test.js.map +1 -1
- package/out-tsc/test/temba-field-config.test.js +133 -0
- package/out-tsc/test/temba-field-config.test.js.map +1 -0
- package/out-tsc/test/temba-flow-editor-node.test.js +14 -14
- package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
- package/out-tsc/test/temba-node-editor.test.js +283 -0
- package/out-tsc/test/temba-node-editor.test.js.map +1 -0
- package/out-tsc/test/temba-select.test.js +85 -0
- package/out-tsc/test/temba-select.test.js.map +1 -1
- package/package.json +1 -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/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_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/editor/router.png +0 -0
- package/screenshots/truth/editor/send_msg.png +0 -0
- package/screenshots/truth/editor/set_contact_language.png +0 -0
- package/screenshots/truth/editor/set_contact_name.png +0 -0
- package/screenshots/truth/editor/set_run_result.png +0 -0
- package/screenshots/truth/editor/wait.png +0 -0
- package/screenshots/truth/formfield/markdown-errors.png +0 -0
- package/screenshots/truth/formfield/plain-text-errors.png +0 -0
- package/screenshots/truth/formfield/widget-only-markdown-errors.png +0 -0
- package/screenshots/truth/integration/checkbox-markdown-errors.png +0 -0
- package/src/events.ts +1 -40
- package/src/flow/{EditorNode.ts → CanvasNode.ts} +424 -48
- package/src/flow/Editor.ts +140 -4
- package/src/flow/NodeEditor.ts +1443 -0
- package/src/flow/Plumber.ts +0 -9
- package/src/flow/actions/add_contact_groups.ts +42 -0
- package/src/flow/actions/add_contact_urn.ts +17 -0
- package/src/flow/actions/add_input_labels.ts +12 -0
- package/src/flow/actions/call_classifier.ts +12 -0
- package/src/flow/actions/call_llm.ts +12 -0
- package/src/flow/actions/call_resthook.ts +12 -0
- package/src/flow/actions/call_webhook.ts +133 -0
- package/src/flow/actions/enter_flow.ts +15 -0
- package/src/flow/actions/open_ticket.ts +12 -0
- package/src/flow/actions/play_audio.ts +12 -0
- package/src/flow/actions/remove_contact_groups.ts +66 -0
- package/src/flow/actions/request_optin.ts +12 -0
- package/src/flow/actions/say_msg.ts +12 -0
- package/src/flow/actions/send_broadcast.ts +35 -0
- package/src/flow/actions/send_email.ts +60 -0
- package/src/flow/actions/send_msg.ts +58 -0
- package/src/flow/actions/set_contact_channel.ts +13 -0
- package/src/flow/actions/set_contact_field.ts +13 -0
- package/src/flow/actions/set_contact_language.ts +11 -0
- package/src/flow/actions/set_contact_name.ts +11 -0
- package/src/flow/actions/set_contact_status.ts +11 -0
- package/src/flow/actions/set_run_result.ts +11 -0
- package/src/flow/actions/split_by_expression_example.ts +88 -0
- package/src/flow/actions/start_session.ts +12 -0
- package/src/flow/actions/transfer_airtime.ts +12 -0
- package/src/flow/config.ts +93 -232
- package/src/flow/nodes/execute_actions.ts +5 -0
- package/src/flow/nodes/split_by_airtime.ts +9 -0
- package/src/flow/nodes/split_by_contact_field.ts +7 -0
- package/src/flow/nodes/split_by_expression.ts +7 -0
- package/src/flow/nodes/split_by_groups.ts +7 -0
- package/src/flow/nodes/split_by_random.ts +10 -0
- package/src/flow/nodes/split_by_run_result.ts +7 -0
- package/src/flow/nodes/split_by_scheme.ts +7 -0
- package/src/flow/nodes/split_by_subflow.ts +9 -0
- package/src/flow/nodes/split_by_webhook.ts +19 -0
- package/src/flow/nodes/wait_for_audio.ts +7 -0
- package/src/flow/nodes/wait_for_digits.ts +7 -0
- package/src/flow/nodes/wait_for_image.ts +7 -0
- package/src/flow/nodes/wait_for_location.ts +7 -0
- package/src/flow/nodes/wait_for_menu.ts +7 -0
- package/src/flow/nodes/wait_for_response.ts +7 -0
- package/src/flow/nodes/wait_for_video.ts +7 -0
- package/src/flow/types.ts +352 -0
- package/src/flow/utils.ts +76 -0
- package/src/form/ArrayEditor.ts +240 -0
- package/src/form/BaseListEditor.ts +177 -0
- package/src/form/Checkbox.ts +22 -3
- package/src/form/Completion.ts +6 -0
- package/src/form/FormField.ts +115 -11
- package/src/form/KeyValueEditor.ts +251 -0
- package/src/form/select/Select.ts +89 -32
- package/src/interfaces.ts +7 -2
- package/src/live/ContactChat.ts +3 -97
- package/src/store/flow-definition.d.ts +6 -1
- package/static/api/contacts.json +30 -0
- package/static/api/groups.json +4 -426
- package/static/api/locations.json +24 -0
- package/static/api/media.json +5 -0
- package/static/api/optins.json +16 -0
- package/static/api/orgs.json +13 -0
- package/static/api/topics.json +21 -0
- package/static/api/users.json +26 -0
- package/static/css/temba-components.css +3 -6
- package/temba-modules.ts +9 -2
- package/test/ActionHelper.ts +142 -0
- package/test/actions/add_contact_groups.test.ts +89 -0
- package/test/actions/remove_contact_groups.test.ts +265 -0
- package/test/actions/send_email.test.ts +214 -0
- package/test/actions/send_msg.test.ts +130 -0
- package/test/temba-action-editing-integration.test.ts +240 -0
- package/test/temba-checkbox.test.ts +1 -1
- package/test/temba-field-config.test.ts +152 -0
- package/test/temba-flow-editor-node.test.ts +18 -18
- package/test/temba-node-editor.test.ts +353 -0
- package/test/temba-select.test.ts +127 -0
- package/test-assets/contacts/history.json +11 -33
- package/web-dev-server.config.mjs +34 -0
- package/.github/workflows/coverage.yml +0 -80
- package/demo/sticky-note-demo.html +0 -155
- package/out-tsc/src/flow/EditorNode.js.map +0 -1
- package/out-tsc/src/flow/render.js +0 -358
- package/out-tsc/src/flow/render.js.map +0 -1
- package/out-tsc/test/temba-flow-render.test.js +0 -794
- package/out-tsc/test/temba-flow-render.test.js.map +0 -1
- package/src/flow/render.ts +0 -443
- package/test/temba-flow-render.test.ts +0 -1003
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
name: 'Update Coverage Reports'
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main]
|
|
6
|
-
|
|
7
|
-
permissions:
|
|
8
|
-
contents: write
|
|
9
|
-
|
|
10
|
-
jobs:
|
|
11
|
-
coverage:
|
|
12
|
-
runs-on: ubuntu-latest
|
|
13
|
-
steps:
|
|
14
|
-
- name: Set Timezone
|
|
15
|
-
uses: szenius/set-timezone@v2.0
|
|
16
|
-
with:
|
|
17
|
-
timezoneLinux: 'UTC'
|
|
18
|
-
|
|
19
|
-
- name: Checkout (GitHub)
|
|
20
|
-
uses: actions/checkout@v4
|
|
21
|
-
with:
|
|
22
|
-
token: ${{ secrets.GITHUB_TOKEN }}
|
|
23
|
-
fetch-depth: 0
|
|
24
|
-
|
|
25
|
-
- run: docker network create --driver bridge textit_default
|
|
26
|
-
|
|
27
|
-
- name: Build and run tests with coverage
|
|
28
|
-
uses: devcontainers/ci@v0.3
|
|
29
|
-
with:
|
|
30
|
-
runCmd: yarn validate && ./generate-coverage-badge.sh
|
|
31
|
-
push: never
|
|
32
|
-
env: |
|
|
33
|
-
CI=true
|
|
34
|
-
|
|
35
|
-
- name: Copy coverage to temp
|
|
36
|
-
run: |
|
|
37
|
-
mkdir -p /tmp/coverage-copy
|
|
38
|
-
cp -r coverage /tmp/coverage-copy/
|
|
39
|
-
|
|
40
|
-
- name: Deploy coverage to coverage branch
|
|
41
|
-
run: |
|
|
42
|
-
git config --local user.email "action@github.com"
|
|
43
|
-
git config --local user.name "GitHub Action"
|
|
44
|
-
|
|
45
|
-
# Remove any coverage directory to avoid ambiguity with branch name
|
|
46
|
-
rm -rf coverage
|
|
47
|
-
|
|
48
|
-
# Create or checkout coverage branch
|
|
49
|
-
if git show-ref --verify --quiet refs/remotes/origin/coverage; then
|
|
50
|
-
git fetch origin coverage
|
|
51
|
-
git checkout coverage
|
|
52
|
-
else
|
|
53
|
-
git checkout --orphan coverage
|
|
54
|
-
git rm -rf . || true
|
|
55
|
-
fi
|
|
56
|
-
|
|
57
|
-
# Copy coverage report files from temp directly to root
|
|
58
|
-
cp -r /tmp/coverage-copy/coverage/lcov-report/* ./
|
|
59
|
-
rm -rf /tmp/coverage-copy
|
|
60
|
-
|
|
61
|
-
# Create .nojekyll for GitHub Pages
|
|
62
|
-
touch .nojekyll
|
|
63
|
-
|
|
64
|
-
# Create .gitignore to exclude build byproducts from coverage branch
|
|
65
|
-
echo "# Ignore build artifacts and local byproducts in coverage branch" > .gitignore
|
|
66
|
-
echo "dist/" >> .gitignore
|
|
67
|
-
echo "node_modules/" >> .gitignore
|
|
68
|
-
echo "out-tsc/" >> .gitignore
|
|
69
|
-
echo "screenshots/test/" >> .gitignore
|
|
70
|
-
echo "static/svg/work/" >> .gitignore
|
|
71
|
-
echo "# Add more patterns as needed" >> .gitignore
|
|
72
|
-
|
|
73
|
-
# Add all files
|
|
74
|
-
git add .
|
|
75
|
-
|
|
76
|
-
# Commit if there are changes
|
|
77
|
-
if ! git diff --staged --quiet; then
|
|
78
|
-
git commit -m "Update coverage reports [skip ci] - $(date)"
|
|
79
|
-
git push origin coverage
|
|
80
|
-
fi
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en-GB">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<title>Sticky Note Example</title>
|
|
6
|
-
<link
|
|
7
|
-
href="/static/css/temba-components.css"
|
|
8
|
-
rel="stylesheet"
|
|
9
|
-
type="text/css"
|
|
10
|
-
/>
|
|
11
|
-
<link
|
|
12
|
-
href="https://fonts.googleapis.com/css?family=Roboto+Mono:300|Roboto:300,400,500"
|
|
13
|
-
rel="stylesheet"
|
|
14
|
-
/>
|
|
15
|
-
<link href="../styles.css" rel="stylesheet" type="text/css" />
|
|
16
|
-
<script type="module" src="../src/flow/StickyNote.ts"></script>
|
|
17
|
-
<link href="/demo/static/css/prism.css" rel="stylesheet" />
|
|
18
|
-
<script type="module" src="/demo/static/js/prism-loader.js"></script>
|
|
19
|
-
</head>
|
|
20
|
-
<body>
|
|
21
|
-
<h1>Sticky Note Example</h1>
|
|
22
|
-
<p><a href="../index.html">← Back to main demo</a></p>
|
|
23
|
-
|
|
24
|
-
<table class="attr-table">
|
|
25
|
-
<thead>
|
|
26
|
-
<tr>
|
|
27
|
-
<th>Attribute</th>
|
|
28
|
-
<th>Description</th>
|
|
29
|
-
<th>Default</th>
|
|
30
|
-
</tr>
|
|
31
|
-
</thead>
|
|
32
|
-
<tbody>
|
|
33
|
-
<tr>
|
|
34
|
-
<td>uuid</td>
|
|
35
|
-
<td>Unique identifier for the sticky note</td>
|
|
36
|
-
<td>None (required)</td>
|
|
37
|
-
</tr>
|
|
38
|
-
<tr>
|
|
39
|
-
<td>data</td>
|
|
40
|
-
<td>
|
|
41
|
-
Object containing position, title, body, and color properties.
|
|
42
|
-
Position: {left: number, top: number}, color: 'yellow' | 'blue' | 'pink' | 'green' | 'gray'
|
|
43
|
-
</td>
|
|
44
|
-
<td>None (required)</td>
|
|
45
|
-
</tr>
|
|
46
|
-
</tbody>
|
|
47
|
-
</table>
|
|
48
|
-
|
|
49
|
-
<section class="doc-section">
|
|
50
|
-
<h2>Events</h2>
|
|
51
|
-
<p>
|
|
52
|
-
The sticky note component fires events when its content is updated through the flow store system.
|
|
53
|
-
Updates to title and body content are automatically synchronized with the flow state.
|
|
54
|
-
</p>
|
|
55
|
-
</section>
|
|
56
|
-
|
|
57
|
-
<div class="example">
|
|
58
|
-
<h3>Basic Sticky Note</h3>
|
|
59
|
-
<p>A simple yellow sticky note with default positioning</p>
|
|
60
|
-
<pre class="example-html"><code class="language-markup"><temba-sticky-note uuid="basic-note"></temba-sticky-note></code></pre>
|
|
61
|
-
<div class="demo-container">
|
|
62
|
-
<temba-sticky-note id="basic-note"></temba-sticky-note>
|
|
63
|
-
</div>
|
|
64
|
-
</div>
|
|
65
|
-
|
|
66
|
-
<div class="example">
|
|
67
|
-
<h3>Colored Sticky Notes</h3>
|
|
68
|
-
<p>Sticky notes with different color themes - click to edit the text, drag to move them around</p>
|
|
69
|
-
<pre class="example-html"><code class="language-markup"><!-- Multiple colored sticky notes -->
|
|
70
|
-
<temba-sticky-note uuid="yellow-note"></temba-sticky-note>
|
|
71
|
-
<temba-sticky-note uuid="blue-note"></temba-sticky-note>
|
|
72
|
-
<temba-sticky-note uuid="pink-note"></temba-sticky-note>
|
|
73
|
-
<temba-sticky-note uuid="green-note"></temba-sticky-note>
|
|
74
|
-
<temba-sticky-note uuid="gray-note"></temba-sticky-note></code></pre>
|
|
75
|
-
<div class="demo-container">
|
|
76
|
-
<temba-sticky-note id="yellow-note"></temba-sticky-note>
|
|
77
|
-
<temba-sticky-note id="blue-note"></temba-sticky-note>
|
|
78
|
-
<temba-sticky-note id="pink-note"></temba-sticky-note>
|
|
79
|
-
<temba-sticky-note id="green-note"></temba-sticky-note>
|
|
80
|
-
<temba-sticky-note id="gray-note"></temba-sticky-note>
|
|
81
|
-
</div>
|
|
82
|
-
<div class="expected">
|
|
83
|
-
<strong>How to use:</strong>
|
|
84
|
-
<ul>
|
|
85
|
-
<li>Click and drag the sticky notes to move them around</li>
|
|
86
|
-
<li>Click on the title or body text to edit it inline</li>
|
|
87
|
-
<li>Press Enter or Escape to finish editing</li>
|
|
88
|
-
<li>Notes snap to a 20px grid when you finish dragging</li>
|
|
89
|
-
<li>Each color has its own visual theme</li>
|
|
90
|
-
</ul>
|
|
91
|
-
</div>
|
|
92
|
-
</div>
|
|
93
|
-
|
|
94
|
-
<script type="module">
|
|
95
|
-
import '/out-tsc/temba-modules.js';
|
|
96
|
-
|
|
97
|
-
// Configure the sticky notes with sample data
|
|
98
|
-
document.addEventListener('DOMContentLoaded', () => {
|
|
99
|
-
const basicNote = document.getElementById('basic-note');
|
|
100
|
-
basicNote.uuid = 'basic-uuid';
|
|
101
|
-
basicNote.data = {
|
|
102
|
-
position: { left: 50, top: 50 },
|
|
103
|
-
title: 'Basic Note',
|
|
104
|
-
body: 'This is a basic sticky note example.',
|
|
105
|
-
color: 'yellow'
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const yellowNote = document.getElementById('yellow-note');
|
|
109
|
-
yellowNote.uuid = 'yellow-uuid';
|
|
110
|
-
yellowNote.data = {
|
|
111
|
-
position: { left: 50, top: 50 },
|
|
112
|
-
title: 'Yellow Note',
|
|
113
|
-
body: 'This is a yellow sticky note! Click to edit me.',
|
|
114
|
-
color: 'yellow'
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
const blueNote = document.getElementById('blue-note');
|
|
118
|
-
blueNote.uuid = 'blue-uuid';
|
|
119
|
-
blueNote.data = {
|
|
120
|
-
position: { left: 300, top: 120 },
|
|
121
|
-
title: 'Blue Note',
|
|
122
|
-
body: 'Blue notes are cool and calm. Drag me around!',
|
|
123
|
-
color: 'blue'
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
const pinkNote = document.getElementById('pink-note');
|
|
127
|
-
pinkNote.uuid = 'pink-uuid';
|
|
128
|
-
pinkNote.data = {
|
|
129
|
-
position: { left: 550, top: 80 },
|
|
130
|
-
title: 'Pink Note',
|
|
131
|
-
body: 'Pink is vibrant and fun. Try editing my text!',
|
|
132
|
-
color: 'pink'
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
const greenNote = document.getElementById('green-note');
|
|
136
|
-
greenNote.uuid = 'green-uuid';
|
|
137
|
-
greenNote.data = {
|
|
138
|
-
position: { left: 100, top: 250 },
|
|
139
|
-
title: 'Green Note',
|
|
140
|
-
body: 'Green represents nature and growth. I can grow in height as you type more content in my body!',
|
|
141
|
-
color: 'green'
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
const grayNote = document.getElementById('gray-note');
|
|
145
|
-
grayNote.uuid = 'gray-uuid';
|
|
146
|
-
grayNote.data = {
|
|
147
|
-
position: { left: 400, top: 300 },
|
|
148
|
-
title: 'Gray Note',
|
|
149
|
-
body: 'Gray is neutral and professional.',
|
|
150
|
-
color: 'gray'
|
|
151
|
-
};
|
|
152
|
-
});
|
|
153
|
-
</script>
|
|
154
|
-
</body>
|
|
155
|
-
</html>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EditorNode.js","sourceRoot":"","sources":["../../../src/flow/EditorNode.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAoC,MAAM,KAAK,CAAC;AAClE,OAAO,EAAE,aAAa,EAAY,MAAM,UAAU,CAAC;AAEnD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,OAAO,UAAW,SAAQ,YAAY;IAC1C,gBAAgB;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAuBD,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAoPV,CAAC;IACH,CAAC;IAED;QACE,KAAK,EAAE,CAAC;QArQV,2CAA2C;QACnC,wBAAmB,GAAwB,IAAI,GAAG,EAAE,CAAC;QAE7D,mDAAmD;QAC3C,sBAAiB,GAAgB,IAAI,GAAG,EAAE,CAAC;QAEnD,6CAA6C;QACrC,0BAAqB,GAAwB,IAAI,GAAG,EAAE,CAAC;QAE/D,qDAAqD;QAC7C,wBAAmB,GAAgB,IAAI,GAAG,EAAE,CAAC;QA4PnD,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3E,CAAC;IAES,OAAO,CACf,OAA0D;;QAE1D,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACvB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,+BAA+B;YAC/B,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC;gBACtC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;oBACnC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;wBAC3B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACrC,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,OAAO,CAAC,UAAU,CACrB,IAAI,CAAC,IAAI,CAAC,IAAI,EACd,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,gBAAgB,CACtB,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;YAED,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC;YAC/B,MAAM,IAAI,GAAG,GAAG,CAAC,qBAAqB,EAAE,CAAC;YAEzC,MAAA,QAAQ,EAAE,0CACN,QAAQ,GACT,YAAY,CACX,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,EAClC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CACnC,CAAC;QACN,CAAC;IACH,CAAC;IAED,oBAAoB;QAClB,0DAA0D;QAC1D,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAE7B,0CAA0C;QAC1C,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YAC7C,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;QAEjC,4CAA4C;QAC5C,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YAC/C,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC;QAEnC,2BAA2B;QAC3B,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;IACnC,CAAC;IAEO,eAAe,CAAC,KAAiB,EAAE,IAAU;QACnD,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,eAAe,EAAE,CAAC;QAExB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC;QAEzB,uCAAuC;QACvC,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,OAAO;QAEnC,mEAAmE;QACnE,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnC,IAAI,CAAC,aAAa,EAAE,CAAC;QAErB,uCAAuC;QACvC,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAEtD,2CAA2C;QAC3C,IAAI,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzC,YAAY,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACrD,CAAC;QAED,gDAAgD;QAChD,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;YACvC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACtC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAExC,uCAAuC;YACvC,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAEvD,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClD,CAAC;IAEO,cAAc,CAAC,IAAU;;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC;QAEzB,qBAAqB;QACrB,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAEtC,4FAA4F;QAC5F,8DAA8D;QAC9D,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEvD,oBAAoB;QACpB,IAAI,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzC,YAAY,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;YACnD,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;QAED,gCAAgC;QAChC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAE1C,6BAA6B;QAC7B,MAAM,WAAW,GAAG,EAAE,GAAG,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC;QACxD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC7C,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CACpC,CAAC;QAEF,kBAAkB;QAClB,MAAM,WAAW,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;QAC1D,MAAA,QAAQ,EAAE,0CAAE,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAE/D,oCAAoC;QACpC,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAEO,uBAAuB,CAC7B,KAAiB,EACjB,MAAc,EACd,KAAa;QAEb,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,eAAe,EAAE,CAAC;QAExB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;QAE7B,kEAAkE;QAClE,IAAI,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACjC,OAAO;QACT,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,aAAa,EAAE,CAAC;QAErB,6CAA6C;QAC7C,IAAI,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7C,YAAY,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzD,CAAC;QAED,gDAAgD;QAChD,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;YACvC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC1C,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5C,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,+BAA+B;QAEzC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACtD,CAAC;IAED,6DAA6D;IACrD,YAAY,CAAC,MAAc,EAAE,MAAc;;QACjD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;QAE7B,qBAAqB;QACrB,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAE1C,oBAAoB;QACpB,IAAI,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7C,YAAY,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;YACvD,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9C,CAAC;QAED,kCAAkC;QAClC,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;QAE5E,+CAA+C;QAC/C,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,WAAW,EAAE;gBAChD,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI;aACrB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,yCAAyC;YACzC,MAAM,WAAW,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;YAC9D,MAAA,QAAQ,EAAE,0CAAE,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAE/D,oCAAoC;YACpC,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAEO,wBAAwB,CAAC,KAAkB;;QACjD,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;QAE3C,mBAAmB;QACnB,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;QAEzC,oEAAoE;QACpE,oEAAoE;QACpE,oCAAoC;QACpC,IAAI,CAAC,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;QAElD,MAAA,QAAQ,EAAE,0CACN,QAAQ,GACT,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IACvE,CAAC;IAEO,WAAW,CAAC,MAAgB,EAAE,aAAsB,KAAK;;QAC/D,OAAO,IAAI,CAAA,wCAAwC,MAAM,CAAC,KAAK;QAC3D,CAAA,MAAA,MAAA,IAAI,CAAC,IAAI,0CAAE,OAAO,0CAAE,MAAM,IAAG,CAAC;YAC9B,CAAC,CAAC,IAAI,CAAA,2DAA2D;YACjE,CAAC,CAAC,IAAI;;0BAEY,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI;WACnD,CAAC;IACV,CAAC;IAEO,YAAY,CAAC,IAAU,EAAE,MAAc,EAAE,KAAa;QAC5D,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAE7D,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,IAAI,CAAA;iCACgB,MAAM,CAAC,IAAI,IAAI,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;qBACvD,KAAK;;;;mBAIP,CAAC,CAAa,EAAE,EAAE,CACzB,IAAI,CAAC,uBAAuB,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC;;;;;;YAM9C,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC;;cAElC,MAAM,CAAC,MAAM;gBACb,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;gBAC7B,CAAC,CAAC,IAAI,CAAA,QAAQ,MAAM,CAAC,IAAI,QAAQ;;;aAGlC,CAAC;QACV,CAAC;QACD,OAAO,IAAI,CAAA;+BACgB,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;mBACxC,KAAK;;;;iBAIP,CAAC,CAAa,EAAE,EAAE,CACzB,IAAI,CAAC,uBAAuB,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC;;;;;QAKhD,MAAM,CAAC,IAAI;WACR,CAAC;IACV,CAAC;IAEO,YAAY,CAAC,MAAc,EAAE,EAAU;QAC7C,MAAM,MAAM,GAAG,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,IAAI,CAAA;UACP,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC;UAC/B,MAAM,CAAC,WAAW;gBAClB,CAAC,CAAC,IAAI,CAAA;;yCAEyB,MAAM,CAAC,WAAW;mBACxC;gBACT,CAAC,CAAC,IAAI;aACH,CAAC;QACV,CAAC;IACH,CAAC;IAEO,gBAAgB,CAAC,IAAU;QACjC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;YACzD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAC1B,CAAC,IAAU,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,SAAS,CAChD,CAAC;YAEF,OAAO,IAAI,CAAA;6BACY,QAAQ,CAAC,IAAI;UAChC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;aAClB,CAAC;QACV,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAA,2BAA2B,UAAU,QAAQ,CAAC;IAC3D,CAAC;IAEO,UAAU,CAAC,IAAU;QAC3B,OAAO,IAAI,CAAA;;cAED,IAAI,CAAC,IAAI;gBACP,UAAU,CAAC;YACjB,IAAI,EAAE,IAAI;YACV,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB;YAClC,QAAQ,EAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;SAChD,CAAC;iBACO,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC;;WAEtD,CAAC;IACV,CAAC;IAEM,MAAM;QACX,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAA,oCAAoC,CAAC;QAClD,CAAC;QAED,OAAO,IAAI,CAAA;;cAED,IAAI,CAAC,IAAI,CAAC,IAAI;;sBAEN,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG;;UAE/D,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;YAC5B,CAAC,CAAC,IAAI,CAAA;;sCAEsB,IAAI,CAAC,wBAAwB;;gBAEnD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE;gBAC5C,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;YACzD,CAAC,CAAC;mCACmB;YACzB,CAAC,CAAC,EAAE;UACJ,IAAI,CAAC,IAAI,CAAC,MAAM;YAChB,CAAC,CAAC,IAAI,CAAA,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;cAClD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACtC,CAAC,CAAC,IAAI,CAAA;gBACA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC7B,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC,CAAC;mBACG;;KAEd,CAAC;IACJ,CAAC;CACF;AAxmBS;IADP,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2CACF;AAGjB;IADP,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;wCACR;AAGX;IADP,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sCACR","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { EDITOR_CONFIG, UIConfig } from './config';\nimport { Action, Exit, Node, NodeUI, Router } from '../store/flow-definition';\nimport { property } from 'lit/decorators.js';\nimport { RapidElement } from '../RapidElement';\nimport { getClasses } from '../utils';\nimport { Plumber } from './Plumber';\nimport { getStore } from '../store/Store';\nimport { CustomEventType } from '../interfaces';\n\nexport class EditorNode extends RapidElement {\n createRenderRoot() {\n return this;\n }\n\n @property({ type: Object })\n private plumber: Plumber;\n\n @property({ type: Object })\n private node: Node;\n\n @property({ type: Object })\n private ui: NodeUI;\n\n // Track exits that are in \"removing\" state\n private exitRemovalTimeouts: Map<string, number> = new Map();\n\n // Set of exit UUIDs that are in the removing state\n private exitRemovingState: Set<string> = new Set();\n\n // Track actions that are in \"removing\" state\n private actionRemovalTimeouts: Map<string, number> = new Map();\n\n // Set of action UUIDs that are in the removing state\n private actionRemovingState: Set<string> = new Set();\n\n static get styles() {\n return css`\n\n .node {\n background-color: #fff;\n box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\n min-width: 200px;\n border-radius: var(--curvature);\n \n color: #333;\n cursor: move;\n user-select: none;\n\n }\n\n .node:hover {\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);\n }\n\n .node.dragging {\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.4);\n transform: scale(1.02);\n z-index: 1000;\n }\n\n .action {\n max-width: 200px;\n position: relative;\n }\n\n .action .remove-button {\n position: absolute;\n top: 5px;\n right: 5px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--color-error, #dc3545);\n color: white;\n border: none;\n cursor: pointer;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n line-height: 1;\n z-index: 10;\n }\n\n .action:hover .remove-button {\n display: flex;\n }\n\n .action.removing .title {\n background-color: var(--color-error, #dc3545) !important;\n }\n\n .action.removing .title .name {\n color: white;\n }\n\n .action.sortable {\n display: flex;\n align-items: stretch;\n }\n\n .action .action-content {\n flex-grow: 1;\n display: flex;\n flex-direction: column;\n }\n\n .action .body {\n padding: 1em;\n }\n\n .action .drag-handle {\n opacity: 0;\n transition: all 200ms ease-in-out;\n cursor: move;\n background: rgba(0, 0, 0, 0.02);\n max-width:0px;\n position: absolute;\n }\n\n .action:hover .drag-handle {\n opacity: 0.5;\n padding: 0.25em;\n max-width: 20px;\n }\n\n .action .drag-handle:hover {\n opacity: 1;\n \n }\n\n .action .title,\n .router .title {\n display: flex;\n color: #fff;\n padding: 5px 1px;\n text-align: center;\n font-size: 1em;\n font-weight: normal;\n\n }\n\n .title .name {\n flex-grow: 1;\n }\n\n .quick-replies {\n margin-top: 0.5em;\n }\n\n .quick-reply {\n background-color: #f0f0f0;\n border: 1px solid #e0e0e0;\n border-radius: calc(var(--curvature) * 1.5);\n padding: 0.2em 1em;\n display: inline-block;\n font-size: 0.8em;\n margin: 0.2em;\n }\n\n .categories {\n display: flex;\n flex-direction: row;\n\n }\n\n .category {\n margin:-1px -0.5px;\n border: 1px solid #f3f3f3;\n padding: 0.75em;\n flex-grow:1;\n text-align: center;\n display: flex;\n flex-direction: column;\n }\n\n .action-exits {\n padding-bottom: 0.6em;\n margin-top: -0.8em;\n }\n\n .category .title {\n font-weight: normal;\n font-size: 1em;\n }\n\n .router .body {\n padding: 0.75em;\n }\n\n .result-name {\n font-weight: bold;\n display: inline-block;\n }\n \n .exit-wrapper {\n display: flex;\n justify-content: center;\n align-items: center;\n position: relative;\n margin-bottom: -1.2em;\n padding-top:0.2em;\n }\n\n .exit {\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background-color: tomato;\n position: relative;\n box-shadow: 0 2px 2px rgba(0, 0, 0, .1);\n cursor: pointer;\n pointer-events: none;\n }\n\n .exit.jtk-connected {\n background: var(--color-connectors, #e6e6e6);\n }\n\n .exit.connected {\n background-color: #fff;\n pointer-events: all;\n }\n\n .exit.connected:hover {\n background-color: var(--color-connectors, #e6e6e6);\n }\n \n .exit.removing, .exit.removing:hover {\n background-color: var(--color-error);\n pointer-events: all;\n }\n \n .exit.removing::before {\n content: '✕';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 8px;\n color: white;\n line-height: 1;\n }\n \n /* Connector in removing state */\n :host {\n --color-connector-removing: var(--color-error);\n }\n \n body svg.plumb-connector.removing path {\n stroke: var(--color-connector-removing, tomato) !important;\n stroke-width: 3px;\n }\n \n body .plumb-connector.removing .plumb-arrow {\n fill: var(--color-connector-removing, tomato) !important;\n stroke: var(--color-connector-removing, transparent) !important;\n }\n\n .category:first-child {\n border-bottom-left-radius: var(--curvature);\n }\n\n .category:last-child {\n border-bottom-right-radius: var(--curvature);\n }\n\n .router .title {\n border-top-left-radius: var(--curvature);\n border-top-right-radius: var(--curvature);\n }\n\n .action{\n overflow: hidden;\n }\n\n .action:first-child .title {\n border-top-left-radius: var(--curvature);\n border-top-right-radius: var(--curvature);\n }\n }`;\n }\n\n constructor() {\n super();\n this.handleActionOrderChanged = this.handleActionOrderChanged.bind(this);\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('node')) {\n // make our initial connections\n if (changes.get('node') === undefined) {\n for (const exit of this.node.exits) {\n if (!exit.destination_uuid) {\n this.plumber.makeSource(exit.uuid);\n } else {\n this.plumber.connectIds(\n this.node.uuid,\n exit.uuid,\n exit.destination_uuid\n );\n }\n }\n }\n\n const ele = this.parentElement;\n const rect = ele.getBoundingClientRect();\n\n getStore()\n ?.getState()\n .expandCanvas(\n this.ui.position.left + rect.width,\n this.ui.position.top + rect.height\n );\n }\n }\n\n disconnectedCallback() {\n // Remove the event listener when the component is removed\n super.disconnectedCallback();\n\n // Clear any pending exit removal timeouts\n this.exitRemovalTimeouts.forEach((timeoutId) => {\n clearTimeout(timeoutId);\n });\n this.exitRemovalTimeouts.clear();\n\n // Clear any pending action removal timeouts\n this.actionRemovalTimeouts.forEach((timeoutId) => {\n clearTimeout(timeoutId);\n });\n this.actionRemovalTimeouts.clear();\n\n // Clear the removing state\n this.exitRemovingState.clear();\n this.actionRemovingState.clear();\n }\n\n private handleExitClick(event: MouseEvent, exit: Exit) {\n event.preventDefault();\n event.stopPropagation();\n\n const exitId = exit.uuid;\n\n // If exit is not connected, do nothing\n if (!exit.destination_uuid) return;\n\n // If the exit is already in removing state, perform the disconnect\n if (this.exitRemovingState.has(exitId)) {\n this.disconnectExit(exit);\n return;\n }\n\n // Start removal UI state\n this.exitRemovingState.add(exitId);\n this.requestUpdate();\n\n // Set the connection to removing state\n this.plumber.setConnectionRemovingState(exitId, true);\n\n // Clear any existing timeout for this exit\n if (this.exitRemovalTimeouts.has(exitId)) {\n clearTimeout(this.exitRemovalTimeouts.get(exitId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.exitRemovingState.delete(exitId);\n this.exitRemovalTimeouts.delete(exitId);\n\n // Reset the connection to normal state\n this.plumber.setConnectionRemovingState(exitId, false);\n\n this.requestUpdate();\n }, 1500);\n\n this.exitRemovalTimeouts.set(exitId, timeoutId);\n }\n\n private disconnectExit(exit: Exit) {\n const exitId = exit.uuid;\n\n // Clear the UI state\n this.exitRemovingState.delete(exitId);\n\n // Reset the connection to normal state (this will be redundant as we're about to remove it,\n // but it's safer to do this in case there's any timing issue)\n this.plumber.setConnectionRemovingState(exitId, false);\n\n // Clear any timeout\n if (this.exitRemovalTimeouts.has(exitId)) {\n clearTimeout(this.exitRemovalTimeouts.get(exitId));\n this.exitRemovalTimeouts.delete(exitId);\n }\n\n // Remove the JSPlumb connection\n this.plumber.removeExitConnection(exitId);\n\n // Update the flow definition\n const updatedExit = { ...exit, destination_uuid: null };\n const updatedExits = this.node.exits.map((e) =>\n e.uuid === exitId ? updatedExit : e\n );\n\n // Update the node\n const updatedNode = { ...this.node, exits: updatedExits };\n getStore()?.getState().updateNode(this.node.uuid, updatedNode);\n\n // Request update to reflect changes\n this.requestUpdate();\n }\n\n private handleActionRemoveClick(\n event: MouseEvent,\n action: Action,\n index: number\n ) {\n event.preventDefault();\n event.stopPropagation();\n\n const actionId = action.uuid;\n\n // If the action is already in removing state, perform the removal\n if (this.actionRemovingState.has(actionId)) {\n this.removeAction(action, index);\n return;\n }\n\n // Start removal UI state\n this.actionRemovingState.add(actionId);\n this.requestUpdate();\n\n // Clear any existing timeout for this action\n if (this.actionRemovalTimeouts.has(actionId)) {\n clearTimeout(this.actionRemovalTimeouts.get(actionId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.actionRemovingState.delete(actionId);\n this.actionRemovalTimeouts.delete(actionId);\n this.requestUpdate();\n }, 1000); // 1 second as per requirements\n\n this.actionRemovalTimeouts.set(actionId, timeoutId);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n private removeAction(action: Action, _index: number) {\n const actionId = action.uuid;\n\n // Clear the UI state\n this.actionRemovingState.delete(actionId);\n\n // Clear any timeout\n if (this.actionRemovalTimeouts.has(actionId)) {\n clearTimeout(this.actionRemovalTimeouts.get(actionId));\n this.actionRemovalTimeouts.delete(actionId);\n }\n\n // Remove the action from the node\n const updatedActions = this.node.actions.filter((a) => a.uuid !== actionId);\n\n // If no actions remain, remove the entire node\n if (updatedActions.length === 0) {\n this.fireCustomEvent(CustomEventType.NodeDeleted, {\n uuid: this.node.uuid\n });\n } else {\n // Update the node with remaining actions\n const updatedNode = { ...this.node, actions: updatedActions };\n getStore()?.getState().updateNode(this.node.uuid, updatedNode);\n\n // Request update to reflect changes\n this.requestUpdate();\n }\n }\n\n private handleActionOrderChanged(event: CustomEvent) {\n const [fromIdx, toIdx] = event.detail.swap;\n\n // swap our actions\n const newActions = [...this.node.actions];\n const movedAction = newActions.splice(fromIdx, 1)[0];\n newActions.splice(toIdx, 0, movedAction);\n\n // udate our internal reprensentation, this isn't strictly necessary\n // since the editor will update us from it's definition subscription\n // but it makes testing a lot easier\n this.node = { ...this.node, actions: newActions };\n\n getStore()\n ?.getState()\n .updateNode(this.node.uuid, { ...this.node, actions: newActions });\n }\n\n private renderTitle(config: UIConfig, isRemoving: boolean = false) {\n return html`<div class=\"title\" style=\"background:${config.color}\">\n ${this.node?.actions?.length > 1\n ? html`<temba-icon class=\"drag-handle\" name=\"sort\"></temba-icon>`\n : null}\n\n <div class=\"name\">${isRemoving ? 'Remove?' : config.name}</div>\n </div>`;\n }\n\n private renderAction(node: Node, action: Action, index: number) {\n const config = EDITOR_CONFIG[action.type];\n const isRemoving = this.actionRemovingState.has(action.uuid);\n\n if (config) {\n return html`<div\n class=\"action sortable ${action.type} ${isRemoving ? 'removing' : ''}\"\n id=\"action-${index}\"\n >\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) =>\n this.handleActionRemoveClick(e, action, index)}\n title=\"Remove action\"\n >\n ✕\n </button>\n <div class=\"action-content\">\n ${this.renderTitle(config, isRemoving)}\n <div class=\"body\">\n ${config.render\n ? config.render(node, action)\n : html`<pre>${action.type}</pre>`}\n </div>\n </div>\n </div>`;\n }\n return html`<div\n class=\"action sortable ${isRemoving ? 'removing' : ''}\"\n id=\"action-${index}\"\n >\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) =>\n this.handleActionRemoveClick(e, action, index)}\n title=\"Remove action\"\n >\n ✕\n </button>\n ${action.type}\n </div>`;\n }\n\n private renderRouter(router: Router, ui: NodeUI) {\n const config = EDITOR_CONFIG[ui.type];\n if (config) {\n return html`<div class=\"router\">\n ${this.renderTitle(config, false)}\n ${router.result_name\n ? html`<div class=\"body\">\n Save as\n <div class=\"result-name\">${router.result_name}</div>\n </div>`\n : null}\n </div>`;\n }\n }\n\n private renderCategories(node: Node) {\n if (!node.router || !node.router.categories) {\n return null;\n }\n const categories = node.router.categories.map((category) => {\n const exit = node.exits.find(\n (exit: Exit) => exit.uuid == category.exit_uuid\n );\n\n return html`<div class=\"category\">\n <div class=\"title\">${category.name}</div>\n ${this.renderExit(exit)}\n </div>`;\n });\n\n return html`<div class=\"categories\">${categories}</div>`;\n }\n\n private renderExit(exit: Exit): TemplateResult {\n return html`<div class=\"exit-wrapper\">\n <div\n id=\"${exit.uuid}\"\n class=${getClasses({\n exit: true,\n connected: !!exit.destination_uuid,\n removing: this.exitRemovingState.has(exit.uuid)\n })}\n @click=${(e: MouseEvent) => this.handleExitClick(e, exit)}\n ></div>\n </div>`;\n }\n\n public render() {\n if (!this.node || !this.ui) {\n return html`<div class=\"node\">Loading...</div>`;\n }\n\n return html`\n <div\n id=\"${this.node.uuid}\"\n class=\"node\"\n style=\"left:${this.ui.position.left}px;top:${this.ui.position.top}px\"\n >\n ${this.node.actions.length > 0\n ? html`<temba-sortable-list\n dragHandle=\"drag-handle\"\n @temba-order-changed=\"${this.handleActionOrderChanged}\"\n >\n ${this.node.actions.map((actionSpec, index) => {\n return this.renderAction(this.node, actionSpec, index);\n })}\n </temba-sortable-list>`\n : ''}\n ${this.node.router\n ? html` ${this.renderRouter(this.node.router, this.ui)}\n ${this.renderCategories(this.node)}`\n : html`<div class=\"action-exits\">\n ${this.node.exits.map((exit) => {\n return this.renderExit(exit);\n })}\n </div>`}\n </div>\n `;\n }\n}\n"]}
|
|
@@ -1,358 +0,0 @@
|
|
|
1
|
-
import { html } from 'lit-html';
|
|
2
|
-
import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
|
|
3
|
-
import { Icon } from '../Icons';
|
|
4
|
-
// URN scheme mapping for user-friendly display
|
|
5
|
-
const urnSchemeMap = {
|
|
6
|
-
tel: 'Phone Number',
|
|
7
|
-
email: 'Email',
|
|
8
|
-
twitter: 'Twitter',
|
|
9
|
-
facebook: 'Facebook',
|
|
10
|
-
telegram: 'Telegram',
|
|
11
|
-
whatsapp: 'WhatsApp',
|
|
12
|
-
viber: 'Viber',
|
|
13
|
-
line: 'Line',
|
|
14
|
-
discord: 'Discord',
|
|
15
|
-
slack: 'Slack',
|
|
16
|
-
external: 'External ID'
|
|
17
|
-
};
|
|
18
|
-
const renderLineItem = (name, icon) => {
|
|
19
|
-
return html `<div style="display:flex;items-align:center">
|
|
20
|
-
${icon
|
|
21
|
-
? html `<temba-icon name=${icon} style="margin-right:0.5em"></temba-icon>`
|
|
22
|
-
: null}
|
|
23
|
-
<div
|
|
24
|
-
style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
|
|
25
|
-
>
|
|
26
|
-
${name}
|
|
27
|
-
</div>
|
|
28
|
-
</div>`;
|
|
29
|
-
};
|
|
30
|
-
const renderNamedObjects = (assets, icon) => {
|
|
31
|
-
const items = [];
|
|
32
|
-
const maxDisplay = 3;
|
|
33
|
-
// Show up to 3 items, or all 4 if exactly 4 items
|
|
34
|
-
const displayCount = assets.length === 4 ? 4 : Math.min(maxDisplay, assets.length);
|
|
35
|
-
for (let i = 0; i < displayCount; i++) {
|
|
36
|
-
const asset = assets[i];
|
|
37
|
-
items.push(renderLineItem(asset.name, icon));
|
|
38
|
-
}
|
|
39
|
-
// Add "+X more" if there are more than 3 items (and not exactly 4)
|
|
40
|
-
if (assets.length > maxDisplay && assets.length !== 4) {
|
|
41
|
-
const remainingCount = assets.length - maxDisplay;
|
|
42
|
-
items.push(html `<div style="display:flex;items-align:center; color: #666;">
|
|
43
|
-
${icon
|
|
44
|
-
? html `<div style="margin-right:0.5em; width: 1em;"></div>` // spacing placeholder
|
|
45
|
-
: null}
|
|
46
|
-
<div>+${remainingCount} more</div>
|
|
47
|
-
</div>`);
|
|
48
|
-
}
|
|
49
|
-
return items;
|
|
50
|
-
};
|
|
51
|
-
export const renderSendMsg = (node, action) => {
|
|
52
|
-
const text = action.text.replace(/\n/g, '<br>');
|
|
53
|
-
return html `
|
|
54
|
-
${unsafeHTML(text)}
|
|
55
|
-
${action.quick_replies.length > 0
|
|
56
|
-
? html `<div class="quick-replies">
|
|
57
|
-
${action.quick_replies.map((reply) => {
|
|
58
|
-
return html `<div class="quick-reply">${reply}</div>`;
|
|
59
|
-
})}
|
|
60
|
-
</div>`
|
|
61
|
-
: null}
|
|
62
|
-
`;
|
|
63
|
-
};
|
|
64
|
-
export const renderSetContactName = (node, action) => {
|
|
65
|
-
return html `<div>Set contact name to <b>${action.name}</b></div>`;
|
|
66
|
-
};
|
|
67
|
-
export const renderSetRunResult = (node, action) => {
|
|
68
|
-
return html `<div>Save ${action.value} as <b>${action.name}</b></div>`;
|
|
69
|
-
};
|
|
70
|
-
export const renderCallWebhook = (node, action) => {
|
|
71
|
-
return html `<div
|
|
72
|
-
style="word-break: break-all; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
|
|
73
|
-
>
|
|
74
|
-
${action.url}
|
|
75
|
-
</div>`;
|
|
76
|
-
};
|
|
77
|
-
export const renderAddToGroups = (node, action) => {
|
|
78
|
-
return html `<div>${renderNamedObjects(action.groups, 'group')}</div>`;
|
|
79
|
-
};
|
|
80
|
-
export const renderRemoveFromGroups = (node, action) => {
|
|
81
|
-
return html `<div>${renderNamedObjects(action.groups, 'group')}</div>`;
|
|
82
|
-
};
|
|
83
|
-
export const renderSetContactField = (node, action) => {
|
|
84
|
-
return html `<div>
|
|
85
|
-
Set <b>${action.field.name}</b> to <b>${action.value}</b>
|
|
86
|
-
</div>`;
|
|
87
|
-
};
|
|
88
|
-
export const renderSetContactLanguage = (node, action) => {
|
|
89
|
-
return html `<div>Set contact language to <b>${action.language}</b></div>`;
|
|
90
|
-
};
|
|
91
|
-
export const renderSetContactStatus = (node, action) => {
|
|
92
|
-
return html `<div>Set contact status to <b>${action.status}</b></div>`;
|
|
93
|
-
};
|
|
94
|
-
export const renderSetContactChannel = (node, action) => {
|
|
95
|
-
return html `<div>Set contact channel to <b>${action.channel.name}</b></div>`;
|
|
96
|
-
};
|
|
97
|
-
export const renderAddContactUrn = (node, action) => {
|
|
98
|
-
const friendlyScheme = urnSchemeMap[action.scheme] || action.scheme;
|
|
99
|
-
return html `<div
|
|
100
|
-
style="word-wrap: break-word; overflow: hidden; text-overflow: ellipsis;"
|
|
101
|
-
>
|
|
102
|
-
Add ${friendlyScheme} <b>${action.path}</b>
|
|
103
|
-
</div>`;
|
|
104
|
-
};
|
|
105
|
-
export const renderSendEmail = (node, action) => {
|
|
106
|
-
const addressList = action.addresses.join(', ');
|
|
107
|
-
return html `<div>
|
|
108
|
-
<div
|
|
109
|
-
style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
|
|
110
|
-
>
|
|
111
|
-
<b>${addressList}</b>
|
|
112
|
-
</div>
|
|
113
|
-
<div style="margin-top: 0.5em">
|
|
114
|
-
<div
|
|
115
|
-
style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
|
|
116
|
-
>
|
|
117
|
-
${action.subject}
|
|
118
|
-
</div>
|
|
119
|
-
<div
|
|
120
|
-
style="margin-top: 0.25em; word-wrap: break-word; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"
|
|
121
|
-
>
|
|
122
|
-
${action.body}
|
|
123
|
-
</div>
|
|
124
|
-
</div>
|
|
125
|
-
</div>`;
|
|
126
|
-
};
|
|
127
|
-
export const renderSendBroadcast = (node, action) => {
|
|
128
|
-
const hasGroups = action.groups && action.groups.length > 0;
|
|
129
|
-
const hasContacts = action.contacts && action.contacts.length > 0;
|
|
130
|
-
return html `<div>
|
|
131
|
-
<div style="word-wrap: break-word; margin-bottom: 0.5em">
|
|
132
|
-
${action.text}
|
|
133
|
-
</div>
|
|
134
|
-
${hasGroups
|
|
135
|
-
? html `<div style="margin-bottom: 0.25em">
|
|
136
|
-
<div style="font-weight: bold; margin-bottom: 0.25em">Groups:</div>
|
|
137
|
-
${renderNamedObjects(action.groups, 'group')}
|
|
138
|
-
</div>`
|
|
139
|
-
: null}
|
|
140
|
-
${hasContacts
|
|
141
|
-
? html `<div>
|
|
142
|
-
<div style="font-weight: bold; margin-bottom: 0.25em">Contacts:</div>
|
|
143
|
-
${renderNamedObjects(action.contacts, 'contact')}
|
|
144
|
-
</div>`
|
|
145
|
-
: null}
|
|
146
|
-
</div>`;
|
|
147
|
-
};
|
|
148
|
-
export const renderEnterFlow = (node, action) => {
|
|
149
|
-
return html `<div>Enter flow <b>${action.flow.name}</b></div>`;
|
|
150
|
-
};
|
|
151
|
-
export const renderStartSession = (node, action) => {
|
|
152
|
-
const hasGroups = action.groups && action.groups.length > 0;
|
|
153
|
-
const hasContacts = action.contacts && action.contacts.length > 0;
|
|
154
|
-
return html `<div>
|
|
155
|
-
${hasGroups
|
|
156
|
-
? html `<div style="margin-top: 0.5em">
|
|
157
|
-
<div style="font-weight: bold; margin-bottom: 0.25em">Groups:</div>
|
|
158
|
-
${renderNamedObjects(action.groups, 'group')}
|
|
159
|
-
</div>`
|
|
160
|
-
: null}
|
|
161
|
-
${hasContacts
|
|
162
|
-
? html `<div style="margin-top: 0.5em">
|
|
163
|
-
<div style="font-weight: bold; margin-bottom: 0.25em">Contacts:</div>
|
|
164
|
-
${renderNamedObjects(action.contacts, 'contact')}
|
|
165
|
-
</div>`
|
|
166
|
-
: null}
|
|
167
|
-
${action.create_contact
|
|
168
|
-
? renderLineItem('Create contact', Icon.contact)
|
|
169
|
-
: null}
|
|
170
|
-
${renderLineItem(action.flow.name, Icon.flow)}
|
|
171
|
-
</div>`;
|
|
172
|
-
};
|
|
173
|
-
export const renderTransferAirtime = (node, action) => {
|
|
174
|
-
const amounts = action.amounts.join(', ');
|
|
175
|
-
return html `<div>
|
|
176
|
-
Transfer airtime amounts: <b>${amounts}</b>
|
|
177
|
-
<div>Save result as <b>${action.result_name}</b></div>
|
|
178
|
-
</div>`;
|
|
179
|
-
};
|
|
180
|
-
export const renderCallClassifier = (node, action) => {
|
|
181
|
-
return html `<div>
|
|
182
|
-
<div>Call classifier <b>${action.classifier.name}</b></div>
|
|
183
|
-
<div style="margin-top: 0.25em; word-wrap: break-word">
|
|
184
|
-
Input: <b>${action.input}</b>
|
|
185
|
-
</div>
|
|
186
|
-
<div style="margin-top: 0.25em">
|
|
187
|
-
Save result as <b>${action.result_name}</b>
|
|
188
|
-
</div>
|
|
189
|
-
</div>`;
|
|
190
|
-
};
|
|
191
|
-
export const renderCallResthook = (node, action) => {
|
|
192
|
-
return html `<div>
|
|
193
|
-
<div>Call resthook <b>${action.resthook}</b></div>
|
|
194
|
-
<div style="margin-top: 0.25em">
|
|
195
|
-
Save result as <b>${action.result_name}</b>
|
|
196
|
-
</div>
|
|
197
|
-
</div>`;
|
|
198
|
-
};
|
|
199
|
-
export const renderCallLLM = (node, action) => {
|
|
200
|
-
return html `<div>
|
|
201
|
-
<div style="margin-top: 0.25em; display: flex; align-items: center;">
|
|
202
|
-
<temba-icon name="ai" style="margin-right: 0.5em"></temba-icon>
|
|
203
|
-
<span
|
|
204
|
-
style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
|
|
205
|
-
>
|
|
206
|
-
${action.llm.name}
|
|
207
|
-
</span>
|
|
208
|
-
</div>
|
|
209
|
-
<div
|
|
210
|
-
style="margin-top: 0.25em; word-wrap: break-word; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"
|
|
211
|
-
>
|
|
212
|
-
${action.instructions}
|
|
213
|
-
</div>
|
|
214
|
-
</div>`;
|
|
215
|
-
};
|
|
216
|
-
export const renderOpenTicket = (node, action) => {
|
|
217
|
-
return html `<div>
|
|
218
|
-
<div
|
|
219
|
-
style="word-wrap: break-word; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"
|
|
220
|
-
>
|
|
221
|
-
${action.body}
|
|
222
|
-
</div>
|
|
223
|
-
${action.assignee
|
|
224
|
-
? html `<div
|
|
225
|
-
style="margin-top: 0.25em; display: flex; align-items: center;"
|
|
226
|
-
>
|
|
227
|
-
<temba-icon name="user" style="margin-right: 0.5em"></temba-icon>
|
|
228
|
-
<span
|
|
229
|
-
style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
|
|
230
|
-
>
|
|
231
|
-
${action.assignee.name}
|
|
232
|
-
</span>
|
|
233
|
-
</div>`
|
|
234
|
-
: null}
|
|
235
|
-
${action.topic
|
|
236
|
-
? html `<div
|
|
237
|
-
style="margin-top: 0.25em; display: flex; align-items: center;"
|
|
238
|
-
>
|
|
239
|
-
<temba-icon name="topic" style="margin-right: 0.5em"></temba-icon>
|
|
240
|
-
<span
|
|
241
|
-
style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
|
|
242
|
-
>
|
|
243
|
-
${action.topic.name}
|
|
244
|
-
</span>
|
|
245
|
-
</div>`
|
|
246
|
-
: null}
|
|
247
|
-
</div>`;
|
|
248
|
-
};
|
|
249
|
-
export const renderRequestOptin = (node, action) => {
|
|
250
|
-
return html `<div>Request opt-in for <b>${action.optin.name}</b></div>`;
|
|
251
|
-
};
|
|
252
|
-
export const renderAddInputLabels = (node, action) => {
|
|
253
|
-
return html `<div>${renderNamedObjects(action.labels, 'label')}</div>`;
|
|
254
|
-
};
|
|
255
|
-
export const renderSayMsg = (node, action) => {
|
|
256
|
-
return html `<div>
|
|
257
|
-
<div
|
|
258
|
-
style="word-wrap: break-word; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
|
|
259
|
-
>
|
|
260
|
-
${action.text}
|
|
261
|
-
</div>
|
|
262
|
-
${action.audio_url
|
|
263
|
-
? html `<div
|
|
264
|
-
style="margin-top: 0.5em; display: flex; align-items: center;"
|
|
265
|
-
>
|
|
266
|
-
<temba-icon name="audio" style="margin-right: 0.25em"></temba-icon>
|
|
267
|
-
<span
|
|
268
|
-
style="word-break: break-all; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
|
|
269
|
-
>${action.audio_url}</span
|
|
270
|
-
>
|
|
271
|
-
</div>`
|
|
272
|
-
: null}
|
|
273
|
-
</div>`;
|
|
274
|
-
};
|
|
275
|
-
export const renderPlayAudio = (node, action) => {
|
|
276
|
-
return html `<div style="display: flex; align-items: center;">
|
|
277
|
-
<temba-icon name="audio" style="margin-right: 0.25em"></temba-icon>
|
|
278
|
-
<span
|
|
279
|
-
style="word-break: break-all; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
|
|
280
|
-
>${action.audio_url}</span
|
|
281
|
-
>
|
|
282
|
-
</div>`;
|
|
283
|
-
};
|
|
284
|
-
export const renderWaitForResponse = (node, action) => {
|
|
285
|
-
return html `<div>
|
|
286
|
-
Wait for message response
|
|
287
|
-
${action.timeout
|
|
288
|
-
? html `<div style="margin-top: 0.25em">
|
|
289
|
-
Timeout after <b>${action.timeout}</b> seconds
|
|
290
|
-
</div>`
|
|
291
|
-
: null}
|
|
292
|
-
</div>`;
|
|
293
|
-
};
|
|
294
|
-
export const renderWaitForMenu = (node, action) => {
|
|
295
|
-
return html `<div>
|
|
296
|
-
Wait for menu selection: <b>${action.menu.name}</b>
|
|
297
|
-
${action.timeout
|
|
298
|
-
? html `<div style="margin-top: 0.25em">
|
|
299
|
-
Timeout after <b>${action.timeout}</b> seconds
|
|
300
|
-
</div>`
|
|
301
|
-
: null}
|
|
302
|
-
</div>`;
|
|
303
|
-
};
|
|
304
|
-
export const renderWaitForDigits = (node, action) => {
|
|
305
|
-
return html `<div>
|
|
306
|
-
Wait for <b>${action.count}</b> digit${action.count !== 1 ? 's' : ''}
|
|
307
|
-
${action.timeout
|
|
308
|
-
? html `<div style="margin-top: 0.25em">
|
|
309
|
-
Timeout after <b>${action.timeout}</b> seconds
|
|
310
|
-
</div>`
|
|
311
|
-
: null}
|
|
312
|
-
</div>`;
|
|
313
|
-
};
|
|
314
|
-
export const renderWaitForAudio = (node, action) => {
|
|
315
|
-
return html `<div>
|
|
316
|
-
<temba-icon name="audio" style="margin-right: 0.25em"></temba-icon>
|
|
317
|
-
Wait for audio recording
|
|
318
|
-
${action.timeout
|
|
319
|
-
? html `<div style="margin-top: 0.25em">
|
|
320
|
-
Timeout after <b>${action.timeout}</b> seconds
|
|
321
|
-
</div>`
|
|
322
|
-
: null}
|
|
323
|
-
</div>`;
|
|
324
|
-
};
|
|
325
|
-
export const renderWaitForVideo = (node, action) => {
|
|
326
|
-
return html `<div>
|
|
327
|
-
<temba-icon name="video" style="margin-right: 0.25em"></temba-icon>
|
|
328
|
-
Wait for video recording
|
|
329
|
-
${action.timeout
|
|
330
|
-
? html `<div style="margin-top: 0.25em">
|
|
331
|
-
Timeout after <b>${action.timeout}</b> seconds
|
|
332
|
-
</div>`
|
|
333
|
-
: null}
|
|
334
|
-
</div>`;
|
|
335
|
-
};
|
|
336
|
-
export const renderWaitForImage = (node, action) => {
|
|
337
|
-
return html `<div>
|
|
338
|
-
<temba-icon name="image" style="margin-right: 0.25em"></temba-icon>
|
|
339
|
-
Wait for image
|
|
340
|
-
${action.timeout
|
|
341
|
-
? html `<div style="margin-top: 0.25em">
|
|
342
|
-
Timeout after <b>${action.timeout}</b> seconds
|
|
343
|
-
</div>`
|
|
344
|
-
: null}
|
|
345
|
-
</div>`;
|
|
346
|
-
};
|
|
347
|
-
export const renderWaitForLocation = (node, action) => {
|
|
348
|
-
return html `<div>
|
|
349
|
-
<temba-icon name="location" style="margin-right: 0.25em"></temba-icon>
|
|
350
|
-
Wait for location
|
|
351
|
-
${action.timeout
|
|
352
|
-
? html `<div style="margin-top: 0.25em">
|
|
353
|
-
Timeout after <b>${action.timeout}</b> seconds
|
|
354
|
-
</div>`
|
|
355
|
-
: null}
|
|
356
|
-
</div>`;
|
|
357
|
-
};
|
|
358
|
-
//# sourceMappingURL=render.js.map
|