@capillarytech/creatives-library 8.0.289 → 8.0.290-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.
Files changed (52) hide show
  1. package/constants/unified.js +0 -1
  2. package/initialState.js +0 -2
  3. package/package.json +1 -1
  4. package/utils/common.js +5 -8
  5. package/utils/commonUtils.js +4 -85
  6. package/utils/tagValidations.js +84 -222
  7. package/utils/tests/commonUtil.test.js +461 -118
  8. package/utils/tests/tagValidations.test.js +280 -358
  9. package/v2Components/ErrorInfoNote/index.js +2 -5
  10. package/v2Components/FormBuilder/index.js +78 -161
  11. package/v2Components/FormBuilder/messages.js +0 -8
  12. package/v2Components/HtmlEditor/HTMLEditor.js +0 -5
  13. package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +0 -1
  14. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +0 -15
  15. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +1 -2
  16. package/v2Containers/Cap/mockData.js +0 -14
  17. package/v2Containers/Cap/reducer.js +3 -55
  18. package/v2Containers/Cap/tests/reducer.test.js +0 -102
  19. package/v2Containers/CreativesContainer/SlideBoxFooter.js +3 -1
  20. package/v2Containers/CreativesContainer/index.js +19 -6
  21. package/v2Containers/Email/index.js +1 -5
  22. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +10 -62
  23. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +12 -115
  24. package/v2Containers/FTP/index.js +2 -51
  25. package/v2Containers/FTP/messages.js +0 -4
  26. package/v2Containers/InApp/index.js +1 -96
  27. package/v2Containers/InApp/tests/index.test.js +17 -6
  28. package/v2Containers/InappAdvance/index.js +2 -103
  29. package/v2Containers/Line/Container/Text/index.js +0 -1
  30. package/v2Containers/MobilePush/Create/index.js +6 -16
  31. package/v2Containers/MobilePush/Edit/index.js +6 -16
  32. package/v2Containers/MobilePushNew/index.js +2 -33
  33. package/v2Containers/Rcs/index.js +12 -37
  34. package/v2Containers/Sms/Create/index.js +31 -3
  35. package/v2Containers/Sms/Create/messages.js +4 -0
  36. package/v2Containers/Sms/Edit/index.js +29 -3
  37. package/v2Containers/Sms/commonMethods.js +6 -6
  38. package/v2Containers/SmsTrai/Edit/index.js +6 -47
  39. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +6 -6
  40. package/v2Containers/Templates/reducer.js +3 -1
  41. package/v2Containers/Templates/tests/reducer.test.js +12 -0
  42. package/v2Containers/Viber/index.js +0 -1
  43. package/v2Containers/WebPush/Create/components/BrandIconSection.test.js +264 -0
  44. package/v2Containers/WebPush/Create/components/__snapshots__/BrandIconSection.test.js.snap +187 -0
  45. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +1 -3
  46. package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +0 -7
  47. package/v2Containers/WebPush/Create/index.js +2 -2
  48. package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +269 -0
  49. package/v2Containers/WebPush/Create/utils/validation.js +17 -2
  50. package/v2Containers/WebPush/Create/utils/validation.test.js +0 -24
  51. package/v2Containers/Whatsapp/index.js +9 -17
  52. package/v2Containers/Zalo/index.js +3 -11
@@ -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(
@@ -1016,6 +1016,275 @@ describe('NotificationContainer', () => {
1016
1016
  });
1017
1017
  });
1018
1018
 
1019
+ describe('platform.browser getter — 2-part vs 3-part class names', () => {
1020
+ it('derives browser from 2-part class name (macos-chrome → parts[1])', () => {
1021
+ // 'macos-chrome'.split('-') = ['macos', 'chrome'] → length=2 → browser = parts[1] = 'chrome'
1022
+ const wrapper = mountWithIntl(
1023
+ <NotificationContainer {...defaultProps} selectedOS={OS_MACOS} selectedBrowser={BROWSER_CHROME} />
1024
+ );
1025
+ expect(wrapper.find('.notification-container').hasClass('macos-chrome')).toBe(true);
1026
+ });
1027
+
1028
+ it('derives browser from 3-part class name (android-mobile-chrome → parts[2])', () => {
1029
+ // 'android-mobile-chrome'.split('-') = ['android', 'mobile', 'chrome'] → length=3 → browser = parts[2] = 'chrome'
1030
+ const wrapper = mountWithIntl(
1031
+ <NotificationContainer {...defaultProps} selectedOS={OS_ANDROID_MOBILE} selectedBrowser={BROWSER_CHROME} />
1032
+ );
1033
+ expect(wrapper.find('.notification-container').hasClass('android-mobile-chrome')).toBe(true);
1034
+ });
1035
+
1036
+ it('derives browser from 3-part class name for Android Tablet (android-tablet-firefox → parts[2])', () => {
1037
+ const wrapper = mountWithIntl(
1038
+ <NotificationContainer {...defaultProps} selectedOS={OS_ANDROID_TABLET} selectedBrowser={BROWSER_FIREFOX} />
1039
+ );
1040
+ expect(wrapper.find('.notification-container').hasClass('android-tablet-firefox')).toBe(true);
1041
+ });
1042
+ });
1043
+
1044
+ describe('platform.isIOS getter (selectedOS === OS_IOS)', () => {
1045
+ it('is true for iOS — renders IOSHeader', () => {
1046
+ const wrapper = mountWithIntl(
1047
+ <NotificationContainer {...defaultProps} selectedOS={OS_IOS} selectedBrowser={BROWSER_CHROME} />
1048
+ );
1049
+ expect(wrapper.find(IOSHeader).exists()).toBe(true);
1050
+ });
1051
+
1052
+ it('is false for macOS — does not render IOSHeader', () => {
1053
+ const wrapper = mountWithIntl(
1054
+ <NotificationContainer {...defaultProps} selectedOS={OS_MACOS} selectedBrowser={BROWSER_CHROME} />
1055
+ );
1056
+ expect(wrapper.find(IOSHeader).exists()).toBe(false);
1057
+ });
1058
+
1059
+ it('is false for Android Mobile — does not render IOSHeader', () => {
1060
+ const wrapper = mountWithIntl(
1061
+ <NotificationContainer {...defaultProps} selectedOS={OS_ANDROID_MOBILE} selectedBrowser={BROWSER_CHROME} />
1062
+ );
1063
+ expect(wrapper.find(IOSHeader).exists()).toBe(false);
1064
+ });
1065
+
1066
+ it('is false for Windows — does not render IOSHeader', () => {
1067
+ const wrapper = mountWithIntl(
1068
+ <NotificationContainer {...defaultProps} selectedOS={OS_WINDOWS} selectedBrowser={BROWSER_CHROME} />
1069
+ );
1070
+ expect(wrapper.find(IOSHeader).exists()).toBe(false);
1071
+ });
1072
+ });
1073
+
1074
+ describe('platform.isIPadOS getter (selectedOS === OS_IPADOS)', () => {
1075
+ it('is true for iPadOS — renders IOSHeader', () => {
1076
+ const wrapper = mountWithIntl(
1077
+ <NotificationContainer {...defaultProps} selectedOS={OS_IPADOS} selectedBrowser={BROWSER_CHROME} />
1078
+ );
1079
+ expect(wrapper.find(IOSHeader).exists()).toBe(true);
1080
+ });
1081
+
1082
+ it('is false for Android Tablet — does not render IOSHeader', () => {
1083
+ const wrapper = mountWithIntl(
1084
+ <NotificationContainer {...defaultProps} selectedOS={OS_ANDROID_TABLET} selectedBrowser={BROWSER_CHROME} />
1085
+ );
1086
+ expect(wrapper.find(IOSHeader).exists()).toBe(false);
1087
+ expect(wrapper.find(AndroidMobileChromeHeader).exists()).toBe(true);
1088
+ });
1089
+
1090
+ it('is false for Windows — does not render IOSHeader', () => {
1091
+ const wrapper = mountWithIntl(
1092
+ <NotificationContainer {...defaultProps} selectedOS={OS_WINDOWS} selectedBrowser={BROWSER_CHROME} />
1093
+ );
1094
+ expect(wrapper.find(IOSHeader).exists()).toBe(false);
1095
+ });
1096
+
1097
+ it('is false for macOS — does not render IOSHeader', () => {
1098
+ const wrapper = mountWithIntl(
1099
+ <NotificationContainer {...defaultProps} selectedOS={OS_MACOS} selectedBrowser={BROWSER_SAFARI} />
1100
+ );
1101
+ expect(wrapper.find(IOSHeader).exists()).toBe(false);
1102
+ });
1103
+ });
1104
+
1105
+ describe('platform.isMacOsBrandIconBrowser getter (isMacOs && supportsBrandIcon)', () => {
1106
+ it('is true for macOS + Chrome (Chrome is in BRAND_ICON_SUPPORTED_BROWSERS) — shows brand icon in expanded', () => {
1107
+ const wrapper = mountWithIntl(
1108
+ <NotificationContainer
1109
+ {...defaultProps}
1110
+ selectedOS={OS_MACOS}
1111
+ selectedBrowser={BROWSER_CHROME}
1112
+ notificationState={NOTIFICATION_STATE_EXPANDED}
1113
+ brandIcon="brand.png"
1114
+ enableBrandIconPreview={true}
1115
+ />
1116
+ );
1117
+ expect(wrapper.find(NotificationExpandedContent).prop('shouldShowBrandIconInExpandedMac')).toBe(true);
1118
+ });
1119
+
1120
+ it('is true for macOS + Edge (Edge is in BRAND_ICON_SUPPORTED_BROWSERS)', () => {
1121
+ const wrapper = mountWithIntl(
1122
+ <NotificationContainer
1123
+ {...defaultProps}
1124
+ selectedOS={OS_MACOS}
1125
+ selectedBrowser={BROWSER_EDGE}
1126
+ notificationState={NOTIFICATION_STATE_EXPANDED}
1127
+ brandIcon="brand.png"
1128
+ enableBrandIconPreview={true}
1129
+ />
1130
+ );
1131
+ expect(wrapper.find(NotificationExpandedContent).prop('shouldShowBrandIconInExpandedMac')).toBe(true);
1132
+ });
1133
+
1134
+ it('is true for macOS + Opera (Opera is in BRAND_ICON_SUPPORTED_BROWSERS)', () => {
1135
+ const wrapper = mountWithIntl(
1136
+ <NotificationContainer
1137
+ {...defaultProps}
1138
+ selectedOS={OS_MACOS}
1139
+ selectedBrowser={BROWSER_OPERA}
1140
+ notificationState={NOTIFICATION_STATE_EXPANDED}
1141
+ brandIcon="brand.png"
1142
+ enableBrandIconPreview={true}
1143
+ />
1144
+ );
1145
+ expect(wrapper.find(NotificationExpandedContent).prop('shouldShowBrandIconInExpandedMac')).toBe(true);
1146
+ });
1147
+
1148
+ it('is false for macOS + Safari (Safari is NOT in BRAND_ICON_SUPPORTED_BROWSERS)', () => {
1149
+ const wrapper = mountWithIntl(
1150
+ <NotificationContainer
1151
+ {...defaultProps}
1152
+ selectedOS={OS_MACOS}
1153
+ selectedBrowser={BROWSER_SAFARI}
1154
+ notificationState={NOTIFICATION_STATE_EXPANDED}
1155
+ brandIcon="brand.png"
1156
+ enableBrandIconPreview={true}
1157
+ />
1158
+ );
1159
+ expect(wrapper.find(NotificationExpandedContent).prop('shouldShowBrandIconInExpandedMac')).toBe(false);
1160
+ });
1161
+
1162
+ it('is false for Windows + Chrome (not macOS) — renders WindowsChromeExpanded instead', () => {
1163
+ const wrapper = mountWithIntl(
1164
+ <NotificationContainer
1165
+ {...defaultProps}
1166
+ selectedOS={OS_WINDOWS}
1167
+ selectedBrowser={BROWSER_CHROME}
1168
+ notificationState={NOTIFICATION_STATE_EXPANDED}
1169
+ brandIcon="brand.png"
1170
+ enableBrandIconPreview={true}
1171
+ />
1172
+ );
1173
+ expect(wrapper.find(NotificationExpandedContent).exists()).toBe(false);
1174
+ expect(wrapper.find(WindowsChromeExpanded).exists()).toBe(true);
1175
+ });
1176
+
1177
+ it('is false for macOS + Chrome when brandIcon is empty', () => {
1178
+ const wrapper = mountWithIntl(
1179
+ <NotificationContainer
1180
+ {...defaultProps}
1181
+ selectedOS={OS_MACOS}
1182
+ selectedBrowser={BROWSER_CHROME}
1183
+ notificationState={NOTIFICATION_STATE_EXPANDED}
1184
+ brandIcon=""
1185
+ enableBrandIconPreview={true}
1186
+ />
1187
+ );
1188
+ expect(wrapper.find(NotificationExpandedContent).prop('shouldShowBrandIconInExpandedMac')).toBe(false);
1189
+ });
1190
+ });
1191
+
1192
+ describe('shouldRenderSeparateIOSCTAs behavior', () => {
1193
+ const iosCollapsedWithCTAs = {
1194
+ ...defaultProps,
1195
+ selectedOS: OS_IOS,
1196
+ selectedBrowser: BROWSER_CHROME,
1197
+ notificationState: NOTIFICATION_STATE_COLLAPSED,
1198
+ showSeparateIOSCTAs: true,
1199
+ enableCtas: true,
1200
+ buttons: [{ text: 'Accept' }, { text: 'Dismiss' }],
1201
+ };
1202
+
1203
+ it('renders ios-notification-wrapper when all conditions are satisfied', () => {
1204
+ const wrapper = mountWithIntl(<NotificationContainer {...iosCollapsedWithCTAs} />);
1205
+ expect(wrapper.find('.ios-notification-wrapper').exists()).toBe(true);
1206
+ });
1207
+
1208
+ it('renders ios-cta-container inside the wrapper', () => {
1209
+ const wrapper = mountWithIntl(<NotificationContainer {...iosCollapsedWithCTAs} />);
1210
+ expect(wrapper.find('.ios-cta-container').exists()).toBe(true);
1211
+ });
1212
+
1213
+ it('renders one ios-cta-button per button', () => {
1214
+ const wrapper = mountWithIntl(<NotificationContainer {...iosCollapsedWithCTAs} />);
1215
+ expect(wrapper.find('.ios-cta-button').length).toBe(2);
1216
+ });
1217
+
1218
+ it('renders the correct button label text', () => {
1219
+ const wrapper = mountWithIntl(
1220
+ <NotificationContainer
1221
+ {...iosCollapsedWithCTAs}
1222
+ buttons={[{ text: 'Confirm' }]}
1223
+ />
1224
+ );
1225
+ expect(wrapper.find('.ios-cta-button').first().text()).toBe('Confirm');
1226
+ });
1227
+
1228
+ it('still renders the notification-container inside the wrapper', () => {
1229
+ const wrapper = mountWithIntl(<NotificationContainer {...iosCollapsedWithCTAs} />);
1230
+ const iosWrapper = wrapper.find('.ios-notification-wrapper');
1231
+ expect(iosWrapper.find('.notification-container').exists()).toBe(true);
1232
+ });
1233
+
1234
+ it('does NOT render ios-notification-wrapper when showSeparateIOSCTAs is false', () => {
1235
+ const wrapper = mountWithIntl(
1236
+ <NotificationContainer {...iosCollapsedWithCTAs} showSeparateIOSCTAs={false} />
1237
+ );
1238
+ expect(wrapper.find('.ios-notification-wrapper').exists()).toBe(false);
1239
+ });
1240
+
1241
+ it('does NOT render ios-notification-wrapper when expanded (isExpanded is true)', () => {
1242
+ const wrapper = mountWithIntl(
1243
+ <NotificationContainer
1244
+ {...iosCollapsedWithCTAs}
1245
+ notificationState={NOTIFICATION_STATE_EXPANDED}
1246
+ supportsExpanded={true}
1247
+ />
1248
+ );
1249
+ expect(wrapper.find('.ios-notification-wrapper').exists()).toBe(false);
1250
+ });
1251
+
1252
+ it('does NOT render ios-notification-wrapper when enableCtas is false', () => {
1253
+ const wrapper = mountWithIntl(
1254
+ <NotificationContainer {...iosCollapsedWithCTAs} enableCtas={false} />
1255
+ );
1256
+ expect(wrapper.find('.ios-notification-wrapper').exists()).toBe(false);
1257
+ });
1258
+
1259
+ it('does NOT render ios-notification-wrapper when buttons array is empty', () => {
1260
+ const wrapper = mountWithIntl(
1261
+ <NotificationContainer {...iosCollapsedWithCTAs} buttons={[]} />
1262
+ );
1263
+ expect(wrapper.find('.ios-notification-wrapper').exists()).toBe(false);
1264
+ });
1265
+
1266
+ it('does NOT render ios-notification-wrapper for iPadOS (not an iOS browser)', () => {
1267
+ const wrapper = mountWithIntl(
1268
+ <NotificationContainer {...iosCollapsedWithCTAs} selectedOS={OS_IPADOS} />
1269
+ );
1270
+ expect(wrapper.find('.ios-notification-wrapper').exists()).toBe(false);
1271
+ });
1272
+
1273
+ it('does NOT render ios-notification-wrapper for macOS', () => {
1274
+ const wrapper = mountWithIntl(
1275
+ <NotificationContainer {...iosCollapsedWithCTAs} selectedOS={OS_MACOS} />
1276
+ );
1277
+ expect(wrapper.find('.ios-notification-wrapper').exists()).toBe(false);
1278
+ });
1279
+
1280
+ it('does NOT render ios-notification-wrapper for Android Mobile', () => {
1281
+ const wrapper = mountWithIntl(
1282
+ <NotificationContainer {...iosCollapsedWithCTAs} selectedOS={OS_ANDROID_MOBILE} />
1283
+ );
1284
+ expect(wrapper.find('.ios-notification-wrapper').exists()).toBe(false);
1285
+ });
1286
+ });
1287
+
1019
1288
  describe('Snapshot Tests', () => {
1020
1289
  it('should match snapshot for macOS Chrome collapsed', () => {
1021
1290
  const wrapper = shallowWithIntl(
@@ -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
 
@@ -183,10 +183,8 @@ describe('validation', () => {
183
183
  describe('validateMessageContent', () => {
184
184
  const mockValidationConfig = {
185
185
  tagsParam: [],
186
- injectedTagsParams: [],
187
186
  location: {},
188
187
  tagModule: '',
189
- eventContextTags: [],
190
188
  };
191
189
 
192
190
  beforeEach(() => {
@@ -225,17 +223,6 @@ describe('validation', () => {
225
223
  });
226
224
  });
227
225
 
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
226
  it('should return error message for unbalanced curly braces', () => {
240
227
  validateTags.mockReturnValue({
241
228
  isBraceError: true,
@@ -245,22 +232,11 @@ describe('validation', () => {
245
232
  expect(mockFormatMessage).toHaveBeenCalledWith(globalMessages.unbalanacedCurlyBraces);
246
233
  });
247
234
 
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
235
  it('should pass validation config to validateTags', () => {
258
236
  const customConfig = {
259
237
  tagsParam: [{ id: 1, name: 'Tag1' }],
260
- injectedTagsParams: [{ id: 2, name: 'Tag2' }],
261
238
  location: { query: { type: 'test' } },
262
239
  tagModule: 'custom',
263
- eventContextTags: [{ id: 3, name: 'Tag3' }],
264
240
  };
265
241
  validateTags.mockReturnValue({});
266
242
  validateMessageContent('Valid message', mockFormatMessage, mockMessages, customConfig);
@@ -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(unsupportedTagsLengthCheck);
646
+ updateIsHeaderTagValidationError(validationResponse.isBraceError);
651
647
  } else if (type === CAROUSEL_TEXT) {
652
- return [{fieldName: "carouselTagValidationErrMessage", value: validationResponse}, {fieldName: "carouselTagValidationErr", value: unsupportedTagsLengthCheck}];
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(unsupportedTagsLengthCheck);
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 { unsupportedTags = [], isBraceError } = validationResponse;
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
- tagError = formatMessage(globalMessages.unbalanacedCurlyBraces);
2686
+ return <CapError>{formatMessage(globalMessages.unbalanacedCurlyBraces)}</CapError>;
2695
2687
  }
2696
- return <CapError>{tagError}</CapError>;
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 { unsupportedTags = [], isBraceError } = tagValidationResponse;
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
- tagError = formatMessage(globalMessages.unbalanacedCurlyBraces);
279
+ return formatMessage(globalMessages.unbalanacedCurlyBraces);
288
280
  }
289
- return tagError;
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