@nyaruka/temba-components 0.141.1 → 0.142.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/CHANGELOG.md +15 -0
- package/dist/static/svg/index.svg +1 -1
- package/dist/temba-components.js +849 -655
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/Icons.js +3 -1
- package/out-tsc/src/Icons.js.map +1 -1
- package/out-tsc/src/display/Button.js +2 -2
- package/out-tsc/src/display/Button.js.map +1 -1
- package/out-tsc/src/display/FloatingTab.js.map +1 -1
- package/out-tsc/src/flow/CanvasMenu.js +24 -1
- package/out-tsc/src/flow/CanvasMenu.js.map +1 -1
- package/out-tsc/src/flow/CanvasNode.js +7 -2
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +654 -66
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/NodeEditor.js +8 -5
- package/out-tsc/src/flow/NodeEditor.js.map +1 -1
- package/out-tsc/src/flow/Plumber.js +40 -28
- package/out-tsc/src/flow/Plumber.js.map +1 -1
- package/out-tsc/src/flow/actions/send_msg.js +2 -1
- package/out-tsc/src/flow/actions/send_msg.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_response.js +1 -1
- package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
- package/out-tsc/src/flow/reflow.js +393 -0
- package/out-tsc/src/flow/reflow.js.map +1 -0
- package/out-tsc/src/flow/types.js.map +1 -1
- package/out-tsc/src/flow/utils.js +18 -3
- package/out-tsc/src/flow/utils.js.map +1 -1
- package/out-tsc/src/form/Compose.js +5 -0
- package/out-tsc/src/form/Compose.js.map +1 -1
- package/out-tsc/src/form/FieldRenderer.js +1 -3
- package/out-tsc/src/form/FieldRenderer.js.map +1 -1
- package/out-tsc/src/layout/Dialog.js +2 -0
- package/out-tsc/src/layout/Dialog.js.map +1 -1
- package/out-tsc/src/list/SortableList.js +39 -19
- package/out-tsc/src/list/SortableList.js.map +1 -1
- package/out-tsc/test/temba-canvas-menu.test.js +44 -0
- package/out-tsc/test/temba-canvas-menu.test.js.map +1 -1
- package/out-tsc/test/temba-flow-collision.test.js +25 -0
- package/out-tsc/test/temba-flow-collision.test.js.map +1 -1
- package/out-tsc/test/temba-flow-editor-zoom.test.js +491 -0
- package/out-tsc/test/temba-flow-editor-zoom.test.js.map +1 -0
- package/out-tsc/test/temba-flow-editor.test.js +145 -1
- package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
- package/out-tsc/test/temba-flow-node-drag.test.js +123 -0
- package/out-tsc/test/temba-flow-node-drag.test.js.map +1 -1
- package/out-tsc/test/temba-flow-plumber.test.js +31 -0
- package/out-tsc/test/temba-flow-plumber.test.js.map +1 -1
- package/out-tsc/test/temba-flow-reflow.test.js +472 -0
- package/out-tsc/test/temba-flow-reflow.test.js.map +1 -0
- package/out-tsc/test/temba-sortable-list.test.js +93 -0
- package/out-tsc/test/temba-sortable-list.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_urn/editor/expression-facebook.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/expression-phone.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/facebook-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/instagram-handle.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/line-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/phone-number.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/telegram-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/viber-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/wechat-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/whatsapp.png +0 -0
- package/screenshots/truth/actions/enter_flow/editor/basic-flow.png +0 -0
- package/screenshots/truth/actions/enter_flow/editor/long-flow-name.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/say_msg/editor/multiline-text.png +0 -0
- package/screenshots/truth/actions/say_msg/editor/simple-text.png +0 -0
- package/screenshots/truth/actions/say_msg/editor/text-with-audio-url.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/contacts-only.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/groups-and-contacts.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/groups-only.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/many-groups.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/multiline-text.png +0 -0
- package/screenshots/truth/actions/send_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_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/set_contact_channel/editor/sms-channel.png +0 -0
- package/screenshots/truth/actions/set_contact_channel/editor/whatsapp-channel.png +0 -0
- package/screenshots/truth/actions/set_contact_field/editor/clear-value.png +0 -0
- package/screenshots/truth/actions/set_contact_field/editor/set-value.png +0 -0
- package/screenshots/truth/actions/set_contact_language/editor/english.png +0 -0
- package/screenshots/truth/actions/set_contact_language/editor/french.png +0 -0
- package/screenshots/truth/actions/set_contact_status/editor/active.png +0 -0
- package/screenshots/truth/actions/set_contact_status/editor/archived.png +0 -0
- package/screenshots/truth/actions/set_contact_status/editor/blocked.png +0 -0
- package/screenshots/truth/actions/set_run_result/editor/expression-value.png +0 -0
- package/screenshots/truth/actions/set_run_result/editor/with-category.png +0 -0
- package/screenshots/truth/actions/start_session/editor/contact-query.png +0 -0
- package/screenshots/truth/actions/start_session/editor/contacts-only.png +0 -0
- package/screenshots/truth/actions/start_session/editor/create-contact.png +0 -0
- package/screenshots/truth/actions/start_session/editor/groups-and-contacts.png +0 -0
- package/screenshots/truth/actions/start_session/editor/groups-only.png +0 -0
- package/screenshots/truth/actions/start_session/editor/many-recipients.png +0 -0
- package/screenshots/truth/list/fields-dragging.png +0 -0
- package/screenshots/truth/list/sortable-dragging.png +0 -0
- package/screenshots/truth/modax/simple.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_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_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/wait_for_dial/editor/dial-with-limits.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/digits-with-rules.png +0 -0
- package/screenshots/truth/nodes/wait_for_menu/editor/menu-with-digits.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/src/Icons.ts +3 -1
- package/src/display/Button.ts +2 -2
- package/src/display/FloatingTab.ts +1 -1
- package/src/flow/CanvasMenu.ts +28 -3
- package/src/flow/CanvasNode.ts +7 -2
- package/src/flow/Editor.ts +755 -75
- package/src/flow/NodeEditor.ts +8 -4
- package/src/flow/Plumber.ts +65 -35
- package/src/flow/actions/send_msg.ts +2 -1
- package/src/flow/nodes/wait_for_response.ts +1 -1
- package/src/flow/reflow.ts +534 -0
- package/src/flow/types.ts +1 -0
- package/src/flow/utils.ts +19 -3
- package/src/form/Compose.ts +5 -0
- package/src/form/FieldRenderer.ts +1 -3
- package/src/layout/Dialog.ts +2 -0
- package/src/list/SortableList.ts +40 -19
- package/static/svg/index.svg +1 -1
- package/static/svg/work/traced/expand-06.svg +1 -0
- package/static/svg/work/used/expand-06.svg +3 -0
- package/test/temba-canvas-menu.test.ts +55 -0
- package/test/temba-flow-collision.test.ts +31 -0
- package/test/temba-flow-editor-zoom.test.ts +583 -0
- package/test/temba-flow-editor.test.ts +187 -1
- package/test/temba-flow-node-drag.test.ts +171 -0
- package/test/temba-flow-plumber.test.ts +38 -0
- package/test/temba-flow-reflow.test.ts +703 -0
- package/test/temba-sortable-list.test.ts +120 -0
- package/screenshots/truth/actions/call_llm/editor/information-extraction.png +0 -0
- package/screenshots/truth/actions/call_llm/editor/sentiment-analysis.png +0 -0
- package/screenshots/truth/actions/call_llm/editor/summarization.png +0 -0
- package/screenshots/truth/actions/call_llm/editor/translation-task.png +0 -0
- package/screenshots/truth/actions/call_llm/render/information-extraction.png +0 -0
- package/screenshots/truth/actions/call_llm/render/sentiment-analysis.png +0 -0
- package/screenshots/truth/actions/call_llm/render/summarization.png +0 -0
- package/screenshots/truth/actions/call_llm/render/translation-task.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/with-attachments.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/with-attachments.png +0 -0
- package/screenshots/truth/compose/attachments-with-failures.png +0 -0
- package/screenshots/truth/compose/attachments-with-files-and-failures.png +0 -0
- package/screenshots/truth/contacts/tickets-assignment.png +0 -0
- package/screenshots/truth/contacts/tickets.png +0 -0
- package/screenshots/truth/flow/editor-basic.png +0 -0
- package/screenshots/truth/formfield/markdown-errors.png +0 -0
- package/screenshots/truth/formfield/no-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/omnibox/selected.png +0 -0
- package/screenshots/truth/select/enabled-multi-selection.png +0 -0
- package/screenshots/truth/select/endpoint-initial-value-updated.png +0 -0
- package/screenshots/truth/select/endpoint-initial-value.png +0 -0
- package/screenshots/truth/select/initial-value.png +0 -0
- package/screenshots/truth/select/multi-reorder-final.png +0 -0
- package/screenshots/truth/select/multi-reorder-initial.png +0 -0
- package/screenshots/truth/select/selected-multi-test.png +0 -0
- package/screenshots/truth/select/value-initial.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/screenshots/truth/webchat/connecting-state.png +0 -0
|
@@ -217,4 +217,124 @@ describe('temba-sortable-list', () => {
|
|
|
217
217
|
const dragStopEvent = await dragStop;
|
|
218
218
|
expect(dragStopEvent.detail.isExternal).to.be.true;
|
|
219
219
|
});
|
|
220
|
+
|
|
221
|
+
describe('zoom-aware dimensions', () => {
|
|
222
|
+
it('stores layout dimensions on mousedown via offsetWidth/offsetHeight', async () => {
|
|
223
|
+
const list: SortableList = await createSorter(BORING_LIST);
|
|
224
|
+
await list.updateComplete;
|
|
225
|
+
|
|
226
|
+
const bounds = list.getBoundingClientRect();
|
|
227
|
+
|
|
228
|
+
// Start drag
|
|
229
|
+
await moveMouse(bounds.left + 20, bounds.bottom - 10);
|
|
230
|
+
await mouseDown();
|
|
231
|
+
|
|
232
|
+
// originalLayoutSize should be set using offsetWidth/offsetHeight
|
|
233
|
+
expect(list.originalLayoutSize).to.not.be.null;
|
|
234
|
+
// At zoom=1.0, layout size equals viewport size
|
|
235
|
+
expect(list.originalLayoutSize.width).to.equal(
|
|
236
|
+
list.originalElementRect.width
|
|
237
|
+
);
|
|
238
|
+
expect(list.originalLayoutSize.height).to.equal(
|
|
239
|
+
list.originalElementRect.height
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
await mouseUp();
|
|
243
|
+
clock.runAll();
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('ghost uses scale(1.03) without ancestor transform', async () => {
|
|
247
|
+
const list: SortableList = await createSorter(BORING_LIST);
|
|
248
|
+
await list.updateComplete;
|
|
249
|
+
|
|
250
|
+
const bounds = list.getBoundingClientRect();
|
|
251
|
+
|
|
252
|
+
// Start drag past threshold to create ghost
|
|
253
|
+
await moveMouse(bounds.left + 20, bounds.bottom - 10);
|
|
254
|
+
await mouseDown();
|
|
255
|
+
await moveMouse(bounds.left + 30, bounds.bottom - 10);
|
|
256
|
+
clock.runAll();
|
|
257
|
+
|
|
258
|
+
expect(list.ghostElement).to.not.be.null;
|
|
259
|
+
expect(list.ghostElement.style.transform).to.equal('scale(1.03)');
|
|
260
|
+
// transformOrigin should NOT be set to '0 0' when there's no ancestor scale
|
|
261
|
+
expect(list.ghostElement.style.transformOrigin).to.not.equal('0 0');
|
|
262
|
+
|
|
263
|
+
await mouseUp();
|
|
264
|
+
clock.runAll();
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it('detects ancestor scale and applies it to ghost', () => {
|
|
268
|
+
// Unit test the ghost scaling logic directly:
|
|
269
|
+
// When originalElementRect (viewport) differs from originalLayoutSize (layout),
|
|
270
|
+
// the ancestor scale is detected and applied to the ghost.
|
|
271
|
+
const list = new SortableList();
|
|
272
|
+
|
|
273
|
+
// Simulate being inside a container with transform: scale(0.5)
|
|
274
|
+
// Layout dimensions: 100x20, viewport dimensions: 50x10
|
|
275
|
+
list.originalElementRect = {
|
|
276
|
+
width: 50,
|
|
277
|
+
height: 10,
|
|
278
|
+
left: 0,
|
|
279
|
+
top: 0,
|
|
280
|
+
right: 50,
|
|
281
|
+
bottom: 10,
|
|
282
|
+
x: 0,
|
|
283
|
+
y: 0,
|
|
284
|
+
toJSON: () => ({})
|
|
285
|
+
} as DOMRect;
|
|
286
|
+
list.originalLayoutSize = { width: 100, height: 20 };
|
|
287
|
+
|
|
288
|
+
// Calculate ancestor scale the same way the component does
|
|
289
|
+
const ancestorScale =
|
|
290
|
+
list.originalLayoutSize.width > 0
|
|
291
|
+
? list.originalElementRect.width / list.originalLayoutSize.width
|
|
292
|
+
: 1;
|
|
293
|
+
const hasAncestorScale = Math.abs(ancestorScale - 1) > 0.001;
|
|
294
|
+
|
|
295
|
+
expect(hasAncestorScale).to.be.true;
|
|
296
|
+
expect(ancestorScale).to.equal(0.5);
|
|
297
|
+
|
|
298
|
+
// The ghost would get: transform: scale(0.5 * 1.03) = scale(0.515)
|
|
299
|
+
const expectedScale = ancestorScale * 1.03;
|
|
300
|
+
expect(expectedScale).to.be.closeTo(0.515, 0.001);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it('uses originalLayoutSize for placeholder sizing', () => {
|
|
304
|
+
// Verify that the component stores separate layout vs viewport dimensions
|
|
305
|
+
const list = new SortableList();
|
|
306
|
+
|
|
307
|
+
// At zoom=1.0, both should be the same
|
|
308
|
+
const mockRect = {
|
|
309
|
+
width: 100,
|
|
310
|
+
height: 20,
|
|
311
|
+
left: 0,
|
|
312
|
+
top: 0,
|
|
313
|
+
right: 100,
|
|
314
|
+
bottom: 20,
|
|
315
|
+
x: 0,
|
|
316
|
+
y: 0,
|
|
317
|
+
toJSON: () => ({})
|
|
318
|
+
} as DOMRect;
|
|
319
|
+
|
|
320
|
+
list.originalElementRect = mockRect;
|
|
321
|
+
list.originalLayoutSize = { width: 100, height: 20 };
|
|
322
|
+
|
|
323
|
+
// At zoom=1.0, they match
|
|
324
|
+
expect(list.originalLayoutSize.width).to.equal(
|
|
325
|
+
list.originalElementRect.width
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
// At zoom=0.5, viewport rect would be half but layout stays the same
|
|
329
|
+
list.originalElementRect = {
|
|
330
|
+
...mockRect,
|
|
331
|
+
width: 50,
|
|
332
|
+
height: 10
|
|
333
|
+
} as DOMRect;
|
|
334
|
+
|
|
335
|
+
// Layout size is independent of zoom
|
|
336
|
+
expect(list.originalLayoutSize.width).to.equal(100);
|
|
337
|
+
expect(list.originalLayoutSize.height).to.equal(20);
|
|
338
|
+
});
|
|
339
|
+
});
|
|
220
340
|
});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|