@capillarytech/creatives-library 8.0.306 → 8.0.307

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 (54) hide show
  1. package/constants/unified.js +5 -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 +36 -93
  6. package/utils/tagValidations.js +83 -223
  7. package/utils/tests/commonUtil.test.js +147 -124
  8. package/utils/tests/tagValidations.test.js +441 -358
  9. package/v2Components/ErrorInfoNote/index.js +2 -5
  10. package/v2Components/FormBuilder/index.js +137 -203
  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/SlideBoxContent.js +5 -1
  20. package/v2Containers/CreativesContainer/SlideBoxFooter.js +13 -5
  21. package/v2Containers/CreativesContainer/constants.js +6 -0
  22. package/v2Containers/CreativesContainer/index.js +47 -7
  23. package/v2Containers/Email/index.js +1 -5
  24. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +23 -70
  25. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +20 -120
  26. package/v2Containers/FTP/index.js +2 -51
  27. package/v2Containers/FTP/messages.js +0 -4
  28. package/v2Containers/InApp/index.js +35 -107
  29. package/v2Containers/InApp/tests/index.test.js +17 -6
  30. package/v2Containers/InappAdvance/index.js +4 -112
  31. package/v2Containers/InappAdvance/tests/index.test.js +2 -0
  32. package/v2Containers/Line/Container/Text/index.js +0 -1
  33. package/v2Containers/MobilePush/Create/index.js +59 -19
  34. package/v2Containers/MobilePush/Edit/index.js +48 -20
  35. package/v2Containers/MobilePushNew/index.js +12 -32
  36. package/v2Containers/MobilepushWrapper/index.js +3 -1
  37. package/v2Containers/Rcs/index.js +12 -37
  38. package/v2Containers/Sms/Create/index.js +39 -3
  39. package/v2Containers/Sms/Create/messages.js +4 -0
  40. package/v2Containers/Sms/Edit/index.js +35 -3
  41. package/v2Containers/Sms/commonMethods.js +3 -6
  42. package/v2Containers/Sms/tests/commonMethods.test.js +122 -0
  43. package/v2Containers/SmsTrai/Edit/index.js +11 -47
  44. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +6 -6
  45. package/v2Containers/SmsWrapper/index.js +2 -0
  46. package/v2Containers/TemplatesV2/index.js +28 -13
  47. package/v2Containers/Viber/index.js +0 -1
  48. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +1 -3
  49. package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +0 -7
  50. package/v2Containers/WebPush/Create/index.js +2 -2
  51. package/v2Containers/WebPush/Create/utils/validation.js +17 -8
  52. package/v2Containers/WebPush/Create/utils/validation.test.js +44 -24
  53. package/v2Containers/Whatsapp/index.js +9 -17
  54. 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=".4"
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=".6"
4330
+ key=".5"
4331
4331
  style={
4332
4332
  Object {
4333
4333
  "marginBottom": "100px",
@@ -15254,7 +15254,7 @@ FREE GIFTS-
15254
15254
  <CapCheckbox
15255
15255
  checked={false}
15256
15256
  disabled={false}
15257
- key=".4"
15257
+ key=".3"
15258
15258
  labelType="h4"
15259
15259
  onChange={[Function]}
15260
15260
  >
@@ -15316,7 +15316,7 @@ FREE GIFTS-
15316
15316
  </div>
15317
15317
  </CapCheckbox>
15318
15318
  <div
15319
- key=".6"
15319
+ key=".5"
15320
15320
  style={
15321
15321
  Object {
15322
15322
  "marginBottom": "100px",
@@ -26273,7 +26273,7 @@ FREE GIFTS-
26273
26273
  <CapCheckbox
26274
26274
  checked={false}
26275
26275
  disabled={false}
26276
- key=".4"
26276
+ key=".3"
26277
26277
  labelType="h4"
26278
26278
  onChange={[Function]}
26279
26279
  >
@@ -26335,7 +26335,7 @@ FREE GIFTS-
26335
26335
  </div>
26336
26336
  </CapCheckbox>
26337
26337
  <div
26338
- key=".6"
26338
+ key=".5"
26339
26339
  style={
26340
26340
  Object {
26341
26341
  "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 <>
@@ -29,11 +29,18 @@ import FTP from '../FTP';
29
29
  import Gallery from '../Assets/Gallery';
30
30
  import withStyles from '../../hoc/withStyles';
31
31
  import styles, { CapTabStyle } from './TemplatesV2.style';
32
- import { CREATIVES_UI_VIEW, LOYALTY, WHATSAPP, RCS, LINE, EMAIL, ASSETS, JP_LOCALE_HIDE_FEATURE, ZALO, INAPP, WEBPUSH } from '../App/constants';
32
+ import { CREATIVES_UI_VIEW, FTP as FTP_CHANNEL, LOYALTY, WHATSAPP, RCS, LINE, EMAIL, ASSETS, JP_LOCALE_HIDE_FEATURE, ZALO, INAPP, WEBPUSH } from '../App/constants';
33
33
  import AccessForbidden from '../../v2Components/AccessForbidden';
34
34
  import { getObjFromQueryParams } from '../../utils/v2common';
35
35
  import { makeSelectAuthenticated, selectCurrentOrgDetails } from "../../v2Containers/Cap/selectors";
36
- import { LOYALTY_SUPPORTED_ACTION, COMMON_CHANNELS } from "../CreativesContainer/constants";
36
+ import {
37
+ CALL_TASK,
38
+ COMMON_CHANNELS,
39
+ LOYALTY_SUPPORTED_ACTION,
40
+ MOBILE_PUSH,
41
+ NORMALIZED_CHANNEL_ALIASES,
42
+ SMS,
43
+ } from "../CreativesContainer/constants";
37
44
 
38
45
  const {CapCustomCardList} = CapCustomCard;
39
46
 
@@ -95,8 +102,16 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
95
102
  return str.replace(/([a-z0-9])([A-Z])/g, '$1_$2').replace(/[^a-zA-Z0-9]+/g, '_').toLowerCase();
96
103
  };
97
104
 
98
- const normalizedChannelsToHideSet = new Set((channelsToHide || []).map((c) => normalizeChannel(c)));
99
- const normalizedChannelsToDisableSet = new Set((channelsToDisable || []).map((c) => normalizeChannel(c)));
105
+ const buildChannelSet = (channelList) => {
106
+ const normalized = (channelList || []).map((c) => normalizeChannel(c));
107
+ const withAliases = normalized.flatMap((norm) => {
108
+ const canonical = NORMALIZED_CHANNEL_ALIASES[norm];
109
+ return canonical ? [norm, canonical] : [norm];
110
+ });
111
+ return new Set(withAliases);
112
+ };
113
+ const normalizedChannelsToHideSet = buildChannelSet(channelsToHide);
114
+ const normalizedChannelsToDisableSet = buildChannelSet(channelsToDisable);
100
115
 
101
116
  // Build filtered panes by examining each pane's `key` and checking against normalized hide set
102
117
  let filteredPanes = Object.keys(defaultPanes).map((k) => defaultPanes[k]).filter((pane) => {
@@ -108,12 +123,12 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
108
123
  filteredPanes.push({ content: <div></div>, tab: intl.formatMessage(messages.gallery), key: 'assets' });
109
124
  } else {
110
125
  // Add special-mode panes only when not hidden (use normalized checks)
111
- if (!normalizedChannelsToHideSet.has('call_task')) {
112
- filteredPanes.push({ content: <div></div>, tab: intl.formatMessage(messages.callTask), key: 'call_task' });
126
+ if (!normalizedChannelsToHideSet.has(CALL_TASK.toLowerCase())) {
127
+ filteredPanes.push({ content: <div></div>, tab: intl.formatMessage(messages.callTask), key: CALL_TASK.toLowerCase() });
113
128
  }
114
- if (!normalizedChannelsToHideSet.has('ftp')) {
115
- filteredPanes.push({ content: <></>, tab: intl.formatMessage(messages.FTP), key: 'ftp' });
116
- defaultChannel = 'FTP';
129
+ if (!normalizedChannelsToHideSet.has(FTP_CHANNEL.toLowerCase())) {
130
+ filteredPanes.push({ content: <></>, tab: intl.formatMessage(messages.FTP), key: FTP_CHANNEL.toLowerCase() });
131
+ defaultChannel = FTP_CHANNEL;
117
132
  }
118
133
 
119
134
  // Create a local copy of COMMON_CHANNELS to avoid mutating the imported array
@@ -163,15 +178,15 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
163
178
 
164
179
  // If audience is anonymous, prefer mobilepush as default (if not hidden)
165
180
  if (isAnonymousType) {
166
- const mobilePushNorm = normalizeChannel('mobilepush');
181
+ const mobilePushNorm = normalizeChannel(MOBILE_PUSH.toLowerCase());
167
182
  if (!normalizedChannelsToHideSet.has(mobilePushNorm)) {
168
- defaultChannel = 'mobilepush';
183
+ defaultChannel = MOBILE_PUSH.toLowerCase();
169
184
  }
170
185
  }
171
186
 
172
- const channel = ['sms', 'email', 'mobilepush', 'line', 'call_task'];
187
+ const defaultChannelOrder = [SMS.toLowerCase(), EMAIL, MOBILE_PUSH.toLowerCase(), LINE, CALL_TASK.toLowerCase()];
173
188
  if (normalizedChannelsToDisableSet.size > 0) {
174
- channel.some((ch) => {
189
+ defaultChannelOrder.some((ch) => {
175
190
  if (!normalizedChannelsToDisableSet.has(ch)) {
176
191
  defaultChannel = ch;
177
192
  return true;
@@ -234,7 +234,6 @@ export const Viber = (props) => {
234
234
  const { valid, isBraceError } = validateTags({
235
235
  content: value,
236
236
  tagsParam: tags,
237
- injectedTagsParams: injectedTags,
238
237
  location,
239
238
  tagModule: 'outbound',
240
239
  isFullMode,
@@ -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, injectedTags, location, getDefaultTags, eventContextTags],
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
 
@@ -65,12 +80,6 @@ export const validateMessageContent = (value, formatMessage, messages, validatio
65
80
  isFullMode,
66
81
  }) || {};
67
82
 
68
- if (validationResponse?.unsupportedTags?.length) {
69
- return formatMessage(globalMessages.unsupportedTagsValidationError, {
70
- unsupportedTags: validationResponse.unsupportedTags.join(', '),
71
- });
72
- }
73
-
74
83
  if (validationResponse?.isBraceError) {
75
84
  return formatMessage(globalMessages.unbalanacedCurlyBraces);
76
85
  }
@@ -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,16 @@ 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 pass isFullMode to validateTags when provided', () => {
321
+ validateTags.mockReturnValue({});
322
+ validateMessageContent('Valid message', mockFormatMessage, mockMessages, mockValidationConfig, true);
323
+ expect(validateTags).toHaveBeenCalledWith({
324
+ content: 'Valid message',
325
+ ...mockValidationConfig,
326
+ isFullMode: true,
327
+ });
328
+ });
309
329
  });
310
330
  });
311
331
 
@@ -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