@capillarytech/creatives-library 8.0.248 → 8.0.250
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/package.json +1 -1
- package/utils/tests/transformerUtils.test.js +297 -0
- package/utils/transformerUtils.js +40 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +2 -0
- package/v2Containers/CreativesContainer/constants.js +1 -0
- package/v2Containers/CreativesContainer/index.js +168 -0
- package/v2Containers/Email/index.js +3 -7
- package/v2Containers/TemplatesV2/index.js +8 -7
- package/v2Containers/WebPush/Create/components/ButtonsLinksSection.test.js +4 -4
- package/v2Containers/WebPush/Create/components/__snapshots__/ButtonsLinksSection.test.js.snap +2 -2
- package/v2Containers/WebPush/Create/index.js +104 -12
- package/v2Containers/WebPush/Create/preview/WebPushPreview.js +6 -1
- package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +384 -0
- package/v2Containers/WebPush/Create/utils/payloadBuilder.js +4 -2
- package/v2Containers/WebPush/Create/utils/payloadBuilder.test.js +13 -7
- package/v2Containers/WebPush/constants.js +6 -2
- package/v2Containers/WebPush/tests/selectors.test.js +117 -0
package/package.json
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
RCS,
|
|
16
16
|
LINE,
|
|
17
17
|
VIBER,
|
|
18
|
+
WEBPUSH,
|
|
18
19
|
} from "../../v2Containers/CreativesContainer/constants";
|
|
19
20
|
|
|
20
21
|
describe("transformerUtils", () => {
|
|
@@ -1182,6 +1183,302 @@ describe("transformerUtils", () => {
|
|
|
1182
1183
|
});
|
|
1183
1184
|
});
|
|
1184
1185
|
|
|
1186
|
+
describe("WebPush payload transformation", () => {
|
|
1187
|
+
it("should transform WebPush data correctly with minimal data", () => {
|
|
1188
|
+
const mockData = {
|
|
1189
|
+
channel: WEBPUSH,
|
|
1190
|
+
messageSubject: "test webpush notification"
|
|
1191
|
+
};
|
|
1192
|
+
|
|
1193
|
+
const result = transformChannelPayload(mockData);
|
|
1194
|
+
|
|
1195
|
+
expect(result.centralCommsPayload).toBeDefined();
|
|
1196
|
+
expect(result.centralCommsPayload.channel).toEqual(WEBPUSH);
|
|
1197
|
+
expect(result.centralCommsPayload.webpushMessageContent.messageSubject).toEqual(
|
|
1198
|
+
"test webpush notification"
|
|
1199
|
+
);
|
|
1200
|
+
expect(result.centralCommsPayload.clientName).toEqual("VENENO");
|
|
1201
|
+
});
|
|
1202
|
+
|
|
1203
|
+
it("should transform WebPush data with all options", () => {
|
|
1204
|
+
const mockData = {
|
|
1205
|
+
channel: WEBPUSH,
|
|
1206
|
+
messageSubject: "test webpush notification",
|
|
1207
|
+
messageContent: {
|
|
1208
|
+
content: {
|
|
1209
|
+
accountId: 12345,
|
|
1210
|
+
content: {
|
|
1211
|
+
title: "WebPush Title",
|
|
1212
|
+
message: "WebPush Message",
|
|
1213
|
+
iconImageUrl: "https://example.com/icon.png",
|
|
1214
|
+
cta: {
|
|
1215
|
+
actionLink: "https://example.com/action",
|
|
1216
|
+
actionText: "Click Here"
|
|
1217
|
+
},
|
|
1218
|
+
expandableDetails: {
|
|
1219
|
+
style: "BIG_TEXT",
|
|
1220
|
+
message: "Expanded Message"
|
|
1221
|
+
}
|
|
1222
|
+
},
|
|
1223
|
+
offers: [
|
|
1224
|
+
{ id: "offer-1", title: "Offer 1" },
|
|
1225
|
+
{ id: "offer-2", title: "Offer 2" }
|
|
1226
|
+
]
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
};
|
|
1230
|
+
|
|
1231
|
+
const options = {
|
|
1232
|
+
loyaltyMetaData: {
|
|
1233
|
+
actionId: "action-123",
|
|
1234
|
+
ouId: 456,
|
|
1235
|
+
clientName: "TestClient",
|
|
1236
|
+
module: "TestModule",
|
|
1237
|
+
transformedMessageDetails: {
|
|
1238
|
+
webpushDeliverySettings: {
|
|
1239
|
+
sendDate: "2023-01-01",
|
|
1240
|
+
priority: "HIGH"
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
};
|
|
1245
|
+
|
|
1246
|
+
const result = transformChannelPayload(mockData, options);
|
|
1247
|
+
|
|
1248
|
+
// Check base payload
|
|
1249
|
+
expect(result.centralCommsPayload.sourceEntityId).toEqual("action-123");
|
|
1250
|
+
expect(result.centralCommsPayload.ouId).toEqual(456);
|
|
1251
|
+
expect(result.centralCommsPayload.clientName).toEqual("TestClient");
|
|
1252
|
+
expect(result.centralCommsPayload.module).toEqual("TestModule");
|
|
1253
|
+
|
|
1254
|
+
// Check WebPush-specific content
|
|
1255
|
+
expect(result.centralCommsPayload.webpushMessageContent.channel).toEqual(WEBPUSH);
|
|
1256
|
+
expect(result.centralCommsPayload.webpushMessageContent.accountId).toEqual(12345);
|
|
1257
|
+
expect(result.centralCommsPayload.webpushMessageContent.messageSubject).toEqual(
|
|
1258
|
+
"test webpush notification"
|
|
1259
|
+
);
|
|
1260
|
+
expect(result.centralCommsPayload.webpushMessageContent.content.title).toEqual(
|
|
1261
|
+
"WebPush Title"
|
|
1262
|
+
);
|
|
1263
|
+
expect(result.centralCommsPayload.webpushMessageContent.content.message).toEqual(
|
|
1264
|
+
"WebPush Message"
|
|
1265
|
+
);
|
|
1266
|
+
expect(result.centralCommsPayload.webpushMessageContent.content.iconImageUrl).toEqual(
|
|
1267
|
+
"https://example.com/icon.png"
|
|
1268
|
+
);
|
|
1269
|
+
expect(result.centralCommsPayload.webpushMessageContent.content.cta).toEqual({
|
|
1270
|
+
actionLink: "https://example.com/action",
|
|
1271
|
+
actionText: "Click Here"
|
|
1272
|
+
});
|
|
1273
|
+
expect(result.centralCommsPayload.webpushMessageContent.content.expandableDetails).toEqual({
|
|
1274
|
+
style: "BIG_TEXT",
|
|
1275
|
+
message: "Expanded Message"
|
|
1276
|
+
});
|
|
1277
|
+
expect(result.centralCommsPayload.webpushMessageContent.offers).toEqual([
|
|
1278
|
+
{ id: "offer-1", title: "Offer 1" },
|
|
1279
|
+
{ id: "offer-2", title: "Offer 2" }
|
|
1280
|
+
]);
|
|
1281
|
+
|
|
1282
|
+
// Check delivery settings
|
|
1283
|
+
expect(result.centralCommsPayload.webpushDeliverySettings).toEqual({
|
|
1284
|
+
sendDate: "2023-01-01",
|
|
1285
|
+
priority: "HIGH"
|
|
1286
|
+
});
|
|
1287
|
+
});
|
|
1288
|
+
|
|
1289
|
+
it("should handle missing messageContent structure", () => {
|
|
1290
|
+
const mockData = {
|
|
1291
|
+
channel: WEBPUSH,
|
|
1292
|
+
messageSubject: "test webpush notification"
|
|
1293
|
+
};
|
|
1294
|
+
|
|
1295
|
+
const result = transformChannelPayload(mockData);
|
|
1296
|
+
|
|
1297
|
+
expect(result.centralCommsPayload.webpushMessageContent.accountId).toEqual(0);
|
|
1298
|
+
expect(result.centralCommsPayload.webpushMessageContent.content.title).toEqual("");
|
|
1299
|
+
expect(result.centralCommsPayload.webpushMessageContent.content.message).toEqual("");
|
|
1300
|
+
expect(result.centralCommsPayload.webpushMessageContent.offers).toEqual([]);
|
|
1301
|
+
});
|
|
1302
|
+
|
|
1303
|
+
it("should handle missing content properties", () => {
|
|
1304
|
+
const mockData = {
|
|
1305
|
+
channel: WEBPUSH,
|
|
1306
|
+
messageSubject: "test webpush notification",
|
|
1307
|
+
messageContent: {
|
|
1308
|
+
content: {
|
|
1309
|
+
accountId: 12345,
|
|
1310
|
+
content: {}
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
};
|
|
1314
|
+
|
|
1315
|
+
const result = transformChannelPayload(mockData);
|
|
1316
|
+
|
|
1317
|
+
expect(result.centralCommsPayload.webpushMessageContent.accountId).toEqual(12345);
|
|
1318
|
+
expect(result.centralCommsPayload.webpushMessageContent.content.title).toEqual("");
|
|
1319
|
+
expect(result.centralCommsPayload.webpushMessageContent.content.message).toEqual("");
|
|
1320
|
+
expect(result.centralCommsPayload.webpushMessageContent.content.iconImageUrl).toBeUndefined();
|
|
1321
|
+
expect(result.centralCommsPayload.webpushMessageContent.content.cta).toBeUndefined();
|
|
1322
|
+
expect(result.centralCommsPayload.webpushMessageContent.content.expandableDetails).toBeUndefined();
|
|
1323
|
+
});
|
|
1324
|
+
|
|
1325
|
+
it("should conditionally include iconImageUrl only when present", () => {
|
|
1326
|
+
const mockDataWithoutIcon = {
|
|
1327
|
+
channel: WEBPUSH,
|
|
1328
|
+
messageSubject: "test",
|
|
1329
|
+
messageContent: {
|
|
1330
|
+
content: {
|
|
1331
|
+
content: {
|
|
1332
|
+
title: "Title",
|
|
1333
|
+
message: "Message"
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
};
|
|
1338
|
+
|
|
1339
|
+
const resultWithoutIcon = transformChannelPayload(mockDataWithoutIcon);
|
|
1340
|
+
expect(resultWithoutIcon.centralCommsPayload.webpushMessageContent.content.iconImageUrl).toBeUndefined();
|
|
1341
|
+
|
|
1342
|
+
const mockDataWithIcon = {
|
|
1343
|
+
channel: WEBPUSH,
|
|
1344
|
+
messageSubject: "test",
|
|
1345
|
+
messageContent: {
|
|
1346
|
+
content: {
|
|
1347
|
+
content: {
|
|
1348
|
+
title: "Title",
|
|
1349
|
+
message: "Message",
|
|
1350
|
+
iconImageUrl: "https://example.com/icon.png"
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
};
|
|
1355
|
+
|
|
1356
|
+
const resultWithIcon = transformChannelPayload(mockDataWithIcon);
|
|
1357
|
+
expect(resultWithIcon.centralCommsPayload.webpushMessageContent.content.iconImageUrl).toEqual(
|
|
1358
|
+
"https://example.com/icon.png"
|
|
1359
|
+
);
|
|
1360
|
+
});
|
|
1361
|
+
|
|
1362
|
+
it("should conditionally include cta only when present", () => {
|
|
1363
|
+
const mockDataWithoutCta = {
|
|
1364
|
+
channel: WEBPUSH,
|
|
1365
|
+
messageSubject: "test",
|
|
1366
|
+
messageContent: {
|
|
1367
|
+
content: {
|
|
1368
|
+
content: {
|
|
1369
|
+
title: "Title",
|
|
1370
|
+
message: "Message"
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
};
|
|
1375
|
+
|
|
1376
|
+
const resultWithoutCta = transformChannelPayload(mockDataWithoutCta);
|
|
1377
|
+
expect(resultWithoutCta.centralCommsPayload.webpushMessageContent.content.cta).toBeUndefined();
|
|
1378
|
+
|
|
1379
|
+
const mockDataWithCta = {
|
|
1380
|
+
channel: WEBPUSH,
|
|
1381
|
+
messageSubject: "test",
|
|
1382
|
+
messageContent: {
|
|
1383
|
+
content: {
|
|
1384
|
+
content: {
|
|
1385
|
+
title: "Title",
|
|
1386
|
+
message: "Message",
|
|
1387
|
+
cta: {
|
|
1388
|
+
actionLink: "https://example.com",
|
|
1389
|
+
actionText: "Click"
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
};
|
|
1395
|
+
|
|
1396
|
+
const resultWithCta = transformChannelPayload(mockDataWithCta);
|
|
1397
|
+
expect(resultWithCta.centralCommsPayload.webpushMessageContent.content.cta).toEqual({
|
|
1398
|
+
actionLink: "https://example.com",
|
|
1399
|
+
actionText: "Click"
|
|
1400
|
+
});
|
|
1401
|
+
});
|
|
1402
|
+
|
|
1403
|
+
it("should conditionally include expandableDetails only when present", () => {
|
|
1404
|
+
const mockDataWithoutExpandable = {
|
|
1405
|
+
channel: WEBPUSH,
|
|
1406
|
+
messageSubject: "test",
|
|
1407
|
+
messageContent: {
|
|
1408
|
+
content: {
|
|
1409
|
+
content: {
|
|
1410
|
+
title: "Title",
|
|
1411
|
+
message: "Message"
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
};
|
|
1416
|
+
|
|
1417
|
+
const resultWithoutExpandable = transformChannelPayload(mockDataWithoutExpandable);
|
|
1418
|
+
expect(resultWithoutExpandable.centralCommsPayload.webpushMessageContent.content.expandableDetails).toBeUndefined();
|
|
1419
|
+
|
|
1420
|
+
const mockDataWithExpandable = {
|
|
1421
|
+
channel: WEBPUSH,
|
|
1422
|
+
messageSubject: "test",
|
|
1423
|
+
messageContent: {
|
|
1424
|
+
content: {
|
|
1425
|
+
content: {
|
|
1426
|
+
title: "Title",
|
|
1427
|
+
message: "Message",
|
|
1428
|
+
expandableDetails: {
|
|
1429
|
+
style: "BIG_TEXT",
|
|
1430
|
+
message: "Expanded"
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
};
|
|
1436
|
+
|
|
1437
|
+
const resultWithExpandable = transformChannelPayload(mockDataWithExpandable);
|
|
1438
|
+
expect(resultWithExpandable.centralCommsPayload.webpushMessageContent.content.expandableDetails).toEqual({
|
|
1439
|
+
style: "BIG_TEXT",
|
|
1440
|
+
message: "Expanded"
|
|
1441
|
+
});
|
|
1442
|
+
});
|
|
1443
|
+
|
|
1444
|
+
it("should handle undefined webpushDeliverySettings", () => {
|
|
1445
|
+
const mockData = {
|
|
1446
|
+
channel: WEBPUSH,
|
|
1447
|
+
messageSubject: "test webpush notification"
|
|
1448
|
+
};
|
|
1449
|
+
|
|
1450
|
+
const options = {
|
|
1451
|
+
loyaltyMetaData: {
|
|
1452
|
+
transformedMessageDetails: {}
|
|
1453
|
+
}
|
|
1454
|
+
};
|
|
1455
|
+
|
|
1456
|
+
const result = transformChannelPayload(mockData, options);
|
|
1457
|
+
|
|
1458
|
+
expect(result.centralCommsPayload.webpushDeliverySettings).toEqual({});
|
|
1459
|
+
});
|
|
1460
|
+
|
|
1461
|
+
it("should handle empty offers array", () => {
|
|
1462
|
+
const mockData = {
|
|
1463
|
+
channel: WEBPUSH,
|
|
1464
|
+
messageSubject: "test",
|
|
1465
|
+
messageContent: {
|
|
1466
|
+
content: {
|
|
1467
|
+
content: {
|
|
1468
|
+
title: "Title",
|
|
1469
|
+
message: "Message"
|
|
1470
|
+
},
|
|
1471
|
+
offers: []
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
};
|
|
1475
|
+
|
|
1476
|
+
const result = transformChannelPayload(mockData);
|
|
1477
|
+
|
|
1478
|
+
expect(result.centralCommsPayload.webpushMessageContent.offers).toEqual([]);
|
|
1479
|
+
});
|
|
1480
|
+
});
|
|
1481
|
+
|
|
1185
1482
|
describe("getTemplateDiffState", () => {
|
|
1186
1483
|
it("should return false for unsupported channel", () => {
|
|
1187
1484
|
const result = getTemplateDiffState("UNSUPPORTED_CHANNEL", {}, {});
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
RCS,
|
|
11
11
|
LINE,
|
|
12
12
|
VIBER,
|
|
13
|
+
WEBPUSH,
|
|
13
14
|
EMF,
|
|
14
15
|
VENENO,
|
|
15
16
|
TEXT,
|
|
@@ -63,6 +64,8 @@ export const transformChannelPayload = (data, options = {}) => {
|
|
|
63
64
|
return transformLinePayload(data, options);
|
|
64
65
|
case VIBER:
|
|
65
66
|
return transformViberPayload(data, options);
|
|
67
|
+
case WEBPUSH:
|
|
68
|
+
return transformWebpushPayload(data, options);
|
|
66
69
|
default:
|
|
67
70
|
return data; // Return unchanged for unsupported channels
|
|
68
71
|
}
|
|
@@ -317,6 +320,43 @@ const transformViberPayload = (viberData, options = {}) => {
|
|
|
317
320
|
return payload;
|
|
318
321
|
};
|
|
319
322
|
|
|
323
|
+
/**
|
|
324
|
+
* Transforms WebPush data to the required payload format
|
|
325
|
+
* @param {Object} webpushData - Current WebPush data
|
|
326
|
+
* @param {Object} options - Additional options (ouId, sourceEntityId, etc.)
|
|
327
|
+
* @returns {Object} - Transformed WebPush payload
|
|
328
|
+
*/
|
|
329
|
+
const transformWebpushPayload = (webpushData, options = {}) => {
|
|
330
|
+
const { loyaltyMetaData = {} } = options;
|
|
331
|
+
const { transformedMessageDetails = {} } = loyaltyMetaData;
|
|
332
|
+
const { webpushDeliverySettings = {} } = transformedMessageDetails || {};
|
|
333
|
+
|
|
334
|
+
// Get base payload structure
|
|
335
|
+
const payload = createBasePayload(WEBPUSH, loyaltyMetaData);
|
|
336
|
+
|
|
337
|
+
// Extract webpush content from messageContent.content.content structure
|
|
338
|
+
const webpushContent = webpushData?.messageContent?.content?.content || {};
|
|
339
|
+
const accountId = webpushData?.messageContent?.content?.accountId || 0;
|
|
340
|
+
|
|
341
|
+
// Add WebPush-specific properties
|
|
342
|
+
payload.centralCommsPayload.webpushMessageContent = {
|
|
343
|
+
channel: WEBPUSH,
|
|
344
|
+
accountId,
|
|
345
|
+
content: {
|
|
346
|
+
title: webpushContent?.title || '',
|
|
347
|
+
message: webpushContent?.message || '',
|
|
348
|
+
...(webpushContent?.iconImageUrl && { iconImageUrl: webpushContent.iconImageUrl }),
|
|
349
|
+
...(webpushContent?.cta && { cta: webpushContent.cta }),
|
|
350
|
+
...(webpushContent?.expandableDetails && { expandableDetails: webpushContent.expandableDetails }),
|
|
351
|
+
},
|
|
352
|
+
messageSubject: webpushData?.messageSubject || "",
|
|
353
|
+
offers: webpushData?.messageContent?.content?.offers || [],
|
|
354
|
+
};
|
|
355
|
+
payload.centralCommsPayload.webpushDeliverySettings = webpushDeliverySettings;
|
|
356
|
+
|
|
357
|
+
return payload;
|
|
358
|
+
};
|
|
359
|
+
|
|
320
360
|
// Checks if the template has changed
|
|
321
361
|
export const getTemplateDiffState = (channel, oldData, newData) => {
|
|
322
362
|
switch (channel.toUpperCase()) {
|
|
@@ -1051,6 +1051,8 @@ export function SlideBoxContent(props) {
|
|
|
1051
1051
|
isFullMode={isFullMode}
|
|
1052
1052
|
handleClose={handleClose}
|
|
1053
1053
|
onCreateComplete={onCreateComplete}
|
|
1054
|
+
getFormData={getFormData}
|
|
1055
|
+
isGetFormData={isGetFormData}
|
|
1054
1056
|
templateData={isEditWebPush ? templateData : undefined}
|
|
1055
1057
|
creativesMode={creativesMode}
|
|
1056
1058
|
params={isEditWebPush && templateData ? { id: templateData._id } : undefined}
|
|
@@ -50,3 +50,4 @@ export const BIG_TEXT = "BIG_TEXT";
|
|
|
50
50
|
export const GENERIC = "GENERIC";
|
|
51
51
|
export const LIQUID_ERROR_MSG = "LIQUID_ERROR_MSG";
|
|
52
52
|
export const STANDARD_ERROR_MSG = "STANDARD_ERROR_MSG";
|
|
53
|
+
export const COMMON_CHANNELS = ['sms', 'email', 'wechat', 'mobilepush', 'webpush', 'line', 'viber', 'facebook', 'call_task', 'ftp', 'assets'];
|
|
@@ -42,6 +42,7 @@ import { makeSelectFetchingCmsData } from '../Email/selectors';
|
|
|
42
42
|
import {
|
|
43
43
|
IMAGE as LINE_IMAGE, IMAGE_MAP, IMAGE_CAROUSEL, VIDEO as LINE_VIDEO, TEMPLATE, STICKER,
|
|
44
44
|
} from '../Line/Container/constants';
|
|
45
|
+
import {EXTERNAL_URL, SITE_URL, WEBPUSH_MEDIA_TYPES} from '../WebPush/constants';
|
|
45
46
|
import { IMAGE, VIDEO } from '../Facebook/Advertisement/constant';
|
|
46
47
|
import {RCS_STATUSES} from '../Rcs/constants';
|
|
47
48
|
import { CREATIVE } from '../Facebook/constants';
|
|
@@ -708,6 +709,73 @@ export class Creatives extends React.Component {
|
|
|
708
709
|
};
|
|
709
710
|
break;
|
|
710
711
|
}
|
|
712
|
+
case constants.WEBPUSH: {
|
|
713
|
+
// Convert from campaign format (messageContent.content.content) to creatives format
|
|
714
|
+
const webpushContent = get(templateData, 'content', {});
|
|
715
|
+
const accountId = get(templateData, 'accountId');
|
|
716
|
+
const {
|
|
717
|
+
title,
|
|
718
|
+
message,
|
|
719
|
+
iconImageUrl: brandIcon = "",
|
|
720
|
+
cta,
|
|
721
|
+
expandableDetails
|
|
722
|
+
} = webpushContent || {};
|
|
723
|
+
|
|
724
|
+
// Map cta to onClickAction
|
|
725
|
+
let onClickAction = null;
|
|
726
|
+
if (cta) {
|
|
727
|
+
if (cta?.type === EXTERNAL_URL) {
|
|
728
|
+
onClickAction = {
|
|
729
|
+
type: URL,
|
|
730
|
+
url: cta?.actionLink || '',
|
|
731
|
+
};
|
|
732
|
+
} else {
|
|
733
|
+
onClickAction = {
|
|
734
|
+
type: cta?.type || SITE_URL,
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// Map expandableDetails.ctas to ctas array
|
|
740
|
+
let ctas = [];
|
|
741
|
+
if (expandableDetails?.ctas && expandableDetails?.ctas?.length > 0) {
|
|
742
|
+
ctas = expandableDetails?.ctas?.map((ctaItem) => ({
|
|
743
|
+
actionText: ctaItem?.title || ctaItem?.actionText || '',
|
|
744
|
+
type: URL,
|
|
745
|
+
actionLink: ctaItem?.actionLink || '',
|
|
746
|
+
}));
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
// Map expandableDetails.media to image if present
|
|
750
|
+
let image = null;
|
|
751
|
+
if (expandableDetails?.media && expandableDetails?.media?.length > 0) {
|
|
752
|
+
const firstMedia = expandableDetails?.media[0];
|
|
753
|
+
if (firstMedia?.type === WEBPUSH_MEDIA_TYPES.IMAGE && firstMedia?.url) {
|
|
754
|
+
image = firstMedia?.url;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
creativesTemplateData = {
|
|
759
|
+
type: channel,
|
|
760
|
+
name: templateData?.messageSubject,
|
|
761
|
+
versions: {
|
|
762
|
+
base: {
|
|
763
|
+
content: {
|
|
764
|
+
webpush: {
|
|
765
|
+
title: title || '',
|
|
766
|
+
message: message || '',
|
|
767
|
+
...(brandIcon && { brandIcon }),
|
|
768
|
+
...(onClickAction && { onClickAction }),
|
|
769
|
+
...(ctas.length > 0 && { ctas }),
|
|
770
|
+
...(image && { image, mediaType: IMAGE }),
|
|
771
|
+
},
|
|
772
|
+
},
|
|
773
|
+
},
|
|
774
|
+
},
|
|
775
|
+
definition: { accountId },
|
|
776
|
+
};
|
|
777
|
+
break;
|
|
778
|
+
}
|
|
711
779
|
default:
|
|
712
780
|
break;
|
|
713
781
|
}
|
|
@@ -1122,6 +1190,105 @@ export class Creatives extends React.Component {
|
|
|
1122
1190
|
}
|
|
1123
1191
|
}
|
|
1124
1192
|
break;
|
|
1193
|
+
case constants.WEBPUSH: {
|
|
1194
|
+
if (template.value) {
|
|
1195
|
+
const channelTemplate = template.value;
|
|
1196
|
+
const accountId = get(channelTemplate, 'definition.accountId');
|
|
1197
|
+
const webpushContent = get(channelTemplate, 'versions.base.content.webpush', {});
|
|
1198
|
+
const {
|
|
1199
|
+
title,
|
|
1200
|
+
message,
|
|
1201
|
+
brandIcon,
|
|
1202
|
+
iconImageUrl: templateImageUrl ,
|
|
1203
|
+
onClickAction,
|
|
1204
|
+
ctas: templateCtas,
|
|
1205
|
+
cta: templateCta,
|
|
1206
|
+
expandableDetails: templateExpandableDetails,
|
|
1207
|
+
image
|
|
1208
|
+
} = webpushContent || {};
|
|
1209
|
+
|
|
1210
|
+
const iconImageUrl = brandIcon || templateImageUrl || '';
|
|
1211
|
+
|
|
1212
|
+
// Map onClickAction to cta
|
|
1213
|
+
let cta = null;
|
|
1214
|
+
if (onClickAction) {
|
|
1215
|
+
if (onClickAction?.type === URL) {
|
|
1216
|
+
cta = {
|
|
1217
|
+
type: EXTERNAL_URL,
|
|
1218
|
+
actionLink: onClickAction?.url || '',
|
|
1219
|
+
};
|
|
1220
|
+
} else {
|
|
1221
|
+
cta = {
|
|
1222
|
+
type: onClickAction?.type || SITE_URL,
|
|
1223
|
+
actionLink: onClickAction?.url || '',
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
} else if (templateCta) {
|
|
1227
|
+
// Fallback to cta if onClickAction is not present
|
|
1228
|
+
cta = {
|
|
1229
|
+
type: templateCta?.type || EXTERNAL_URL,
|
|
1230
|
+
actionLink: templateCta?.actionLink || '',
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
// Map ctas array to expandableDetails.ctas
|
|
1235
|
+
let expandableDetails = null;
|
|
1236
|
+
const hasCtas = templateCtas && templateCtas.length > 0;
|
|
1237
|
+
const hasImage = image;
|
|
1238
|
+
|
|
1239
|
+
if (hasCtas || hasImage) {
|
|
1240
|
+
expandableDetails = {
|
|
1241
|
+
media: [],
|
|
1242
|
+
ctas: [],
|
|
1243
|
+
};
|
|
1244
|
+
|
|
1245
|
+
// Map image to expandableDetails.media
|
|
1246
|
+
if (hasImage) {
|
|
1247
|
+
expandableDetails.media = [{
|
|
1248
|
+
url: image,
|
|
1249
|
+
type: IMAGE,
|
|
1250
|
+
}];
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
// Map ctas array to expandableDetails.ctas
|
|
1254
|
+
if (hasCtas) {
|
|
1255
|
+
expandableDetails.ctas = templateCtas.map((ctaItem) => ({
|
|
1256
|
+
type: ctaItem?.type === URL ? EXTERNAL_URL : ctaItem?.type,
|
|
1257
|
+
action: ctaItem?.action || '',
|
|
1258
|
+
title: ctaItem?.actionText || ctaItem?.title || '',
|
|
1259
|
+
actionLink: ctaItem?.actionLink || '',
|
|
1260
|
+
}));
|
|
1261
|
+
}
|
|
1262
|
+
} else if (templateExpandableDetails) {
|
|
1263
|
+
// If expandableDetails already exists, use it
|
|
1264
|
+
expandableDetails = {
|
|
1265
|
+
media: templateExpandableDetails?.media || [],
|
|
1266
|
+
ctas: templateExpandableDetails?.ctas || [],
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
// Convert from creatives format to campaign format
|
|
1271
|
+
templateData = {
|
|
1272
|
+
channel,
|
|
1273
|
+
messageContent: {
|
|
1274
|
+
content: {
|
|
1275
|
+
channel: constants.WEBPUSH,
|
|
1276
|
+
accountId,
|
|
1277
|
+
content: {
|
|
1278
|
+
title: title || '',
|
|
1279
|
+
message: message || '',
|
|
1280
|
+
...(iconImageUrl && { iconImageUrl }),
|
|
1281
|
+
...(cta && { cta }),
|
|
1282
|
+
...(expandableDetails && { expandableDetails }),
|
|
1283
|
+
},
|
|
1284
|
+
messageSubject: channelTemplate?.name ? channelTemplate.name : 'messageSubject',
|
|
1285
|
+
offers: [],
|
|
1286
|
+
},
|
|
1287
|
+
},
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
break;
|
|
1291
|
+
}
|
|
1125
1292
|
default:
|
|
1126
1293
|
break;
|
|
1127
1294
|
}
|
|
@@ -1173,6 +1340,7 @@ export class Creatives extends React.Component {
|
|
|
1173
1340
|
case constants.SMS:
|
|
1174
1341
|
case constants.WECHAT:
|
|
1175
1342
|
case constants.VIBER:
|
|
1343
|
+
case constants.WEBPUSH:
|
|
1176
1344
|
break;
|
|
1177
1345
|
case constants.EMAIL:
|
|
1178
1346
|
gtmDetails = {
|
|
@@ -62,7 +62,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
62
62
|
isEdit: false,
|
|
63
63
|
schema: {},
|
|
64
64
|
loading: false,
|
|
65
|
-
isFormValid: true,
|
|
66
65
|
injectedTags: {},
|
|
67
66
|
checkValidation: false,
|
|
68
67
|
saveEdmDataMode: 'save',
|
|
@@ -889,9 +888,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
889
888
|
return '';
|
|
890
889
|
}
|
|
891
890
|
|
|
892
|
-
setFormValidity = (
|
|
893
|
-
this.setState({isFormValid});
|
|
894
|
-
}
|
|
891
|
+
setFormValidity = () => {}
|
|
895
892
|
|
|
896
893
|
setEditData(editData) {
|
|
897
894
|
const isBEESupport = (this.props.location.query.isBEESupport !== "false") || false;
|
|
@@ -1118,7 +1115,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
1118
1115
|
isEdit: false,
|
|
1119
1116
|
schema: {},
|
|
1120
1117
|
loading: false,
|
|
1121
|
-
isFormValid: true,
|
|
1122
1118
|
injectedTags: {},
|
|
1123
1119
|
checkValidation: false,
|
|
1124
1120
|
tabKey: '',
|
|
@@ -2460,14 +2456,14 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
2460
2456
|
}
|
|
2461
2457
|
|
|
2462
2458
|
saveFormData = (passedData) => {
|
|
2463
|
-
//saveFormData gets called only when validation result is true
|
|
2464
2459
|
if (this.state.gettingFormData && !this.props.isFullMode) {
|
|
2465
2460
|
const response = {
|
|
2466
2461
|
action: "getFormData",
|
|
2467
2462
|
postAction: this.state.getFormDataValue || 'next',
|
|
2468
2463
|
id: _.get(this.props, 'Email.templateDetails._id', ''),
|
|
2469
2464
|
value: this.transformFormData(passedData),
|
|
2470
|
-
|
|
2465
|
+
//saveFormData gets called only when validation result is true
|
|
2466
|
+
validity: true,
|
|
2471
2467
|
type: 'EMAIL',
|
|
2472
2468
|
};
|
|
2473
2469
|
|
|
@@ -34,7 +34,7 @@ import { CREATIVES_UI_VIEW, LOYALTY, WHATSAPP, RCS, LINE, EMAIL, ASSETS, JP_LOCA
|
|
|
34
34
|
import AccessForbidden from '../../v2Components/AccessForbidden';
|
|
35
35
|
import { getObjFromQueryParams } from '../../utils/v2common';
|
|
36
36
|
import { makeSelectAuthenticated, selectCurrentOrgDetails } from "../../v2Containers/Cap/selectors";
|
|
37
|
-
import { LOYALTY_SUPPORTED_ACTION } from "../CreativesContainer/constants";
|
|
37
|
+
import { LOYALTY_SUPPORTED_ACTION, COMMON_CHANNELS } from "../CreativesContainer/constants";
|
|
38
38
|
|
|
39
39
|
const {CapCustomCardList} = CapCustomCard;
|
|
40
40
|
|
|
@@ -66,7 +66,7 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
66
66
|
//'wechat': {content: this.getTemplatesComponent('wechat'), tab: 'Wechat', key: 'wechat'},
|
|
67
67
|
mPush: {content: <></>, tab: intl.formatMessage(messages.pushNotification), key: 'mobilepush'},
|
|
68
68
|
...(commonUtil.hasWebPushFeatureEnabled() ? {
|
|
69
|
-
|
|
69
|
+
webpush: {
|
|
70
70
|
content: <div></div>,
|
|
71
71
|
tab: intl.formatMessage(messages.webPush),
|
|
72
72
|
key: WEBPUSH,
|
|
@@ -95,7 +95,7 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
95
95
|
return obj;
|
|
96
96
|
}, []);
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
if (isFullMode ) {
|
|
99
99
|
filteredPanes.push({content: <div></div>, tab: intl.formatMessage(messages.gallery), key: 'assets'});
|
|
100
100
|
} else {
|
|
101
101
|
if (!channelsToHide.includes('callTask')) {
|
|
@@ -105,18 +105,19 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
105
105
|
filteredPanes.push({content: <></>, tab: intl.formatMessage(messages.FTP), key: 'ftp'});
|
|
106
106
|
defaultChannel = 'FTP';
|
|
107
107
|
}
|
|
108
|
-
const commonChannels = ['sms', 'email', 'wechat', 'mobilepush', 'line', 'viber', 'facebook', 'call_task', 'ftp', 'assets'];
|
|
109
108
|
|
|
109
|
+
// Create a local copy of COMMON_CHANNELS to avoid mutating the imported array
|
|
110
|
+
const channels = [...COMMON_CHANNELS];
|
|
110
111
|
const { actionName = ''} = loyaltyMetaData;
|
|
111
112
|
if (isLoyaltyModule && actionName === LOYALTY_SUPPORTED_ACTION) {
|
|
112
|
-
|
|
113
|
+
channels.push(WHATSAPP, ZALO);
|
|
113
114
|
}
|
|
114
115
|
|
|
115
|
-
// we only show channels which other than
|
|
116
|
+
// we only show channels which other than COMMON_CHANNELS
|
|
116
117
|
// if it is coming in enableNewChannels array
|
|
117
118
|
filteredPanes = filteredPanes.filter((item) => {
|
|
118
119
|
const channel = item.key;
|
|
119
|
-
if (!
|
|
120
|
+
if (!channels.includes(channel)) {
|
|
120
121
|
return enableNewChannels.includes(channel.toUpperCase());
|
|
121
122
|
}
|
|
122
123
|
return true;
|