@nyaruka/temba-components 0.133.0 → 0.134.1
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 +17 -0
- package/demo/components/webchat/example.html +1 -1
- package/dist/locales/es.js +5 -5
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/fr.js +5 -5
- package/dist/locales/fr.js.map +1 -1
- package/dist/locales/locale-codes.js +2 -11
- package/dist/locales/locale-codes.js.map +1 -1
- package/dist/locales/pt.js +5 -5
- package/dist/locales/pt.js.map +1 -1
- package/dist/temba-components.js +307 -259
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/display/Chat.js +223 -90
- package/out-tsc/src/display/Chat.js.map +1 -1
- package/out-tsc/src/display/TembaUser.js +3 -3
- package/out-tsc/src/display/TembaUser.js.map +1 -1
- package/out-tsc/src/events.js.map +1 -1
- package/out-tsc/src/flow/CanvasNode.js +8 -0
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +117 -28
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/utils.js +141 -0
- package/out-tsc/src/flow/utils.js.map +1 -1
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/live/ContactChat.js +122 -170
- package/out-tsc/src/live/ContactChat.js.map +1 -1
- package/out-tsc/src/locales/es.js +5 -5
- package/out-tsc/src/locales/es.js.map +1 -1
- package/out-tsc/src/locales/fr.js +5 -5
- package/out-tsc/src/locales/fr.js.map +1 -1
- package/out-tsc/src/locales/locale-codes.js +2 -11
- package/out-tsc/src/locales/locale-codes.js.map +1 -1
- package/out-tsc/src/locales/pt.js +5 -5
- package/out-tsc/src/locales/pt.js.map +1 -1
- package/out-tsc/src/store/AppState.js +3 -0
- package/out-tsc/src/store/AppState.js.map +1 -1
- package/out-tsc/src/store/Store.js +5 -5
- package/out-tsc/src/store/Store.js.map +1 -1
- package/out-tsc/src/webchat/WebChat.js +22 -9
- package/out-tsc/src/webchat/WebChat.js.map +1 -1
- package/out-tsc/test/actions/send_broadcast.test.js +9 -4
- package/out-tsc/test/actions/send_broadcast.test.js.map +1 -1
- package/out-tsc/test/temba-flow-collision.test.js +673 -0
- package/out-tsc/test/temba-flow-collision.test.js.map +1 -0
- package/out-tsc/test/temba-flow-editor-node.test.js +128 -42
- package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/contacts/chat-failure.png +0 -0
- package/screenshots/truth/contacts/chat-for-archived-contact.png +0 -0
- package/screenshots/truth/contacts/chat-for-blocked-contact.png +0 -0
- package/screenshots/truth/contacts/chat-for-stopped-contact.png +0 -0
- package/screenshots/truth/contacts/chat-sends-attachments-only.png +0 -0
- package/screenshots/truth/contacts/chat-sends-text-and-attachments.png +0 -0
- package/screenshots/truth/contacts/chat-sends-text-only.png +0 -0
- package/src/display/Chat.ts +303 -129
- package/src/display/TembaUser.ts +3 -2
- package/src/events.ts +11 -8
- package/src/flow/CanvasNode.ts +10 -0
- package/src/flow/Editor.ts +156 -28
- package/src/flow/utils.ts +207 -1
- package/src/interfaces.ts +7 -0
- package/src/live/ContactChat.ts +129 -180
- package/src/locales/es.ts +13 -18
- package/src/locales/fr.ts +13 -18
- package/src/locales/locale-codes.ts +2 -11
- package/src/locales/pt.ts +13 -18
- package/src/store/AppState.ts +2 -0
- package/src/store/Store.ts +5 -5
- package/src/webchat/WebChat.ts +24 -10
- package/test/actions/send_broadcast.test.ts +2 -1
- package/test/temba-flow-collision.test.ts +833 -0
- package/test/temba-flow-editor-node.test.ts +142 -47
|
@@ -1220,55 +1220,60 @@ describe('EditorNode', () => {
|
|
|
1220
1220
|
]
|
|
1221
1221
|
};
|
|
1222
1222
|
|
|
1223
|
-
editorNode['node'] = mockNode;
|
|
1224
|
-
|
|
1225
1223
|
const mockFlowDefinition = {
|
|
1224
|
+
language: 'en',
|
|
1225
|
+
localization: {},
|
|
1226
|
+
name: 'Test Flow',
|
|
1227
|
+
type: 'messaging' as const,
|
|
1228
|
+
uuid: 'test-uuid',
|
|
1229
|
+
revision: 1,
|
|
1230
|
+
spec_version: '14.3',
|
|
1226
1231
|
nodes: [
|
|
1227
1232
|
{
|
|
1228
1233
|
uuid: 'node-before',
|
|
1234
|
+
actions: [],
|
|
1229
1235
|
exits: [{ uuid: 'exit-before', destination_uuid: 'test-node' }]
|
|
1230
1236
|
},
|
|
1231
1237
|
mockNode,
|
|
1232
1238
|
{
|
|
1233
1239
|
uuid: 'node-after',
|
|
1240
|
+
actions: [],
|
|
1234
1241
|
exits: []
|
|
1235
1242
|
}
|
|
1236
|
-
]
|
|
1243
|
+
],
|
|
1244
|
+
_ui: {
|
|
1245
|
+
nodes: {},
|
|
1246
|
+
languages: []
|
|
1247
|
+
}
|
|
1237
1248
|
};
|
|
1238
1249
|
|
|
1239
|
-
//
|
|
1240
|
-
const
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
expect(destinations).to.have.length(3);
|
|
1245
|
-
expect(destinations.every((dest) => dest === 'node-after')).to.be.true;
|
|
1250
|
+
// Set up the zustand store with our test flow
|
|
1251
|
+
const { zustand } = await import('../src/store/AppState');
|
|
1252
|
+
zustand.setState({
|
|
1253
|
+
flowDefinition: mockFlowDefinition as any
|
|
1254
|
+
});
|
|
1246
1255
|
|
|
1247
|
-
//
|
|
1248
|
-
const
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1256
|
+
// Verify initial state - node-before points to test-node
|
|
1257
|
+
const initialNodeBefore = zustand
|
|
1258
|
+
.getState()
|
|
1259
|
+
.flowDefinition.nodes.find((n) => n.uuid === 'node-before');
|
|
1260
|
+
expect(initialNodeBefore.exits[0].destination_uuid).to.equal('test-node');
|
|
1252
1261
|
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
for (const exit of node.exits) {
|
|
1256
|
-
if (exit.destination_uuid === mockNode.uuid) {
|
|
1257
|
-
incomingConnections.push({
|
|
1258
|
-
exitUuid: exit.uuid,
|
|
1259
|
-
sourceNodeUuid: node.uuid
|
|
1260
|
-
});
|
|
1261
|
-
}
|
|
1262
|
-
}
|
|
1263
|
-
}
|
|
1264
|
-
}
|
|
1262
|
+
// Call removeNodes to trigger the rerouting logic
|
|
1263
|
+
zustand.getState().removeNodes(['test-node']);
|
|
1265
1264
|
|
|
1266
|
-
// Verify
|
|
1267
|
-
|
|
1268
|
-
expect(
|
|
1265
|
+
// Verify that the node was removed
|
|
1266
|
+
const remainingNodes = zustand.getState().flowDefinition.nodes;
|
|
1267
|
+
expect(remainingNodes.find((n) => n.uuid === 'test-node')).to.be
|
|
1268
|
+
.undefined;
|
|
1269
1269
|
|
|
1270
|
-
//
|
|
1271
|
-
|
|
1270
|
+
// Verify that node-before's exit was rerouted to node-after
|
|
1271
|
+
const updatedNodeBefore = remainingNodes.find(
|
|
1272
|
+
(n) => n.uuid === 'node-before'
|
|
1273
|
+
);
|
|
1274
|
+
expect(updatedNodeBefore.exits[0].destination_uuid).to.equal(
|
|
1275
|
+
'node-after'
|
|
1276
|
+
);
|
|
1272
1277
|
});
|
|
1273
1278
|
|
|
1274
1279
|
it('does not reroute connections when node has exits with different destinations', async () => {
|
|
@@ -1289,16 +1294,63 @@ describe('EditorNode', () => {
|
|
|
1289
1294
|
]
|
|
1290
1295
|
};
|
|
1291
1296
|
|
|
1292
|
-
const
|
|
1293
|
-
|
|
1294
|
-
|
|
1297
|
+
const mockFlowDefinition = {
|
|
1298
|
+
language: 'en',
|
|
1299
|
+
localization: {},
|
|
1300
|
+
name: 'Test Flow',
|
|
1301
|
+
type: 'messaging' as const,
|
|
1302
|
+
uuid: 'test-uuid',
|
|
1303
|
+
revision: 1,
|
|
1304
|
+
spec_version: '14.3',
|
|
1305
|
+
nodes: [
|
|
1306
|
+
{
|
|
1307
|
+
uuid: 'node-before',
|
|
1308
|
+
actions: [],
|
|
1309
|
+
exits: [{ uuid: 'exit-before', destination_uuid: 'test-node' }]
|
|
1310
|
+
},
|
|
1311
|
+
mockNode,
|
|
1312
|
+
{
|
|
1313
|
+
uuid: 'node-after-1',
|
|
1314
|
+
actions: [],
|
|
1315
|
+
exits: []
|
|
1316
|
+
},
|
|
1317
|
+
{
|
|
1318
|
+
uuid: 'node-after-2',
|
|
1319
|
+
actions: [],
|
|
1320
|
+
exits: []
|
|
1321
|
+
}
|
|
1322
|
+
],
|
|
1323
|
+
_ui: {
|
|
1324
|
+
nodes: {},
|
|
1325
|
+
languages: []
|
|
1326
|
+
}
|
|
1327
|
+
};
|
|
1328
|
+
|
|
1329
|
+
// Set up the zustand store with our test flow
|
|
1330
|
+
const { zustand } = await import('../src/store/AppState');
|
|
1331
|
+
zustand.setState({
|
|
1332
|
+
flowDefinition: mockFlowDefinition as any
|
|
1333
|
+
});
|
|
1295
1334
|
|
|
1296
|
-
// Verify
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
.
|
|
1335
|
+
// Verify initial state
|
|
1336
|
+
const initialNodeBefore = zustand
|
|
1337
|
+
.getState()
|
|
1338
|
+
.flowDefinition.nodes.find((n) => n.uuid === 'node-before');
|
|
1339
|
+
expect(initialNodeBefore.exits[0].destination_uuid).to.equal('test-node');
|
|
1340
|
+
|
|
1341
|
+
// Call removeNodes
|
|
1342
|
+
zustand.getState().removeNodes(['test-node']);
|
|
1343
|
+
|
|
1344
|
+
// Verify that the node was removed
|
|
1345
|
+
const remainingNodes = zustand.getState().flowDefinition.nodes;
|
|
1346
|
+
expect(remainingNodes.find((n) => n.uuid === 'test-node')).to.be
|
|
1347
|
+
.undefined;
|
|
1300
1348
|
|
|
1301
|
-
//
|
|
1349
|
+
// Verify that incoming connection was cleared (set to null), not rerouted
|
|
1350
|
+
const updatedNodeBefore = remainingNodes.find(
|
|
1351
|
+
(n) => n.uuid === 'node-before'
|
|
1352
|
+
);
|
|
1353
|
+
expect(updatedNodeBefore.exits[0].destination_uuid).to.be.null;
|
|
1302
1354
|
});
|
|
1303
1355
|
|
|
1304
1356
|
it('does not reroute connections when node has exits with null destinations', async () => {
|
|
@@ -1319,15 +1371,58 @@ describe('EditorNode', () => {
|
|
|
1319
1371
|
]
|
|
1320
1372
|
};
|
|
1321
1373
|
|
|
1322
|
-
const
|
|
1323
|
-
|
|
1324
|
-
|
|
1374
|
+
const mockFlowDefinition = {
|
|
1375
|
+
language: 'en',
|
|
1376
|
+
localization: {},
|
|
1377
|
+
name: 'Test Flow',
|
|
1378
|
+
type: 'messaging' as const,
|
|
1379
|
+
uuid: 'test-uuid',
|
|
1380
|
+
revision: 1,
|
|
1381
|
+
spec_version: '14.3',
|
|
1382
|
+
nodes: [
|
|
1383
|
+
{
|
|
1384
|
+
uuid: 'node-before',
|
|
1385
|
+
actions: [],
|
|
1386
|
+
exits: [{ uuid: 'exit-before', destination_uuid: 'test-node' }]
|
|
1387
|
+
},
|
|
1388
|
+
mockNode,
|
|
1389
|
+
{
|
|
1390
|
+
uuid: 'node-after',
|
|
1391
|
+
actions: [],
|
|
1392
|
+
exits: []
|
|
1393
|
+
}
|
|
1394
|
+
],
|
|
1395
|
+
_ui: {
|
|
1396
|
+
nodes: {},
|
|
1397
|
+
languages: []
|
|
1398
|
+
}
|
|
1399
|
+
};
|
|
1400
|
+
|
|
1401
|
+
// Set up the zustand store with our test flow
|
|
1402
|
+
const { zustand } = await import('../src/store/AppState');
|
|
1403
|
+
zustand.setState({
|
|
1404
|
+
flowDefinition: mockFlowDefinition as any
|
|
1405
|
+
});
|
|
1406
|
+
|
|
1407
|
+
// Verify initial state
|
|
1408
|
+
const initialNodeBefore = zustand
|
|
1409
|
+
.getState()
|
|
1410
|
+
.flowDefinition.nodes.find((n) => n.uuid === 'node-before');
|
|
1411
|
+
expect(initialNodeBefore.exits[0].destination_uuid).to.equal('test-node');
|
|
1325
1412
|
|
|
1326
|
-
//
|
|
1327
|
-
|
|
1328
|
-
expect(destinations.length).to.not.equal(mockNode.exits.length);
|
|
1413
|
+
// Call removeNodes
|
|
1414
|
+
zustand.getState().removeNodes(['test-node']);
|
|
1329
1415
|
|
|
1330
|
-
//
|
|
1416
|
+
// Verify that the node was removed
|
|
1417
|
+
const remainingNodes = zustand.getState().flowDefinition.nodes;
|
|
1418
|
+
expect(remainingNodes.find((n) => n.uuid === 'test-node')).to.be
|
|
1419
|
+
.undefined;
|
|
1420
|
+
|
|
1421
|
+
// Verify that incoming connection was cleared (set to null), not rerouted
|
|
1422
|
+
const updatedNodeBefore = remainingNodes.find(
|
|
1423
|
+
(n) => n.uuid === 'node-before'
|
|
1424
|
+
);
|
|
1425
|
+
expect(updatedNodeBefore.exits[0].destination_uuid).to.be.null;
|
|
1331
1426
|
});
|
|
1332
1427
|
});
|
|
1333
1428
|
|