@capillarytech/creatives-library 8.0.285 → 8.0.287-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 (42) 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 +2 -83
  6. package/utils/tagValidations.js +84 -222
  7. package/utils/tests/commonUtil.test.js +147 -118
  8. package/utils/tests/tagValidations.test.js +280 -358
  9. package/v2Components/ErrorInfoNote/index.js +2 -5
  10. package/v2Components/FormBuilder/index.js +64 -158
  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/index.js +0 -1
  20. package/v2Containers/Email/index.js +1 -5
  21. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +10 -62
  22. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +12 -115
  23. package/v2Containers/FTP/index.js +2 -51
  24. package/v2Containers/FTP/messages.js +0 -4
  25. package/v2Containers/InApp/index.js +1 -96
  26. package/v2Containers/InApp/tests/index.test.js +17 -6
  27. package/v2Containers/InappAdvance/index.js +2 -103
  28. package/v2Containers/Line/Container/Text/index.js +0 -1
  29. package/v2Containers/MobilePushNew/index.js +2 -33
  30. package/v2Containers/Rcs/index.js +12 -37
  31. package/v2Containers/SmsTrai/Create/index.scss +1 -1
  32. package/v2Containers/SmsTrai/Edit/index.js +6 -47
  33. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +6 -6
  34. package/v2Containers/Viber/index.js +0 -1
  35. package/v2Containers/Viber/index.scss +1 -1
  36. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +1 -3
  37. package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +0 -7
  38. package/v2Containers/WebPush/Create/index.js +2 -2
  39. package/v2Containers/WebPush/Create/utils/validation.js +18 -9
  40. package/v2Containers/WebPush/Create/utils/validation.test.js +0 -24
  41. package/v2Containers/Whatsapp/index.js +9 -17
  42. package/v2Containers/Zalo/index.js +3 -11
@@ -50,9 +50,7 @@ import injectReducer from '../../utils/injectReducer';
50
50
  import v2InAppReducer from '../InApp/reducer';
51
51
  import { v2InAppSagas } from '../InApp/sagas';
52
52
  import injectSaga from '../../utils/injectSaga';
53
- import { validateTags } from "../../utils/tagValidations";
54
53
  import { validateInAppContent } from "../../utils/commonUtils";
55
- import { hasLiquidSupportFeature } from "../../utils/common";
56
54
  import formBuilderMessages from "../../v2Components/FormBuilder/messages";
57
55
  import { getSingleTab, hasAnyErrors } from "../InApp/utils";
58
56
  import ErrorInfoNote from "../../v2Components/ErrorInfoNote";
@@ -817,11 +815,9 @@ export const InappAdvanced = (props) => {
817
815
  const latestHtmlValues = await saveAllBeeInstances();
818
816
  const payload = createPayload(latestHtmlValues);
819
817
 
820
- // Validate the INAPP content
821
- const isLiquidFlow = hasLiquidSupportFeature();
822
818
  // Skip validation if no tags are available (e.g., in tests or when tags haven't loaded)
823
819
  const hasTags = tags && tags.length > 0;
824
- if (isLiquidFlow && hasTags) {
820
+ if (hasTags) {
825
821
  validateInAppContent(payload, {
826
822
  currentTab: panes === ANDROID ? 1 : 2, // Convert ANDROID/IOS to tab numbers
827
823
  onError,
@@ -829,10 +825,6 @@ export const InappAdvanced = (props) => {
829
825
  getLiquidTags: (content, callback) => globalActions.getLiquidTags(content, callback),
830
826
  formatMessage,
831
827
  messages: formBuilderMessages,
832
- tagLookupMap: metaEntities?.tagLookupMap || {},
833
- eventContextTags: metaEntities?.eventContextTags || [],
834
- isLiquidFlow,
835
- forwardedTags: {},
836
828
  skipTags: (tag) => {
837
829
  // Skip certain tags if needed
838
830
  const skipRegexes = [
@@ -847,92 +839,7 @@ export const InappAdvanced = (props) => {
847
839
  },
848
840
  singleTab: getSingleTab(accountData),
849
841
  });
850
- } else if (hasTags) {
851
- // For non-liquid flow, validate tags using validateTags (only if tags are available)
852
- const androidContent = latestHtmlValues?.android || (androidBeeHtml?.value || (typeof androidBeeHtml === 'string' ? androidBeeHtml : ''));
853
- const iosContent = latestHtmlValues?.ios || (iosBeeHtml?.value || (typeof iosBeeHtml === 'string' ? iosBeeHtml : ''));
854
-
855
- const androidSupported = get(accountData, 'selectedWeChatAccount.configs.android') === DEVICE_SUPPORTED || get(editContent, 'ANDROID.deviceType') === ANDROID;
856
- const iosSupported = get(accountData, 'selectedWeChatAccount.configs.ios') === DEVICE_SUPPORTED || get(editContent, 'IOS.deviceType') === IOS_CAPITAL;
857
-
858
- let hasErrors = false;
859
- const newErrors = {
860
- STANDARD_ERROR_MSG: {
861
- ANDROID: [],
862
- IOS: [],
863
- GENERIC: [],
864
- },
865
- LIQUID_ERROR_MSG: {
866
- ANDROID: [],
867
- IOS: [],
868
- GENERIC: [],
869
- },
870
- };
871
-
872
- // Validate Android content
873
- if (androidSupported && androidContent && androidContent?.trim() !== '') {
874
- const validationResponse = validateTags({
875
- content: androidContent,
876
- tagsParam: tags,
877
- injectedTagsParams: injectedTags || {},
878
- location,
879
- tagModule: getDefaultTags,
880
- eventContextTags: metaEntities?.eventContextTags || [],
881
- isFullMode,
882
- }) || {};
883
-
884
- if (validationResponse?.unsupportedTags?.length > 0) {
885
- hasErrors = true;
886
- newErrors.LIQUID_ERROR_MSG.ANDROID.push(
887
- formatMessage(globalMessages.unsupportedTagsValidationError, {
888
- unsupportedTags: validationResponse.unsupportedTags.join(", "),
889
- })
890
- );
891
- }
892
- if (validationResponse?.isBraceError) {
893
- hasErrors = true;
894
- newErrors.LIQUID_ERROR_MSG.ANDROID.push(
895
- formatMessage(globalMessages.unbalanacedCurlyBraces)
896
- );
897
- }
898
- }
899
-
900
- // Validate iOS content
901
- if (iosSupported && iosContent && iosContent?.trim() !== '') {
902
- const validationResponse = validateTags({
903
- content: iosContent,
904
- tagsParam: tags,
905
- injectedTagsParams: injectedTags || {},
906
- location,
907
- tagModule: getDefaultTags,
908
- eventContextTags: metaEntities?.eventContextTags || [],
909
- isFullMode,
910
- }) || {};
911
-
912
- if (validationResponse?.unsupportedTags?.length > 0) {
913
- hasErrors = true;
914
- newErrors.LIQUID_ERROR_MSG.IOS.push(
915
- formatMessage(globalMessages.unsupportedTagsValidationError, {
916
- unsupportedTags: validationResponse.unsupportedTags.join(", "),
917
- })
918
- );
919
- }
920
- if (validationResponse?.isBraceError) {
921
- hasErrors = true;
922
- newErrors.LIQUID_ERROR_MSG.IOS.push(
923
- formatMessage(globalMessages.unbalanacedCurlyBraces)
924
- );
925
- }
926
- }
927
-
928
- if (hasErrors) {
929
- setErrorMessage(newErrors);
930
- } else {
931
- // No errors, proceed with submission
932
- onSuccess();
933
- }
934
842
  } else {
935
- // No tags available, skip validation and proceed directly
936
843
  onSuccess();
937
844
  }
938
845
  };
@@ -1038,15 +945,7 @@ export const InappAdvanced = (props) => {
1038
945
  )}
1039
946
  <CapButton
1040
947
  onClick={async () => {
1041
- const isLiquidFlow = hasLiquidSupportFeature();
1042
- const hasTags = tags && tags?.length > 0;
1043
- if (isLiquidFlow || hasTags) {
1044
- // Use validation middleware for tag validation
1045
- await liquidMiddleWare();
1046
- } else {
1047
- // No validation needed, proceed directly
1048
- await onDoneCallback();
1049
- }
948
+ await liquidMiddleWare();
1050
949
  }}
1051
950
  disabled={isDisableDone()}
1052
951
  className="inapp-create-btn"
@@ -137,7 +137,6 @@ export const LineText = ({
137
137
  const { valid, isBraceError } = validateTags({
138
138
  content: value,
139
139
  tagsParam: tags,
140
- injectedTagsParams: injectedTags,
141
140
  location,
142
141
  tagModule: 'outbound',
143
142
  isFullMode,
@@ -77,7 +77,6 @@ import { getContent } from "../MobilePush/commonMethods";
77
77
  import { getMessageObject } from "../../utils/messageUtils";
78
78
  import { gtmPush } from "../../utils/gtmTrackers";
79
79
  import mobilePushReducer from "./reducer";
80
- import { hasLiquidSupportFeature } from "../../utils/common";
81
80
  import formBuilderMessages from "../../v2Components/FormBuilder/messages";
82
81
  import { validateMobilePushContent } from "../../utils/commonUtils";
83
82
  import { getSingleTab } from "../InApp/utils";
@@ -799,10 +798,9 @@ const MobilePushNew = ({
799
798
  (value) => {
800
799
  let errorTemplateDescMessage = "";
801
800
 
802
- const { unsupportedTags, isBraceError } = validateTags({
801
+ const { isBraceError } = validateTags({
803
802
  content: value,
804
803
  tagsParam: tags,
805
- injectedTagsParams: injectedTags,
806
804
  location,
807
805
  tagModule: getDefaultTags,
808
806
  isFullMode,
@@ -812,14 +810,6 @@ const MobilePushNew = ({
812
810
  messages.emptyTemplateDescErrorMessage
813
811
  );
814
812
  }
815
- if (unsupportedTags?.length > 0) {
816
- errorTemplateDescMessage = formatMessage(
817
- globalMessages.unsupportedTagsValidationError,
818
- {
819
- unsupportedTags,
820
- }
821
- );
822
- }
823
813
  if (isBraceError) {
824
814
  errorTemplateDescMessage = formatMessage(
825
815
  globalMessages.unbalanacedCurlyBraces
@@ -2606,20 +2596,6 @@ const MobilePushNew = ({
2606
2596
  getLiquidTags: globalActionsProps.getLiquidTags,
2607
2597
  formatMessage,
2608
2598
  messages: formBuilderMessages,
2609
- tagLookupMap: metaEntities?.tagLookupMap || {},
2610
- eventContextTags: metaEntities?.eventContextTags || [],
2611
- isLiquidFlow: hasLiquidSupportFeature(),
2612
- forwardedTags: {},
2613
- skipTags: (tag) => {
2614
- const skipRegexes = [
2615
- /dynamic_expiry_date_after_\d+_days\.FORMAT_\d/,
2616
- /unsubscribe\(#[a-zA-Z\d]{6}\)/,
2617
- /Link_to_[a-zA-z]/,
2618
- /SURVEY.*\.TOKEN/,
2619
- /^[A-Za-z].*\([a-zA-Z\d]*\)/,
2620
- ];
2621
- return skipRegexes.some((regex) => regex.test(tag));
2622
- },
2623
2599
  singleTab: getSingleTab(accountData),
2624
2600
  });
2625
2601
  }, [
@@ -2628,12 +2604,9 @@ const MobilePushNew = ({
2628
2604
  activeTab,
2629
2605
  globalActionsProps,
2630
2606
  formatMessage,
2631
- metaEntities,
2632
2607
  accountData,
2633
2608
  ]);
2634
2609
 
2635
- const isLiquidFlow = hasLiquidSupportFeature();
2636
-
2637
2610
  useEffect(() => {
2638
2611
  // Always map to { label } for both platforms
2639
2612
  const newButtons = Array.isArray(ctaData)
@@ -3030,11 +3003,7 @@ const MobilePushNew = ({
3030
3003
  <CapButton
3031
3004
  type="primary"
3032
3005
  onClick={() => {
3033
- if (isLiquidFlow) {
3034
- liquidMiddleWare();
3035
- } else {
3036
- handleSave();
3037
- }
3006
+ liquidMiddleWare();
3038
3007
  }}
3039
3008
  className="save-button"
3040
3009
  disabled={isSaveDisabled}
@@ -394,23 +394,15 @@ export const Rcs = (props) => {
394
394
  const validationResponse =
395
395
  validateTags({
396
396
  content: contentForValidation,
397
- tagsParam: tags,
398
- injectedTagsParams: injectedTags,
399
- location,
400
- tagModule: getDefaultTags,
401
- eventContextTags,
402
- isFullMode,
403
- }) || {};
404
- const unsupportedTagsLengthCheck =
405
- validationResponse?.unsupportedTags?.length > 0;
406
- const errorMsg =
407
- (unsupportedTagsLengthCheck &&
408
- formatMessage(globalMessages.unsupportedTagsValidationError, {
409
- unsupportedTags: validationResponse.unsupportedTags,
410
- })) ||
411
- (validationResponse.isBraceError &&
412
- formatMessage(globalMessages.unbalanacedCurlyBraces)) ||
413
- false;
397
+ tagsParam: tags,
398
+ location,
399
+ tagModule: getDefaultTags,
400
+ isFullMode,
401
+ }) || {};
402
+ const errorMsg =
403
+ (validationResponse?.isBraceError &&
404
+ formatMessage(globalMessages.unbalanacedCurlyBraces)) ||
405
+ false;
414
406
  if (type === TITLE_TEXT) setTemplateTitleError(errorMsg);
415
407
  if (type === MESSAGE_TEXT) setTemplateDescError(errorMsg);
416
408
  };
@@ -835,10 +827,9 @@ export const Rcs = (props) => {
835
827
 
836
828
  const templateDescErrorHandler = (value) => {
837
829
  let errorMessage = false;
838
- const { unsupportedTags, isBraceError } = validateTags({
830
+ const { isBraceError } = validateTags({
839
831
  content: value,
840
832
  tagsParam: tags,
841
- injectedTagsParams: injectedTags,
842
833
  location,
843
834
  tagModule: getDefaultTags,
844
835
  isFullMode,
@@ -868,26 +859,10 @@ export const Rcs = (props) => {
868
859
  };
869
860
 
870
861
  const fallbackMessageErrorHandler = (value) => {
871
- let errorMessage = false;
872
- const { unsupportedTags } = validateTags({
873
- content: value,
874
- tagsParam: tags,
875
- injectedTagsParams: injectedTags,
876
- location,
877
- tagModule: getDefaultTags,
878
- isFullMode,
879
- }) || {};
880
862
  if (value?.length > FALLBACK_MESSAGE_MAX_LENGTH) {
881
- errorMessage = formatMessage(messages.fallbackMsgLenError);
882
- } else if (unsupportedTags?.length > 0) {
883
- errorMessage = formatMessage(
884
- globalMessages.unsupportedTagsValidationError,
885
- {
886
- unsupportedTags,
887
- },
888
- );
863
+ return formatMessage(messages.fallbackMsgLenError);
889
864
  }
890
- return errorMessage;
865
+ return false;
891
866
  };
892
867
 
893
868
  // Check for forbidden characters: square brackets [] and single curly braces {}
@@ -98,5 +98,5 @@
98
98
  }
99
99
 
100
100
  .create-dlt-msg {
101
- margin-left: 100px;
101
+ margin-left: 6.25rem;
102
102
  }
@@ -39,10 +39,8 @@ import formBuilderMessages from '../../../v2Components/FormBuilder/messages';
39
39
  import UnifiedPreview from '../../../v2Components/CommonTestAndPreview/UnifiedPreview';
40
40
  import TestAndPreviewSlidebox from '../../../v2Components/TestAndPreviewSlidebox';
41
41
  import withCreatives from '../../../hoc/withCreatives';
42
- import { validateTags } from '../../../utils/tagValidations';
43
42
  import {
44
43
  CHARLIMIT,
45
- SMS,
46
44
  SMS_TRAI_VAR,
47
45
  TAG,
48
46
  EMBEDDED,
@@ -51,16 +49,15 @@ import {
51
49
  ALL,
52
50
  LIBRARY,
53
51
  } from './constants';
52
+ import { SMS } from '../../CreativesContainer/constants';
54
53
  import v2EditSmsReducer from '../../Sms/Edit/reducer';
55
54
  import { v2SmsEditSagas } from '../../Sms/Edit/sagas';
56
55
  import ErrorInfoNote from '../../../v2Components/ErrorInfoNote';
57
56
  import { validateLiquidTemplateContent } from '../../../utils/commonUtils';
58
- import { hasLiquidSupportFeature } from '../../../utils/common';
59
57
  import { ANDROID } from '../../../v2Components/CommonTestAndPreview/constants';
60
58
 
61
59
  let varMap = {};
62
60
  let traiData = {};
63
- let tagValidationResponse = {};
64
61
  const { TextArea } = CapInput;
65
62
  const { CapLabelInline } = CapLabel;
66
63
 
@@ -94,7 +91,6 @@ export const SmsTraiEdit = (props) => {
94
91
  const [tags, updateTags] = useState([]);
95
92
  const [textAreaId, updateTextAreaId] = useState();
96
93
  const [isValidationError, updateIsValidationError] = useState(false);
97
- const [isTagValidationError, updateIsTagValidationError] = useState(false);
98
94
  const [totalMessageLength, setTotalMessageLength] = useState(0);
99
95
  const [isUnicodeAllowed, updateIsUnicodeAllowed] = useState(true);
100
96
  const [showMsgLengthNote, updateshowMsgLengthNote] = useState(false);
@@ -229,29 +225,6 @@ export const SmsTraiEdit = (props) => {
229
225
  }
230
226
  }, []);
231
227
 
232
- //performs tag validation
233
- useEffect(() => {
234
- if (
235
- !isFullMode &&
236
- updatedSmsEditor?.length > 0 &&
237
- !updatedSmsEditor.includes(SMS_TRAI_VAR)
238
- ) {
239
- tagValidationResponse =
240
- validateTags({
241
- content: updatedSmsEditor.join(''),
242
- tagsParam: tags,
243
- injectedTagsParams: injectedTags,
244
- location,
245
- tagModule: getDefaultTags,
246
- eventContextTags,
247
- isFullMode,
248
- }) || {};
249
- updateIsTagValidationError(
250
- tagValidationResponse.unsupportedTags.length > 0,
251
- );
252
- }
253
- }, [updatedSmsEditor, tags]);
254
-
255
228
  const computeUpdatedSmsEditor = () => {
256
229
  const arr = [...tempMsgArray];
257
230
  const varMapKeys = Object.keys(varMap)?.map((key) => Number(key.slice(8)))?.sort((a, b) => a - b) || [];
@@ -288,6 +261,8 @@ export const SmsTraiEdit = (props) => {
288
261
  };
289
262
 
290
263
  const onSubmitWrapper = () => {
264
+ setIsLiquidValidationError(false);
265
+ setLiquidErrorMessages({});
291
266
  const content = updatedSmsEditor.join('');
292
267
  const onError = ({ standardErrors, liquidErrors }) => {
293
268
  setLiquidErrorMessages({
@@ -298,6 +273,8 @@ export const SmsTraiEdit = (props) => {
298
273
  };
299
274
 
300
275
  const onSuccess = () => {
276
+ setIsLiquidValidationError(false);
277
+ setLiquidErrorMessages({});
301
278
  onDoneCallback();
302
279
  };
303
280
  validateLiquidTemplateContent(content, {
@@ -306,10 +283,6 @@ export const SmsTraiEdit = (props) => {
306
283
  messages: formBuilderMessages,
307
284
  onError,
308
285
  onSuccess,
309
- tagLookupMap: metaEntities?.tagLookupMap,
310
- eventContextTags,
311
- isLiquidFlow: true,
312
- forwardedTags: {},
313
286
  });
314
287
  };
315
288
 
@@ -548,17 +521,6 @@ export const SmsTraiEdit = (props) => {
548
521
  return countVarChar;
549
522
  };
550
523
 
551
- const tagValidationErrorMessage = () => {
552
- const { unsupportedTags = [] } = tagValidationResponse;
553
- let tagError = '';
554
- if (unsupportedTags.length > 0) {
555
- tagError = formatMessage(messages.unsupportedTagsValidationError, {
556
- unsupportedTags,
557
- });
558
- }
559
- return <CapError>{tagError}</CapError>;
560
- };
561
-
562
524
  const disablehandler = () => {
563
525
  if (traiData && !isEmpty(traiData)) {
564
526
  const msg = get(traiData, `versions.base.sms-editor`, '');
@@ -604,7 +566,6 @@ export const SmsTraiEdit = (props) => {
604
566
  setShowTestAndPreviewSlidebox(false);
605
567
  };
606
568
 
607
- const isLiquidSupportFeatureEnabled = hasLiquidSupportFeature();
608
569
  return (
609
570
  <>
610
571
  <CapSpin spinning={loading || fetchingLiquidTags} tip={fetchingLiquidTags && formatMessage(formBuilderMessages.liquidSpinText)}>
@@ -662,7 +623,6 @@ export const SmsTraiEdit = (props) => {
662
623
  <CapRow>
663
624
  {smsLengthForVar()}
664
625
  </CapRow>
665
- {isTagValidationError && tagValidationErrorMessage()}
666
626
  <CapCheckbox onChange={unicodeHandler} checked={isUnicodeAllowed} disabled={disablehandler()}>
667
627
  {formatMessage(messages.unicodeLabel)}
668
628
  </CapCheckbox>
@@ -693,9 +653,8 @@ export const SmsTraiEdit = (props) => {
693
653
  <FormattedMessage {...messages.testAndPreviewButtonLabel} />
694
654
  </CapButton>
695
655
  <CapButton
696
- onClick={isLiquidSupportFeatureEnabled ? onSubmitWrapper : onDoneCallback}
656
+ onClick={onSubmitWrapper}
697
657
  className="create-msg"
698
- disabled={isTagValidationError || (isLiquidSupportFeatureEnabled && !isObject(metaEntities?.tagLookupMap))}
699
658
  >
700
659
  <FormattedMessage {...messages.saveButtonLabel} />
701
660
  </CapButton>
@@ -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",
@@ -15176,7 +15176,7 @@ FREE GIFTS-
15176
15176
  <CapCheckbox
15177
15177
  checked={false}
15178
15178
  disabled={false}
15179
- key=".4"
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=".6"
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=".4"
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=".6"
26182
+ key=".5"
26183
26183
  style={
26184
26184
  Object {
26185
26185
  "marginBottom": "100px",
@@ -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,
@@ -121,5 +121,5 @@
121
121
  margin-top: $CAP_SPACE_08;
122
122
  }
123
123
  .test-and-preview-button {
124
- margin-left: 100px;
124
+ margin-left: 6.25rem;
125
125
  }
@@ -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
 
@@ -285,8 +285,8 @@ const WebPushCreate = ({
285
285
  const validateTemplateName = useCallback((value) => validateTemplateNameUtil(value), []);
286
286
 
287
287
  const validateTitle = useCallback(
288
- (value) => validateTitleUtil(value, formatMessage, messages),
289
- [formatMessage],
288
+ (value) => validateTitleUtil(value, formatMessage, messages, validationConfig, isFullMode),
289
+ [formatMessage, validationConfig, isFullMode],
290
290
  );
291
291
 
292
292
  const validateUrl = useCallback(
@@ -10,16 +10,31 @@ import globalMessages from '../../../Cap/messages';
10
10
  export const validateTemplateName = (value) => !value || value.trim() === '';
11
11
 
12
12
  /**
13
- * Validates notification title
13
+ * Validates notification title (required and optional tag validation)
14
14
  * @param {string} value - The title value
15
15
  * @param {Function} formatMessage - i18n format message function
16
16
  * @param {Object} messages - Message definitions
17
+ * @param {Object} [validationConfig] - Optional config for tag validation
18
+ * @param {boolean} [isFullMode] - Optional; when set with validationConfig, runs tag validation
17
19
  * @returns {string} Error message if invalid, empty string if valid
18
20
  */
19
- export const validateTitle = (value, formatMessage, messages) => {
21
+ export const validateTitle = (value, formatMessage, messages, validationConfig, isFullMode) => {
20
22
  if (!value || value.trim() === '') {
21
23
  return formatMessage(messages.titleRequired);
22
24
  }
25
+
26
+ if (validationConfig != null) {
27
+ const validationResponse = validateTags({
28
+ content: value,
29
+ ...validationConfig,
30
+ isFullMode,
31
+ }) || {};
32
+
33
+ if (validationResponse?.isBraceError) {
34
+ return formatMessage(globalMessages.unbalanacedCurlyBraces);
35
+ }
36
+ }
37
+
23
38
  return '';
24
39
  };
25
40
 
@@ -60,13 +75,7 @@ export const validateMessageContent = (value, formatMessage, messages, validatio
60
75
  ...validationConfig,
61
76
  isFullMode,
62
77
  }) || {};
63
-
64
- if (validationResponse?.unsupportedTags?.length) {
65
- return formatMessage(globalMessages.unsupportedTagsValidationError, {
66
- unsupportedTags: validationResponse.unsupportedTags.join(', '),
67
- });
68
- }
69
-
78
+
70
79
  if (validationResponse?.isBraceError) {
71
80
  return formatMessage(globalMessages.unbalanacedCurlyBraces);
72
81
  }
@@ -169,10 +169,8 @@ describe('validation', () => {
169
169
  describe('validateMessageContent', () => {
170
170
  const mockValidationConfig = {
171
171
  tagsParam: [],
172
- injectedTagsParams: [],
173
172
  location: {},
174
173
  tagModule: '',
175
- eventContextTags: [],
176
174
  };
177
175
 
178
176
  beforeEach(() => {
@@ -211,17 +209,6 @@ describe('validation', () => {
211
209
  });
212
210
  });
213
211
 
214
- it('should return error message for unsupported tags', () => {
215
- validateTags.mockReturnValue({
216
- unsupportedTags: ['tag1', 'tag2'],
217
- });
218
- const result = validateMessageContent('Message with {tag1} and {tag2}', mockFormatMessage, mockMessages, mockValidationConfig);
219
- expect(result).toBe('Unsupported tags: tag1, tag2');
220
- expect(mockFormatMessage).toHaveBeenCalledWith(globalMessages.unsupportedTagsValidationError, {
221
- unsupportedTags: 'tag1, tag2',
222
- });
223
- });
224
-
225
212
  it('should return error message for unbalanced curly braces', () => {
226
213
  validateTags.mockReturnValue({
227
214
  isBraceError: true,
@@ -231,22 +218,11 @@ describe('validation', () => {
231
218
  expect(mockFormatMessage).toHaveBeenCalledWith(globalMessages.unbalanacedCurlyBraces);
232
219
  });
233
220
 
234
- it('should return error message for both unsupported tags and brace error (unsupported tags takes precedence)', () => {
235
- validateTags.mockReturnValue({
236
- unsupportedTags: ['tag1'],
237
- isBraceError: true,
238
- });
239
- const result = validateMessageContent('Message with {tag1}', mockFormatMessage, mockMessages, mockValidationConfig);
240
- expect(result).toBe('Unsupported tags: tag1');
241
- });
242
-
243
221
  it('should pass validation config to validateTags', () => {
244
222
  const customConfig = {
245
223
  tagsParam: [{ id: 1, name: 'Tag1' }],
246
- injectedTagsParams: [{ id: 2, name: 'Tag2' }],
247
224
  location: { query: { type: 'test' } },
248
225
  tagModule: 'custom',
249
- eventContextTags: [{ id: 3, name: 'Tag3' }],
250
226
  };
251
227
  validateTags.mockReturnValue({});
252
228
  validateMessageContent('Valid message', mockFormatMessage, mockMessages, customConfig);