@nyaruka/temba-components 0.129.3 → 0.129.5
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 +19 -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 +1211 -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 +92 -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 +158 -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 +1454 -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 +105 -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 +234 -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,5 +1,6 @@
|
|
|
1
1
|
import { css, html, PropertyValueMap, TemplateResult } from 'lit';
|
|
2
|
-
import {
|
|
2
|
+
import { repeat } from 'lit/directives/repeat.js';
|
|
3
|
+
import { ACTION_CONFIG, ActionConfig, NODE_CONFIG, NodeConfig } from './config';
|
|
3
4
|
import { Action, Exit, Node, NodeUI, Router } from '../store/flow-definition';
|
|
4
5
|
import { property } from 'lit/decorators.js';
|
|
5
6
|
import { RapidElement } from '../RapidElement';
|
|
@@ -8,7 +9,9 @@ import { Plumber } from './Plumber';
|
|
|
8
9
|
import { getStore } from '../store/Store';
|
|
9
10
|
import { CustomEventType } from '../interfaces';
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
const DRAG_THRESHOLD = 5;
|
|
13
|
+
|
|
14
|
+
export class CanvasNode extends RapidElement {
|
|
12
15
|
createRenderRoot() {
|
|
13
16
|
return this;
|
|
14
17
|
}
|
|
@@ -34,6 +37,15 @@ export class EditorNode extends RapidElement {
|
|
|
34
37
|
// Set of action UUIDs that are in the removing state
|
|
35
38
|
private actionRemovingState: Set<string> = new Set();
|
|
36
39
|
|
|
40
|
+
// Track action click state to distinguish from drag
|
|
41
|
+
private actionClickStartPos: { x: number; y: number } | null = null;
|
|
42
|
+
private pendingActionClick: { action: Action; event: MouseEvent } | null =
|
|
43
|
+
null;
|
|
44
|
+
|
|
45
|
+
// Track node click state to distinguish from drag
|
|
46
|
+
private nodeClickStartPos: { x: number; y: number } | null = null;
|
|
47
|
+
private pendingNodeClick: { event: MouseEvent } | null = null;
|
|
48
|
+
|
|
37
49
|
static get styles() {
|
|
38
50
|
return css`
|
|
39
51
|
|
|
@@ -49,6 +61,11 @@ export class EditorNode extends RapidElement {
|
|
|
49
61
|
|
|
50
62
|
}
|
|
51
63
|
|
|
64
|
+
/* Cap width for execute_actions nodes */
|
|
65
|
+
.node.execute-actions {
|
|
66
|
+
max-width: 200px;
|
|
67
|
+
}
|
|
68
|
+
|
|
52
69
|
.node:hover {
|
|
53
70
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
|
54
71
|
}
|
|
@@ -60,8 +77,8 @@ export class EditorNode extends RapidElement {
|
|
|
60
77
|
}
|
|
61
78
|
|
|
62
79
|
.action {
|
|
63
|
-
max-width: 200px;
|
|
64
80
|
position: relative;
|
|
81
|
+
font-size: 13px;
|
|
65
82
|
}
|
|
66
83
|
|
|
67
84
|
.action .remove-button {
|
|
@@ -83,18 +100,40 @@ export class EditorNode extends RapidElement {
|
|
|
83
100
|
z-index: 10;
|
|
84
101
|
}
|
|
85
102
|
|
|
86
|
-
.action:hover .remove-button
|
|
103
|
+
.action:hover .remove-button,
|
|
104
|
+
.router:hover .remove-button {
|
|
87
105
|
display: flex;
|
|
88
106
|
}
|
|
89
107
|
|
|
90
|
-
.action.removing .title
|
|
108
|
+
.action.removing .title,
|
|
109
|
+
.router .title.removing {
|
|
91
110
|
background-color: var(--color-error, #dc3545) !important;
|
|
92
111
|
}
|
|
93
112
|
|
|
94
|
-
.action.removing .title .name
|
|
113
|
+
.action.removing .title .name,
|
|
114
|
+
.router .title.removing .name {
|
|
95
115
|
color: white;
|
|
96
116
|
}
|
|
97
117
|
|
|
118
|
+
.router .remove-button {
|
|
119
|
+
position: absolute;
|
|
120
|
+
top: 5px;
|
|
121
|
+
right: 5px;
|
|
122
|
+
width: 16px;
|
|
123
|
+
height: 16px;
|
|
124
|
+
border-radius: 50%;
|
|
125
|
+
background: var(--color-error, #dc3545);
|
|
126
|
+
color: white;
|
|
127
|
+
border: none;
|
|
128
|
+
cursor: pointer;
|
|
129
|
+
display: none;
|
|
130
|
+
align-items: center;
|
|
131
|
+
justify-content: center;
|
|
132
|
+
font-size: 10px;
|
|
133
|
+
line-height: 1;
|
|
134
|
+
z-index: 10;
|
|
135
|
+
}
|
|
136
|
+
|
|
98
137
|
.action.sortable {
|
|
99
138
|
display: flex;
|
|
100
139
|
align-items: stretch;
|
|
@@ -104,10 +143,17 @@ export class EditorNode extends RapidElement {
|
|
|
104
143
|
flex-grow: 1;
|
|
105
144
|
display: flex;
|
|
106
145
|
flex-direction: column;
|
|
146
|
+
min-width: 0; /* Allow flex item to shrink below its content size */
|
|
147
|
+
overflow: hidden;
|
|
107
148
|
}
|
|
108
149
|
|
|
109
150
|
.action .body {
|
|
110
|
-
padding:
|
|
151
|
+
padding: 0.75em;
|
|
152
|
+
word-wrap: break-word;
|
|
153
|
+
overflow-wrap: break-word;
|
|
154
|
+
hyphens: auto;
|
|
155
|
+
white-space: normal;
|
|
156
|
+
overflow: hidden;
|
|
111
157
|
}
|
|
112
158
|
|
|
113
159
|
.action .drag-handle {
|
|
@@ -183,6 +229,10 @@ export class EditorNode extends RapidElement {
|
|
|
183
229
|
.category .title {
|
|
184
230
|
font-weight: normal;
|
|
185
231
|
font-size: 1em;
|
|
232
|
+
max-width: 150px;
|
|
233
|
+
white-space: nowrap;
|
|
234
|
+
overflow: hidden;
|
|
235
|
+
text-overflow: ellipsis;
|
|
186
236
|
}
|
|
187
237
|
|
|
188
238
|
.router .body {
|
|
@@ -292,10 +342,14 @@ export class EditorNode extends RapidElement {
|
|
|
292
342
|
): void {
|
|
293
343
|
super.updated(changes);
|
|
294
344
|
if (changes.has('node')) {
|
|
295
|
-
//
|
|
296
|
-
if (
|
|
345
|
+
// Only proceed if plumber is available (for tests that don't set it up)
|
|
346
|
+
if (this.plumber) {
|
|
347
|
+
this.plumber.removeNodeConnections(this.node.uuid);
|
|
348
|
+
// make our initial connections
|
|
297
349
|
for (const exit of this.node.exits) {
|
|
298
350
|
if (!exit.destination_uuid) {
|
|
351
|
+
// if we have no destination, then we are a source
|
|
352
|
+
// so make our source endpoint
|
|
299
353
|
this.plumber.makeSource(exit.uuid);
|
|
300
354
|
} else {
|
|
301
355
|
this.plumber.connectIds(
|
|
@@ -305,17 +359,21 @@ export class EditorNode extends RapidElement {
|
|
|
305
359
|
);
|
|
306
360
|
}
|
|
307
361
|
}
|
|
362
|
+
|
|
363
|
+
this.plumber.revalidate([this.node.uuid]);
|
|
308
364
|
}
|
|
309
365
|
|
|
310
366
|
const ele = this.parentElement;
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
367
|
+
if (ele) {
|
|
368
|
+
const rect = ele.getBoundingClientRect();
|
|
369
|
+
|
|
370
|
+
getStore()
|
|
371
|
+
?.getState()
|
|
372
|
+
.expandCanvas(
|
|
373
|
+
this.ui.position.left + rect.width,
|
|
374
|
+
this.ui.position.top + rect.height
|
|
375
|
+
);
|
|
376
|
+
}
|
|
319
377
|
}
|
|
320
378
|
}
|
|
321
379
|
|
|
@@ -480,6 +538,55 @@ export class EditorNode extends RapidElement {
|
|
|
480
538
|
}
|
|
481
539
|
}
|
|
482
540
|
|
|
541
|
+
private handleNodeRemoveClick(event: MouseEvent) {
|
|
542
|
+
event.preventDefault();
|
|
543
|
+
event.stopPropagation();
|
|
544
|
+
|
|
545
|
+
const nodeId = this.node.uuid;
|
|
546
|
+
|
|
547
|
+
// If the node is already in removing state, perform the removal
|
|
548
|
+
if (this.actionRemovingState.has(nodeId)) {
|
|
549
|
+
this.removeNode();
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// Start removal UI state
|
|
554
|
+
this.actionRemovingState.add(nodeId);
|
|
555
|
+
this.requestUpdate();
|
|
556
|
+
|
|
557
|
+
// Clear any existing timeout for this node
|
|
558
|
+
if (this.actionRemovalTimeouts.has(nodeId)) {
|
|
559
|
+
clearTimeout(this.actionRemovalTimeouts.get(nodeId));
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// Set timeout to reset UI if user doesn't click
|
|
563
|
+
const timeoutId = window.setTimeout(() => {
|
|
564
|
+
this.actionRemovingState.delete(nodeId);
|
|
565
|
+
this.actionRemovalTimeouts.delete(nodeId);
|
|
566
|
+
this.requestUpdate();
|
|
567
|
+
}, 1000); // 1 second as per requirements
|
|
568
|
+
|
|
569
|
+
this.actionRemovalTimeouts.set(nodeId, timeoutId);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
private removeNode() {
|
|
573
|
+
const nodeId = this.node.uuid;
|
|
574
|
+
|
|
575
|
+
// Clear the UI state
|
|
576
|
+
this.actionRemovingState.delete(nodeId);
|
|
577
|
+
|
|
578
|
+
// Clear any timeout
|
|
579
|
+
if (this.actionRemovalTimeouts.has(nodeId)) {
|
|
580
|
+
clearTimeout(this.actionRemovalTimeouts.get(nodeId));
|
|
581
|
+
this.actionRemovalTimeouts.delete(nodeId);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// Fire the node deleted event
|
|
585
|
+
this.fireCustomEvent(CustomEventType.NodeDeleted, {
|
|
586
|
+
uuid: this.node.uuid
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
|
|
483
590
|
private handleActionOrderChanged(event: CustomEvent) {
|
|
484
591
|
const [fromIdx, toIdx] = event.detail.swap;
|
|
485
592
|
|
|
@@ -498,7 +605,197 @@ export class EditorNode extends RapidElement {
|
|
|
498
605
|
.updateNode(this.node.uuid, { ...this.node, actions: newActions });
|
|
499
606
|
}
|
|
500
607
|
|
|
501
|
-
private
|
|
608
|
+
private handleActionMouseDown(event: MouseEvent, action: Action): void {
|
|
609
|
+
// Don't handle clicks on the remove button or when action is in removing state
|
|
610
|
+
const target = event.target as HTMLElement;
|
|
611
|
+
if (
|
|
612
|
+
target.closest('.remove-button') ||
|
|
613
|
+
this.actionRemovingState.has(action.uuid)
|
|
614
|
+
) {
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// Store the starting position and action for later comparison
|
|
619
|
+
// Don't prevent default - let the Editor's drag system work normally
|
|
620
|
+
this.actionClickStartPos = { x: event.clientX, y: event.clientY };
|
|
621
|
+
this.pendingActionClick = { action, event };
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
private handleActionMouseUp(event: MouseEvent, action: Action): void {
|
|
625
|
+
// Don't handle if we don't have a pending click or if it's not the same action
|
|
626
|
+
if (
|
|
627
|
+
!this.pendingActionClick ||
|
|
628
|
+
this.pendingActionClick.action.uuid !== action.uuid
|
|
629
|
+
) {
|
|
630
|
+
this.actionClickStartPos = null;
|
|
631
|
+
this.pendingActionClick = null;
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// Don't handle clicks on the remove button or when action is in removing state
|
|
636
|
+
const target = event.target as HTMLElement;
|
|
637
|
+
if (
|
|
638
|
+
target.closest('.remove-button') ||
|
|
639
|
+
this.actionRemovingState.has(action.uuid)
|
|
640
|
+
) {
|
|
641
|
+
this.actionClickStartPos = null;
|
|
642
|
+
this.pendingActionClick = null;
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
// Check if the mouse moved beyond the drag threshold
|
|
647
|
+
if (this.actionClickStartPos) {
|
|
648
|
+
const deltaX = event.clientX - this.actionClickStartPos.x;
|
|
649
|
+
const deltaY = event.clientY - this.actionClickStartPos.y;
|
|
650
|
+
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
651
|
+
|
|
652
|
+
// Check if the Editor is currently in dragging mode
|
|
653
|
+
const editor = this.closest('temba-flow-editor') as any;
|
|
654
|
+
const editorWasDragging = editor?.dragging;
|
|
655
|
+
|
|
656
|
+
// Only fire the action edit event if we haven't dragged beyond the threshold
|
|
657
|
+
// AND either there's no Editor parent (test case) or the Editor didn't drag the node
|
|
658
|
+
if (distance <= DRAG_THRESHOLD && (!editor || !editorWasDragging)) {
|
|
659
|
+
// Fire event to request action editing
|
|
660
|
+
this.fireCustomEvent(CustomEventType.ActionEditRequested, {
|
|
661
|
+
action,
|
|
662
|
+
nodeUuid: this.node.uuid
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// Clean up
|
|
668
|
+
this.actionClickStartPos = null;
|
|
669
|
+
this.pendingActionClick = null;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
private handleActionClick(event: MouseEvent, action: Action): void {
|
|
673
|
+
// This method is kept for backward compatibility but should not be used
|
|
674
|
+
// The new mousedown/mouseup approach handles click vs drag properly
|
|
675
|
+
event.preventDefault();
|
|
676
|
+
event.stopPropagation();
|
|
677
|
+
|
|
678
|
+
// Don't handle clicks on the remove button or when action is in removing state
|
|
679
|
+
const target = event.target as HTMLElement;
|
|
680
|
+
if (
|
|
681
|
+
target.closest('.remove-button') ||
|
|
682
|
+
this.actionRemovingState.has(action.uuid)
|
|
683
|
+
) {
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// Fire event to request action editing
|
|
688
|
+
this.fireCustomEvent(CustomEventType.ActionEditRequested, {
|
|
689
|
+
action,
|
|
690
|
+
nodeUuid: this.node.uuid
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
private handleNodeEditClick(event: MouseEvent): void {
|
|
695
|
+
event.preventDefault();
|
|
696
|
+
event.stopPropagation();
|
|
697
|
+
|
|
698
|
+
// Don't handle clicks on the remove button or when node is in removing state
|
|
699
|
+
const target = event.target as HTMLElement;
|
|
700
|
+
if (
|
|
701
|
+
target.closest('.remove-button') ||
|
|
702
|
+
this.actionRemovingState.has(this.node.uuid)
|
|
703
|
+
) {
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
// Fire node edit requested event if the node has a router
|
|
708
|
+
if (this.node.router) {
|
|
709
|
+
// If router node has exactly one action, open the action editor directly
|
|
710
|
+
if (this.node.actions && this.node.actions.length === 1) {
|
|
711
|
+
this.fireCustomEvent(CustomEventType.ActionEditRequested, {
|
|
712
|
+
action: this.node.actions[0],
|
|
713
|
+
nodeUuid: this.node.uuid
|
|
714
|
+
});
|
|
715
|
+
} else {
|
|
716
|
+
// Otherwise open the node editor as before
|
|
717
|
+
this.fireCustomEvent(CustomEventType.NodeEditRequested, {
|
|
718
|
+
node: this.node,
|
|
719
|
+
nodeUI: this.ui
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
private handleNodeMouseDown(event: MouseEvent): void {
|
|
726
|
+
// Don't handle clicks on the remove button or when node is in removing state
|
|
727
|
+
const target = event.target as HTMLElement;
|
|
728
|
+
if (
|
|
729
|
+
target.closest('.remove-button') ||
|
|
730
|
+
this.actionRemovingState.has(this.node.uuid)
|
|
731
|
+
) {
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
// Store the starting position for later comparison
|
|
736
|
+
// Don't prevent default - let the Editor's drag system work normally
|
|
737
|
+
this.nodeClickStartPos = { x: event.clientX, y: event.clientY };
|
|
738
|
+
this.pendingNodeClick = { event };
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
private handleNodeMouseUp(event: MouseEvent): void {
|
|
742
|
+
// Don't handle if we don't have a pending click
|
|
743
|
+
if (!this.pendingNodeClick) {
|
|
744
|
+
this.nodeClickStartPos = null;
|
|
745
|
+
this.pendingNodeClick = null;
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
// Don't handle clicks on the remove button or when node is in removing state
|
|
750
|
+
const target = event.target as HTMLElement;
|
|
751
|
+
if (
|
|
752
|
+
target.closest('.remove-button') ||
|
|
753
|
+
this.actionRemovingState.has(this.node.uuid)
|
|
754
|
+
) {
|
|
755
|
+
this.nodeClickStartPos = null;
|
|
756
|
+
this.pendingNodeClick = null;
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
// Check if the mouse moved beyond the drag threshold
|
|
761
|
+
if (this.nodeClickStartPos) {
|
|
762
|
+
const deltaX = event.clientX - this.nodeClickStartPos.x;
|
|
763
|
+
const deltaY = event.clientY - this.nodeClickStartPos.y;
|
|
764
|
+
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
765
|
+
|
|
766
|
+
// Check if the Editor is currently in dragging mode
|
|
767
|
+
const editor = this.closest('temba-flow-editor') as any;
|
|
768
|
+
const editorWasDragging = editor?.dragging;
|
|
769
|
+
|
|
770
|
+
// Only fire the node edit event if we haven't dragged beyond the threshold
|
|
771
|
+
// AND either there's no Editor parent (test case) or the Editor didn't drag the node
|
|
772
|
+
if (distance <= 5 && (!editor || !editorWasDragging)) {
|
|
773
|
+
// Using literal 5 instead of DRAG_THRESHOLD since it's not imported
|
|
774
|
+
// Fire event to request node editing if the node has a router
|
|
775
|
+
if (this.node.router) {
|
|
776
|
+
// If router node has exactly one action, open the action editor directly
|
|
777
|
+
if (this.node.actions && this.node.actions.length === 1) {
|
|
778
|
+
this.fireCustomEvent(CustomEventType.ActionEditRequested, {
|
|
779
|
+
action: this.node.actions[0],
|
|
780
|
+
nodeUuid: this.node.uuid
|
|
781
|
+
});
|
|
782
|
+
} else {
|
|
783
|
+
// Otherwise open the node editor as before
|
|
784
|
+
this.fireCustomEvent(CustomEventType.NodeEditRequested, {
|
|
785
|
+
node: this.node,
|
|
786
|
+
nodeUI: this.ui
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// Clean up
|
|
794
|
+
this.nodeClickStartPos = null;
|
|
795
|
+
this.pendingNodeClick = null;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
private renderTitle(config: ActionConfig, isRemoving: boolean = false) {
|
|
502
799
|
return html`<div class="title" style="background:${config.color}">
|
|
503
800
|
${this.node?.actions?.length > 1
|
|
504
801
|
? html`<temba-icon class="drag-handle" name="sort"></temba-icon>`
|
|
@@ -508,8 +805,17 @@ export class EditorNode extends RapidElement {
|
|
|
508
805
|
</div>`;
|
|
509
806
|
}
|
|
510
807
|
|
|
808
|
+
private renderNodeTitle(config: NodeConfig, isRemoving: boolean = false) {
|
|
809
|
+
return html`<div
|
|
810
|
+
class="title ${isRemoving ? 'removing' : ''}"
|
|
811
|
+
style="background:${config.color}"
|
|
812
|
+
>
|
|
813
|
+
<div class="name">${isRemoving ? 'Remove?' : config.name}</div>
|
|
814
|
+
</div>`;
|
|
815
|
+
}
|
|
816
|
+
|
|
511
817
|
private renderAction(node: Node, action: Action, index: number) {
|
|
512
|
-
const config =
|
|
818
|
+
const config = ACTION_CONFIG[action.type];
|
|
513
819
|
const isRemoving = this.actionRemovingState.has(action.uuid);
|
|
514
820
|
|
|
515
821
|
if (config) {
|
|
@@ -525,7 +831,12 @@ export class EditorNode extends RapidElement {
|
|
|
525
831
|
>
|
|
526
832
|
✕
|
|
527
833
|
</button>
|
|
528
|
-
<div
|
|
834
|
+
<div
|
|
835
|
+
class="action-content"
|
|
836
|
+
@mousedown=${(e: MouseEvent) => this.handleActionMouseDown(e, action)}
|
|
837
|
+
@mouseup=${(e: MouseEvent) => this.handleActionMouseUp(e, action)}
|
|
838
|
+
style="cursor: pointer;"
|
|
839
|
+
>
|
|
529
840
|
${this.renderTitle(config, isRemoving)}
|
|
530
841
|
<div class="body">
|
|
531
842
|
${config.render
|
|
@@ -552,12 +863,39 @@ export class EditorNode extends RapidElement {
|
|
|
552
863
|
}
|
|
553
864
|
|
|
554
865
|
private renderRouter(router: Router, ui: NodeUI) {
|
|
555
|
-
const
|
|
556
|
-
if (
|
|
557
|
-
|
|
558
|
-
|
|
866
|
+
const nodeConfig = NODE_CONFIG[ui.type];
|
|
867
|
+
if (nodeConfig) {
|
|
868
|
+
// For tests that call renderRouter directly without setting this.node
|
|
869
|
+
const hasActions = this.node ? this.node.actions.length > 0 : false;
|
|
870
|
+
const isRemoving =
|
|
871
|
+
this.node &&
|
|
872
|
+
this.node.actions.length === 0 &&
|
|
873
|
+
this.actionRemovingState.has(this.node.uuid);
|
|
874
|
+
|
|
875
|
+
return html`<div class="router" style="position: relative;">
|
|
876
|
+
${!hasActions
|
|
877
|
+
? html` <button
|
|
878
|
+
class="remove-button"
|
|
879
|
+
@click=${(e: MouseEvent) => this.handleNodeRemoveClick(e)}
|
|
880
|
+
title="Remove node"
|
|
881
|
+
>
|
|
882
|
+
✕
|
|
883
|
+
</button>
|
|
884
|
+
<div
|
|
885
|
+
@mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}
|
|
886
|
+
@mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}
|
|
887
|
+
style="cursor: pointer;"
|
|
888
|
+
>
|
|
889
|
+
${this.renderNodeTitle(nodeConfig, isRemoving)}
|
|
890
|
+
</div>`
|
|
891
|
+
: ''}
|
|
559
892
|
${router.result_name
|
|
560
|
-
? html`<div
|
|
893
|
+
? html`<div
|
|
894
|
+
class="body"
|
|
895
|
+
@mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}
|
|
896
|
+
@mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}
|
|
897
|
+
style="cursor: pointer;"
|
|
898
|
+
>
|
|
561
899
|
Save as
|
|
562
900
|
<div class="result-name">${router.result_name}</div>
|
|
563
901
|
</div>`
|
|
@@ -570,18 +908,28 @@ export class EditorNode extends RapidElement {
|
|
|
570
908
|
if (!node.router || !node.router.categories) {
|
|
571
909
|
return null;
|
|
572
910
|
}
|
|
573
|
-
const categories = node.router.categories.map((category) => {
|
|
574
|
-
const exit = node.exits.find(
|
|
575
|
-
(exit: Exit) => exit.uuid == category.exit_uuid
|
|
576
|
-
);
|
|
577
|
-
|
|
578
|
-
return html`<div class="category">
|
|
579
|
-
<div class="title">${category.name}</div>
|
|
580
|
-
${this.renderExit(exit)}
|
|
581
|
-
</div>`;
|
|
582
|
-
});
|
|
583
911
|
|
|
584
|
-
return html`<div class="categories"
|
|
912
|
+
return html`<div class="categories">
|
|
913
|
+
${repeat(
|
|
914
|
+
node.router.categories,
|
|
915
|
+
(category) => category.uuid,
|
|
916
|
+
(category) => {
|
|
917
|
+
const exit = node.exits.find(
|
|
918
|
+
(exit: Exit) => exit.uuid == category.exit_uuid
|
|
919
|
+
);
|
|
920
|
+
|
|
921
|
+
return html`<div
|
|
922
|
+
class="category"
|
|
923
|
+
@mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}
|
|
924
|
+
@mouseup=${(e: MouseEvent) => this.handleNodeMouseUp(e)}
|
|
925
|
+
style="cursor: pointer;"
|
|
926
|
+
>
|
|
927
|
+
<div class="title">${category.name}</div>
|
|
928
|
+
${this.renderExit(exit)}
|
|
929
|
+
</div>`;
|
|
930
|
+
}
|
|
931
|
+
)}
|
|
932
|
+
</div>`;
|
|
585
933
|
}
|
|
586
934
|
|
|
587
935
|
private renderExit(exit: Exit): TemplateResult {
|
|
@@ -603,29 +951,57 @@ export class EditorNode extends RapidElement {
|
|
|
603
951
|
return html`<div class="node">Loading...</div>`;
|
|
604
952
|
}
|
|
605
953
|
|
|
954
|
+
const nodeConfig = NODE_CONFIG[this.ui.type];
|
|
955
|
+
|
|
606
956
|
return html`
|
|
607
957
|
<div
|
|
608
958
|
id="${this.node.uuid}"
|
|
609
|
-
class="node
|
|
959
|
+
class="node ${this.ui.type === 'execute_actions'
|
|
960
|
+
? 'execute-actions'
|
|
961
|
+
: ''}"
|
|
610
962
|
style="left:${this.ui.position.left}px;top:${this.ui.position.top}px"
|
|
611
963
|
>
|
|
612
964
|
${this.node.actions.length > 0
|
|
613
|
-
?
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
965
|
+
? this.ui.type === 'execute_actions'
|
|
966
|
+
? html`<temba-sortable-list
|
|
967
|
+
dragHandle="drag-handle"
|
|
968
|
+
@temba-order-changed="${this.handleActionOrderChanged}"
|
|
969
|
+
>
|
|
970
|
+
${repeat(
|
|
971
|
+
this.node.actions,
|
|
972
|
+
(action) => action.uuid,
|
|
973
|
+
(action, index) => this.renderAction(this.node, action, index)
|
|
974
|
+
)}
|
|
975
|
+
</temba-sortable-list>`
|
|
976
|
+
: html`${repeat(
|
|
977
|
+
this.node.actions,
|
|
978
|
+
(action) => action.uuid,
|
|
979
|
+
(action, index) => this.renderAction(this.node, action, index)
|
|
980
|
+
)}`
|
|
981
|
+
: !this.node.router && nodeConfig && nodeConfig.name
|
|
982
|
+
? html`<div class="router" style="position: relative;">
|
|
983
|
+
<button
|
|
984
|
+
class="remove-button"
|
|
985
|
+
@click=${(e: MouseEvent) => this.handleNodeRemoveClick(e)}
|
|
986
|
+
title="Remove node"
|
|
987
|
+
>
|
|
988
|
+
✕
|
|
989
|
+
</button>
|
|
990
|
+
${this.renderNodeTitle(
|
|
991
|
+
nodeConfig,
|
|
992
|
+
this.actionRemovingState.has(this.node.uuid)
|
|
993
|
+
)}
|
|
994
|
+
</div>`
|
|
621
995
|
: ''}
|
|
622
996
|
${this.node.router
|
|
623
997
|
? html` ${this.renderRouter(this.node.router, this.ui)}
|
|
624
998
|
${this.renderCategories(this.node)}`
|
|
625
999
|
: html`<div class="action-exits">
|
|
626
|
-
${
|
|
627
|
-
|
|
628
|
-
|
|
1000
|
+
${repeat(
|
|
1001
|
+
this.node.exits,
|
|
1002
|
+
(exit) => exit.uuid,
|
|
1003
|
+
(exit) => this.renderExit(exit)
|
|
1004
|
+
)}
|
|
629
1005
|
</div>`}
|
|
630
1006
|
</div>
|
|
631
1007
|
`;
|