@nyaruka/temba-components 0.130.1 → 0.130.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -4
- package/DEV_DATA.md +89 -0
- package/demo/data/flows/food-order.json +4 -4
- package/demo/data/flows/sample-flow.json +132 -147
- package/dist/temba-components.js +764 -628
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/display/Chat.js +5 -3
- package/out-tsc/src/display/Chat.js.map +1 -1
- package/out-tsc/src/events.js.map +1 -1
- package/out-tsc/src/flow/CanvasNode.js +83 -78
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +1 -0
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/NodeEditor.js +47 -3
- package/out-tsc/src/flow/NodeEditor.js.map +1 -1
- package/out-tsc/src/flow/actions/add_contact_urn.js +1 -1
- package/out-tsc/src/flow/actions/add_contact_urn.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_channel.js +1 -1
- package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_field.js +2 -1
- package/out-tsc/src/flow/actions/set_contact_field.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_language.js +3 -1
- package/out-tsc/src/flow/actions/set_contact_language.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_name.js +1 -1
- package/out-tsc/src/flow/actions/set_contact_name.js.map +1 -1
- package/out-tsc/src/flow/actions/set_contact_status.js +17 -14
- package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -1
- package/out-tsc/src/flow/actions/set_run_result.js +1 -1
- package/out-tsc/src/flow/actions/set_run_result.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_llm.js +12 -12
- package/out-tsc/src/flow/nodes/split_by_llm.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_response.js +609 -6
- package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
- package/out-tsc/src/flow/operators.js +194 -0
- package/out-tsc/src/flow/operators.js.map +1 -0
- package/out-tsc/src/flow/types.js.map +1 -1
- package/out-tsc/src/form/ArrayEditor.js +84 -19
- package/out-tsc/src/form/ArrayEditor.js.map +1 -1
- package/out-tsc/src/form/Checkbox.js +12 -0
- package/out-tsc/src/form/Checkbox.js.map +1 -1
- package/out-tsc/src/form/FieldRenderer.js +13 -3
- package/out-tsc/src/form/FieldRenderer.js.map +1 -1
- package/out-tsc/src/form/TextInput.js +20 -1
- package/out-tsc/src/form/TextInput.js.map +1 -1
- package/out-tsc/src/form/select/Select.js +7 -0
- package/out-tsc/src/form/select/Select.js.map +1 -1
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/layout/Dialog.js +3 -4
- package/out-tsc/src/layout/Dialog.js.map +1 -1
- package/out-tsc/src/list/RunList.js +2 -2
- package/out-tsc/src/list/RunList.js.map +1 -1
- package/out-tsc/src/live/ContactChat.js +114 -34
- package/out-tsc/src/live/ContactChat.js.map +1 -1
- package/out-tsc/src/live/ContactDetails.js +7 -0
- package/out-tsc/src/live/ContactDetails.js.map +1 -1
- package/out-tsc/src/live/ContactNameFetch.js +1 -1
- package/out-tsc/src/live/ContactNameFetch.js.map +1 -1
- package/out-tsc/test/NodeHelper.js +25 -27
- package/out-tsc/test/NodeHelper.js.map +1 -1
- package/out-tsc/test/nodes/split_by_llm.test.js +12 -4
- package/out-tsc/test/nodes/split_by_llm.test.js.map +1 -1
- package/out-tsc/test/nodes/split_by_llm_categorize.test.js +101 -91
- package/out-tsc/test/nodes/split_by_llm_categorize.test.js.map +1 -1
- package/out-tsc/test/nodes/split_by_random.test.js +120 -112
- package/out-tsc/test/nodes/split_by_random.test.js.map +1 -1
- package/out-tsc/test/nodes/wait_for_digits.test.js +131 -111
- package/out-tsc/test/nodes/wait_for_digits.test.js.map +1 -1
- package/out-tsc/test/nodes/wait_for_response.test.js +549 -85
- package/out-tsc/test/nodes/wait_for_response.test.js.map +1 -1
- package/out-tsc/test/temba-checkbox.test.js +32 -32
- package/out-tsc/test/temba-checkbox.test.js.map +1 -1
- package/out-tsc/test/temba-contact-chat.test.js +2 -1
- package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
- package/out-tsc/test/temba-dropdown.test.js +0 -4
- package/out-tsc/test/temba-dropdown.test.js.map +1 -1
- package/out-tsc/test/temba-flow-editor-node.test.js +9 -4
- package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
- package/out-tsc/test/temba-integration-markdown.test.js +13 -15
- package/out-tsc/test/temba-integration-markdown.test.js.map +1 -1
- package/out-tsc/test/temba-node-editor.test.js +5 -38
- package/out-tsc/test/temba-node-editor.test.js.map +1 -1
- package/out-tsc/test/temba-run-list.test.js +2 -2
- package/out-tsc/test/temba-run-list.test.js.map +1 -1
- package/out-tsc/test/utils.test.js +2 -1
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +6 -2
- 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/checkbox/checkbox-label-background-hover.png +0 -0
- package/screenshots/truth/checkbox/checkbox-whitespace-label-no-background-hover.png +0 -0
- package/screenshots/truth/checkbox/checkbox-with-help-text.png +0 -0
- package/screenshots/truth/checkbox/checked.png +0 -0
- package/screenshots/truth/checkbox/default.png +0 -0
- package/screenshots/truth/editor/wait.png +0 -0
- package/screenshots/truth/integration/textinput-markdown-errors.png +0 -0
- package/screenshots/truth/lightbox/img-zoomed.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/editor/information-extraction.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/editor/sentiment-analysis.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/editor/summarization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/editor/translation-task.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/information-extraction.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/sentiment-analysis.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/summarization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/translation-task.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/basic-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/custom-input-and-result-name.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/many-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/minimal-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/basic-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/minimal-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_random/editor/ab-test-multiple-variants.png +0 -0
- package/screenshots/truth/nodes/split_by_random/editor/sampling-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/editor/three-way-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/editor/two-bucket-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/ab-test-multiple-variants.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/basic-digits-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/phone-number-collection.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/single-digit-with-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/verification-code.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/phone-number-collection.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/single-digit-with-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/verification-code.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/basic-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/custom-result-name.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/no-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/short-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
- package/screenshots/truth/run-list/basic.png +0 -0
- package/screenshots/truth/templates/default.png +0 -0
- package/screenshots/truth/wait-for-response/rules-editor.png +0 -0
- package/screenshots/truth/wait-for-response/timeout-editor-unchecked.png +0 -0
- package/screenshots/truth/wait-for-response/timeout-editor.png +0 -0
- package/scripts/dev-data-sync.mjs +182 -0
- package/src/display/Chat.ts +6 -4
- package/src/events.ts +6 -5
- package/src/flow/CanvasNode.ts +89 -79
- package/src/flow/Editor.ts +1 -0
- package/src/flow/NodeEditor.ts +55 -3
- package/src/flow/actions/add_contact_urn.ts +1 -1
- package/src/flow/actions/set_contact_channel.ts +1 -1
- package/src/flow/actions/set_contact_field.ts +2 -1
- package/src/flow/actions/set_contact_language.ts +3 -1
- package/src/flow/actions/set_contact_name.ts +1 -1
- package/src/flow/actions/set_contact_status.ts +18 -18
- package/src/flow/actions/set_run_result.ts +1 -1
- package/src/flow/nodes/split_by_llm.ts +14 -13
- package/src/flow/nodes/wait_for_response.ts +717 -5
- package/src/flow/operators.ts +215 -0
- package/src/flow/types.ts +10 -2
- package/src/form/ArrayEditor.ts +117 -37
- package/src/form/Checkbox.ts +12 -0
- package/src/form/FieldRenderer.ts +24 -3
- package/src/form/TextInput.ts +19 -1
- package/src/form/select/Select.ts +7 -0
- package/src/interfaces.ts +1 -1
- package/src/layout/Dialog.ts +4 -4
- package/src/list/RunList.ts +2 -2
- package/src/live/ContactChat.ts +144 -58
- package/src/live/ContactDetails.ts +7 -0
- package/src/live/ContactNameFetch.ts +1 -1
- package/static/api/labels.json +6 -1
- package/test/NodeHelper.ts +38 -40
- package/test/nodes/split_by_llm.test.ts +43 -32
- package/test/nodes/split_by_llm_categorize.test.ts +130 -120
- package/test/nodes/split_by_random.test.ts +136 -128
- package/test/nodes/wait_for_digits.test.ts +147 -127
- package/test/nodes/wait_for_response.test.ts +657 -104
- package/test/temba-checkbox.test.ts +36 -32
- package/test/temba-contact-chat.test.ts +2 -1
- package/test/temba-dropdown.test.ts +0 -12
- package/test/temba-flow-editor-node.test.ts +11 -4
- package/test/temba-integration-markdown.test.ts +16 -17
- package/test/temba-node-editor.test.ts +5 -43
- package/test/temba-run-list.test.ts +2 -2
- package/test/utils.test.ts +2 -1
- package/test-assets/list/runs.json +8 -8
- package/web-dev-mock.mjs +86 -30
- package/web-dev-server.config.mjs +272 -31
- package/screenshots/truth/dropdown/bottom-edge-collision.png +0 -0
- package/screenshots/truth/dropdown/right-edge-collision.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/integration/checkbox-markdown-errors.png +0 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
// Flow router operator configurations
|
|
2
|
+
// These define the available operators for rule-based routing in flow nodes
|
|
3
|
+
|
|
4
|
+
export interface OperatorConfig {
|
|
5
|
+
type: string;
|
|
6
|
+
name: string;
|
|
7
|
+
operands: number; // Number of operands required (0 = no input needed, 1 = single value, 2 = two values)
|
|
8
|
+
categoryName?: string; // Default category name when operands is 0
|
|
9
|
+
visibility?: 'hidden' | 'visible'; // Whether to show in UI
|
|
10
|
+
filter?: string; // Feature filter requirement
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// All available operators for flow routing
|
|
14
|
+
export const OPERATORS: OperatorConfig[] = [
|
|
15
|
+
// Text operators
|
|
16
|
+
{
|
|
17
|
+
type: 'has_any_word',
|
|
18
|
+
name: 'has any of the words',
|
|
19
|
+
operands: 1
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
type: 'has_all_words',
|
|
23
|
+
name: 'has all of the words',
|
|
24
|
+
operands: 1
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
type: 'has_phrase',
|
|
28
|
+
name: 'has the phrase',
|
|
29
|
+
operands: 1
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
type: 'has_only_phrase',
|
|
33
|
+
name: 'has only the phrase',
|
|
34
|
+
operands: 1
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'has_beginning',
|
|
38
|
+
name: 'starts with',
|
|
39
|
+
operands: 1
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
type: 'has_text',
|
|
43
|
+
name: 'has some text',
|
|
44
|
+
operands: 0,
|
|
45
|
+
categoryName: 'Has Text'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
type: 'has_pattern',
|
|
49
|
+
name: 'matches regex',
|
|
50
|
+
operands: 1
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
// Number operators
|
|
54
|
+
{
|
|
55
|
+
type: 'has_number',
|
|
56
|
+
name: 'has a number',
|
|
57
|
+
operands: 0,
|
|
58
|
+
categoryName: 'Has Number'
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
type: 'has_number_between',
|
|
62
|
+
name: 'has a number between',
|
|
63
|
+
operands: 2
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
type: 'has_number_lt',
|
|
67
|
+
name: 'has a number below',
|
|
68
|
+
operands: 1
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: 'has_number_lte',
|
|
72
|
+
name: 'has a number at or below',
|
|
73
|
+
operands: 1
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
type: 'has_number_eq',
|
|
77
|
+
name: 'has a number equal to',
|
|
78
|
+
operands: 1
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
type: 'has_number_gte',
|
|
82
|
+
name: 'has a number at or above',
|
|
83
|
+
operands: 1
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
type: 'has_number_gt',
|
|
87
|
+
name: 'has a number above',
|
|
88
|
+
operands: 1
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
// Date operators
|
|
92
|
+
{
|
|
93
|
+
type: 'has_date',
|
|
94
|
+
name: 'has a date',
|
|
95
|
+
operands: 0,
|
|
96
|
+
categoryName: 'Has Date'
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
type: 'has_date_lt',
|
|
100
|
+
name: 'has a date before',
|
|
101
|
+
operands: 1
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
type: 'has_date_eq',
|
|
105
|
+
name: 'has a date equal to',
|
|
106
|
+
operands: 1
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
type: 'has_date_gt',
|
|
110
|
+
name: 'has a date after',
|
|
111
|
+
operands: 1
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
type: 'has_time',
|
|
115
|
+
name: 'has a time',
|
|
116
|
+
operands: 0,
|
|
117
|
+
categoryName: 'Has Time'
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
// Contact data operators
|
|
121
|
+
{
|
|
122
|
+
type: 'has_phone',
|
|
123
|
+
name: 'has a phone number',
|
|
124
|
+
operands: 0,
|
|
125
|
+
categoryName: 'Has Phone'
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
type: 'has_email',
|
|
129
|
+
name: 'has an email',
|
|
130
|
+
operands: 0,
|
|
131
|
+
categoryName: 'Has Email'
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
// Location operators (require location feature)
|
|
135
|
+
{
|
|
136
|
+
type: 'has_state',
|
|
137
|
+
name: 'has state',
|
|
138
|
+
operands: 0,
|
|
139
|
+
categoryName: 'Has State',
|
|
140
|
+
filter: 'HAS_LOCATIONS'
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
type: 'has_district',
|
|
144
|
+
name: 'has district',
|
|
145
|
+
operands: 1,
|
|
146
|
+
categoryName: 'Has District',
|
|
147
|
+
filter: 'HAS_LOCATIONS'
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: 'has_ward',
|
|
151
|
+
name: 'has ward',
|
|
152
|
+
operands: 2,
|
|
153
|
+
categoryName: 'Has Ward',
|
|
154
|
+
filter: 'HAS_LOCATIONS'
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
// Hidden/system operators
|
|
158
|
+
{
|
|
159
|
+
type: 'has_group',
|
|
160
|
+
name: 'is in the group',
|
|
161
|
+
operands: 1,
|
|
162
|
+
visibility: 'hidden'
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
type: 'has_category',
|
|
166
|
+
name: 'has the category',
|
|
167
|
+
operands: 0,
|
|
168
|
+
visibility: 'hidden'
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
type: 'has_error',
|
|
172
|
+
name: 'has an error',
|
|
173
|
+
operands: 0,
|
|
174
|
+
categoryName: 'Has Error',
|
|
175
|
+
visibility: 'hidden'
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
type: 'has_value',
|
|
179
|
+
name: 'is not empty',
|
|
180
|
+
operands: 0,
|
|
181
|
+
categoryName: 'Not Empty',
|
|
182
|
+
visibility: 'hidden'
|
|
183
|
+
}
|
|
184
|
+
];
|
|
185
|
+
|
|
186
|
+
// Get operators suitable for wait_for_response rules
|
|
187
|
+
export const getWaitForResponseOperators = (): OperatorConfig[] => {
|
|
188
|
+
return OPERATORS.filter(
|
|
189
|
+
(op) => op.visibility !== 'hidden' && !op.filter // For now, exclude location operators unless we support feature detection
|
|
190
|
+
);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// Get operator configuration by type
|
|
194
|
+
export const getOperatorConfig = (type: string): OperatorConfig | undefined => {
|
|
195
|
+
return OPERATORS.find((op) => op.type === type);
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
// Convert operators to select options
|
|
199
|
+
export const operatorsToSelectOptions = (operators: OperatorConfig[]) => {
|
|
200
|
+
return operators.map((op) => ({
|
|
201
|
+
value: op.type,
|
|
202
|
+
name: op.name
|
|
203
|
+
}));
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// Create an operator object for select components
|
|
207
|
+
export const createOperatorOption = (
|
|
208
|
+
type: string
|
|
209
|
+
): { value: string; name: string } => {
|
|
210
|
+
const config = getOperatorConfig(type);
|
|
211
|
+
return {
|
|
212
|
+
value: type,
|
|
213
|
+
name: config ? config.name : type
|
|
214
|
+
};
|
|
215
|
+
};
|
package/src/flow/types.ts
CHANGED
|
@@ -70,6 +70,7 @@ export interface FormData extends Record<string, any> {}
|
|
|
70
70
|
export interface FormConfig {
|
|
71
71
|
form?: Record<string, FieldConfig>;
|
|
72
72
|
layout?: LayoutItem[];
|
|
73
|
+
gutter?: LayoutItem[];
|
|
73
74
|
sanitize?: (formData: FormData) => void;
|
|
74
75
|
validate?: (formData: FormData) => ValidationResult;
|
|
75
76
|
}
|
|
@@ -78,6 +79,7 @@ export interface NodeConfig extends FormConfig {
|
|
|
78
79
|
type: string;
|
|
79
80
|
name?: string;
|
|
80
81
|
color?: string;
|
|
82
|
+
dialogSize?: 'small' | 'medium' | 'large' | 'xlarge';
|
|
81
83
|
action?: ActionConfig;
|
|
82
84
|
router?: {
|
|
83
85
|
type: 'switch' | 'random';
|
|
@@ -103,7 +105,7 @@ export interface NodeConfig extends FormConfig {
|
|
|
103
105
|
|
|
104
106
|
// New field configuration system for generic form generation
|
|
105
107
|
export interface BaseFieldConfig {
|
|
106
|
-
label?: string;
|
|
108
|
+
label?: string | ((formData: Record<string, any>) => string);
|
|
107
109
|
required?: boolean;
|
|
108
110
|
evaluated?: boolean;
|
|
109
111
|
dependsOn?: string[];
|
|
@@ -121,6 +123,7 @@ export interface BaseFieldConfig {
|
|
|
121
123
|
|
|
122
124
|
// Layout properties
|
|
123
125
|
maxWidth?: string;
|
|
126
|
+
width?: string;
|
|
124
127
|
|
|
125
128
|
// Conditional rendering
|
|
126
129
|
conditions?: {
|
|
@@ -132,6 +135,7 @@ export interface BaseFieldConfig {
|
|
|
132
135
|
export interface TextFieldConfig extends BaseFieldConfig {
|
|
133
136
|
type: 'text';
|
|
134
137
|
placeholder?: string;
|
|
138
|
+
flavor?: 'xsmall' | 'small' | 'large';
|
|
135
139
|
}
|
|
136
140
|
|
|
137
141
|
export interface TextareaFieldConfig extends BaseFieldConfig {
|
|
@@ -155,7 +159,7 @@ export interface SelectFieldConfig extends BaseFieldConfig {
|
|
|
155
159
|
endpoint?: string;
|
|
156
160
|
emails?: boolean;
|
|
157
161
|
getName?: (item: any) => string;
|
|
158
|
-
flavor?: 'small' | 'large';
|
|
162
|
+
flavor?: 'xsmall' | 'small' | 'large';
|
|
159
163
|
createArbitraryOption?: (input: string, options: any[]) => any;
|
|
160
164
|
allowCreate?: boolean;
|
|
161
165
|
getDynamicOptions?: () => Array<{ value: string; name: string }>;
|
|
@@ -176,6 +180,7 @@ export interface ArrayFieldConfig extends BaseFieldConfig {
|
|
|
176
180
|
minItems?: number;
|
|
177
181
|
maxItems?: number;
|
|
178
182
|
itemLabel?: string;
|
|
183
|
+
maintainEmptyItem?: boolean;
|
|
179
184
|
onItemChange?: (
|
|
180
185
|
itemIndex: number,
|
|
181
186
|
field: string,
|
|
@@ -189,6 +194,7 @@ export interface CheckboxFieldConfig extends BaseFieldConfig {
|
|
|
189
194
|
type: 'checkbox';
|
|
190
195
|
size?: number;
|
|
191
196
|
animateChange?: string;
|
|
197
|
+
labelPadding?: string;
|
|
192
198
|
}
|
|
193
199
|
|
|
194
200
|
export interface MessageEditorFieldConfig extends BaseFieldConfig {
|
|
@@ -246,11 +252,13 @@ export type LayoutItem =
|
|
|
246
252
|
export interface ActionConfig extends FormConfig {
|
|
247
253
|
name: string;
|
|
248
254
|
color: string;
|
|
255
|
+
dialogSize?: 'small' | 'medium' | 'large' | 'xlarge';
|
|
249
256
|
evaluated?: string[];
|
|
250
257
|
render?: (node: any, action: any) => TemplateResult;
|
|
251
258
|
|
|
252
259
|
form?: Record<string, FieldConfig>;
|
|
253
260
|
layout?: LayoutItem[]; // optional layout configuration - array of layout items
|
|
261
|
+
gutter?: LayoutItem[]; // fields to render in the dialog gutter (left side of buttons)
|
|
254
262
|
|
|
255
263
|
toFormData?: (action: Action) => any;
|
|
256
264
|
fromFormData?: (formData: any) => Action;
|
package/src/form/ArrayEditor.ts
CHANGED
|
@@ -134,52 +134,115 @@ export class TembaArrayEditor extends BaseListEditor<ListItem> {
|
|
|
134
134
|
): TemplateResult {
|
|
135
135
|
const computedValue = this.computeFieldValue(itemIndex, fieldName, config);
|
|
136
136
|
|
|
137
|
+
// Extract flavor from select config if available
|
|
138
|
+
const flavor =
|
|
139
|
+
config.type === 'select' ? (config as any).flavor || 'small' : 'small';
|
|
140
|
+
|
|
141
|
+
// Build container style with width/maxWidth if specified
|
|
142
|
+
let containerStyle = '';
|
|
143
|
+
if (config.width) {
|
|
144
|
+
containerStyle = `width: ${config.width};`;
|
|
145
|
+
} else if (config.maxWidth) {
|
|
146
|
+
containerStyle = `max-width: ${config.maxWidth};`;
|
|
147
|
+
}
|
|
148
|
+
|
|
137
149
|
// Use FieldRenderer for consistent field rendering
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
const fieldContent = FieldRenderer.renderField(
|
|
151
|
+
fieldName,
|
|
152
|
+
config,
|
|
153
|
+
computedValue,
|
|
154
|
+
{
|
|
155
|
+
showLabel: false, // ArrayEditor doesn't show labels for individual fields
|
|
156
|
+
flavor: flavor,
|
|
157
|
+
extraClasses: 'form-control',
|
|
158
|
+
onChange: (e: Event) => {
|
|
159
|
+
let value: any;
|
|
160
|
+
const target = e.target as any;
|
|
161
|
+
|
|
162
|
+
// Handle different field types and their change events
|
|
163
|
+
if (config.type === 'select') {
|
|
164
|
+
// Use consistent temba-select value normalization
|
|
165
|
+
value = target.values;
|
|
166
|
+
} else {
|
|
167
|
+
// For other field types, use the target value directly
|
|
168
|
+
value = target.value;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
this.handleFieldChange(itemIndex, fieldName, value);
|
|
153
172
|
}
|
|
154
|
-
|
|
155
|
-
this.handleFieldChange(itemIndex, fieldName, value);
|
|
156
173
|
}
|
|
157
|
-
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
// Wrap in container with style if maxWidth is specified
|
|
177
|
+
if (containerStyle) {
|
|
178
|
+
return html`<div style="${containerStyle}">${fieldContent}</div>`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return fieldContent;
|
|
158
182
|
}
|
|
159
183
|
|
|
160
184
|
renderItem(item: ListItem, index: number): TemplateResult {
|
|
161
185
|
const canRemove = this.canRemoveItem(index);
|
|
162
186
|
|
|
187
|
+
// Render fields and track if any value fields are visible
|
|
188
|
+
const fieldElements: TemplateResult[] = [];
|
|
189
|
+
let hasVisibleValueField = false;
|
|
190
|
+
|
|
191
|
+
Object.entries(this.itemConfig).forEach(([fieldName, config]) => {
|
|
192
|
+
// Check visibility condition
|
|
193
|
+
let isVisible = true;
|
|
194
|
+
if (config.conditions?.visible) {
|
|
195
|
+
try {
|
|
196
|
+
const currentItem = this._items[index] || {};
|
|
197
|
+
isVisible = config.conditions.visible(currentItem);
|
|
198
|
+
} catch (error) {
|
|
199
|
+
console.error(`Error checking visibility for ${fieldName}:`, error);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (isVisible) {
|
|
204
|
+
// Check if this is a value field (text input without fixed sizing)
|
|
205
|
+
const isValueField =
|
|
206
|
+
!config.width && !config.maxWidth && config.type === 'text';
|
|
207
|
+
if (isValueField) {
|
|
208
|
+
hasVisibleValueField = true;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
fieldElements.push(html`
|
|
212
|
+
<div
|
|
213
|
+
class="field ${config.width ||
|
|
214
|
+
config.maxWidth ||
|
|
215
|
+
config.type === 'select'
|
|
216
|
+
? 'field-fixed'
|
|
217
|
+
: 'field-flex'}"
|
|
218
|
+
>
|
|
219
|
+
${this.renderArrayField(index, fieldName, config)}
|
|
220
|
+
</div>
|
|
221
|
+
`);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
// If no value fields are visible, add a spacer to maintain alignment
|
|
226
|
+
if (!hasVisibleValueField) {
|
|
227
|
+
// Insert spacer after operator (first field) and before category (last field)
|
|
228
|
+
fieldElements.splice(
|
|
229
|
+
-1,
|
|
230
|
+
0,
|
|
231
|
+
html`<div class="field field-flex spacer"></div>`
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
163
235
|
return html`
|
|
164
236
|
<div class="array-item">
|
|
165
237
|
<div class="item-fields">
|
|
166
|
-
${
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
? html`
|
|
175
|
-
<button
|
|
176
|
-
@click=${() => this.removeItem(index)}
|
|
177
|
-
class="remove-btn"
|
|
178
|
-
>
|
|
179
|
-
<temba-icon name="x"></temba-icon>
|
|
180
|
-
</button>
|
|
181
|
-
`
|
|
182
|
-
: ''}
|
|
238
|
+
${fieldElements}
|
|
239
|
+
<button
|
|
240
|
+
@click=${canRemove ? () => this.removeItem(index) : undefined}
|
|
241
|
+
class="remove-btn ${canRemove ? '' : 'invisible'}"
|
|
242
|
+
?disabled=${!canRemove}
|
|
243
|
+
>
|
|
244
|
+
<temba-icon name="x"></temba-icon>
|
|
245
|
+
</button>
|
|
183
246
|
</div>
|
|
184
247
|
</div>
|
|
185
248
|
`;
|
|
@@ -217,12 +280,24 @@ export class TembaArrayEditor extends BaseListEditor<ListItem> {
|
|
|
217
280
|
}
|
|
218
281
|
|
|
219
282
|
.field {
|
|
220
|
-
|
|
283
|
+
/* Base field styles */
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.field-flex {
|
|
287
|
+
flex: 1; /* Grow to fill remaining space */
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.field-fixed {
|
|
291
|
+
flex: none; /* Don't grow, use content/maxWidth size */
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.spacer {
|
|
295
|
+
/* Empty spacer to maintain layout alignment */
|
|
221
296
|
}
|
|
222
297
|
|
|
223
298
|
.add-btn,
|
|
224
299
|
.remove-btn {
|
|
225
|
-
padding:
|
|
300
|
+
padding: 4px;
|
|
226
301
|
border: 1px solid #ccc;
|
|
227
302
|
border-radius: 4px;
|
|
228
303
|
background: white;
|
|
@@ -239,6 +314,11 @@ export class TembaArrayEditor extends BaseListEditor<ListItem> {
|
|
|
239
314
|
background: #fefefe;
|
|
240
315
|
color: #999;
|
|
241
316
|
}
|
|
317
|
+
|
|
318
|
+
.remove-btn.invisible {
|
|
319
|
+
visibility: hidden;
|
|
320
|
+
cursor: default;
|
|
321
|
+
}
|
|
242
322
|
`;
|
|
243
323
|
}
|
|
244
324
|
}
|
package/src/form/Checkbox.ts
CHANGED
|
@@ -18,6 +18,16 @@ export class Checkbox extends FieldElement {
|
|
|
18
18
|
width: 100%;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
.checkbox-background {
|
|
22
|
+
position: absolute;
|
|
23
|
+
margin-top: 2px;
|
|
24
|
+
margin-left: 2px;
|
|
25
|
+
width: 12px;
|
|
26
|
+
height: 12px;
|
|
27
|
+
background: var(--checkbox-background, rgba(255, 255, 255, 0.8));
|
|
28
|
+
border-radius: 2px;
|
|
29
|
+
}
|
|
30
|
+
|
|
21
31
|
.wrapper.label {
|
|
22
32
|
padding: var(--checkbox-padding, 10px);
|
|
23
33
|
border-radius: var(--curvature);
|
|
@@ -163,7 +173,9 @@ export class Checkbox extends FieldElement {
|
|
|
163
173
|
@click=${this.handleClick}
|
|
164
174
|
>
|
|
165
175
|
<div class="checkbox-container ${this.disabled ? 'disabled' : ''}">
|
|
176
|
+
<div class="checkbox-background"></div>
|
|
166
177
|
${icon}
|
|
178
|
+
|
|
167
179
|
<div class="label-and-help">
|
|
168
180
|
${this.label && String(this.label).trim()
|
|
169
181
|
? html`<div class="checkbox-label">${this.label}</div>`
|
|
@@ -133,6 +133,7 @@ export class FieldRenderer {
|
|
|
133
133
|
.value="${value || ''}"
|
|
134
134
|
placeholder="${config.placeholder || ''}"
|
|
135
135
|
.helpText="${config.helpText || ''}"
|
|
136
|
+
flavor="${config.flavor || 'default'}"
|
|
136
137
|
class="${extraClasses}"
|
|
137
138
|
style="${style}"
|
|
138
139
|
@input="${onChange || (() => {})}"
|
|
@@ -259,12 +260,29 @@ export class FieldRenderer {
|
|
|
259
260
|
value: any,
|
|
260
261
|
context: FieldRenderContext
|
|
261
262
|
): TemplateResult {
|
|
262
|
-
const {
|
|
263
|
+
const {
|
|
264
|
+
errors = [],
|
|
265
|
+
onChange,
|
|
266
|
+
extraClasses,
|
|
267
|
+
style,
|
|
268
|
+
formData = {}
|
|
269
|
+
} = context;
|
|
270
|
+
|
|
271
|
+
// Handle dynamic labels
|
|
272
|
+
const label =
|
|
273
|
+
typeof config.label === 'function'
|
|
274
|
+
? config.label(formData)
|
|
275
|
+
: config.label;
|
|
276
|
+
|
|
277
|
+
// Build custom style including labelPadding
|
|
278
|
+
const customStyle = config.labelPadding
|
|
279
|
+
? `--checkbox-padding: ${config.labelPadding}; ${style || ''}`
|
|
280
|
+
: style || '';
|
|
263
281
|
|
|
264
282
|
return html`<div class="form-field">
|
|
265
283
|
<temba-checkbox
|
|
266
284
|
name="${fieldName}"
|
|
267
|
-
label="${
|
|
285
|
+
label="${label}"
|
|
268
286
|
.helpText="${config.helpText || ''}"
|
|
269
287
|
?required="${config.required}"
|
|
270
288
|
.errors="${errors}"
|
|
@@ -272,7 +290,7 @@ export class FieldRenderer {
|
|
|
272
290
|
size="${config.size || 1.2}"
|
|
273
291
|
animateChange="${config.animateChange || 'pulse'}"
|
|
274
292
|
class="${extraClasses}"
|
|
275
|
-
style="${
|
|
293
|
+
style="${customStyle}"
|
|
276
294
|
@change="${onChange || (() => {})}"
|
|
277
295
|
></temba-checkbox>
|
|
278
296
|
${errors.length
|
|
@@ -338,6 +356,7 @@ export class FieldRenderer {
|
|
|
338
356
|
.itemLabel="${config.itemLabel || 'Item'}"
|
|
339
357
|
.minItems="${config.minItems || 0}"
|
|
340
358
|
.maxItems="${config.maxItems || 0}"
|
|
359
|
+
?maintainEmptyItem="${config.maintainEmptyItem !== false}"
|
|
341
360
|
.onItemChange="${config.onItemChange}"
|
|
342
361
|
.isEmptyItemFn="${config.isEmptyItem}"
|
|
343
362
|
class="${extraClasses}"
|
|
@@ -404,4 +423,6 @@ export interface FieldRenderContext {
|
|
|
404
423
|
style?: string;
|
|
405
424
|
/** Additional data needed for specific field types */
|
|
406
425
|
additionalData?: Record<string, any>;
|
|
426
|
+
/** Form data for dynamic field configurations */
|
|
427
|
+
formData?: Record<string, any>;
|
|
407
428
|
}
|
package/src/form/TextInput.ts
CHANGED
|
@@ -30,6 +30,21 @@ export class TextInput extends FieldElement {
|
|
|
30
30
|
caret-color: var(--input-caret);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
.xsmall {
|
|
34
|
+
--temba-textinput-padding: 6px 8px;
|
|
35
|
+
--temba-textinput-font-size: 13px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.small {
|
|
39
|
+
--temba-textinput-padding: 6px 8px;
|
|
40
|
+
--temba-textinput-font-size: 14px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.large {
|
|
44
|
+
--temba-textinput-padding: 10px 12px;
|
|
45
|
+
--temba-textinput-font-size: 16px;
|
|
46
|
+
}
|
|
47
|
+
|
|
33
48
|
.clear-icon {
|
|
34
49
|
--icon-color: var(--color-text-dark-secondary);
|
|
35
50
|
cursor: pointer;
|
|
@@ -181,6 +196,9 @@ export class TextInput extends FieldElement {
|
|
|
181
196
|
@property({ type: String })
|
|
182
197
|
type = InputType.Text;
|
|
183
198
|
|
|
199
|
+
@property({ type: String })
|
|
200
|
+
flavor = 'default';
|
|
201
|
+
|
|
184
202
|
counterElement: CharCount = null;
|
|
185
203
|
cursorStart = -1;
|
|
186
204
|
cursorEnd = -1;
|
|
@@ -482,7 +500,7 @@ export class TextInput extends FieldElement {
|
|
|
482
500
|
|
|
483
501
|
return html`
|
|
484
502
|
<div
|
|
485
|
-
class="input-container"
|
|
503
|
+
class="input-container ${this.flavor !== 'default' ? this.flavor : ''}"
|
|
486
504
|
style=${styleMap(containerStyle)}
|
|
487
505
|
@click=${this.handleContainerClick}
|
|
488
506
|
>
|
|
@@ -341,6 +341,13 @@ export class Select<T extends SelectOption> extends FieldElement {
|
|
|
341
341
|
--temba-select-min-height: 2.28em;
|
|
342
342
|
}
|
|
343
343
|
|
|
344
|
+
.xsmall {
|
|
345
|
+
--temba-select-selected-padding: 4px 6px;
|
|
346
|
+
--temba-select-selected-line-height: 13px;
|
|
347
|
+
--temba-select-selected-font-size: 13px;
|
|
348
|
+
--temba-select-min-height: 0em;
|
|
349
|
+
}
|
|
350
|
+
|
|
344
351
|
.info-text {
|
|
345
352
|
opacity: 1;
|
|
346
353
|
transition: padding-top var(--transition-speed) ease-in-out,
|
package/src/interfaces.ts
CHANGED
package/src/layout/Dialog.ts
CHANGED
|
@@ -24,7 +24,8 @@ export class Dialog extends ResizeElement {
|
|
|
24
24
|
return {
|
|
25
25
|
small: '400px',
|
|
26
26
|
medium: '600px',
|
|
27
|
-
large: '655px'
|
|
27
|
+
large: '655px',
|
|
28
|
+
xlarge: '800px'
|
|
28
29
|
};
|
|
29
30
|
}
|
|
30
31
|
|
|
@@ -413,10 +414,9 @@ export class Dialog extends ResizeElement {
|
|
|
413
414
|
|
|
414
415
|
public render(): TemplateResult {
|
|
415
416
|
const dialogStyle = {
|
|
416
|
-
width: this.width
|
|
417
|
-
minWidth: '250px',
|
|
418
|
-
maxWidth: '600px'
|
|
417
|
+
width: this.width
|
|
419
418
|
};
|
|
419
|
+
|
|
420
420
|
if (!this.width) {
|
|
421
421
|
dialogStyle['width'] = Dialog.widths[this.size];
|
|
422
422
|
}
|
package/src/list/RunList.ts
CHANGED
|
@@ -155,7 +155,7 @@ export class RunList extends TembaList {
|
|
|
155
155
|
style="width:16em;white-space:nowrap;overflow: hidden; text-overflow: ellipsis;"
|
|
156
156
|
>
|
|
157
157
|
<temba-contact-name
|
|
158
|
-
name=${run.contact?.name || run.contact?.
|
|
158
|
+
name=${run.contact?.name || run.contact?.ref || ''}
|
|
159
159
|
urn=${run.contact?.urn || ''}
|
|
160
160
|
icon-size="15"
|
|
161
161
|
/>
|
|
@@ -269,7 +269,7 @@ export class RunList extends TembaList {
|
|
|
269
269
|
<temba-contact-name
|
|
270
270
|
style="cursor:pointer"
|
|
271
271
|
name=${this.selectedRun.contact?.name ||
|
|
272
|
-
this.selectedRun.contact?.
|
|
272
|
+
this.selectedRun.contact?.ref ||
|
|
273
273
|
''}
|
|
274
274
|
urn=${this.selectedRun.contact?.urn || ''}
|
|
275
275
|
onclick="goto(event, this)"
|