@capillarytech/creatives-library 8.0.291 → 8.0.292-alpha.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/constants/unified.js +3 -1
- package/initialState.js +0 -2
- package/package.json +1 -1
- package/utils/common.js +5 -8
- package/utils/commonUtils.js +4 -85
- package/utils/tagValidations.js +83 -223
- package/utils/tests/commonUtil.test.js +147 -124
- package/utils/tests/tagValidations.test.js +441 -358
- package/v2Components/ErrorInfoNote/index.js +2 -5
- package/v2Components/FormBuilder/index.js +137 -203
- package/v2Components/FormBuilder/messages.js +0 -8
- package/v2Components/HtmlEditor/HTMLEditor.js +0 -5
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +0 -1
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +0 -15
- package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +1 -2
- package/v2Containers/Cap/mockData.js +0 -14
- package/v2Containers/Cap/reducer.js +3 -55
- package/v2Containers/Cap/tests/reducer.test.js +0 -102
- package/v2Containers/CreativesContainer/SlideBoxContent.js +5 -1
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +13 -5
- package/v2Containers/CreativesContainer/index.js +30 -7
- package/v2Containers/Email/index.js +1 -5
- package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +23 -70
- package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +29 -137
- package/v2Containers/FTP/index.js +2 -51
- package/v2Containers/FTP/messages.js +0 -4
- package/v2Containers/InApp/index.js +4 -104
- package/v2Containers/InApp/tests/index.test.js +17 -6
- package/v2Containers/InappAdvance/index.js +4 -108
- package/v2Containers/InappAdvance/tests/index.test.js +2 -0
- package/v2Containers/Line/Container/Text/index.js +0 -1
- package/v2Containers/MobilePush/Create/index.js +42 -19
- package/v2Containers/MobilePush/Edit/index.js +42 -19
- package/v2Containers/MobilePushNew/index.js +12 -32
- package/v2Containers/MobilepushWrapper/index.js +3 -1
- package/v2Containers/Rcs/index.js +12 -37
- package/v2Containers/Sms/Create/index.js +39 -3
- package/v2Containers/Sms/Create/messages.js +4 -0
- package/v2Containers/Sms/Edit/index.js +35 -3
- package/v2Containers/Sms/commonMethods.js +3 -6
- package/v2Containers/Sms/tests/commonMethods.test.js +122 -0
- package/v2Containers/SmsTrai/Edit/index.js +11 -47
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +6 -6
- package/v2Containers/SmsWrapper/index.js +2 -0
- package/v2Containers/Viber/index.js +0 -1
- package/v2Containers/WebPush/Create/hooks/useTagManagement.js +1 -3
- package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +0 -7
- package/v2Containers/WebPush/Create/index.js +2 -2
- package/v2Containers/WebPush/Create/utils/validation.js +17 -2
- package/v2Containers/WebPush/Create/utils/validation.test.js +59 -24
- package/v2Containers/Whatsapp/index.js +9 -17
- package/v2Containers/Zalo/index.js +3 -11
|
@@ -4265,7 +4265,7 @@ FREE GIFTS-
|
|
|
4265
4265
|
<CapCheckbox
|
|
4266
4266
|
checked={false}
|
|
4267
4267
|
disabled={false}
|
|
4268
|
-
key=".
|
|
4268
|
+
key=".3"
|
|
4269
4269
|
labelType="h4"
|
|
4270
4270
|
onChange={[Function]}
|
|
4271
4271
|
>
|
|
@@ -4327,7 +4327,7 @@ FREE GIFTS-
|
|
|
4327
4327
|
</div>
|
|
4328
4328
|
</CapCheckbox>
|
|
4329
4329
|
<div
|
|
4330
|
-
key=".
|
|
4330
|
+
key=".5"
|
|
4331
4331
|
style={
|
|
4332
4332
|
Object {
|
|
4333
4333
|
"marginBottom": "100px",
|
|
@@ -15176,7 +15176,7 @@ FREE GIFTS-
|
|
|
15176
15176
|
<CapCheckbox
|
|
15177
15177
|
checked={false}
|
|
15178
15178
|
disabled={false}
|
|
15179
|
-
key=".
|
|
15179
|
+
key=".3"
|
|
15180
15180
|
labelType="h4"
|
|
15181
15181
|
onChange={[Function]}
|
|
15182
15182
|
>
|
|
@@ -15238,7 +15238,7 @@ FREE GIFTS-
|
|
|
15238
15238
|
</div>
|
|
15239
15239
|
</CapCheckbox>
|
|
15240
15240
|
<div
|
|
15241
|
-
key=".
|
|
15241
|
+
key=".5"
|
|
15242
15242
|
style={
|
|
15243
15243
|
Object {
|
|
15244
15244
|
"marginBottom": "100px",
|
|
@@ -26117,7 +26117,7 @@ FREE GIFTS-
|
|
|
26117
26117
|
<CapCheckbox
|
|
26118
26118
|
checked={false}
|
|
26119
26119
|
disabled={false}
|
|
26120
|
-
key=".
|
|
26120
|
+
key=".3"
|
|
26121
26121
|
labelType="h4"
|
|
26122
26122
|
onChange={[Function]}
|
|
26123
26123
|
>
|
|
@@ -26179,7 +26179,7 @@ FREE GIFTS-
|
|
|
26179
26179
|
</div>
|
|
26180
26180
|
</CapCheckbox>
|
|
26181
26181
|
<div
|
|
26182
|
-
key=".
|
|
26182
|
+
key=".5"
|
|
26183
26183
|
style={
|
|
26184
26184
|
Object {
|
|
26185
26185
|
"marginBottom": "100px",
|
|
@@ -36,6 +36,7 @@ const SmsWrapper = (props) => {
|
|
|
36
36
|
handleTestAndPreview,
|
|
37
37
|
handleCloseTestAndPreview,
|
|
38
38
|
isTestAndPreviewMode,
|
|
39
|
+
onValidationFail,
|
|
39
40
|
} = props;
|
|
40
41
|
|
|
41
42
|
const smsProps = {
|
|
@@ -58,6 +59,7 @@ const SmsWrapper = (props) => {
|
|
|
58
59
|
handleTestAndPreview,
|
|
59
60
|
handleCloseTestAndPreview,
|
|
60
61
|
isTestAndPreviewMode,
|
|
62
|
+
onValidationFail,
|
|
61
63
|
};
|
|
62
64
|
const isTraiDlt = isTraiDLTEnable(isFullMode, smsRegister);
|
|
63
65
|
return <>
|
|
@@ -105,12 +105,10 @@ export const useTagManagement = ({
|
|
|
105
105
|
const validationConfig = useMemo(
|
|
106
106
|
() => ({
|
|
107
107
|
tagsParam: tags,
|
|
108
|
-
injectedTagsParams: injectedTags,
|
|
109
108
|
location,
|
|
110
109
|
tagModule: getDefaultTags,
|
|
111
|
-
eventContextTags,
|
|
112
110
|
}),
|
|
113
|
-
[tags,
|
|
111
|
+
[tags, location, getDefaultTags],
|
|
114
112
|
);
|
|
115
113
|
|
|
116
114
|
return {
|
|
@@ -528,26 +528,19 @@ describe('useTagManagement', () => {
|
|
|
528
528
|
|
|
529
529
|
describe('validationConfig', () => {
|
|
530
530
|
it('should return validation config with tags', () => {
|
|
531
|
-
const injectedTags = [{ id: 5, name: 'Injected Tag' }];
|
|
532
|
-
const eventContextTags = [{ id: 6, name: 'Event Tag' }];
|
|
533
|
-
|
|
534
531
|
const { result } = renderHook(() =>
|
|
535
532
|
useTagManagement({
|
|
536
533
|
location: defaultLocation,
|
|
537
534
|
globalActions: mockGlobalActions,
|
|
538
535
|
metaEntities: defaultMetaEntities,
|
|
539
|
-
injectedTags,
|
|
540
|
-
eventContextTags,
|
|
541
536
|
getDefaultTags: 'custom',
|
|
542
537
|
})
|
|
543
538
|
);
|
|
544
539
|
|
|
545
540
|
expect(result.current.validationConfig).toEqual({
|
|
546
541
|
tagsParam: defaultMetaEntities.tags.standard,
|
|
547
|
-
injectedTagsParams: injectedTags,
|
|
548
542
|
location: defaultLocation,
|
|
549
543
|
tagModule: 'custom',
|
|
550
|
-
eventContextTags,
|
|
551
544
|
});
|
|
552
545
|
});
|
|
553
546
|
|
|
@@ -295,8 +295,8 @@ const WebPushCreate = ({
|
|
|
295
295
|
const validateTemplateName = useCallback((value) => validateTemplateNameUtil(value), []);
|
|
296
296
|
|
|
297
297
|
const validateTitle = useCallback(
|
|
298
|
-
(value) => validateTitleUtil(value, formatMessage, messages, restrictPersonalization),
|
|
299
|
-
[formatMessage, restrictPersonalization],
|
|
298
|
+
(value) => validateTitleUtil(value, formatMessage, messages, restrictPersonalization, validationConfig, isFullMode),
|
|
299
|
+
[formatMessage, restrictPersonalization, validationConfig, isFullMode],
|
|
300
300
|
);
|
|
301
301
|
|
|
302
302
|
const validateUrl = useCallback(
|
|
@@ -11,19 +11,34 @@ import { hasPersonalizationTags } from '../../../../utils/commonUtils';
|
|
|
11
11
|
export const validateTemplateName = (value) => !value || value.trim() === '';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* Validates notification title
|
|
14
|
+
* Validates notification title (required and optional tag validation)
|
|
15
15
|
* @param {string} value - The title value
|
|
16
16
|
* @param {Function} formatMessage - i18n format message function
|
|
17
17
|
* @param {Object} messages - Message definitions
|
|
18
|
+
* @param {Object} [validationConfig] - Optional config for tag validation
|
|
19
|
+
* @param {boolean} [isFullMode] - Optional; when set with validationConfig, runs tag validation
|
|
18
20
|
* @returns {string} Error message if invalid, empty string if valid
|
|
19
21
|
*/
|
|
20
|
-
export const validateTitle = (value, formatMessage, messages, restrictPersonalization) => {
|
|
22
|
+
export const validateTitle = (value, formatMessage, messages, restrictPersonalization, validationConfig, isFullMode) => {
|
|
21
23
|
if (!value || value.trim() === '') {
|
|
22
24
|
return formatMessage(messages.titleRequired);
|
|
23
25
|
}
|
|
24
26
|
if (restrictPersonalization && hasPersonalizationTags(value)) {
|
|
25
27
|
return formatMessage(messages.personalizationTokensErrorMessage);
|
|
26
28
|
}
|
|
29
|
+
|
|
30
|
+
if (validationConfig != null) {
|
|
31
|
+
const validationResponse = validateTags({
|
|
32
|
+
content: value,
|
|
33
|
+
...validationConfig,
|
|
34
|
+
isFullMode,
|
|
35
|
+
}) || {};
|
|
36
|
+
|
|
37
|
+
if (validationResponse?.isBraceError) {
|
|
38
|
+
return formatMessage(globalMessages.unbalanacedCurlyBraces);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
27
42
|
return '';
|
|
28
43
|
};
|
|
29
44
|
|
|
@@ -127,6 +127,40 @@ describe('validation', () => {
|
|
|
127
127
|
expect(result).toBe('Personalization tags are not supported for anonymous customers');
|
|
128
128
|
expect(mockFormatMessage).toHaveBeenCalledWith(mockMessages.personalizationTokensErrorMessage);
|
|
129
129
|
});
|
|
130
|
+
|
|
131
|
+
it('should return brace error when validationConfig is provided and validateTags returns isBraceError', () => {
|
|
132
|
+
const validationConfig = { tagsParam: [], location: {}, tagModule: '' };
|
|
133
|
+
validateTags.mockReturnValue({ isBraceError: true });
|
|
134
|
+
const result = validateTitle(
|
|
135
|
+
'Valid Title',
|
|
136
|
+
mockFormatMessage,
|
|
137
|
+
mockMessages,
|
|
138
|
+
false,
|
|
139
|
+
validationConfig,
|
|
140
|
+
false
|
|
141
|
+
);
|
|
142
|
+
expect(result).toBe('Unbalanced curly braces');
|
|
143
|
+
expect(mockFormatMessage).toHaveBeenCalledWith(globalMessages.unbalanacedCurlyBraces);
|
|
144
|
+
expect(validateTags).toHaveBeenCalledWith({
|
|
145
|
+
content: 'Valid Title',
|
|
146
|
+
...validationConfig,
|
|
147
|
+
isFullMode: false,
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('should not run tag validation when validationConfig is null', () => {
|
|
152
|
+
validateTags.mockClear();
|
|
153
|
+
const result = validateTitle('Valid Title', mockFormatMessage, mockMessages, false, null);
|
|
154
|
+
expect(result).toBe('');
|
|
155
|
+
expect(validateTags).not.toHaveBeenCalled();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('should not run tag validation when validationConfig is undefined', () => {
|
|
159
|
+
validateTags.mockClear();
|
|
160
|
+
const result = validateTitle('Valid Title', mockFormatMessage, mockMessages, false, undefined);
|
|
161
|
+
expect(result).toBe('');
|
|
162
|
+
expect(validateTags).not.toHaveBeenCalled();
|
|
163
|
+
});
|
|
130
164
|
});
|
|
131
165
|
|
|
132
166
|
describe('validateUrl', () => {
|
|
@@ -183,10 +217,8 @@ describe('validation', () => {
|
|
|
183
217
|
describe('validateMessageContent', () => {
|
|
184
218
|
const mockValidationConfig = {
|
|
185
219
|
tagsParam: [],
|
|
186
|
-
injectedTagsParams: [],
|
|
187
220
|
location: {},
|
|
188
221
|
tagModule: '',
|
|
189
|
-
eventContextTags: [],
|
|
190
222
|
};
|
|
191
223
|
|
|
192
224
|
beforeEach(() => {
|
|
@@ -225,17 +257,6 @@ describe('validation', () => {
|
|
|
225
257
|
});
|
|
226
258
|
});
|
|
227
259
|
|
|
228
|
-
it('should return error message for unsupported tags', () => {
|
|
229
|
-
validateTags.mockReturnValue({
|
|
230
|
-
unsupportedTags: ['tag1', 'tag2'],
|
|
231
|
-
});
|
|
232
|
-
const result = validateMessageContent('Message with {tag1} and {tag2}', mockFormatMessage, mockMessages, mockValidationConfig);
|
|
233
|
-
expect(result).toBe('Unsupported tags: tag1, tag2');
|
|
234
|
-
expect(mockFormatMessage).toHaveBeenCalledWith(globalMessages.unsupportedTagsValidationError, {
|
|
235
|
-
unsupportedTags: 'tag1, tag2',
|
|
236
|
-
});
|
|
237
|
-
});
|
|
238
|
-
|
|
239
260
|
it('should return error message for unbalanced curly braces', () => {
|
|
240
261
|
validateTags.mockReturnValue({
|
|
241
262
|
isBraceError: true,
|
|
@@ -245,22 +266,11 @@ describe('validation', () => {
|
|
|
245
266
|
expect(mockFormatMessage).toHaveBeenCalledWith(globalMessages.unbalanacedCurlyBraces);
|
|
246
267
|
});
|
|
247
268
|
|
|
248
|
-
it('should return error message for both unsupported tags and brace error (unsupported tags takes precedence)', () => {
|
|
249
|
-
validateTags.mockReturnValue({
|
|
250
|
-
unsupportedTags: ['tag1'],
|
|
251
|
-
isBraceError: true,
|
|
252
|
-
});
|
|
253
|
-
const result = validateMessageContent('Message with {tag1}', mockFormatMessage, mockMessages, mockValidationConfig);
|
|
254
|
-
expect(result).toBe('Unsupported tags: tag1');
|
|
255
|
-
});
|
|
256
|
-
|
|
257
269
|
it('should pass validation config to validateTags', () => {
|
|
258
270
|
const customConfig = {
|
|
259
271
|
tagsParam: [{ id: 1, name: 'Tag1' }],
|
|
260
|
-
injectedTagsParams: [{ id: 2, name: 'Tag2' }],
|
|
261
272
|
location: { query: { type: 'test' } },
|
|
262
273
|
tagModule: 'custom',
|
|
263
|
-
eventContextTags: [{ id: 3, name: 'Tag3' }],
|
|
264
274
|
};
|
|
265
275
|
validateTags.mockReturnValue({});
|
|
266
276
|
validateMessageContent('Valid message', mockFormatMessage, mockMessages, customConfig);
|
|
@@ -306,6 +316,31 @@ describe('validation', () => {
|
|
|
306
316
|
expect(result).toBe('Personalization tags are not supported for anonymous customers');
|
|
307
317
|
expect(mockFormatMessage).toHaveBeenCalledWith(mockMessages.personalizationTokensErrorMessage);
|
|
308
318
|
});
|
|
319
|
+
|
|
320
|
+
it('should return unsupported tags error when validateTags returns unsupportedTags', () => {
|
|
321
|
+
validateTags.mockReturnValue({ unsupportedTags: ['invalidTag', 'otherTag'] });
|
|
322
|
+
const result = validateMessageContent(
|
|
323
|
+
'Hello {{invalidTag}}',
|
|
324
|
+
mockFormatMessage,
|
|
325
|
+
mockMessages,
|
|
326
|
+
mockValidationConfig
|
|
327
|
+
);
|
|
328
|
+
expect(result).toBe('Unsupported tags: invalidTag, otherTag');
|
|
329
|
+
expect(mockFormatMessage).toHaveBeenCalledWith(
|
|
330
|
+
globalMessages.unsupportedTagsValidationError,
|
|
331
|
+
{ unsupportedTags: 'invalidTag, otherTag' }
|
|
332
|
+
);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
it('should pass isFullMode to validateTags when provided', () => {
|
|
336
|
+
validateTags.mockReturnValue({});
|
|
337
|
+
validateMessageContent('Valid message', mockFormatMessage, mockMessages, mockValidationConfig, true);
|
|
338
|
+
expect(validateTags).toHaveBeenCalledWith({
|
|
339
|
+
content: 'Valid message',
|
|
340
|
+
...mockValidationConfig,
|
|
341
|
+
isFullMode: true,
|
|
342
|
+
});
|
|
343
|
+
});
|
|
309
344
|
});
|
|
310
345
|
});
|
|
311
346
|
|
|
@@ -637,22 +637,21 @@ export const Whatsapp = (props) => {
|
|
|
637
637
|
validateTags({
|
|
638
638
|
content: contentData.join(""),
|
|
639
639
|
tagsParam: tags,
|
|
640
|
-
injectedTagsParams: injectedTags,
|
|
641
640
|
location,
|
|
642
641
|
tagModule: getDefaultTags,
|
|
643
|
-
eventContextTags,
|
|
644
642
|
isFullMode,
|
|
645
643
|
}) || {};
|
|
646
|
-
const unsupportedTagsLengthCheck =
|
|
647
|
-
validationResponse?.unsupportedTags?.length > 0;
|
|
648
644
|
if (type === HEADER_TEXT) {
|
|
649
645
|
headerTagValidationResponse = validationResponse;
|
|
650
|
-
updateIsHeaderTagValidationError(
|
|
646
|
+
updateIsHeaderTagValidationError(validationResponse.isBraceError);
|
|
651
647
|
} else if (type === CAROUSEL_TEXT) {
|
|
652
|
-
return [
|
|
648
|
+
return [
|
|
649
|
+
{ fieldName: "carouselTagValidationErrMessage", value: validationResponse.isBraceError ? validationResponse : {} },
|
|
650
|
+
{ fieldName: "carouselTagValidationErr", value: validationResponse.isBraceError },
|
|
651
|
+
];
|
|
653
652
|
} else {
|
|
654
653
|
tagValidationResponse = validationResponse;
|
|
655
|
-
updateIsTagValidationError(
|
|
654
|
+
updateIsTagValidationError(validationResponse.isBraceError);
|
|
656
655
|
}
|
|
657
656
|
}
|
|
658
657
|
};
|
|
@@ -2682,18 +2681,11 @@ const isAuthenticationTemplate = isEqual(templateCategory, WHATSAPP_CATEGORIES.a
|
|
|
2682
2681
|
} else {
|
|
2683
2682
|
validationResponse = tagValidationResponse;
|
|
2684
2683
|
}
|
|
2685
|
-
const {
|
|
2686
|
-
|
|
2687
|
-
let tagError = "";
|
|
2688
|
-
if (unsupportedTags.length > 0) {
|
|
2689
|
-
tagError = formatMessage(globalMessages.unsupportedTagsValidationError, {
|
|
2690
|
-
unsupportedTags,
|
|
2691
|
-
});
|
|
2692
|
-
}
|
|
2684
|
+
const { isBraceError } = validationResponse || {};
|
|
2693
2685
|
if (isBraceError) {
|
|
2694
|
-
|
|
2686
|
+
return <CapError>{formatMessage(globalMessages.unbalanacedCurlyBraces)}</CapError>;
|
|
2695
2687
|
}
|
|
2696
|
-
return
|
|
2688
|
+
return null;
|
|
2697
2689
|
};
|
|
2698
2690
|
|
|
2699
2691
|
const editModeContent = () => (
|
|
@@ -270,23 +270,15 @@ export const Zalo = (props) => {
|
|
|
270
270
|
validateTags({
|
|
271
271
|
content: message,
|
|
272
272
|
tagsParam: tags,
|
|
273
|
-
injectedTagsParams: injectedTags,
|
|
274
273
|
location,
|
|
275
274
|
tagModule: getDefaultTags,
|
|
276
|
-
eventContextTags,
|
|
277
275
|
isFullMode,
|
|
278
276
|
}) || {};
|
|
279
|
-
const {
|
|
280
|
-
let tagError = '';
|
|
281
|
-
if (unsupportedTags.length > 0) {
|
|
282
|
-
tagError = formatMessage(globalMessages.unsupportedTagsValidationError, {
|
|
283
|
-
unsupportedTags,
|
|
284
|
-
});
|
|
285
|
-
}
|
|
277
|
+
const { isBraceError } = tagValidationResponse;
|
|
286
278
|
if (isBraceError) {
|
|
287
|
-
|
|
279
|
+
return formatMessage(globalMessages.unbalanacedCurlyBraces);
|
|
288
280
|
}
|
|
289
|
-
return
|
|
281
|
+
return '';
|
|
290
282
|
};
|
|
291
283
|
|
|
292
284
|
//this function is used for checking errror validation in this it validate tags error and length error
|