@servicetitan/dte-unlayer 0.153.0 → 0.155.0
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/dist/display-conditions/ConditionRow.d.ts.map +1 -1
- package/dist/display-conditions/ConditionRow.js +111 -95
- package/dist/display-conditions/ConditionRow.js.map +1 -1
- package/dist/display-conditions/DisplayConditionModal.d.ts +3 -3
- package/dist/display-conditions/DisplayConditionModal.d.ts.map +1 -1
- package/dist/display-conditions/DisplayConditionModal.js +8 -95
- package/dist/display-conditions/DisplayConditionModal.js.map +1 -1
- package/dist/display-conditions/useConditionForms.d.ts +22 -0
- package/dist/display-conditions/useConditionForms.d.ts.map +1 -0
- package/dist/display-conditions/useConditionForms.js +110 -0
- package/dist/display-conditions/useConditionForms.js.map +1 -0
- package/dist/e-sign-offset/ESignDateSignedOffsetModal.d.ts +11 -0
- package/dist/e-sign-offset/ESignDateSignedOffsetModal.d.ts.map +1 -0
- package/dist/e-sign-offset/ESignDateSignedOffsetModal.js +192 -0
- package/dist/e-sign-offset/ESignDateSignedOffsetModal.js.map +1 -0
- package/dist/e-sign-offset/ESignOffsetRuleRow.d.ts +20 -0
- package/dist/e-sign-offset/ESignOffsetRuleRow.d.ts.map +1 -0
- package/dist/e-sign-offset/ESignOffsetRuleRow.js +87 -0
- package/dist/e-sign-offset/ESignOffsetRuleRow.js.map +1 -0
- package/dist/e-sign-offset/eSignOffsetController.d.ts +10 -0
- package/dist/e-sign-offset/eSignOffsetController.d.ts.map +1 -0
- package/dist/e-sign-offset/eSignOffsetController.js +27 -0
- package/dist/e-sign-offset/eSignOffsetController.js.map +1 -0
- package/dist/editor-core-source.d.ts +2 -2
- package/dist/editor-core-source.d.ts.map +1 -1
- package/dist/editor-core-source.js +2 -2
- package/dist/editor-core-source.js.map +1 -1
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +8 -0
- package/dist/editor.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/merge-tags.d.ts +6 -10
- package/dist/merge-tags.d.ts.map +1 -1
- package/dist/merge-tags.js +35 -44
- package/dist/merge-tags.js.map +1 -1
- package/dist/shared/const.d.ts +30 -0
- package/dist/shared/const.d.ts.map +1 -1
- package/dist/shared/const.js +5 -0
- package/dist/shared/const.js.map +1 -1
- package/dist/shared/e-sign-offset.d.ts +21 -0
- package/dist/shared/e-sign-offset.d.ts.map +1 -0
- package/dist/shared/e-sign-offset.js +130 -0
- package/dist/shared/e-sign-offset.js.map +1 -0
- package/dist/shared/instance-id.d.ts +13 -0
- package/dist/shared/instance-id.d.ts.map +1 -0
- package/dist/shared/instance-id.js +22 -0
- package/dist/shared/instance-id.js.map +1 -0
- package/dist/store.d.ts +15 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +80 -5
- package/dist/store.js.map +1 -1
- package/dist/tools.d.ts +18 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +68 -1
- package/dist/tools.js.map +1 -1
- package/dist/unlayer-interface.d.ts +11 -1
- package/dist/unlayer-interface.d.ts.map +1 -1
- package/dist/unlayer-interface.js.map +1 -1
- package/dist/unlayer.d.ts.map +1 -1
- package/dist/unlayer.js +5 -3
- package/dist/unlayer.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/e-sign-offset.test.ts +281 -0
- package/src/__tests__/merge-tags.test.ts +98 -76
- package/src/__tests__/store.merge-tags.test.ts +186 -0
- package/src/display-conditions/ConditionRow.tsx +86 -81
- package/src/display-conditions/DisplayConditionModal.tsx +12 -116
- package/src/display-conditions/useConditionForms.ts +146 -0
- package/src/e-sign-offset/ESignDateSignedOffsetModal.tsx +197 -0
- package/src/e-sign-offset/ESignOffsetRuleRow.tsx +101 -0
- package/src/e-sign-offset/eSignOffsetController.ts +39 -0
- package/src/editor-core-source.ts +2 -2
- package/src/editor.tsx +9 -0
- package/src/index.ts +1 -2
- package/src/merge-tags.ts +41 -60
- package/src/shared/const.ts +37 -0
- package/src/shared/e-sign-offset.ts +173 -0
- package/src/shared/instance-id.ts +23 -0
- package/src/store.ts +106 -5
- package/src/tools.ts +87 -1
- package/src/unlayer-interface.tsx +11 -1
- package/src/unlayer.tsx +5 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { toUnlayerMergeTags } from '../merge-tags';
|
|
2
2
|
|
|
3
3
|
const customerNameTag = {
|
|
4
4
|
id: '10',
|
|
@@ -75,7 +75,7 @@ describe('toUnlayerMergeTags', () => {
|
|
|
75
75
|
name: 'Customer Name',
|
|
76
76
|
value: '{{Customer.Name | safe | nl2br }}',
|
|
77
77
|
},
|
|
78
|
-
custom_fields: {
|
|
78
|
+
'custom_fields': {
|
|
79
79
|
name: 'Custom Fields',
|
|
80
80
|
mergeTags: {
|
|
81
81
|
custom_field_12345: {
|
|
@@ -124,6 +124,101 @@ describe('toUnlayerMergeTags', () => {
|
|
|
124
124
|
});
|
|
125
125
|
});
|
|
126
126
|
|
|
127
|
+
describe('when group is a path', () => {
|
|
128
|
+
const intakeScoreTag = {
|
|
129
|
+
id: 'form-7-abc123',
|
|
130
|
+
name: 'Score',
|
|
131
|
+
propertyPath: '{{ __submission_fields["7"]["abc123"] | safe | nl2br }}',
|
|
132
|
+
group: ['Forms', 'Customer Intake'],
|
|
133
|
+
};
|
|
134
|
+
const intakeNotesTag = {
|
|
135
|
+
id: 'form-7-def456',
|
|
136
|
+
name: 'Notes',
|
|
137
|
+
propertyPath: '{{ __submission_fields["7"]["def456"] | safe | nl2br }}',
|
|
138
|
+
group: ['Forms', 'Customer Intake'],
|
|
139
|
+
};
|
|
140
|
+
const inspectionDateTag = {
|
|
141
|
+
id: 'form-9-fed987',
|
|
142
|
+
name: 'Inspection Date',
|
|
143
|
+
propertyPath: '{{ __submission_fields["9"]["fed987"] | safe | nl2br }}',
|
|
144
|
+
group: ['Forms', 'Inspection'],
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const subject = () =>
|
|
148
|
+
toUnlayerMergeTags([
|
|
149
|
+
contractTermTag,
|
|
150
|
+
renewalDateTag,
|
|
151
|
+
intakeScoreTag,
|
|
152
|
+
intakeNotesTag,
|
|
153
|
+
inspectionDateTag,
|
|
154
|
+
]);
|
|
155
|
+
|
|
156
|
+
test('nests one submenu per path segment', () => {
|
|
157
|
+
expect(subject()).toEqual({
|
|
158
|
+
...groupedCustomFields,
|
|
159
|
+
forms: {
|
|
160
|
+
name: 'Forms',
|
|
161
|
+
mergeTags: {
|
|
162
|
+
customer_intake: {
|
|
163
|
+
name: 'Customer Intake',
|
|
164
|
+
mergeTags: {
|
|
165
|
+
form_7_abc123: {
|
|
166
|
+
name: 'Score',
|
|
167
|
+
value: '{{ __submission_fields["7"]["abc123"] | safe | nl2br }}',
|
|
168
|
+
},
|
|
169
|
+
form_7_def456: {
|
|
170
|
+
name: 'Notes',
|
|
171
|
+
value: '{{ __submission_fields["7"]["def456"] | safe | nl2br }}',
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
inspection: {
|
|
176
|
+
name: 'Inspection',
|
|
177
|
+
mergeTags: {
|
|
178
|
+
form_9_fed987: {
|
|
179
|
+
name: 'Inspection Date',
|
|
180
|
+
value: '{{ __submission_fields["9"]["fed987"] | safe | nl2br }}',
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
test('drops blank segments and keeps the remaining path', () => {
|
|
190
|
+
expect(toUnlayerMergeTags([{ ...intakeScoreTag, group: [' ', 'Forms', ''] }])).toEqual({
|
|
191
|
+
forms: {
|
|
192
|
+
name: 'Forms',
|
|
193
|
+
mergeTags: {
|
|
194
|
+
form_7_abc123: {
|
|
195
|
+
name: 'Score',
|
|
196
|
+
value: '{{ __submission_fields["7"]["abc123"] | safe | nl2br }}',
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test('treats an all-blank path as ungrouped', () => {
|
|
204
|
+
expect(toUnlayerMergeTags([{ ...intakeScoreTag, group: [] }])).toEqual({
|
|
205
|
+
form_7_abc123: {
|
|
206
|
+
name: 'Score',
|
|
207
|
+
value: '{{ __submission_fields["7"]["abc123"] | safe | nl2br }}',
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
test('flattens the path when groups are disabled', () => {
|
|
213
|
+
expect(toUnlayerMergeTags([intakeScoreTag], { groups: false })).toEqual({
|
|
214
|
+
form_7_abc123: {
|
|
215
|
+
name: 'Score',
|
|
216
|
+
value: '{{ __submission_fields["7"]["abc123"] | safe | nl2br }}',
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
|
|
127
222
|
describe('when group is blank', () => {
|
|
128
223
|
const subject = () =>
|
|
129
224
|
toUnlayerMergeTags([
|
|
@@ -153,7 +248,7 @@ describe('toUnlayerMergeTags', () => {
|
|
|
153
248
|
name: 'Customer Name',
|
|
154
249
|
value: '{{Customer.Name | safe | nl2br }}',
|
|
155
250
|
},
|
|
156
|
-
custom_field_12345: {
|
|
251
|
+
'custom_field_12345': {
|
|
157
252
|
name: 'Contract Term',
|
|
158
253
|
value: '{{ __custom_fields["Contract Term"] | safe | nl2br }}',
|
|
159
254
|
},
|
|
@@ -161,76 +256,3 @@ describe('toUnlayerMergeTags', () => {
|
|
|
161
256
|
});
|
|
162
257
|
});
|
|
163
258
|
});
|
|
164
|
-
|
|
165
|
-
describe('scheduleUnlayerMergeTags', () => {
|
|
166
|
-
describe('when grouped tags exist', () => {
|
|
167
|
-
const setMergeTags = jest.fn();
|
|
168
|
-
const addEventListener = jest.fn();
|
|
169
|
-
|
|
170
|
-
beforeEach(() => {
|
|
171
|
-
setMergeTags.mockReset();
|
|
172
|
-
addEventListener.mockReset();
|
|
173
|
-
scheduleUnlayerMergeTags(
|
|
174
|
-
{ addEventListener, setMergeTags },
|
|
175
|
-
[customerNameTag, contractTermTag, renewalDateTag],
|
|
176
|
-
);
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
test('does not apply grouped merge tags until the editor is ready', () => {
|
|
180
|
-
expect(setMergeTags).not.toHaveBeenCalled();
|
|
181
|
-
expect(addEventListener).toHaveBeenCalledWith('editor:ready', expect.any(Function));
|
|
182
|
-
expect(addEventListener).toHaveBeenCalledWith('design:loaded', expect.any(Function));
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
test('applies grouped merge tags when the editor is ready', () => {
|
|
186
|
-
addEventListener.mock.calls[0][1]();
|
|
187
|
-
|
|
188
|
-
expect(setMergeTags).toHaveBeenCalledWith({
|
|
189
|
-
'10': {
|
|
190
|
-
name: 'Customer Name',
|
|
191
|
-
value: '{{Customer.Name | safe | nl2br }}',
|
|
192
|
-
},
|
|
193
|
-
...groupedCustomFields,
|
|
194
|
-
});
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
test('applies grouped merge tags only once', () => {
|
|
198
|
-
addEventListener.mock.calls[0][1]();
|
|
199
|
-
addEventListener.mock.calls[1][1]();
|
|
200
|
-
|
|
201
|
-
expect(setMergeTags).toHaveBeenCalledTimes(1);
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
test('retries on design:loaded when setMergeTags throws', () => {
|
|
205
|
-
const consoleError = jest.spyOn(console, 'error').mockImplementation(() => undefined);
|
|
206
|
-
setMergeTags.mockImplementationOnce(() => {
|
|
207
|
-
throw new Error('setMergeTags failed');
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
addEventListener.mock.calls[0][1]();
|
|
211
|
-
addEventListener.mock.calls[1][1]();
|
|
212
|
-
|
|
213
|
-
expect(setMergeTags).toHaveBeenCalledTimes(2);
|
|
214
|
-
expect(consoleError).toHaveBeenCalledWith(
|
|
215
|
-
'[dte-unlayer]',
|
|
216
|
-
'Failed to apply grouped merge tags',
|
|
217
|
-
expect.any(Error),
|
|
218
|
-
);
|
|
219
|
-
consoleError.mockRestore();
|
|
220
|
-
});
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
describe('when tags are missing', () => {
|
|
224
|
-
const setMergeTags = jest.fn();
|
|
225
|
-
const addEventListener = jest.fn();
|
|
226
|
-
|
|
227
|
-
beforeEach(() => {
|
|
228
|
-
scheduleUnlayerMergeTags({ addEventListener, setMergeTags }, undefined);
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
test('does not touch the editor', () => {
|
|
232
|
-
expect(setMergeTags).not.toHaveBeenCalled();
|
|
233
|
-
expect(addEventListener).not.toHaveBeenCalled();
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
});
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { UnlayerStore } from '../store';
|
|
2
|
+
import type { CreateUnlayerEditorProps } from '../unlayer-interface';
|
|
3
|
+
|
|
4
|
+
const editorMock = {
|
|
5
|
+
addEventListener: jest.fn(),
|
|
6
|
+
removeEventListener: jest.fn(),
|
|
7
|
+
registerCallback: jest.fn(),
|
|
8
|
+
unregisterCallback: jest.fn(),
|
|
9
|
+
setMergeTags: jest.fn(),
|
|
10
|
+
loadDesign: jest.fn(),
|
|
11
|
+
setBodyValues: jest.fn(),
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
jest.mock('../loadScript', () => ({ loadScript: jest.fn().mockResolvedValue(undefined) }));
|
|
15
|
+
jest.mock('../unlayer', () => ({
|
|
16
|
+
...jest.requireActual('../unlayer'),
|
|
17
|
+
createUnlayerEditor: jest.fn(() => editorMock),
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
const customerNameTag = {
|
|
21
|
+
id: '10',
|
|
22
|
+
name: 'Customer Name',
|
|
23
|
+
propertyPath: '{{Customer.Name | safe | nl2br }}',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const scoreTag = {
|
|
27
|
+
id: 'form-7-abc',
|
|
28
|
+
name: 'Score',
|
|
29
|
+
propertyPath: '{{ __submission_fields["7"]["abc"] | safe | nl2br }}',
|
|
30
|
+
group: ['Forms', 'Customer Intake'],
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const flatCustomer = {
|
|
34
|
+
'10': { name: 'Customer Name', value: '{{Customer.Name | safe | nl2br }}' },
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const groupedScore = {
|
|
38
|
+
forms: {
|
|
39
|
+
name: 'Forms',
|
|
40
|
+
mergeTags: {
|
|
41
|
+
customer_intake: {
|
|
42
|
+
name: 'Customer Intake',
|
|
43
|
+
mergeTags: {
|
|
44
|
+
form_7_abc: {
|
|
45
|
+
name: 'Score',
|
|
46
|
+
value: '{{ __submission_fields["7"]["abc"] | safe | nl2br }}',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const fireEditorEvent = (event: string) => {
|
|
55
|
+
editorMock.addEventListener.mock.calls
|
|
56
|
+
.filter(([name]) => name === event)
|
|
57
|
+
.forEach(([, handler]) => handler());
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
describe('UnlayerStore merge tags', () => {
|
|
61
|
+
let store: UnlayerStore;
|
|
62
|
+
let consoleError: jest.SpyInstance;
|
|
63
|
+
|
|
64
|
+
const createStore = (props: Partial<CreateUnlayerEditorProps> = {}) => {
|
|
65
|
+
store = new UnlayerStore({ tools: [], ...props });
|
|
66
|
+
return store;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const initStore = async () => {
|
|
70
|
+
(window as any).unlayer = {};
|
|
71
|
+
const container = document.createElement('div');
|
|
72
|
+
container.appendChild(document.createElement('iframe'));
|
|
73
|
+
await store.init(container);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
beforeEach(() => {
|
|
77
|
+
jest.clearAllMocks();
|
|
78
|
+
consoleError = jest.spyOn(console, 'error').mockImplementation(() => undefined);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
afterEach(() => {
|
|
82
|
+
store.destroy();
|
|
83
|
+
consoleError.mockRestore();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe('when the editor initializes with merge tags', () => {
|
|
87
|
+
beforeEach(async () => {
|
|
88
|
+
createStore({ mergeTags: [customerNameTag, scoreTag] });
|
|
89
|
+
await initStore();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('does not touch the editor before it is ready', () => {
|
|
93
|
+
expect(editorMock.setMergeTags).not.toHaveBeenCalled();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('applies the grouped shape once on editor:ready', () => {
|
|
97
|
+
fireEditorEvent('editor:ready');
|
|
98
|
+
fireEditorEvent('design:loaded');
|
|
99
|
+
|
|
100
|
+
expect(editorMock.setMergeTags).toHaveBeenCalledTimes(1);
|
|
101
|
+
expect(editorMock.setMergeTags).toHaveBeenCalledWith({
|
|
102
|
+
...flatCustomer,
|
|
103
|
+
...groupedScore,
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test('applies on design:loaded when editor:ready never fires', () => {
|
|
108
|
+
fireEditorEvent('design:loaded');
|
|
109
|
+
|
|
110
|
+
expect(editorMock.setMergeTags).toHaveBeenCalledTimes(1);
|
|
111
|
+
expect(editorMock.setMergeTags).toHaveBeenCalledWith({
|
|
112
|
+
...flatCustomer,
|
|
113
|
+
...groupedScore,
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('retries on design:loaded when the first apply throws', () => {
|
|
118
|
+
editorMock.setMergeTags.mockImplementationOnce(() => {
|
|
119
|
+
throw new Error('not ready');
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
fireEditorEvent('editor:ready');
|
|
123
|
+
fireEditorEvent('design:loaded');
|
|
124
|
+
fireEditorEvent('design:loaded');
|
|
125
|
+
|
|
126
|
+
expect(editorMock.setMergeTags).toHaveBeenCalledTimes(2);
|
|
127
|
+
expect(consoleError).toHaveBeenCalledWith(
|
|
128
|
+
'[dte-unlayer]',
|
|
129
|
+
'Failed to apply merge tags',
|
|
130
|
+
expect.any(Error),
|
|
131
|
+
);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
describe('with setMergeTags', () => {
|
|
136
|
+
describe('when called before the editor is ready', () => {
|
|
137
|
+
beforeEach(async () => {
|
|
138
|
+
createStore({ mergeTags: [customerNameTag] });
|
|
139
|
+
store.unlayerRef.setMergeTags([customerNameTag, scoreTag]);
|
|
140
|
+
await initStore();
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
test('replaces the initial tags and applies once on ready', () => {
|
|
144
|
+
fireEditorEvent('editor:ready');
|
|
145
|
+
|
|
146
|
+
expect(editorMock.setMergeTags).toHaveBeenCalledTimes(1);
|
|
147
|
+
expect(editorMock.setMergeTags).toHaveBeenCalledWith({
|
|
148
|
+
...flatCustomer,
|
|
149
|
+
...groupedScore,
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe('when called after the editor is ready', () => {
|
|
155
|
+
beforeEach(async () => {
|
|
156
|
+
createStore({ mergeTags: [customerNameTag] });
|
|
157
|
+
await initStore();
|
|
158
|
+
fireEditorEvent('editor:ready');
|
|
159
|
+
editorMock.setMergeTags.mockClear();
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
test('applies immediately', () => {
|
|
163
|
+
store.unlayerRef.setMergeTags([customerNameTag, scoreTag]);
|
|
164
|
+
|
|
165
|
+
expect(editorMock.setMergeTags).toHaveBeenCalledTimes(1);
|
|
166
|
+
expect(editorMock.setMergeTags).toHaveBeenCalledWith({
|
|
167
|
+
...flatCustomer,
|
|
168
|
+
...groupedScore,
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
test('does not re-apply on later design:loaded events', () => {
|
|
173
|
+
store.unlayerRef.setMergeTags([customerNameTag, scoreTag]);
|
|
174
|
+
fireEditorEvent('design:loaded');
|
|
175
|
+
|
|
176
|
+
expect(editorMock.setMergeTags).toHaveBeenCalledTimes(1);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test('ignores an empty set', () => {
|
|
180
|
+
store.unlayerRef.setMergeTags([]);
|
|
181
|
+
|
|
182
|
+
expect(editorMock.setMergeTags).not.toHaveBeenCalled();
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
});
|
|
@@ -178,6 +178,8 @@ export function ConditionRow({
|
|
|
178
178
|
<Flex direction="column" gap="3" style={{ width: '100%' }}>
|
|
179
179
|
<div style={{ width: '100%' }}>
|
|
180
180
|
<Combobox.Select
|
|
181
|
+
flex={1}
|
|
182
|
+
style={{ width: '100%' }}
|
|
181
183
|
disableClearSelection
|
|
182
184
|
itemToKey={(item: SourceOption | null) => item?.value ?? ''}
|
|
183
185
|
itemToString={(item: SourceOption | null) => item?.label ?? ''}
|
|
@@ -203,12 +205,7 @@ export function ConditionRow({
|
|
|
203
205
|
</Combobox.Content>
|
|
204
206
|
</Combobox.Select>
|
|
205
207
|
</div>
|
|
206
|
-
<Flex
|
|
207
|
-
direction="row"
|
|
208
|
-
alignItems="flex-end"
|
|
209
|
-
gap="2"
|
|
210
|
-
style={{ flexWrap: 'wrap', rowGap: 8, width: '100%' }}
|
|
211
|
-
>
|
|
208
|
+
<Flex direction="row" alignItems="flex-end" gap="2" style={{ width: '100%' }}>
|
|
212
209
|
<div
|
|
213
210
|
style={{
|
|
214
211
|
display: 'flex',
|
|
@@ -219,89 +216,97 @@ export function ConditionRow({
|
|
|
219
216
|
>
|
|
220
217
|
<Chip label="IF" size="small" />
|
|
221
218
|
</div>
|
|
222
|
-
<Flex
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
219
|
+
<Flex
|
|
220
|
+
flex={1}
|
|
221
|
+
direction="row"
|
|
222
|
+
alignItems="flex-end"
|
|
223
|
+
gap="2"
|
|
224
|
+
style={{ minWidth: 0, width: '100%' }}
|
|
225
|
+
>
|
|
226
|
+
<Flex flex={1} style={{ minWidth: 0, width: '100%' }}>
|
|
227
|
+
<Combobox.Select
|
|
228
|
+
flex={1}
|
|
229
|
+
style={{ width: '100%' }}
|
|
230
|
+
disableClearSelection
|
|
231
|
+
itemToKey={(item: DataPointOption | null) => item?.fullKey ?? ''}
|
|
232
|
+
itemToString={(item: DataPointOption | null) => item?.title ?? ''}
|
|
233
|
+
items={activeDataPointOptions}
|
|
234
|
+
selectedItem={selectedDataPoint}
|
|
235
|
+
onChange={handleDataPointChange}
|
|
236
|
+
>
|
|
237
|
+
<Combobox.SelectTrigger
|
|
238
|
+
label="Data Point"
|
|
239
|
+
placeholder={
|
|
240
|
+
currentFormId ? 'Select form field...' : 'Select data point...'
|
|
241
|
+
}
|
|
242
|
+
size="small"
|
|
243
|
+
/>
|
|
244
|
+
<Combobox.Content>
|
|
245
|
+
{({ items }: { items: DataPointOption[] }) => (
|
|
246
|
+
<Combobox.List>
|
|
247
|
+
{items.map((item, i) => (
|
|
248
|
+
<Combobox.Item index={i} item={item} key={item.fullKey}>
|
|
249
|
+
{item.title}
|
|
250
|
+
</Combobox.Item>
|
|
251
|
+
))}
|
|
252
|
+
</Combobox.List>
|
|
253
|
+
)}
|
|
254
|
+
</Combobox.Content>
|
|
255
|
+
</Combobox.Select>
|
|
256
|
+
</Flex>
|
|
257
|
+
<Flex flex={1} style={{ minWidth: 0, width: '100%' }}>
|
|
258
|
+
<Combobox.Select
|
|
259
|
+
flex={1}
|
|
260
|
+
style={{ width: '100%' }}
|
|
261
|
+
disableClearSelection
|
|
262
|
+
itemToKey={(item: OperatorOption | null) => item?.value ?? ''}
|
|
263
|
+
itemToString={(item: OperatorOption | null) => item?.label ?? ''}
|
|
264
|
+
items={operatorItems}
|
|
265
|
+
selectedItem={selectedOperator}
|
|
266
|
+
onChange={(item: OperatorOption | null) =>
|
|
267
|
+
onChange({
|
|
268
|
+
...condition,
|
|
269
|
+
operator: (item?.value ??
|
|
270
|
+
'is_equal_to') as SingleCondition['operator'],
|
|
271
|
+
})
|
|
237
272
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
style={{ width: '100%' }}
|
|
257
|
-
disableClearSelection
|
|
258
|
-
itemToKey={(item: OperatorOption | null) => item?.value ?? ''}
|
|
259
|
-
itemToString={(item: OperatorOption | null) => item?.label ?? ''}
|
|
260
|
-
items={operatorItems}
|
|
261
|
-
selectedItem={selectedOperator}
|
|
262
|
-
onChange={(item: OperatorOption | null) =>
|
|
263
|
-
onChange({
|
|
264
|
-
...condition,
|
|
265
|
-
operator: (item?.value ??
|
|
266
|
-
'is_equal_to') as SingleCondition['operator'],
|
|
267
|
-
})
|
|
268
|
-
}
|
|
269
|
-
>
|
|
270
|
-
<Combobox.SelectTrigger
|
|
271
|
-
label="Condition"
|
|
272
|
-
placeholder="Select..."
|
|
273
|
-
size="small"
|
|
274
|
-
/>
|
|
275
|
-
<Combobox.Content>
|
|
276
|
-
{({ items }: { items: OperatorOption[] }) => (
|
|
277
|
-
<Combobox.List>
|
|
278
|
-
{items.map((item, i) => (
|
|
279
|
-
<Combobox.Item index={i} item={item} key={item.value}>
|
|
280
|
-
{item.label}
|
|
281
|
-
</Combobox.Item>
|
|
282
|
-
))}
|
|
283
|
-
</Combobox.List>
|
|
284
|
-
)}
|
|
285
|
-
</Combobox.Content>
|
|
286
|
-
</Combobox.Select>
|
|
287
|
-
</Flex>
|
|
288
|
-
{!isValueLess && (
|
|
289
|
-
<Flex flex={1} style={{ minWidth: 160 }}>
|
|
290
|
-
<LookupValueControl
|
|
291
|
-
value={condition.value}
|
|
292
|
-
fieldType={fieldType}
|
|
293
|
-
lookupSource={selectedDataPoint?.lookupSource}
|
|
294
|
-
onChange={value => onChange({ ...condition, value })}
|
|
295
|
-
/>
|
|
273
|
+
>
|
|
274
|
+
<Combobox.SelectTrigger
|
|
275
|
+
label="Condition"
|
|
276
|
+
placeholder="Select..."
|
|
277
|
+
size="small"
|
|
278
|
+
/>
|
|
279
|
+
<Combobox.Content>
|
|
280
|
+
{({ items }: { items: OperatorOption[] }) => (
|
|
281
|
+
<Combobox.List>
|
|
282
|
+
{items.map((item, i) => (
|
|
283
|
+
<Combobox.Item index={i} item={item} key={item.value}>
|
|
284
|
+
{item.label}
|
|
285
|
+
</Combobox.Item>
|
|
286
|
+
))}
|
|
287
|
+
</Combobox.List>
|
|
288
|
+
)}
|
|
289
|
+
</Combobox.Content>
|
|
290
|
+
</Combobox.Select>
|
|
296
291
|
</Flex>
|
|
297
|
-
|
|
292
|
+
{!isValueLess && (
|
|
293
|
+
<Flex flex="0 0 186px" style={{ minWidth: 0 }}>
|
|
294
|
+
<LookupValueControl
|
|
295
|
+
value={condition.value}
|
|
296
|
+
fieldType={fieldType}
|
|
297
|
+
lookupSource={selectedDataPoint?.lookupSource}
|
|
298
|
+
onChange={value => onChange({ ...condition, value })}
|
|
299
|
+
/>
|
|
300
|
+
</Flex>
|
|
301
|
+
)}
|
|
302
|
+
</Flex>
|
|
298
303
|
{canRemove && (
|
|
299
304
|
<div
|
|
300
305
|
style={{
|
|
301
306
|
display: 'flex',
|
|
302
307
|
alignItems: 'flex-end',
|
|
303
308
|
flexShrink: 0,
|
|
304
|
-
|
|
309
|
+
paddingBottom: 4,
|
|
305
310
|
}}
|
|
306
311
|
>
|
|
307
312
|
<Button
|