@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.
Files changed (37) hide show
  1. package/package.json +1 -1
  2. package/utils/commonUtils.js +3 -359
  3. package/utils/tagValidations.js +5 -20
  4. package/utils/tests/commonUtil.test.js +171 -474
  5. package/utils/tests/tagValidations.test.js +2 -89
  6. package/v2Components/ErrorInfoNote/index.js +46 -114
  7. package/v2Components/ErrorInfoNote/messages.js +0 -25
  8. package/v2Components/ErrorInfoNote/style.scss +1 -14
  9. package/v2Components/FormBuilder/index.js +127 -204
  10. package/v2Components/FormBuilder/messages.js +1 -1
  11. package/v2Containers/Cap/reducer.js +4 -4
  12. package/v2Containers/CreativesContainer/SlideBoxContent.js +3 -23
  13. package/v2Containers/CreativesContainer/SlideBoxFooter.js +1 -3
  14. package/v2Containers/CreativesContainer/constants.js +1 -4
  15. package/v2Containers/CreativesContainer/index.js +19 -44
  16. package/v2Containers/CreativesContainer/messages.js +0 -4
  17. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +3 -21
  18. package/v2Containers/Ebill/index.js +3 -3
  19. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +1 -1
  20. package/v2Containers/InApp/index.js +50 -123
  21. package/v2Containers/InApp/tests/index.test.js +1 -1
  22. package/v2Containers/InApp/tests/sagas.test.js +1 -1
  23. package/v2Containers/InApp/utils.js +0 -37
  24. package/v2Containers/MobilePush/Create/index.js +20 -24
  25. package/v2Containers/MobilePush/Edit/index.js +2 -6
  26. package/v2Containers/MobilepushWrapper/index.js +0 -2
  27. package/v2Containers/Sms/Create/index.js +0 -1
  28. package/v2Containers/Sms/Edit/index.js +0 -2
  29. package/v2Containers/SmsWrapper/index.js +0 -2
  30. package/v2Containers/Whatsapp/constants.js +1 -1
  31. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +57476 -0
  32. package/v2Containers/Whatsapp/tests/index.test.js +88 -0
  33. package/v2Components/ErrorInfoNote/ErrorTypeRenderer.js +0 -127
  34. package/v2Components/ErrorInfoNote/ErrorTypeRenderer.test.js +0 -147
  35. package/v2Components/ErrorInfoNote/utils.js +0 -38
  36. package/v2Components/ErrorInfoNote/utils.test.js +0 -156
  37. 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 ErrorSection = ({
20
- title,
21
- errors,
22
- liquidError,
23
- platformLabel,
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={() => window.open("https://docs.capillarytech.com/docs/liquid-language-in-messages", "_blank")
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
- {platformLabel && (
52
- <CapRow className="error-header-sub-title">
53
- <CapLabel type="label2">{platformLabel}</CapLabel>
54
- </CapRow>
55
- )}
56
- <CapList
57
- className="error-list"
58
- size="small"
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
- <CapLabel type="label2">{error}</CapLabel>
67
- </CapLabel>
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
- // GENERIC (not platform-specific)
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
- <ErrorTypeRenderer
123
- genericErrors={{ standard: genericStandard, liquid: genericLiquid }}
124
- ErrorSectionComponent={ErrorSection}
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
- errorMessages: PropTypes.shape({
138
- LIQUID_ERROR_MSG: PropTypes.oneOfType([
139
- PropTypes.array,
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
  }