@capillarytech/creatives-library 8.0.285-alpha.1 → 8.0.286
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 +1 -0
- package/initialState.js +2 -0
- package/package.json +1 -1
- package/utils/common.js +8 -5
- package/utils/commonUtils.js +83 -2
- package/utils/tagValidations.js +222 -84
- package/utils/tests/commonUtil.test.js +118 -147
- package/utils/tests/tagValidations.test.js +358 -280
- package/v2Components/ErrorInfoNote/index.js +5 -2
- package/v2Components/FormBuilder/index.js +158 -64
- package/v2Components/FormBuilder/messages.js +8 -0
- package/v2Components/HtmlEditor/HTMLEditor.js +5 -0
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +1 -0
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +15 -0
- package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +2 -1
- package/v2Containers/Cap/mockData.js +14 -0
- package/v2Containers/Cap/reducer.js +55 -3
- package/v2Containers/Cap/tests/reducer.test.js +102 -0
- package/v2Containers/CreativesContainer/index.js +1 -0
- package/v2Containers/Email/index.js +5 -1
- package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +62 -10
- package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +115 -12
- package/v2Containers/FTP/index.js +51 -2
- package/v2Containers/FTP/messages.js +4 -0
- package/v2Containers/InApp/index.js +96 -1
- package/v2Containers/InApp/tests/index.test.js +6 -17
- package/v2Containers/InappAdvance/index.js +103 -2
- package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +24 -3
- package/v2Containers/Line/Container/Text/index.js +1 -0
- package/v2Containers/MobilePushNew/index.js +33 -2
- package/v2Containers/Rcs/index.js +37 -12
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +18 -4
- package/v2Containers/SmsTrai/Create/index.scss +1 -1
- package/v2Containers/SmsTrai/Edit/index.js +47 -6
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +6 -6
- package/v2Containers/Viber/index.js +1 -0
- package/v2Containers/Viber/index.scss +1 -1
- package/v2Containers/WebPush/Create/hooks/useTagManagement.js +3 -1
- package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +7 -0
- package/v2Containers/WebPush/Create/index.js +2 -2
- package/v2Containers/WebPush/Create/utils/validation.js +9 -18
- package/v2Containers/WebPush/Create/utils/validation.test.js +24 -0
- package/v2Containers/Whatsapp/index.js +17 -9
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +624 -248
- package/v2Containers/Zalo/index.js +11 -3
|
@@ -50,7 +50,9 @@ 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";
|
|
53
54
|
import { validateInAppContent } from "../../utils/commonUtils";
|
|
55
|
+
import { hasLiquidSupportFeature } from "../../utils/common";
|
|
54
56
|
import formBuilderMessages from "../../v2Components/FormBuilder/messages";
|
|
55
57
|
import { getSingleTab, hasAnyErrors } from "../InApp/utils";
|
|
56
58
|
import ErrorInfoNote from "../../v2Components/ErrorInfoNote";
|
|
@@ -815,9 +817,11 @@ export const InappAdvanced = (props) => {
|
|
|
815
817
|
const latestHtmlValues = await saveAllBeeInstances();
|
|
816
818
|
const payload = createPayload(latestHtmlValues);
|
|
817
819
|
|
|
820
|
+
// Validate the INAPP content
|
|
821
|
+
const isLiquidFlow = hasLiquidSupportFeature();
|
|
818
822
|
// Skip validation if no tags are available (e.g., in tests or when tags haven't loaded)
|
|
819
823
|
const hasTags = tags && tags.length > 0;
|
|
820
|
-
if (hasTags) {
|
|
824
|
+
if (isLiquidFlow && hasTags) {
|
|
821
825
|
validateInAppContent(payload, {
|
|
822
826
|
currentTab: panes === ANDROID ? 1 : 2, // Convert ANDROID/IOS to tab numbers
|
|
823
827
|
onError,
|
|
@@ -825,6 +829,10 @@ export const InappAdvanced = (props) => {
|
|
|
825
829
|
getLiquidTags: (content, callback) => globalActions.getLiquidTags(content, callback),
|
|
826
830
|
formatMessage,
|
|
827
831
|
messages: formBuilderMessages,
|
|
832
|
+
tagLookupMap: metaEntities?.tagLookupMap || {},
|
|
833
|
+
eventContextTags: metaEntities?.eventContextTags || [],
|
|
834
|
+
isLiquidFlow,
|
|
835
|
+
forwardedTags: {},
|
|
828
836
|
skipTags: (tag) => {
|
|
829
837
|
// Skip certain tags if needed
|
|
830
838
|
const skipRegexes = [
|
|
@@ -839,7 +847,92 @@ export const InappAdvanced = (props) => {
|
|
|
839
847
|
},
|
|
840
848
|
singleTab: getSingleTab(accountData),
|
|
841
849
|
});
|
|
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
|
+
}
|
|
842
934
|
} else {
|
|
935
|
+
// No tags available, skip validation and proceed directly
|
|
843
936
|
onSuccess();
|
|
844
937
|
}
|
|
845
938
|
};
|
|
@@ -945,7 +1038,15 @@ export const InappAdvanced = (props) => {
|
|
|
945
1038
|
)}
|
|
946
1039
|
<CapButton
|
|
947
1040
|
onClick={async () => {
|
|
948
|
-
|
|
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
|
+
}
|
|
949
1050
|
}}
|
|
950
1051
|
disabled={isDisableDone()}
|
|
951
1052
|
className="inapp-create-btn"
|
|
@@ -3117,6 +3117,7 @@ new message content.",
|
|
|
3117
3117
|
},
|
|
3118
3118
|
]
|
|
3119
3119
|
}
|
|
3120
|
+
showTruncatedTooltip={false}
|
|
3120
3121
|
size="large"
|
|
3121
3122
|
style={
|
|
3122
3123
|
Object {
|
|
@@ -3135,6 +3136,7 @@ new message content.",
|
|
|
3135
3136
|
/>
|
|
3136
3137
|
}
|
|
3137
3138
|
onChange={[Function]}
|
|
3139
|
+
onDropdownVisibleChange={[Function]}
|
|
3138
3140
|
removeIcon={
|
|
3139
3141
|
<CapIcon
|
|
3140
3142
|
size="s"
|
|
@@ -3199,6 +3201,7 @@ new message content.",
|
|
|
3199
3201
|
onBlur={[Function]}
|
|
3200
3202
|
onChange={[Function]}
|
|
3201
3203
|
onDeselect={[Function]}
|
|
3204
|
+
onDropdownVisibleChange={[Function]}
|
|
3202
3205
|
onFocus={[Function]}
|
|
3203
3206
|
onInputKeyDown={[Function]}
|
|
3204
3207
|
onSearch={[Function]}
|
|
@@ -3437,7 +3440,11 @@ new message content.",
|
|
|
3437
3440
|
}
|
|
3438
3441
|
}
|
|
3439
3442
|
title=""
|
|
3440
|
-
|
|
3443
|
+
>
|
|
3444
|
+
<div
|
|
3445
|
+
className="cap-select-option-tooltip"
|
|
3446
|
+
/>
|
|
3447
|
+
</div>
|
|
3441
3448
|
</div>
|
|
3442
3449
|
<span
|
|
3443
3450
|
className="ant-select-arrow"
|
|
@@ -6940,6 +6947,7 @@ new message content.",
|
|
|
6940
6947
|
},
|
|
6941
6948
|
]
|
|
6942
6949
|
}
|
|
6950
|
+
showTruncatedTooltip={false}
|
|
6943
6951
|
size="large"
|
|
6944
6952
|
style={
|
|
6945
6953
|
Object {
|
|
@@ -6958,6 +6966,7 @@ new message content.",
|
|
|
6958
6966
|
/>
|
|
6959
6967
|
}
|
|
6960
6968
|
onChange={[Function]}
|
|
6969
|
+
onDropdownVisibleChange={[Function]}
|
|
6961
6970
|
removeIcon={
|
|
6962
6971
|
<CapIcon
|
|
6963
6972
|
size="s"
|
|
@@ -7022,6 +7031,7 @@ new message content.",
|
|
|
7022
7031
|
onBlur={[Function]}
|
|
7023
7032
|
onChange={[Function]}
|
|
7024
7033
|
onDeselect={[Function]}
|
|
7034
|
+
onDropdownVisibleChange={[Function]}
|
|
7025
7035
|
onFocus={[Function]}
|
|
7026
7036
|
onInputKeyDown={[Function]}
|
|
7027
7037
|
onSearch={[Function]}
|
|
@@ -7260,7 +7270,11 @@ new message content.",
|
|
|
7260
7270
|
}
|
|
7261
7271
|
}
|
|
7262
7272
|
title=""
|
|
7263
|
-
|
|
7273
|
+
>
|
|
7274
|
+
<div
|
|
7275
|
+
className="cap-select-option-tooltip"
|
|
7276
|
+
/>
|
|
7277
|
+
</div>
|
|
7264
7278
|
</div>
|
|
7265
7279
|
<span
|
|
7266
7280
|
className="ant-select-arrow"
|
|
@@ -10707,6 +10721,7 @@ new message content.",
|
|
|
10707
10721
|
},
|
|
10708
10722
|
]
|
|
10709
10723
|
}
|
|
10724
|
+
showTruncatedTooltip={false}
|
|
10710
10725
|
size="large"
|
|
10711
10726
|
style={
|
|
10712
10727
|
Object {
|
|
@@ -10725,6 +10740,7 @@ new message content.",
|
|
|
10725
10740
|
/>
|
|
10726
10741
|
}
|
|
10727
10742
|
onChange={[Function]}
|
|
10743
|
+
onDropdownVisibleChange={[Function]}
|
|
10728
10744
|
removeIcon={
|
|
10729
10745
|
<CapIcon
|
|
10730
10746
|
size="s"
|
|
@@ -10789,6 +10805,7 @@ new message content.",
|
|
|
10789
10805
|
onBlur={[Function]}
|
|
10790
10806
|
onChange={[Function]}
|
|
10791
10807
|
onDeselect={[Function]}
|
|
10808
|
+
onDropdownVisibleChange={[Function]}
|
|
10792
10809
|
onFocus={[Function]}
|
|
10793
10810
|
onInputKeyDown={[Function]}
|
|
10794
10811
|
onSearch={[Function]}
|
|
@@ -11027,7 +11044,11 @@ new message content.",
|
|
|
11027
11044
|
}
|
|
11028
11045
|
}
|
|
11029
11046
|
title=""
|
|
11030
|
-
|
|
11047
|
+
>
|
|
11048
|
+
<div
|
|
11049
|
+
className="cap-select-option-tooltip"
|
|
11050
|
+
/>
|
|
11051
|
+
</div>
|
|
11031
11052
|
</div>
|
|
11032
11053
|
<span
|
|
11033
11054
|
className="ant-select-arrow"
|
|
@@ -77,6 +77,7 @@ 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";
|
|
80
81
|
import formBuilderMessages from "../../v2Components/FormBuilder/messages";
|
|
81
82
|
import { validateMobilePushContent } from "../../utils/commonUtils";
|
|
82
83
|
import { getSingleTab } from "../InApp/utils";
|
|
@@ -798,9 +799,10 @@ const MobilePushNew = ({
|
|
|
798
799
|
(value) => {
|
|
799
800
|
let errorTemplateDescMessage = "";
|
|
800
801
|
|
|
801
|
-
const { isBraceError } = validateTags({
|
|
802
|
+
const { unsupportedTags, isBraceError } = validateTags({
|
|
802
803
|
content: value,
|
|
803
804
|
tagsParam: tags,
|
|
805
|
+
injectedTagsParams: injectedTags,
|
|
804
806
|
location,
|
|
805
807
|
tagModule: getDefaultTags,
|
|
806
808
|
isFullMode,
|
|
@@ -810,6 +812,14 @@ const MobilePushNew = ({
|
|
|
810
812
|
messages.emptyTemplateDescErrorMessage
|
|
811
813
|
);
|
|
812
814
|
}
|
|
815
|
+
if (unsupportedTags?.length > 0) {
|
|
816
|
+
errorTemplateDescMessage = formatMessage(
|
|
817
|
+
globalMessages.unsupportedTagsValidationError,
|
|
818
|
+
{
|
|
819
|
+
unsupportedTags,
|
|
820
|
+
}
|
|
821
|
+
);
|
|
822
|
+
}
|
|
813
823
|
if (isBraceError) {
|
|
814
824
|
errorTemplateDescMessage = formatMessage(
|
|
815
825
|
globalMessages.unbalanacedCurlyBraces
|
|
@@ -2596,6 +2606,20 @@ const MobilePushNew = ({
|
|
|
2596
2606
|
getLiquidTags: globalActionsProps.getLiquidTags,
|
|
2597
2607
|
formatMessage,
|
|
2598
2608
|
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
|
+
},
|
|
2599
2623
|
singleTab: getSingleTab(accountData),
|
|
2600
2624
|
});
|
|
2601
2625
|
}, [
|
|
@@ -2604,9 +2628,12 @@ const MobilePushNew = ({
|
|
|
2604
2628
|
activeTab,
|
|
2605
2629
|
globalActionsProps,
|
|
2606
2630
|
formatMessage,
|
|
2631
|
+
metaEntities,
|
|
2607
2632
|
accountData,
|
|
2608
2633
|
]);
|
|
2609
2634
|
|
|
2635
|
+
const isLiquidFlow = hasLiquidSupportFeature();
|
|
2636
|
+
|
|
2610
2637
|
useEffect(() => {
|
|
2611
2638
|
// Always map to { label } for both platforms
|
|
2612
2639
|
const newButtons = Array.isArray(ctaData)
|
|
@@ -3003,7 +3030,11 @@ const MobilePushNew = ({
|
|
|
3003
3030
|
<CapButton
|
|
3004
3031
|
type="primary"
|
|
3005
3032
|
onClick={() => {
|
|
3006
|
-
|
|
3033
|
+
if (isLiquidFlow) {
|
|
3034
|
+
liquidMiddleWare();
|
|
3035
|
+
} else {
|
|
3036
|
+
handleSave();
|
|
3037
|
+
}
|
|
3007
3038
|
}}
|
|
3008
3039
|
className="save-button"
|
|
3009
3040
|
disabled={isSaveDisabled}
|
|
@@ -394,15 +394,23 @@ export const Rcs = (props) => {
|
|
|
394
394
|
const validationResponse =
|
|
395
395
|
validateTags({
|
|
396
396
|
content: contentForValidation,
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
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;
|
|
406
414
|
if (type === TITLE_TEXT) setTemplateTitleError(errorMsg);
|
|
407
415
|
if (type === MESSAGE_TEXT) setTemplateDescError(errorMsg);
|
|
408
416
|
};
|
|
@@ -827,9 +835,10 @@ export const Rcs = (props) => {
|
|
|
827
835
|
|
|
828
836
|
const templateDescErrorHandler = (value) => {
|
|
829
837
|
let errorMessage = false;
|
|
830
|
-
const { isBraceError } = validateTags({
|
|
838
|
+
const { unsupportedTags, isBraceError } = validateTags({
|
|
831
839
|
content: value,
|
|
832
840
|
tagsParam: tags,
|
|
841
|
+
injectedTagsParams: injectedTags,
|
|
833
842
|
location,
|
|
834
843
|
tagModule: getDefaultTags,
|
|
835
844
|
isFullMode,
|
|
@@ -859,10 +868,26 @@ export const Rcs = (props) => {
|
|
|
859
868
|
};
|
|
860
869
|
|
|
861
870
|
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
|
+
}) || {};
|
|
862
880
|
if (value?.length > FALLBACK_MESSAGE_MAX_LENGTH) {
|
|
863
|
-
|
|
881
|
+
errorMessage = formatMessage(messages.fallbackMsgLenError);
|
|
882
|
+
} else if (unsupportedTags?.length > 0) {
|
|
883
|
+
errorMessage = formatMessage(
|
|
884
|
+
globalMessages.unsupportedTagsValidationError,
|
|
885
|
+
{
|
|
886
|
+
unsupportedTags,
|
|
887
|
+
},
|
|
888
|
+
);
|
|
864
889
|
}
|
|
865
|
-
return
|
|
890
|
+
return errorMessage;
|
|
866
891
|
};
|
|
867
892
|
|
|
868
893
|
// Check for forbidden characters: square brackets [] and single curly braces {}
|
|
@@ -86505,6 +86505,7 @@ new message content.",
|
|
|
86505
86505
|
},
|
|
86506
86506
|
]
|
|
86507
86507
|
}
|
|
86508
|
+
showTruncatedTooltip={false}
|
|
86508
86509
|
size="large"
|
|
86509
86510
|
style={
|
|
86510
86511
|
Object {
|
|
@@ -86524,6 +86525,7 @@ new message content.",
|
|
|
86524
86525
|
/>
|
|
86525
86526
|
}
|
|
86526
86527
|
onChange={[Function]}
|
|
86528
|
+
onDropdownVisibleChange={[Function]}
|
|
86527
86529
|
removeIcon={
|
|
86528
86530
|
<_default
|
|
86529
86531
|
size="s"
|
|
@@ -86589,6 +86591,7 @@ new message content.",
|
|
|
86589
86591
|
onBlur={[Function]}
|
|
86590
86592
|
onChange={[Function]}
|
|
86591
86593
|
onDeselect={[Function]}
|
|
86594
|
+
onDropdownVisibleChange={[Function]}
|
|
86592
86595
|
onFocus={[Function]}
|
|
86593
86596
|
onInputKeyDown={[Function]}
|
|
86594
86597
|
onSearch={[Function]}
|
|
@@ -86827,9 +86830,13 @@ new message content.",
|
|
|
86827
86830
|
"opacity": 1,
|
|
86828
86831
|
}
|
|
86829
86832
|
}
|
|
86830
|
-
title="
|
|
86833
|
+
title=""
|
|
86831
86834
|
>
|
|
86832
|
-
|
|
86835
|
+
<div
|
|
86836
|
+
className="cap-select-option-tooltip"
|
|
86837
|
+
>
|
|
86838
|
+
Vertical Medium
|
|
86839
|
+
</div>
|
|
86833
86840
|
</div>
|
|
86834
86841
|
</div>
|
|
86835
86842
|
<span
|
|
@@ -105847,6 +105854,7 @@ new message content.",
|
|
|
105847
105854
|
},
|
|
105848
105855
|
]
|
|
105849
105856
|
}
|
|
105857
|
+
showTruncatedTooltip={false}
|
|
105850
105858
|
size="large"
|
|
105851
105859
|
style={
|
|
105852
105860
|
Object {
|
|
@@ -105866,6 +105874,7 @@ new message content.",
|
|
|
105866
105874
|
/>
|
|
105867
105875
|
}
|
|
105868
105876
|
onChange={[Function]}
|
|
105877
|
+
onDropdownVisibleChange={[Function]}
|
|
105869
105878
|
removeIcon={
|
|
105870
105879
|
<_default
|
|
105871
105880
|
size="s"
|
|
@@ -105931,6 +105940,7 @@ new message content.",
|
|
|
105931
105940
|
onBlur={[Function]}
|
|
105932
105941
|
onChange={[Function]}
|
|
105933
105942
|
onDeselect={[Function]}
|
|
105943
|
+
onDropdownVisibleChange={[Function]}
|
|
105934
105944
|
onFocus={[Function]}
|
|
105935
105945
|
onInputKeyDown={[Function]}
|
|
105936
105946
|
onSearch={[Function]}
|
|
@@ -106169,9 +106179,13 @@ new message content.",
|
|
|
106169
106179
|
"opacity": 1,
|
|
106170
106180
|
}
|
|
106171
106181
|
}
|
|
106172
|
-
title="
|
|
106182
|
+
title=""
|
|
106173
106183
|
>
|
|
106174
|
-
|
|
106184
|
+
<div
|
|
106185
|
+
className="cap-select-option-tooltip"
|
|
106186
|
+
>
|
|
106187
|
+
Vertical Medium
|
|
106188
|
+
</div>
|
|
106175
106189
|
</div>
|
|
106176
106190
|
</div>
|
|
106177
106191
|
<span
|
|
@@ -39,8 +39,10 @@ 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';
|
|
42
43
|
import {
|
|
43
44
|
CHARLIMIT,
|
|
45
|
+
SMS,
|
|
44
46
|
SMS_TRAI_VAR,
|
|
45
47
|
TAG,
|
|
46
48
|
EMBEDDED,
|
|
@@ -49,15 +51,16 @@ import {
|
|
|
49
51
|
ALL,
|
|
50
52
|
LIBRARY,
|
|
51
53
|
} from './constants';
|
|
52
|
-
import { SMS } from '../../CreativesContainer/constants';
|
|
53
54
|
import v2EditSmsReducer from '../../Sms/Edit/reducer';
|
|
54
55
|
import { v2SmsEditSagas } from '../../Sms/Edit/sagas';
|
|
55
56
|
import ErrorInfoNote from '../../../v2Components/ErrorInfoNote';
|
|
56
57
|
import { validateLiquidTemplateContent } from '../../../utils/commonUtils';
|
|
58
|
+
import { hasLiquidSupportFeature } from '../../../utils/common';
|
|
57
59
|
import { ANDROID } from '../../../v2Components/CommonTestAndPreview/constants';
|
|
58
60
|
|
|
59
61
|
let varMap = {};
|
|
60
62
|
let traiData = {};
|
|
63
|
+
let tagValidationResponse = {};
|
|
61
64
|
const { TextArea } = CapInput;
|
|
62
65
|
const { CapLabelInline } = CapLabel;
|
|
63
66
|
|
|
@@ -91,6 +94,7 @@ export const SmsTraiEdit = (props) => {
|
|
|
91
94
|
const [tags, updateTags] = useState([]);
|
|
92
95
|
const [textAreaId, updateTextAreaId] = useState();
|
|
93
96
|
const [isValidationError, updateIsValidationError] = useState(false);
|
|
97
|
+
const [isTagValidationError, updateIsTagValidationError] = useState(false);
|
|
94
98
|
const [totalMessageLength, setTotalMessageLength] = useState(0);
|
|
95
99
|
const [isUnicodeAllowed, updateIsUnicodeAllowed] = useState(true);
|
|
96
100
|
const [showMsgLengthNote, updateshowMsgLengthNote] = useState(false);
|
|
@@ -225,6 +229,29 @@ export const SmsTraiEdit = (props) => {
|
|
|
225
229
|
}
|
|
226
230
|
}, []);
|
|
227
231
|
|
|
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
|
+
|
|
228
255
|
const computeUpdatedSmsEditor = () => {
|
|
229
256
|
const arr = [...tempMsgArray];
|
|
230
257
|
const varMapKeys = Object.keys(varMap)?.map((key) => Number(key.slice(8)))?.sort((a, b) => a - b) || [];
|
|
@@ -261,8 +288,6 @@ export const SmsTraiEdit = (props) => {
|
|
|
261
288
|
};
|
|
262
289
|
|
|
263
290
|
const onSubmitWrapper = () => {
|
|
264
|
-
setIsLiquidValidationError(false);
|
|
265
|
-
setLiquidErrorMessages({});
|
|
266
291
|
const content = updatedSmsEditor.join('');
|
|
267
292
|
const onError = ({ standardErrors, liquidErrors }) => {
|
|
268
293
|
setLiquidErrorMessages({
|
|
@@ -273,8 +298,6 @@ export const SmsTraiEdit = (props) => {
|
|
|
273
298
|
};
|
|
274
299
|
|
|
275
300
|
const onSuccess = () => {
|
|
276
|
-
setIsLiquidValidationError(false);
|
|
277
|
-
setLiquidErrorMessages({});
|
|
278
301
|
onDoneCallback();
|
|
279
302
|
};
|
|
280
303
|
validateLiquidTemplateContent(content, {
|
|
@@ -283,6 +306,10 @@ export const SmsTraiEdit = (props) => {
|
|
|
283
306
|
messages: formBuilderMessages,
|
|
284
307
|
onError,
|
|
285
308
|
onSuccess,
|
|
309
|
+
tagLookupMap: metaEntities?.tagLookupMap,
|
|
310
|
+
eventContextTags,
|
|
311
|
+
isLiquidFlow: true,
|
|
312
|
+
forwardedTags: {},
|
|
286
313
|
});
|
|
287
314
|
};
|
|
288
315
|
|
|
@@ -521,6 +548,17 @@ export const SmsTraiEdit = (props) => {
|
|
|
521
548
|
return countVarChar;
|
|
522
549
|
};
|
|
523
550
|
|
|
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
|
+
|
|
524
562
|
const disablehandler = () => {
|
|
525
563
|
if (traiData && !isEmpty(traiData)) {
|
|
526
564
|
const msg = get(traiData, `versions.base.sms-editor`, '');
|
|
@@ -566,6 +604,7 @@ export const SmsTraiEdit = (props) => {
|
|
|
566
604
|
setShowTestAndPreviewSlidebox(false);
|
|
567
605
|
};
|
|
568
606
|
|
|
607
|
+
const isLiquidSupportFeatureEnabled = hasLiquidSupportFeature();
|
|
569
608
|
return (
|
|
570
609
|
<>
|
|
571
610
|
<CapSpin spinning={loading || fetchingLiquidTags} tip={fetchingLiquidTags && formatMessage(formBuilderMessages.liquidSpinText)}>
|
|
@@ -623,6 +662,7 @@ export const SmsTraiEdit = (props) => {
|
|
|
623
662
|
<CapRow>
|
|
624
663
|
{smsLengthForVar()}
|
|
625
664
|
</CapRow>
|
|
665
|
+
{isTagValidationError && tagValidationErrorMessage()}
|
|
626
666
|
<CapCheckbox onChange={unicodeHandler} checked={isUnicodeAllowed} disabled={disablehandler()}>
|
|
627
667
|
{formatMessage(messages.unicodeLabel)}
|
|
628
668
|
</CapCheckbox>
|
|
@@ -653,8 +693,9 @@ export const SmsTraiEdit = (props) => {
|
|
|
653
693
|
<FormattedMessage {...messages.testAndPreviewButtonLabel} />
|
|
654
694
|
</CapButton>
|
|
655
695
|
<CapButton
|
|
656
|
-
onClick={onSubmitWrapper}
|
|
696
|
+
onClick={isLiquidSupportFeatureEnabled ? onSubmitWrapper : onDoneCallback}
|
|
657
697
|
className="create-msg"
|
|
698
|
+
disabled={isTagValidationError || (isLiquidSupportFeatureEnabled && !isObject(metaEntities?.tagLookupMap))}
|
|
658
699
|
>
|
|
659
700
|
<FormattedMessage {...messages.saveButtonLabel} />
|
|
660
701
|
</CapButton>
|