@capillarytech/creatives-library 8.0.186 → 8.0.187
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/config/app.js +0 -1
- package/package.json +1 -1
- package/services/api.js +0 -1
- package/v2Components/CapActionButton/index.js +3 -1
- package/v2Containers/CreativesContainer/SlideBoxContent.js +0 -4
- package/v2Containers/CreativesContainer/index.js +10 -29
- package/v2Containers/Rcs/index.js +257 -53
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +1680 -0
- package/v2Containers/Whatsapp/constants.js +1 -22
- package/v2Containers/Whatsapp/index.js +1 -14
package/config/app.js
CHANGED
|
@@ -21,7 +21,6 @@ const config = {
|
|
|
21
21
|
},
|
|
22
22
|
development: {
|
|
23
23
|
api_endpoint: 'https://crm-nightly-new.cc.capillarytech.com/arya/api/v1/creatives',
|
|
24
|
-
// api_endpoint: 'http://localhost:2022/arya/api/v1/creatives',
|
|
25
24
|
campaigns_api_endpoint: 'https://crm-nightly-new.cc.capillarytech.com/iris/v2/campaigns',
|
|
26
25
|
campaigns_api_org_endpoint: 'https://crm-nightly-new.cc.capillarytech.com/iris/v2/org/campaign',
|
|
27
26
|
auth_endpoint: 'https://crm-nightly-new.cc.capillarytech.com/arya/api/v1/auth',
|
package/package.json
CHANGED
package/services/api.js
CHANGED
|
@@ -264,7 +264,6 @@ export const getUserData = () => {
|
|
|
264
264
|
|
|
265
265
|
export const createTemplate = ({template}) => {
|
|
266
266
|
const url = `${API_ENDPOINT}/templates/SMS`;
|
|
267
|
-
console.log("creating template",template);
|
|
268
267
|
return request(url, getAPICallObject('POST', template));
|
|
269
268
|
};
|
|
270
269
|
|
|
@@ -83,7 +83,9 @@ export const CapActionButton = (props) => {
|
|
|
83
83
|
const onButtonTextChange = ({target}) => {
|
|
84
84
|
const { value, id } = target;
|
|
85
85
|
let errorMessage = '';
|
|
86
|
-
if (
|
|
86
|
+
if (value.length > BTN_MAX_LENGTH) {
|
|
87
|
+
errorMessage = formatMessage(messages.ctaButtonTextLengthError);
|
|
88
|
+
} if (!isValidText(value)) {
|
|
87
89
|
errorMessage = formatMessage(messages.ctaButtonErrorMessage);
|
|
88
90
|
}
|
|
89
91
|
setButtonError(errorMessage);
|
|
@@ -378,7 +378,6 @@ export function SlideBoxContent(props) {
|
|
|
378
378
|
};
|
|
379
379
|
}
|
|
380
380
|
case constants.RCS: {
|
|
381
|
-
console.log("in slidebox content .js");
|
|
382
381
|
const template = cloneDeep(templateDataObject);
|
|
383
382
|
const { description = "", media: { mediaUrl = "" } = {}, title = "", suggestions = [] } = get(template, 'versions.base.content.RCS.rcsContent.cardContent[0]', {});
|
|
384
383
|
return {
|
|
@@ -393,10 +392,7 @@ export function SlideBoxContent(props) {
|
|
|
393
392
|
};
|
|
394
393
|
}
|
|
395
394
|
default:
|
|
396
|
-
{
|
|
397
|
-
console.log("in default case");
|
|
398
395
|
return get(templateDataObject, `versions.base.content`);
|
|
399
|
-
}
|
|
400
396
|
}
|
|
401
397
|
};
|
|
402
398
|
|
|
@@ -633,34 +633,7 @@ export class Creatives extends React.Component {
|
|
|
633
633
|
channel = constants.RCS,
|
|
634
634
|
} = templateData || {};
|
|
635
635
|
const cardContent = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
|
|
636
|
-
const
|
|
637
|
-
const reverseMapText = (text, cardVarMapped) => {
|
|
638
|
-
if (!text || !cardVarMapped || Object.keys(cardVarMapped).length === 0) {
|
|
639
|
-
return text;
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
let reversedText = text;
|
|
643
|
-
Object.entries(cardVarMapped).forEach(([key, value]) => {
|
|
644
|
-
const cleanValue = value.replace(/^\{\{|\}\}$/g, '');
|
|
645
|
-
const valuePattern = new RegExp(`\\{\\{${cleanValue}\\}\\}`, 'g');
|
|
646
|
-
reversedText = reversedText.replace(valuePattern, `{{${key}}}`);
|
|
647
|
-
});
|
|
648
|
-
return reversedText;
|
|
649
|
-
};
|
|
650
|
-
|
|
651
|
-
const updatedRcsContent = {
|
|
652
|
-
...rcsContent,
|
|
653
|
-
cardContent: [
|
|
654
|
-
{
|
|
655
|
-
...cardContent,
|
|
656
|
-
Status: RCS_STATUSES.approved,
|
|
657
|
-
title: reverseMapText(cardContent.title, cardVarMapped),
|
|
658
|
-
description: reverseMapText(cardContent.description, cardVarMapped),
|
|
659
|
-
cardVarMapped: {},
|
|
660
|
-
},
|
|
661
|
-
...(rcsContent.cardContent?.slice(1) || []),
|
|
662
|
-
],
|
|
663
|
-
};
|
|
636
|
+
const Status = RCS_STATUSES.approved || '';
|
|
664
637
|
|
|
665
638
|
creativesTemplateData = {
|
|
666
639
|
type: channel,
|
|
@@ -670,7 +643,15 @@ export class Creatives extends React.Component {
|
|
|
670
643
|
base: {
|
|
671
644
|
content: {
|
|
672
645
|
RCS: {
|
|
673
|
-
rcsContent:
|
|
646
|
+
rcsContent: {
|
|
647
|
+
...rcsContent,
|
|
648
|
+
cardContent: [
|
|
649
|
+
{
|
|
650
|
+
...cardContent,
|
|
651
|
+
Status,
|
|
652
|
+
},
|
|
653
|
+
],
|
|
654
|
+
},
|
|
674
655
|
smsFallBackContent,
|
|
675
656
|
},
|
|
676
657
|
},
|
|
@@ -298,7 +298,7 @@ export const Rcs = (props) => {
|
|
|
298
298
|
// );
|
|
299
299
|
// }
|
|
300
300
|
if (type === titletype) {
|
|
301
|
-
const
|
|
301
|
+
const errorMsg =
|
|
302
302
|
(unsupportedTagsLengthCheck &&
|
|
303
303
|
formatMessage(globalMessages.unsupportedTagsValidationError, {
|
|
304
304
|
unsupportedTags: validationResponse.unsupportedTags,
|
|
@@ -306,10 +306,10 @@ export const Rcs = (props) => {
|
|
|
306
306
|
(validationResponse.isBraceError &&
|
|
307
307
|
formatMessage(globalMessages.unbalanacedCurlyBraces)) ||
|
|
308
308
|
false;
|
|
309
|
-
|
|
310
|
-
setTemplateTitleError(
|
|
309
|
+
// Only update if changed to prevent flicker
|
|
310
|
+
setTemplateTitleError((prev) => (prev !== errorMsg ? errorMsg : prev));
|
|
311
311
|
} else if (type === descType) {
|
|
312
|
-
const
|
|
312
|
+
const errorMsg =
|
|
313
313
|
(unsupportedTagsLengthCheck &&
|
|
314
314
|
formatMessage(globalMessages.unsupportedTagsValidationError, {
|
|
315
315
|
unsupportedTags: validationResponse.unsupportedTags,
|
|
@@ -317,18 +317,29 @@ export const Rcs = (props) => {
|
|
|
317
317
|
(validationResponse.isBraceError &&
|
|
318
318
|
formatMessage(globalMessages.unbalanacedCurlyBraces)) ||
|
|
319
319
|
false;
|
|
320
|
-
|
|
321
|
-
setTemplateDescError(error);
|
|
320
|
+
setTemplateDescError((prev) => (prev !== errorMsg ? errorMsg : prev));
|
|
322
321
|
}
|
|
323
322
|
};
|
|
324
323
|
|
|
325
324
|
useEffect(() => {
|
|
326
|
-
|
|
327
|
-
|
|
325
|
+
const hasInteraction = !isEmpty(cardVarMapped) || Object.values(rcsTextVariables || {}).some(group => Object.values(group || {}).some(v => (v || '').trim() !== ''));
|
|
326
|
+
if (!hasInteraction) {
|
|
327
|
+
setTemplateTitleError(false);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
const mapped = getMappedDesc(templateTitle, cardVarMapped);
|
|
331
|
+
tagValidation(mapped, titletype);
|
|
332
|
+
}, [templateTitle, tags, injectedTags, cardVarMapped, rcsTextVariables]);
|
|
328
333
|
|
|
329
334
|
useEffect(() => {
|
|
330
|
-
|
|
331
|
-
|
|
335
|
+
const hasInteraction = !isEmpty(cardVarMapped) || Object.values(rcsTextVariables || {}).some(group => Object.values(group || {}).some(v => (v || '').trim() !== ''));
|
|
336
|
+
if (!hasInteraction) {
|
|
337
|
+
setTemplateDescError(false);
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
const mapped = getMappedDesc(templateDesc, cardVarMapped);
|
|
341
|
+
tagValidation(mapped, descType);
|
|
342
|
+
}, [templateDesc, tags, injectedTags, cardVarMapped, rcsTextVariables]);
|
|
332
343
|
|
|
333
344
|
|
|
334
345
|
const RcsLabel = styled.div`
|
|
@@ -384,6 +395,33 @@ export const Rcs = (props) => {
|
|
|
384
395
|
return updated;
|
|
385
396
|
});
|
|
386
397
|
}, [templateTitle]);
|
|
398
|
+
|
|
399
|
+
// Prefill variable inputs from existing mapping on load/edit
|
|
400
|
+
useEffect(() => {
|
|
401
|
+
if (!templateTitle && !templateDesc) return;
|
|
402
|
+
const buildPrefill = (targetString) => {
|
|
403
|
+
const arr = splitTemplateVarString(targetString);
|
|
404
|
+
const pre = {};
|
|
405
|
+
arr.forEach((elem, idx) => {
|
|
406
|
+
if (rcsVarTestRegex.test(elem)) {
|
|
407
|
+
const varName = elem.replace(/^\{\{|\}\}$/g, '');
|
|
408
|
+
const mapped = cardVarMapped[varName] ?? cardVarMapped[elem];
|
|
409
|
+
if (mapped) {
|
|
410
|
+
pre[idx] = /^\{\{[\s\S]*\}\}$/.test(mapped) ? mapped : `{{${mapped}}}`;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
return pre;
|
|
415
|
+
};
|
|
416
|
+
const prefilledTitle = buildPrefill(templateTitle);
|
|
417
|
+
const prefilledDesc = buildPrefill(templateDesc);
|
|
418
|
+
if (Object.keys(prefilledTitle).length === 0 && Object.keys(prefilledDesc).length === 0) return;
|
|
419
|
+
setRcsTextVariables(prev => ({
|
|
420
|
+
...prev,
|
|
421
|
+
[TITLE_TEXT]: { ...(prev[TITLE_TEXT] || {}), ...prefilledTitle },
|
|
422
|
+
[MESSAGE_TEXT]: { ...(prev[MESSAGE_TEXT] || {}), ...prefilledDesc },
|
|
423
|
+
}));
|
|
424
|
+
}, [templateTitle, templateDesc, cardVarMapped]);
|
|
387
425
|
|
|
388
426
|
useEffect(() => {
|
|
389
427
|
if(!isEditFlow && isFullMode){
|
|
@@ -477,8 +515,13 @@ export const Rcs = (props) => {
|
|
|
477
515
|
}
|
|
478
516
|
setEditFlow(true);
|
|
479
517
|
setTemplateName(details.name || '');
|
|
480
|
-
|
|
481
|
-
|
|
518
|
+
const loadedTitle = get(details, 'versions.base.content.RCS.rcsContent.cardContent[0].title', '');
|
|
519
|
+
const loadedDesc = get(details, 'versions.base.content.RCS.rcsContent.cardContent[0].description', '');
|
|
520
|
+
const loadedMap = get(details, 'versions.base.content.RCS.rcsContent.cardContent[0].cardVarMapped', {});
|
|
521
|
+
const normalizedTitle = (!isFullMode && !isEmpty(loadedMap)) ? getUnmappedDesc(loadedTitle, loadedMap) : loadedTitle;
|
|
522
|
+
const normalizedDesc = (!isFullMode && !isEmpty(loadedMap)) ? getUnmappedDesc(loadedDesc, loadedMap) : loadedDesc;
|
|
523
|
+
setTemplateTitle(normalizedTitle);
|
|
524
|
+
setTemplateDesc(normalizedDesc);
|
|
482
525
|
setSuggestions(get(details, 'versions.base.content.RCS.rcsContent.cardContent[0].suggestions', []));
|
|
483
526
|
templateStatusHelper(details);
|
|
484
527
|
const mediaData = get(details, 'versions.base.content.RCS.rcsContent.cardContent[0].media', '');
|
|
@@ -556,44 +599,99 @@ export const Rcs = (props) => {
|
|
|
556
599
|
};
|
|
557
600
|
|
|
558
601
|
const onTagSelect = (tag) => {
|
|
602
|
+
// Determine target input (index and type). If nothing focused, pick the first available variable slot.
|
|
603
|
+
let targetType = focusedVarType;
|
|
604
|
+
let targetIndex;
|
|
605
|
+
let tokenAtIndex = '';
|
|
559
606
|
if (!focusedVarId) {
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
607
|
+
// Try description first
|
|
608
|
+
const descArray = splitTemplateVarString(templateDesc);
|
|
609
|
+
let found = false;
|
|
610
|
+
for (let i = 0; i < descArray.length; i += 1) {
|
|
611
|
+
const elem = descArray[i];
|
|
612
|
+
if (rcsVarTestRegex.test(elem)) {
|
|
613
|
+
const currentVal = (rcsTextVariables?.[MESSAGE_TEXT]?.[i]) || '';
|
|
614
|
+
if (!currentVal) {
|
|
615
|
+
targetType = MESSAGE_TEXT;
|
|
616
|
+
targetIndex = i;
|
|
617
|
+
tokenAtIndex = elem;
|
|
618
|
+
found = true;
|
|
619
|
+
break;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
// If no empty slot in description, try title
|
|
624
|
+
if (!found) {
|
|
625
|
+
const titleArray = splitTemplateVarString(templateTitle);
|
|
626
|
+
for (let i = 0; i < titleArray.length; i += 1) {
|
|
627
|
+
const elem = titleArray[i];
|
|
628
|
+
if (rcsVarTestRegex.test(elem)) {
|
|
629
|
+
const currentVal = (rcsTextVariables?.[TITLE_TEXT]?.[i]) || '';
|
|
630
|
+
if (!currentVal) {
|
|
631
|
+
targetType = TITLE_TEXT;
|
|
632
|
+
targetIndex = i;
|
|
633
|
+
tokenAtIndex = elem;
|
|
634
|
+
found = true;
|
|
635
|
+
break;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
if (!targetType || targetIndex === undefined) {
|
|
641
|
+
CapNotification.error({
|
|
642
|
+
message: formatMessage(messages.noVariableFocused) || "Please select a variable to insert the label.",
|
|
643
|
+
});
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
} else {
|
|
647
|
+
targetIndex = parseInt(focusedVarId.split('_').pop(), 10);
|
|
648
|
+
const arr = splitTemplateVarString(targetType === TITLE_TEXT ? templateTitle : templateDesc);
|
|
649
|
+
tokenAtIndex = arr[targetIndex] || '';
|
|
564
650
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
[index]: `{{${tag}}}`,
|
|
576
|
-
},
|
|
577
|
-
};
|
|
578
|
-
return newState;
|
|
579
|
-
});
|
|
651
|
+
|
|
652
|
+
// Update the visual input field
|
|
653
|
+
setRcsTextVariables((prev) => ({
|
|
654
|
+
...prev,
|
|
655
|
+
[targetType]: {
|
|
656
|
+
...(prev[targetType] || {}),
|
|
657
|
+
[targetIndex]: `{{${tag}}}`,
|
|
658
|
+
},
|
|
659
|
+
}));
|
|
660
|
+
|
|
580
661
|
// Store the variable-to-tag mapping
|
|
581
|
-
setCardVarMapped(prev => {
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
662
|
+
setCardVarMapped((prev) => {
|
|
663
|
+
// Determine stable variable name
|
|
664
|
+
const defaultVarName = (focusedVarId ? focusedVarId.split('_')[0] : tokenAtIndex).replace(/^\{\{|\}\}$/g, '');
|
|
665
|
+
const tokenName = tokenAtIndex.replace(/^\{\{|\}\}$/g, '');
|
|
666
|
+
|
|
667
|
+
// If this template had been saved with resolved tags, infer original key via inverse lookup
|
|
668
|
+
let variableName = defaultVarName;
|
|
669
|
+
if (prev && Object.keys(prev).length > 0) {
|
|
670
|
+
const entry = Object.entries(prev).find(([, v]) => {
|
|
671
|
+
const val = v || '';
|
|
672
|
+
const braced = /^\{\{[\s\S]*\}\}$/.test(val) ? val : `{{${val}}}`;
|
|
673
|
+
return braced === `{{${tokenName}}}`;
|
|
674
|
+
});
|
|
675
|
+
if (entry) {
|
|
676
|
+
const [keyFromMap] = entry;
|
|
677
|
+
variableName = keyFromMap;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
const mappedValue = isFullMode ? tag : `{{${tag}}}`;
|
|
682
|
+
|
|
683
|
+
// Clean up any accidental keys equal to the tag token name (e.g., 'gt') to avoid duplicates
|
|
684
|
+
const cleaned = { ...prev };
|
|
685
|
+
if (tokenName && Object.prototype.hasOwnProperty.call(cleaned, tokenName)) {
|
|
686
|
+
delete cleaned[tokenName];
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
return {
|
|
690
|
+
...cleaned,
|
|
691
|
+
[variableName]: mappedValue,
|
|
593
692
|
};
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
693
|
+
});
|
|
694
|
+
|
|
597
695
|
};
|
|
598
696
|
|
|
599
697
|
const onTagSelectFallback = (data) => {
|
|
@@ -907,15 +1005,32 @@ const splitTemplateVarString = (str) => {
|
|
|
907
1005
|
});
|
|
908
1006
|
|
|
909
1007
|
if (type === TITLE_TEXT) {
|
|
910
|
-
|
|
911
|
-
|
|
1008
|
+
// Only run tag-based validation to avoid flicker from multiple setters
|
|
1009
|
+
tagValidation(reconstructed, titletype);
|
|
912
1010
|
} else {
|
|
913
|
-
|
|
914
|
-
|
|
1011
|
+
// Only run tag-based validation to avoid flicker from multiple setters
|
|
1012
|
+
tagValidation(reconstructed, descType);
|
|
915
1013
|
}
|
|
916
1014
|
|
|
917
1015
|
return updated;
|
|
918
1016
|
});
|
|
1017
|
+
|
|
1018
|
+
// Keep mapping in sync with what user types in the variable input
|
|
1019
|
+
const targetStringForMap = type === TITLE_TEXT ? templateTitle : templateDesc;
|
|
1020
|
+
const arrForMap = splitTemplateVarString(targetStringForMap);
|
|
1021
|
+
const token = arrForMap[index] || '';
|
|
1022
|
+
if (rcsVarTestRegex.test(token)) {
|
|
1023
|
+
const variableName = token.replace(/^\{\{|\}\}$/g, '');
|
|
1024
|
+
const normalized = value
|
|
1025
|
+
? (/^\{\{[\s\S]*\}\}$/.test(value) ? value : `{{${value}}}`)
|
|
1026
|
+
: '';
|
|
1027
|
+
setCardVarMapped(prev => {
|
|
1028
|
+
const next = { ...prev };
|
|
1029
|
+
// Keep the variable key even when empty; store empty string as value
|
|
1030
|
+
next[variableName] = (normalized && normalized.trim() !== '') ? normalized : '';
|
|
1031
|
+
return next;
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
919
1034
|
};
|
|
920
1035
|
|
|
921
1036
|
const setTextAreaId = (e, type) => {
|
|
@@ -1055,6 +1170,11 @@ const splitTemplateVarString = (str) => {
|
|
|
1055
1170
|
/>
|
|
1056
1171
|
)}
|
|
1057
1172
|
</div>
|
|
1173
|
+
{(isEditFlow || !isFullMode) && templateTitleError && (
|
|
1174
|
+
<CapError className="rcs-template-title-error">
|
|
1175
|
+
{templateTitleError}
|
|
1176
|
+
</CapError>
|
|
1177
|
+
)}
|
|
1058
1178
|
</>
|
|
1059
1179
|
)}
|
|
1060
1180
|
|
|
@@ -1138,6 +1258,11 @@ const splitTemplateVarString = (str) => {
|
|
|
1138
1258
|
)
|
|
1139
1259
|
}
|
|
1140
1260
|
</div>
|
|
1261
|
+
{(isEditFlow || !isFullMode) && templateDescError && (
|
|
1262
|
+
<CapError className="rcs-template-message-error">
|
|
1263
|
+
{templateDescError}
|
|
1264
|
+
</CapError>
|
|
1265
|
+
)}
|
|
1141
1266
|
</CapRow>
|
|
1142
1267
|
{renderButtonComponent()}
|
|
1143
1268
|
</>
|
|
@@ -1674,8 +1799,9 @@ const splitTemplateVarString = (str) => {
|
|
|
1674
1799
|
const getRcsPreview = () => {
|
|
1675
1800
|
|
|
1676
1801
|
const dimensionObj = RCS_IMAGE_DIMENSIONS[selectedDimension];
|
|
1677
|
-
|
|
1678
|
-
const
|
|
1802
|
+
// Always show resolved values in preview
|
|
1803
|
+
const mappedDesc = getMappedDesc(templateDesc, cardVarMapped);
|
|
1804
|
+
const mappedTitle = getMappedDesc(templateTitle, cardVarMapped);
|
|
1679
1805
|
return (
|
|
1680
1806
|
<TemplatePreview
|
|
1681
1807
|
channel={RCS}
|
|
@@ -1712,6 +1838,21 @@ const splitTemplateVarString = (str) => {
|
|
|
1712
1838
|
return elem;
|
|
1713
1839
|
}).join('');
|
|
1714
1840
|
};
|
|
1841
|
+
|
|
1842
|
+
const getUnmappedDesc = (str, mapping) => {
|
|
1843
|
+
if (!str) return '';
|
|
1844
|
+
if (!mapping || Object.keys(mapping).length === 0) return str;
|
|
1845
|
+
let result = str;
|
|
1846
|
+
Object.keys(mapping).forEach((key) => {
|
|
1847
|
+
const value = mapping[key];
|
|
1848
|
+
if (!value) return;
|
|
1849
|
+
const bracedValue = /^\{\{[\s\S]*\}\}$/.test(value) ? value : `{{${value}}}`;
|
|
1850
|
+
const escaped = bracedValue.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
1851
|
+
const regex = new RegExp(escaped, 'g');
|
|
1852
|
+
result = result.replace(regex, `{{${key}}}`);
|
|
1853
|
+
});
|
|
1854
|
+
return result;
|
|
1855
|
+
};
|
|
1715
1856
|
|
|
1716
1857
|
const createPayload = () => {
|
|
1717
1858
|
const base = get(dltEditData, `versions.base`, {});
|
|
@@ -1843,6 +1984,37 @@ const splitTemplateVarString = (str) => {
|
|
|
1843
1984
|
}
|
|
1844
1985
|
}
|
|
1845
1986
|
|
|
1987
|
+
if(!isFullMode){
|
|
1988
|
+
const titleVars = splitTemplateVarString(templateTitle).filter(elem => rcsVarTestRegex.test(elem)).map(v => v.replace(/^\{\{|\}\}$/g, ''));
|
|
1989
|
+
const descVars = splitTemplateVarString(templateDesc).filter(elem => rcsVarTestRegex.test(elem)).map(v => v.replace(/^\{\{|\}\}$/g, ''));
|
|
1990
|
+
const allVars = Array.from(new Set([ ...titleVars, ...descVars ]));
|
|
1991
|
+
|
|
1992
|
+
if (allVars.length > 0 && isEmpty(cardVarMapped)) {
|
|
1993
|
+
return true;
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
const hasEmptyMapping =
|
|
1997
|
+
cardVarMapped &&
|
|
1998
|
+
Object.keys(cardVarMapped).length > 0 &&
|
|
1999
|
+
Object.entries(cardVarMapped).some(([_, v]) => {
|
|
2000
|
+
if (typeof v !== 'string') return !v; // null/undefined
|
|
2001
|
+
return v.trim() === ''; // empty string
|
|
2002
|
+
});
|
|
2003
|
+
|
|
2004
|
+
if (hasEmptyMapping) {
|
|
2005
|
+
return true;
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
const anyMissing = allVars.some(name => {
|
|
2009
|
+
const v = cardVarMapped?.[name];
|
|
2010
|
+
if (typeof v !== 'string') return !v;
|
|
2011
|
+
return v.trim() === '';
|
|
2012
|
+
});
|
|
2013
|
+
if (anyMissing) {
|
|
2014
|
+
return true;
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
|
|
1846
2018
|
if (isMediaTypeText && templateDesc.trim() === '') {
|
|
1847
2019
|
console.log("isMediaTypeText", isMediaTypeText);
|
|
1848
2020
|
console.log("templateDesc", templateDesc);
|
|
@@ -1869,7 +2041,7 @@ const splitTemplateVarString = (str) => {
|
|
|
1869
2041
|
return true;
|
|
1870
2042
|
}
|
|
1871
2043
|
}
|
|
1872
|
-
if (templateDescError || fallbackMessageError) {
|
|
2044
|
+
if (templateDescError || templateTitleError || fallbackMessageError) {
|
|
1873
2045
|
console.log("disabled becuase template desc or fallback message has error");
|
|
1874
2046
|
return true;
|
|
1875
2047
|
}
|
|
@@ -1887,7 +2059,36 @@ const splitTemplateVarString = (str) => {
|
|
|
1887
2059
|
return true;
|
|
1888
2060
|
}
|
|
1889
2061
|
}
|
|
2062
|
+
if(!isFullMode){
|
|
2063
|
+
const titleVars = splitTemplateVarString(templateTitle).filter(elem => rcsVarTestRegex.test(elem)).map(v => v.replace(/^\{\{|\}\}$/g, ''));
|
|
2064
|
+
const descVars = splitTemplateVarString(templateDesc).filter(elem => rcsVarTestRegex.test(elem)).map(v => v.replace(/^\{\{|\}\}$/g, ''));
|
|
2065
|
+
const allVars = Array.from(new Set([ ...titleVars, ...descVars ]));
|
|
2066
|
+
|
|
2067
|
+
if (allVars.length > 0 && isEmpty(cardVarMapped)) {
|
|
2068
|
+
return true;
|
|
2069
|
+
}
|
|
1890
2070
|
|
|
2071
|
+
const hasEmptyMapping =
|
|
2072
|
+
cardVarMapped &&
|
|
2073
|
+
Object.keys(cardVarMapped).length > 0 &&
|
|
2074
|
+
Object.entries(cardVarMapped).some(([_, v]) => {
|
|
2075
|
+
if (typeof v !== 'string') return !v; // null/undefined
|
|
2076
|
+
return v.trim() === ''; // empty string
|
|
2077
|
+
});
|
|
2078
|
+
|
|
2079
|
+
if (hasEmptyMapping) {
|
|
2080
|
+
return true;
|
|
2081
|
+
}
|
|
2082
|
+
|
|
2083
|
+
const anyMissing = allVars.some(name => {
|
|
2084
|
+
const v = cardVarMapped?.[name];
|
|
2085
|
+
if (typeof v !== 'string') return !v;
|
|
2086
|
+
return v.trim() === '';
|
|
2087
|
+
});
|
|
2088
|
+
if (anyMissing) {
|
|
2089
|
+
return true;
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
1891
2092
|
if (isMediaTypeText && templateDesc.trim() === '') {
|
|
1892
2093
|
console.log('disabled becuase template desc is empty');
|
|
1893
2094
|
return true;
|
|
@@ -1910,6 +2111,9 @@ const splitTemplateVarString = (str) => {
|
|
|
1910
2111
|
return true;
|
|
1911
2112
|
}
|
|
1912
2113
|
}
|
|
2114
|
+
if (templateTitleError || templateDescError || fallbackMessageError) {
|
|
2115
|
+
return true;
|
|
2116
|
+
}
|
|
1913
2117
|
return false;
|
|
1914
2118
|
};
|
|
1915
2119
|
|