@capillarytech/creatives-library 8.0.114-alpha.1 → 8.0.114
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/package.json +1 -1
- package/utils/commonUtils.js +3 -359
- package/utils/tagValidations.js +5 -20
- package/utils/tests/commonUtil.test.js +171 -474
- package/utils/tests/tagValidations.test.js +2 -89
- package/v2Components/ErrorInfoNote/index.js +46 -114
- package/v2Components/ErrorInfoNote/messages.js +0 -25
- package/v2Components/ErrorInfoNote/style.scss +1 -14
- package/v2Components/FormBuilder/index.js +127 -204
- package/v2Components/FormBuilder/messages.js +1 -1
- package/v2Containers/Cap/reducer.js +4 -4
- package/v2Containers/CreativesContainer/SlideBoxContent.js +3 -23
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +1 -3
- package/v2Containers/CreativesContainer/constants.js +1 -4
- package/v2Containers/CreativesContainer/index.js +19 -44
- package/v2Containers/CreativesContainer/messages.js +0 -4
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +3 -21
- package/v2Containers/Ebill/index.js +3 -3
- package/v2Containers/EmailWrapper/components/EmailWrapperView.js +1 -1
- package/v2Containers/InApp/index.js +50 -123
- package/v2Containers/InApp/tests/index.test.js +1 -1
- package/v2Containers/InApp/tests/sagas.test.js +1 -1
- package/v2Containers/InApp/utils.js +0 -37
- package/v2Containers/MobilePush/Create/index.js +20 -24
- package/v2Containers/MobilePush/Edit/index.js +2 -6
- package/v2Containers/MobilepushWrapper/index.js +0 -2
- package/v2Containers/Sms/Create/index.js +0 -1
- package/v2Containers/Sms/Edit/index.js +0 -2
- package/v2Containers/SmsWrapper/index.js +0 -2
- package/v2Containers/Whatsapp/constants.js +1 -1
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +57476 -0
- package/v2Containers/Whatsapp/tests/index.test.js +88 -0
- package/v2Components/ErrorInfoNote/ErrorTypeRenderer.js +0 -127
- package/v2Components/ErrorInfoNote/ErrorTypeRenderer.test.js +0 -147
- package/v2Components/ErrorInfoNote/utils.js +0 -38
- package/v2Components/ErrorInfoNote/utils.test.js +0 -156
- package/v2Containers/InApp/tests/utils.test.js +0 -41
|
@@ -1,15 +1,6 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import '@testing-library/jest-dom';
|
|
2
|
-
import {
|
|
3
|
-
checkSupport,
|
|
4
|
-
extractNames,
|
|
5
|
-
getTagMapValue,
|
|
6
|
-
getForwardedMapValues,
|
|
7
|
-
preprocessHtml,
|
|
8
|
-
validateIfTagClosed,
|
|
9
|
-
validateTags,
|
|
10
|
-
skipTags,
|
|
11
|
-
isInsideLiquidBlock,
|
|
12
|
-
} from '../tagValidations';
|
|
3
|
+
import { checkSupport, extractNames, getTagMapValue,getForwardedMapValues, preprocessHtml, validateIfTagClosed,validateTags, skipTags } from '../tagValidations';
|
|
13
4
|
import { eventContextTags } from '../../v2Containers/TagList/tests/mockdata';
|
|
14
5
|
|
|
15
6
|
describe("check if curly brackets are balanced", () => {
|
|
@@ -815,82 +806,4 @@ describe('getForwardedMapValues', () => {
|
|
|
815
806
|
|
|
816
807
|
expect(input).toEqual(inputCopy);
|
|
817
808
|
});
|
|
818
|
-
});
|
|
819
|
-
|
|
820
|
-
describe('isInsideLiquidBlock', () => {
|
|
821
|
-
it('returns true for index inside a single block', () => {
|
|
822
|
-
const content = 'Hello {% assign foo = 1 %} World';
|
|
823
|
-
// Index of 'a' in 'assign' inside the block
|
|
824
|
-
const tagIndex = content.indexOf('assign');
|
|
825
|
-
expect(isInsideLiquidBlock(content, tagIndex)).toBe(true);
|
|
826
|
-
});
|
|
827
|
-
|
|
828
|
-
it('returns false for index outside any block', () => {
|
|
829
|
-
const content = 'Hello {% assign foo = 1 %} World';
|
|
830
|
-
// Index of 'H' in 'Hello'
|
|
831
|
-
expect(isInsideLiquidBlock(content, 0)).toBe(false);
|
|
832
|
-
// Index of 'W' in 'World'
|
|
833
|
-
expect(isInsideLiquidBlock(content, content.indexOf('World'))).toBe(false);
|
|
834
|
-
});
|
|
835
|
-
|
|
836
|
-
it('returns true for index at the start of a block', () => {
|
|
837
|
-
const content = 'Hello {% assign foo = 1 %} World';
|
|
838
|
-
// Index of '{' in '{%'
|
|
839
|
-
const tagIndex = content.indexOf('{%');
|
|
840
|
-
expect(isInsideLiquidBlock(content, tagIndex)).toBe(true);
|
|
841
|
-
});
|
|
842
|
-
|
|
843
|
-
it('returns false for index at the end of a block (exclusive)', () => {
|
|
844
|
-
const content = 'Hello {% assign foo = 1 %} World';
|
|
845
|
-
// Index just after the closing '%}'
|
|
846
|
-
const blockEnd = content.indexOf('%}') + 2;
|
|
847
|
-
expect(isInsideLiquidBlock(content, blockEnd)).toBe(false);
|
|
848
|
-
});
|
|
849
|
-
|
|
850
|
-
it('returns true for index inside the second of multiple blocks', () => {
|
|
851
|
-
const content = 'A {% first %} B {% second %} C';
|
|
852
|
-
const tagIndex = content.indexOf('second');
|
|
853
|
-
expect(isInsideLiquidBlock(content, tagIndex)).toBe(true);
|
|
854
|
-
});
|
|
855
|
-
|
|
856
|
-
it('returns false for index between blocks', () => {
|
|
857
|
-
const content = 'A {% first %} B {% second %} C';
|
|
858
|
-
// Index of 'B' (between blocks)
|
|
859
|
-
const tagIndex = content.indexOf('B');
|
|
860
|
-
expect(isInsideLiquidBlock(content, tagIndex)).toBe(false);
|
|
861
|
-
});
|
|
862
|
-
|
|
863
|
-
it('returns false for empty string', () => {
|
|
864
|
-
expect(isInsideLiquidBlock('', 0)).toBe(false);
|
|
865
|
-
});
|
|
866
|
-
|
|
867
|
-
it('returns false if there are no blocks', () => {
|
|
868
|
-
const content = 'Just some text with no blocks';
|
|
869
|
-
expect(isInsideLiquidBlock(content, 5)).toBe(false);
|
|
870
|
-
});
|
|
871
|
-
|
|
872
|
-
it('returns false for negative index', () => {
|
|
873
|
-
const content = 'Hello {% assign foo = 1 %} World';
|
|
874
|
-
expect(isInsideLiquidBlock(content, -1)).toBe(false);
|
|
875
|
-
});
|
|
876
|
-
|
|
877
|
-
it('returns false for index beyond string length', () => {
|
|
878
|
-
const content = 'Hello {% assign foo = 1 %} World';
|
|
879
|
-
expect(isInsideLiquidBlock(content, 100)).toBe(false);
|
|
880
|
-
});
|
|
881
|
-
|
|
882
|
-
it('works for nested-like blocks (not truly nested)', () => {
|
|
883
|
-
const content = 'A {% outer {% inner %} outer %} B';
|
|
884
|
-
// Index of 'inner' (should be inside the first block)
|
|
885
|
-
const tagIndex = content.indexOf('inner');
|
|
886
|
-
expect(isInsideLiquidBlock(content, tagIndex)).toBe(true);
|
|
887
|
-
});
|
|
888
|
-
|
|
889
|
-
it('returns true for index at last char inside block', () => {
|
|
890
|
-
const content = 'A {% foo %} B';
|
|
891
|
-
// Index of last char inside block (just before %})
|
|
892
|
-
const blockStart = content.indexOf('{%');
|
|
893
|
-
const blockEnd = content.indexOf('%}');
|
|
894
|
-
expect(isInsideLiquidBlock(content, blockEnd - 1)).toBe(true);
|
|
895
|
-
});
|
|
896
809
|
});
|
|
@@ -9,25 +9,19 @@ import {
|
|
|
9
9
|
FormattedMessage,
|
|
10
10
|
FormattedNumber,
|
|
11
11
|
injectIntl,
|
|
12
|
+
intlShape,
|
|
12
13
|
} from "react-intl";
|
|
13
14
|
import "./style.scss";
|
|
14
15
|
import messages from "./messages";
|
|
15
|
-
import { processErrors } from "./utils";
|
|
16
|
-
import ErrorTypeRenderer from "./ErrorTypeRenderer";
|
|
17
|
-
import { ANDROID, GENERIC, IOS } from "../../v2Containers/CreativesContainer/constants";
|
|
18
16
|
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
<>
|
|
26
|
-
{title && (
|
|
17
|
+
export const ErrorInfoNote = (props) => {
|
|
18
|
+
|
|
19
|
+
const { LIQUID_ERROR_MSG = [], STANDARD_ERROR_MSG = [] } = props?.errorMessages || {};
|
|
20
|
+
|
|
21
|
+
const ErrorSection = ({ title = "", errors = [], liquidError = false }) => (
|
|
22
|
+
<>
|
|
27
23
|
<CapRow
|
|
28
|
-
className={`error-header ${
|
|
29
|
-
!liquidError ? "standard-error-header" : ""
|
|
30
|
-
}`}
|
|
24
|
+
className={`error-header ${!liquidError ? "standard-error-header": ""}`}
|
|
31
25
|
>
|
|
32
26
|
<>
|
|
33
27
|
<CapIcon size="s" type="warning" className="warning-icon" />
|
|
@@ -38,7 +32,8 @@ const ErrorSection = ({
|
|
|
38
32
|
<CapButton
|
|
39
33
|
type="flat"
|
|
40
34
|
className="add-btn"
|
|
41
|
-
onClick={() =>
|
|
35
|
+
onClick={() =>
|
|
36
|
+
window.open(`https://docs.capillarytech.com/docs/liquid-language-in-messages`, "_blank")
|
|
42
37
|
}
|
|
43
38
|
>
|
|
44
39
|
<FormattedMessage {...messages.liquidDoc} />
|
|
@@ -47,111 +42,48 @@ const ErrorSection = ({
|
|
|
47
42
|
)}
|
|
48
43
|
</>
|
|
49
44
|
</CapRow>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
dataSource={errors}
|
|
60
|
-
renderItem={(error, index) => (
|
|
61
|
-
<CapList.Item>
|
|
62
|
-
<CapLabel type="label2" className="cap-list-v2-error-item">
|
|
63
|
-
<CapLabel type="label2">
|
|
64
|
-
<FormattedNumber value={index + 1} />.
|
|
45
|
+
<CapList
|
|
46
|
+
className="error-list"
|
|
47
|
+
size="small"
|
|
48
|
+
dataSource={errors}
|
|
49
|
+
renderItem={(error, index) => (
|
|
50
|
+
<CapList.Item>
|
|
51
|
+
<CapLabel type="label2" className="cap-list-v2-error-item">
|
|
52
|
+
<CapLabel type="label2"><FormattedNumber value={index + 1} />.</CapLabel>
|
|
53
|
+
<CapLabel type="label2">{error}</CapLabel>
|
|
65
54
|
</CapLabel>
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
</CapList.Item>
|
|
69
|
-
)}
|
|
70
|
-
/>
|
|
71
|
-
</>
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
ErrorSection.propTypes = {
|
|
75
|
-
title: PropTypes.node.isRequired,
|
|
76
|
-
errors: PropTypes.array,
|
|
77
|
-
liquidError: PropTypes.bool,
|
|
78
|
-
platformLabel: PropTypes.string,
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
ErrorSection.defaultProps = {
|
|
82
|
-
errors: [],
|
|
83
|
-
liquidError: false,
|
|
84
|
-
platformLabel: null,
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
export const ErrorInfoNote = (props) => {
|
|
88
|
-
const { errorMessages } = props;
|
|
89
|
-
|
|
90
|
-
const {
|
|
91
|
-
LIQUID_ERROR_MSG: rawLiquidErrors = [],
|
|
92
|
-
STANDARD_ERROR_MSG: rawStandardErrors = [],
|
|
93
|
-
} = errorMessages || {};
|
|
94
|
-
|
|
95
|
-
// Detect if platform-specific (ANDROID/IOS) or GENERIC
|
|
96
|
-
const isObject = typeof rawStandardErrors === 'object' && rawStandardErrors !== null;
|
|
97
|
-
const isNotArray = !Array.isArray(rawStandardErrors);
|
|
98
|
-
const hasPlatformKeys = isObject && isNotArray && [ANDROID, IOS, GENERIC].some((key) => key in rawStandardErrors);
|
|
99
|
-
|
|
100
|
-
if (hasPlatformKeys) {
|
|
101
|
-
// Platform-specific
|
|
102
|
-
const androidErrors = {
|
|
103
|
-
standard: processErrors(rawStandardErrors, 'standard', ANDROID, messages),
|
|
104
|
-
liquid: processErrors(rawLiquidErrors, 'liquid', ANDROID, messages),
|
|
105
|
-
};
|
|
106
|
-
const iosErrors = {
|
|
107
|
-
standard: processErrors(rawStandardErrors, 'standard', IOS, messages),
|
|
108
|
-
liquid: processErrors(rawLiquidErrors, 'liquid', IOS, messages),
|
|
109
|
-
};
|
|
110
|
-
return (
|
|
111
|
-
<ErrorTypeRenderer
|
|
112
|
-
androidErrors={androidErrors}
|
|
113
|
-
iosErrors={iosErrors}
|
|
114
|
-
ErrorSectionComponent={ErrorSection}
|
|
55
|
+
</CapList.Item>
|
|
56
|
+
)}
|
|
115
57
|
/>
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const genericStandard = processErrors(rawStandardErrors, 'standard', null, messages);
|
|
120
|
-
const genericLiquid = processErrors(rawLiquidErrors, 'liquid', null, messages);
|
|
58
|
+
</>
|
|
59
|
+
);
|
|
60
|
+
const liquidErrors = LIQUID_ERROR_MSG?.length;
|
|
121
61
|
return (
|
|
122
|
-
<
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
62
|
+
<div className="error-container">
|
|
63
|
+
{STANDARD_ERROR_MSG?.length > 0 && (
|
|
64
|
+
<>
|
|
65
|
+
<ErrorSection
|
|
66
|
+
title={
|
|
67
|
+
<FormattedMessage {...messages.standardErrorHeader} />
|
|
68
|
+
}
|
|
69
|
+
errors={STANDARD_ERROR_MSG}
|
|
70
|
+
/>
|
|
71
|
+
</>
|
|
72
|
+
)}
|
|
73
|
+
{liquidErrors > 0 && (
|
|
74
|
+
<ErrorSection
|
|
75
|
+
title={<FormattedMessage {...messages.dynamicErrorHeader} />}
|
|
76
|
+
errors={LIQUID_ERROR_MSG}
|
|
77
|
+
liquidError={true}
|
|
78
|
+
/>
|
|
79
|
+
)}
|
|
80
|
+
</div>
|
|
126
81
|
);
|
|
127
82
|
};
|
|
128
|
-
|
|
129
|
-
ErrorInfoNote.defaultProps = {
|
|
130
|
-
errorMessages: {
|
|
131
|
-
LIQUID_ERROR_MSG: [],
|
|
132
|
-
STANDARD_ERROR_MSG: [],
|
|
133
|
-
},
|
|
134
|
-
};
|
|
135
|
-
|
|
136
83
|
ErrorInfoNote.propTypes = {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
PropTypes.shape({
|
|
141
|
-
ANDROID: PropTypes.array,
|
|
142
|
-
IOS: PropTypes.array,
|
|
143
|
-
GENERIC: PropTypes.array,
|
|
144
|
-
}),
|
|
145
|
-
]),
|
|
146
|
-
STANDARD_ERROR_MSG: PropTypes.oneOfType([
|
|
147
|
-
PropTypes.array,
|
|
148
|
-
PropTypes.shape({
|
|
149
|
-
ANDROID: PropTypes.array,
|
|
150
|
-
IOS: PropTypes.array,
|
|
151
|
-
GENERIC: PropTypes.array,
|
|
152
|
-
}),
|
|
153
|
-
]),
|
|
154
|
-
}),
|
|
84
|
+
errorMessage: PropTypes.string,
|
|
85
|
+
errorType: PropTypes.string,
|
|
86
|
+
intl: intlShape.isRequired,
|
|
155
87
|
};
|
|
156
88
|
|
|
157
89
|
export default injectIntl(ErrorInfoNote);
|
|
@@ -26,29 +26,4 @@ export default defineMessages({
|
|
|
26
26
|
defaultMessage:
|
|
27
27
|
"Aira can make mistakes. Please verify the suggestions before applying them"
|
|
28
28
|
},
|
|
29
|
-
liquidDocLink: {
|
|
30
|
-
id: `${scope}.liquidDocLink`,
|
|
31
|
-
defaultMessage:
|
|
32
|
-
"https://docs.capillarytech.com/docs/liquid-language-in-messages"
|
|
33
|
-
},
|
|
34
|
-
androidDynamicErrorHeader: {
|
|
35
|
-
id: `${scope}.androidDynamicErrorHeader`,
|
|
36
|
-
defaultMessage:
|
|
37
|
-
"Errors found in Android Dynamic Tags"
|
|
38
|
-
},
|
|
39
|
-
iosDynamicErrorHeader: {
|
|
40
|
-
id: `${scope}.iosDynamicErrorHeader`,
|
|
41
|
-
defaultMessage:
|
|
42
|
-
"Errors found in iOS Dynamic Tags"
|
|
43
|
-
},
|
|
44
|
-
androidStandardErrorHeader: {
|
|
45
|
-
id: `${scope}.androidStandardErrorHeader`,
|
|
46
|
-
defaultMessage:
|
|
47
|
-
"Errors found in Android Standard Tags"
|
|
48
|
-
},
|
|
49
|
-
iosStandardErrorHeader: {
|
|
50
|
-
id: `${scope}.iosStandardErrorHeader`,
|
|
51
|
-
defaultMessage:
|
|
52
|
-
"Errors found in iOS Standard Tags"
|
|
53
|
-
},
|
|
54
29
|
});
|
|
@@ -58,28 +58,15 @@
|
|
|
58
58
|
gap: $CAP_SPACE_04;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
|
|
62
61
|
.liquid-divider {
|
|
63
|
-
&.ant-divider.cap-divider-v2
|
|
62
|
+
&.ant-divider.cap-divider-v2{
|
|
64
63
|
background: $FONT_COLOR_04;
|
|
65
64
|
}
|
|
66
65
|
margin: $CAP_SPACE_08 0;
|
|
67
66
|
}
|
|
68
67
|
|
|
69
|
-
.platform-divider {
|
|
70
|
-
&.ant-divider.cap-divider-v2 {
|
|
71
|
-
background: $FONT_COLOR_04;
|
|
72
|
-
margin: $CAP_SPACE_12 0;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
68
|
.aria-error-footer {
|
|
77
69
|
display: flex;
|
|
78
70
|
align-items: center;
|
|
79
71
|
gap: $CAP_SPACE_04;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.error-header-sub-title {
|
|
83
|
-
margin-left: $CAP_SPACE_04;
|
|
84
|
-
font-weight: 500;
|
|
85
72
|
}
|