@capillarytech/creatives-library 8.0.345-alpha.12 → 8.0.345-alpha.13

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 (138) hide show
  1. package/constants/unified.js +0 -29
  2. package/package.json +1 -1
  3. package/services/api.js +20 -0
  4. package/services/tests/api.test.js +59 -13
  5. package/utils/commonUtils.js +1 -19
  6. package/v2Components/CapActionButton/constants.js +0 -7
  7. package/v2Components/CapActionButton/index.js +109 -167
  8. package/v2Components/CapActionButton/index.scss +6 -157
  9. package/v2Components/CapActionButton/messages.js +3 -19
  10. package/v2Components/CapActionButton/tests/index.test.js +17 -41
  11. package/v2Components/CapCustomSkeleton/index.js +1 -1
  12. package/v2Components/CapCustomSkeleton/tests/__snapshots__/index.test.js.snap +12 -12
  13. package/v2Components/CapTagList/index.js +0 -10
  14. package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +49 -70
  15. package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
  16. package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -207
  17. package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +0 -16
  18. package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +10 -85
  19. package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +0 -30
  20. package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +11 -79
  21. package/v2Components/CommonTestAndPreview/SendTestMessage.js +5 -10
  22. package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +15 -160
  23. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +76 -341
  24. package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +4 -133
  25. package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +0 -11
  26. package/v2Components/CommonTestAndPreview/constants.js +2 -38
  27. package/v2Components/CommonTestAndPreview/index.js +186 -676
  28. package/v2Components/CommonTestAndPreview/messages.js +3 -49
  29. package/v2Components/CommonTestAndPreview/sagas.js +6 -15
  30. package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +284 -308
  31. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +65 -231
  32. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +5 -118
  33. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +0 -341
  34. package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +1 -8
  35. package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +13 -34
  36. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +283 -281
  37. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +1 -199
  38. package/v2Components/CommonTestAndPreview/tests/index.test.js +4 -132
  39. package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
  40. package/v2Components/FormBuilder/index.js +10 -8
  41. package/v2Components/TemplatePreview/_templatePreview.scss +23 -33
  42. package/v2Components/TemplatePreview/index.js +28 -143
  43. package/v2Components/TemplatePreview/tests/index.test.js +0 -142
  44. package/v2Components/TestAndPreviewSlidebox/index.js +1 -13
  45. package/v2Components/TestAndPreviewSlidebox/sagas.js +4 -11
  46. package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +1 -3
  47. package/v2Containers/Assets/images/archive_Empty_Illustration.svg +9 -0
  48. package/v2Containers/CreativesContainer/SlideBoxContent.js +4 -36
  49. package/v2Containers/CreativesContainer/SlideBoxFooter.js +4 -11
  50. package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -29
  51. package/v2Containers/CreativesContainer/constants.js +0 -9
  52. package/v2Containers/CreativesContainer/index.js +108 -300
  53. package/v2Containers/CreativesContainer/index.scss +1 -51
  54. package/v2Containers/CreativesContainer/messages.js +4 -0
  55. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +34 -78
  56. package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +16 -79
  57. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -8
  58. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +98 -357
  59. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +18 -20
  60. package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
  61. package/v2Containers/Rcs/constants.js +8 -119
  62. package/v2Containers/Rcs/index.js +812 -2375
  63. package/v2Containers/Rcs/index.scss +6 -276
  64. package/v2Containers/Rcs/messages.js +3 -38
  65. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +70345 -98302
  66. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +5 -0
  67. package/v2Containers/Rcs/tests/index.test.js +121 -152
  68. package/v2Containers/Rcs/tests/mockData.js +0 -38
  69. package/v2Containers/Rcs/tests/utils.test.js +30 -646
  70. package/v2Containers/Rcs/utils.js +11 -478
  71. package/v2Containers/Sms/Create/index.js +40 -100
  72. package/v2Containers/SmsTrai/Create/index.js +4 -9
  73. package/v2Containers/SmsTrai/Edit/constants.js +0 -2
  74. package/v2Containers/SmsTrai/Edit/index.js +130 -636
  75. package/v2Containers/SmsTrai/Edit/messages.js +4 -14
  76. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2296 -4249
  77. package/v2Containers/SmsWrapper/index.js +8 -37
  78. package/v2Containers/TagList/index.js +0 -6
  79. package/v2Containers/Templates/ChannelTypeIllustration.js +23 -6
  80. package/v2Containers/Templates/_templates.scss +126 -181
  81. package/v2Containers/Templates/actions.js +36 -11
  82. package/v2Containers/Templates/constants.js +23 -2
  83. package/v2Containers/Templates/index.js +333 -142
  84. package/v2Containers/Templates/messages.js +68 -0
  85. package/v2Containers/Templates/reducer.js +68 -0
  86. package/v2Containers/Templates/sagas.js +98 -55
  87. package/v2Containers/Templates/selectors.js +12 -0
  88. package/v2Containers/Templates/tests/ChannelTypeIllustration.test.js +12 -0
  89. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1256 -1042
  90. package/v2Containers/Templates/tests/index.test.js +6 -0
  91. package/v2Containers/Templates/tests/reducer.test.js +178 -0
  92. package/v2Containers/Templates/tests/sagas.test.js +436 -200
  93. package/v2Containers/Templates/tests/selector.test.js +32 -0
  94. package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -72
  95. package/v2Containers/TemplatesV2/index.js +23 -86
  96. package/v2Containers/Whatsapp/index.js +20 -3
  97. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +34 -578
  98. package/utils/rcsPayloadUtils.js +0 -92
  99. package/utils/templateVarUtils.js +0 -201
  100. package/utils/tests/templateVarUtils.test.js +0 -204
  101. package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js.rej +0 -18
  102. package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
  103. package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +0 -67
  104. package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +0 -87
  105. package/v2Components/SmsFallback/constants.js +0 -73
  106. package/v2Components/SmsFallback/index.js +0 -955
  107. package/v2Components/SmsFallback/index.scss +0 -265
  108. package/v2Components/SmsFallback/messages.js +0 -78
  109. package/v2Components/SmsFallback/smsFallbackUtils.js +0 -118
  110. package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +0 -50
  111. package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +0 -147
  112. package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +0 -304
  113. package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +0 -197
  114. package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -277
  115. package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +0 -422
  116. package/v2Components/SmsFallback/useLocalTemplateList.js +0 -92
  117. package/v2Components/TemplatePreview/constants.js +0 -2
  118. package/v2Components/VarSegmentMessageEditor/constants.js +0 -2
  119. package/v2Components/VarSegmentMessageEditor/index.js +0 -125
  120. package/v2Components/VarSegmentMessageEditor/index.scss +0 -46
  121. package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +0 -43
  122. package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +0 -67
  123. package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +0 -90
  124. package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +0 -258
  125. package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +0 -125
  126. package/v2Containers/Rcs/index.js.rej +0 -1336
  127. package/v2Containers/Rcs/index.scss.rej +0 -74
  128. package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +0 -225
  129. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap.rej +0 -128
  130. package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +0 -318
  131. package/v2Containers/Sms/smsFormDataHelpers.js +0 -67
  132. package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +0 -253
  133. package/v2Containers/SmsTrai/Edit/index.scss +0 -121
  134. package/v2Containers/Templates/TemplatesActionBar.js +0 -101
  135. package/v2Containers/Templates/tests/TemplatesActionBar.test.js +0 -120
  136. package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +0 -180
  137. package/v2Containers/Templates/utils/smsTemplatesListApi.js +0 -79
  138. package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +0 -131
@@ -1,92 +0,0 @@
1
- import { useState, useCallback, useRef } from 'react';
2
-
3
- /**
4
- * @param {Object} options
5
- * @param {(params: { page: number, search: string, reset: boolean }) => Promise<{ templates: Array, totalCount: number }>} options.fetchTemplates
6
- * @param {number} [options.perPage=25]
7
- */
8
- export function useLocalTemplateList({ fetchTemplates, perPage = 25 }) {
9
- const [listData, setListData] = useState({ templates: [], totalCount: 0 });
10
- const [loading, setLoading] = useState(false);
11
- const [page, setPage] = useState(1);
12
- const [search, setSearchState] = useState('');
13
- const searchRef = useRef('');
14
- /** Drops stale responses when a newer fetch starts (search / reset while a request is in flight). */
15
- const fetchGenerationRef = useRef(0);
16
- const setSearch = useCallback((value) => {
17
- const term = typeof value === 'string' ? value : '';
18
- searchRef.current = term;
19
- setSearchState(term);
20
- }, []);
21
- const lastFetchFullPageRef = useRef(false);
22
-
23
- const { templates = [], totalCount = 0 } = listData ?? {};
24
- const hasKnownTotal = (totalCount ?? 0) > 0;
25
- const hasMoreByTotal = (totalCount ?? 0) > (templates?.length ?? 0);
26
- const hasMoreByFullPage =
27
- !hasKnownTotal && lastFetchFullPageRef.current && (templates?.length ?? 0) > 0;
28
- const canLoadMore = (hasMoreByTotal || hasMoreByFullPage) && !loading;
29
-
30
- const runFetch = useCallback(
31
- async ({ page: p = 1, reset = true, search: searchTerm } = {}) => {
32
- const term = searchTerm !== undefined ? searchTerm : searchRef.current;
33
- const gen = ++fetchGenerationRef.current;
34
- setLoading(true);
35
- try {
36
- const result = await fetchTemplates({ page: p, search: term, reset });
37
- if (gen !== fetchGenerationRef.current) {
38
- return;
39
- }
40
- const nextTemplates = result?.templates ?? [];
41
- const nextTotalCount = result?.totalCount ?? 0;
42
- lastFetchFullPageRef.current = nextTemplates.length >= perPage;
43
- setListData((prev) => ({
44
- templates: reset ? nextTemplates : [...(prev.templates || []), ...nextTemplates],
45
- totalCount: nextTotalCount > 0 ? nextTotalCount : (reset ? 0 : prev.totalCount),
46
- }));
47
- setPage(p);
48
- } catch (e) {
49
- if (gen !== fetchGenerationRef.current) {
50
- return;
51
- }
52
- lastFetchFullPageRef.current = false;
53
- if (reset) {
54
- setListData({ templates: [], totalCount: 0 });
55
- setPage(1);
56
- }
57
- } finally {
58
- if (gen === fetchGenerationRef.current) {
59
- setLoading(false);
60
- }
61
- }
62
- },
63
- [fetchTemplates, perPage]
64
- );
65
-
66
- const loadMore = useCallback(() => {
67
- if (!canLoadMore) return;
68
- runFetch({ page: page + 1, reset: false, search: searchRef.current });
69
- }, [canLoadMore, page, runFetch]);
70
-
71
- const reset = useCallback(
72
- (searchTerm) => {
73
- const term = searchTerm !== undefined ? searchTerm : searchRef.current;
74
- setSearch(term);
75
- lastFetchFullPageRef.current = false;
76
- runFetch({ page: 1, reset: true, search: term });
77
- },
78
- [runFetch, setSearch]
79
- );
80
-
81
- return {
82
- templates,
83
- totalCount,
84
- loading,
85
- page,
86
- search,
87
- setSearch,
88
- loadMore,
89
- reset,
90
- canLoadMore,
91
- };
92
- }
@@ -1,2 +0,0 @@
1
- /** Matches {{ varName }} placeholders (alphanumeric + underscore) */
2
- export const TEMPLATE_VAR_REGEX = /\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/g;
@@ -1,2 +0,0 @@
1
- /** Default prefix before variable name in variable-slot placeholders. */
2
- export const VAR_SEGMENT_PLACEHOLDER_PREFIX = 'enter the value for ';
@@ -1,125 +0,0 @@
1
- /**
2
- * Shared message editor that renders template text with {{var}} and/or DLT `{#var#}` segments as
3
- * variable inputs and static text as headings.
4
- * Reused by RCS (title/description), SmsTrai Edit (SMS fallback), and WhatsApp (edit message/header).
5
- */
6
- import React from 'react';
7
- import PropTypes from 'prop-types';
8
- import CapRow from '@capillarytech/cap-ui-library/CapRow';
9
- import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
10
- import CapInput from '@capillarytech/cap-ui-library/CapInput';
11
- import {
12
- splitTemplateVarString,
13
- DEFAULT_MUSTACHE_VAR_REGEX,
14
- isAnyTemplateVarToken,
15
- } from '../../utils/templateVarUtils';
16
-
17
- import './index.scss';
18
- import { VAR_SEGMENT_PLACEHOLDER_PREFIX } from './constants';
19
-
20
- const { TextArea } = CapInput;
21
-
22
- export function VarSegmentMessageEditor({
23
- templateString = '',
24
- valueMap = {},
25
- onChange,
26
- onFocus,
27
- placeholderPrefix = VAR_SEGMENT_PLACEHOLDER_PREFIX,
28
- getPlaceholder,
29
- wrapperClassName = 'rcs_text_area_wrapper',
30
- rowClassName = 'rcs-edit-template-message-input',
31
- headingClassName = 'rcs-edit-template-message-split',
32
- varRegex,
33
- readOnly = false,
34
- disabled = false,
35
- footerContent,
36
- renderVarFooter,
37
- }) {
38
- const segments = splitTemplateVarString(templateString, varRegex || DEFAULT_MUSTACHE_VAR_REGEX);
39
- if (!segments?.length) return null;
40
-
41
- return (
42
- <div className={wrapperClassName}>
43
- <CapRow className={rowClassName}>
44
- {segments.map((segmentToken, segmentIndex) => {
45
- const isVar =
46
- typeof segmentToken === 'string' && isAnyTemplateVarToken(segmentToken);
47
- if (isVar) {
48
- const varSegmentFieldId = `${segmentToken}_${segmentIndex}`;
49
- const slotValueFromMap = valueMap?.[varSegmentFieldId];
50
- // Missing key: show empty (not the raw {{…}} token) so cleared slots and incomplete maps
51
- // cannot resurrect the token; placeholder still guides the user.
52
- const value =
53
- slotValueFromMap !== undefined && slotValueFromMap !== null ? slotValueFromMap : '';
54
- if (readOnly) {
55
- return (
56
- <CapHeading
57
- key={varSegmentFieldId}
58
- type="h4"
59
- className={`${headingClassName} var-segment-message-editor__read-only-value`.trim()}
60
- >
61
- {value}
62
- </CapHeading>
63
- );
64
- }
65
- const fromGet = getPlaceholder && getPlaceholder(segmentToken, segmentIndex);
66
- const placeholder =
67
- fromGet !== undefined && fromGet !== null && fromGet !== ''
68
- ? fromGet
69
- : `${placeholderPrefix}${segmentToken}`;
70
- return (
71
- <div key={varSegmentFieldId} className="var-segment-message-editor__var-slot">
72
- <TextArea
73
- id={varSegmentFieldId}
74
- placeholder={placeholder}
75
- autosize={{ minRows: 1, maxRows: 3 }}
76
- value={value}
77
- onFocus={() => onFocus && onFocus(varSegmentFieldId)}
78
- onChange={(e) =>
79
- onChange && onChange(varSegmentFieldId, e?.target?.value ?? '')}
80
- disabled={disabled}
81
- />
82
- {renderVarFooter
83
- ? renderVarFooter(segmentToken, segmentIndex, varSegmentFieldId)
84
- : null}
85
- </div>
86
- );
87
- }
88
- if (segmentToken) {
89
- return (
90
- <CapHeading
91
- key={`static_${segmentIndex}_${segmentToken}`}
92
- type="h4"
93
- className={headingClassName}
94
- >
95
- {segmentToken}
96
- </CapHeading>
97
- );
98
- }
99
- return null;
100
- })}
101
- </CapRow>
102
- {footerContent}
103
- </div>
104
- );
105
- }
106
-
107
- VarSegmentMessageEditor.propTypes = {
108
- templateString: PropTypes.string,
109
- valueMap: PropTypes.object,
110
- onChange: PropTypes.func,
111
- onFocus: PropTypes.func,
112
- placeholderPrefix: PropTypes.string,
113
- getPlaceholder: PropTypes.func,
114
- wrapperClassName: PropTypes.string,
115
- rowClassName: PropTypes.string,
116
- headingClassName: PropTypes.string,
117
- varRegex: PropTypes.object,
118
- readOnly: PropTypes.bool,
119
- disabled: PropTypes.bool,
120
- footerContent: PropTypes.node,
121
- /** Optional hint below a variable field (e.g. DLT `{#var#}` max length). */
122
- renderVarFooter: PropTypes.func,
123
- };
124
-
125
- export default VarSegmentMessageEditor;
@@ -1,46 +0,0 @@
1
- @import '~@capillarytech/cap-ui-library/styles/_variables';
2
-
3
- /* Same look as RCS edit message block: background, spacing, text color */
4
- .rcs_text_area_wrapper {
5
- .rcs-edit-template-message-input {
6
- background-color: $CAP_G10;
7
- padding: $CAP_SPACE_12 $CAP_SPACE_16 $CAP_SPACE_16;
8
- }
9
-
10
- .rcs-edit-template-message-split {
11
- margin: 0 0 $CAP_SPACE_04 0;
12
- overflow: hidden;
13
- text-overflow: ellipsis;
14
- color: $FONT_COLOR_04;
15
- font-weight: 500;
16
- }
17
-
18
- /* Variable chips: match RCS edit (white field, light border, 4px radius) */
19
- .rcs-edit-template-message-input .ant-input,
20
- .rcs-edit-template-message-input textarea.ant-input {
21
- margin: 0 0 0.125rem 0;
22
- border-radius: 0.25rem;
23
- border: 0.0625rem solid $CAP_G07;
24
- background-color: $CAP_WHITE;
25
- overflow: hidden;
26
- }
27
-
28
- /* Small gap between tag border and the next line (static text) */
29
- .rcs-edit-template-message-input :not(:first-child) {
30
- margin-top: $CAP_SPACE_08;
31
- }
32
-
33
- .rcs-edit-template-message-input > *:last-child {
34
- margin-bottom: 0;
35
- }
36
-
37
- .var-segment-message-editor__var-slot {
38
- display: flex;
39
- flex-direction: column;
40
- width: 100%;
41
- }
42
- }
43
-
44
- .var-segment-message-editor__read-only-value {
45
- margin: 0;
46
- }
@@ -1,43 +0,0 @@
1
- /**
2
- * Styled wrapper for CapSlideBox used by CreativesContainer and RCS SMS fallback
3
- * so header/content/footer margins match.
4
- */
5
- import styled from 'styled-components';
6
- import { CAP_SPACE_16 } from '@capillarytech/cap-ui-library/styled/variables';
7
-
8
- const CreativesSlideBoxWrapper = styled.div`
9
- .cap-slide-box-v2-container {
10
- /*
11
- * Liquid-error spacing must stay *inside* the content column. margin-bottom on
12
- * .slidebox-content-container added to the in-flow height past 100vh, so the outer
13
- * .cap-slide-box-v2-container (overflow-y: auto in cap-ui) gained a second scrollbar.
14
- */
15
- .slidebox-header {
16
- margin-bottom: ${({ slideBoxWrapperMargin }) => `${slideBoxWrapperMargin}`};
17
- padding: 0 rem;
18
- &.has-footer {
19
- overflow-x: hidden;
20
- }
21
- }
22
- .slidebox-content-container {
23
- margin-bottom: 0;
24
- padding: 0 rem;
25
- padding-bottom: ${({ slideBoxWrapperMargin }) => `${slideBoxWrapperMargin}`};
26
- box-sizing: border-box;
27
- &.has-footer {
28
- overflow-x: hidden;
29
- }
30
- }
31
- .slidebox-footer {
32
- /* Only apply margin-bottom to footer when ErrorInfoNote is shown in footer (BEE editor) */
33
- /* For HTML Editor, errors are shown in ValidationErrorDisplay (inside content area), so no footer margin needed */
34
- margin-bottom: ${({ shouldApplyFooterMargin }) => (shouldApplyFooterMargin ? `${CAP_SPACE_16}` : '0')};
35
- padding: 0 rem;
36
- &.has-footer {
37
- overflow-x: hidden;
38
- }
39
- }
40
- }
41
- `;
42
-
43
- export default CreativesSlideBoxWrapper;
@@ -1,67 +0,0 @@
1
- /**
2
- * Shared logic for CreativesContainer slidebox + embedded flows (e.g. RCS SMS fallback)
3
- * that mirror the same footer liquid errors and layout margins.
4
- */
5
- import get from 'lodash/get';
6
- import {
7
- CAP_SPACE_32,
8
- CAP_SPACE_56,
9
- CAP_SPACE_64,
10
- } from '@capillarytech/cap-ui-library/styled/variables';
11
- import * as constants from './constants';
12
-
13
- /**
14
- * Returns true if value is "deep empty": no errors present.
15
- * Same rules as CreativesContainer (used for liquid / standard error payloads).
16
- */
17
- export function isDeepEmpty(value) {
18
- if (value == null) return true;
19
- if (typeof value === 'string') return value.length === 0;
20
- if (Array.isArray(value)) return value.length === 0;
21
- if (typeof value === 'object') {
22
- return Object.values(value).every(isDeepEmpty);
23
- }
24
- return false;
25
- }
26
-
27
- /**
28
- * Header/content margin below slidebox chrome when ErrorInfoNote stacks errors — same formula as CreativesContainer#render.
29
- */
30
- export function getSlideBoxWrapperMarginFromLiquidErrors(liquidErrorMessage) {
31
- return (get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0
32
- && get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0)
33
- ? CAP_SPACE_64
34
- : get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0
35
- ? CAP_SPACE_56
36
- : get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0
37
- ? CAP_SPACE_32
38
- : 0;
39
- }
40
-
41
- /**
42
- * Maps FormBuilder `showLiquidErrorInFooter` args to slidebox footer state.
43
- * Returns `null` when CreativesContainer intentionally skips updating (Mobile Push OLD empty clear).
44
- */
45
- export function computeLiquidFooterUpdateFromFormBuilder(
46
- errorMessagesFromFormBuilder,
47
- currentFormBuilderTab,
48
- { previousIsLiquidValidationError, currentChannelUpper } = {},
49
- ) {
50
- const liquidMsgs = get(errorMessagesFromFormBuilder, constants.LIQUID_ERROR_MSG, []);
51
- const standardMsgs = get(errorMessagesFromFormBuilder, constants.STANDARD_ERROR_MSG, []);
52
- const hasLiquid = !isDeepEmpty(liquidMsgs);
53
- const hasStandard = !isDeepEmpty(standardMsgs);
54
- const isLiquidValidationError = hasLiquid || hasStandard;
55
- const isMobilePush = currentChannelUpper === constants.MOBILE_PUSH;
56
- if (!hasLiquid && !hasStandard && previousIsLiquidValidationError && isMobilePush) {
57
- return null;
58
- }
59
- return {
60
- isLiquidValidationError,
61
- liquidErrorMessage: errorMessagesFromFormBuilder,
62
- activeFormBuilderTab:
63
- currentFormBuilderTab === 1
64
- ? constants.ANDROID
65
- : (currentFormBuilderTab === 2 ? constants.IOS : null),
66
- };
67
- }
@@ -1,90 +0,0 @@
1
- /**
2
- * Covers `localTemplatesConfig` / `useLocalTemplates` branch in SlideBoxContent → TemplatesV2
3
- * (embedded SMS template list / RCS SMS fallback).
4
- */
5
- import React from 'react';
6
- import { mountWithIntl, shallowWithIntl } from '../../../helpers/intl-enzym-test-helpers';
7
- import { SlideBoxContent } from '../SlideBoxContent';
8
-
9
- const mockTemplatesV2 = jest.fn(() => <div data-testid="templates-v2-mock" />);
10
- jest.mock('../../TemplatesV2', () => ({
11
- __esModule: true,
12
- default: (props) => mockTemplatesV2(props),
13
- }));
14
-
15
- const baseProps = {
16
- slidBoxContent: 'templates',
17
- currentChannel: 'SMS',
18
- onSelectTemplate: jest.fn(),
19
- onPreviewTemplate: jest.fn(),
20
- onCreateNew: jest.fn(),
21
- onChannelChange: jest.fn(),
22
- location: { pathname: '/sms', query: {}, search: '' },
23
- cap: {},
24
- channelsToHide: [],
25
- channelsToDisable: [],
26
- handleClose: jest.fn(),
27
- messageDetails: {},
28
- onCreateComplete: jest.fn(),
29
- };
30
-
31
- describe('SlideBoxContent local templates (TemplatesV2)', () => {
32
- beforeEach(() => {
33
- mockTemplatesV2.mockClear();
34
- });
35
-
36
- // Use mount when asserting TemplatesV2 mock calls: shallow does not invoke children under styled CreativesWrapper.
37
- it('renders TemplatesV2 in full mode when useLocalTemplates is true', () => {
38
- mountWithIntl(
39
- <SlideBoxContent
40
- {...baseProps}
41
- isFullMode
42
- localTemplatesConfig={{
43
- useLocalTemplates: true,
44
- localTemplates: [],
45
- localTemplatesLoading: false,
46
- }}
47
- />,
48
- );
49
- expect(mockTemplatesV2).toHaveBeenCalled();
50
- const passed = mockTemplatesV2.mock.calls[mockTemplatesV2.mock.calls.length - 1][0];
51
- expect(passed.localTemplatesConfig.useLocalTemplates).toBe(true);
52
- });
53
-
54
- it('does not render TemplatesV2 in full mode when useLocalTemplates is false', () => {
55
- shallowWithIntl(
56
- <SlideBoxContent
57
- {...baseProps}
58
- isFullMode
59
- localTemplatesConfig={{ useLocalTemplates: false }}
60
- />,
61
- );
62
- expect(mockTemplatesV2).not.toHaveBeenCalled();
63
- });
64
-
65
- it('renders TemplatesV2 in library mode without localTemplates flag', () => {
66
- mountWithIntl(
67
- <SlideBoxContent
68
- {...baseProps}
69
- isFullMode={false}
70
- />,
71
- );
72
- expect(mockTemplatesV2).toHaveBeenCalled();
73
- });
74
-
75
- it('merges top-level local template props via pick when localTemplatesConfig is omitted', () => {
76
- mountWithIntl(
77
- <SlideBoxContent
78
- {...baseProps}
79
- isFullMode
80
- useLocalTemplates
81
- localTemplates={[{ _id: '1' }]}
82
- localTemplatesLoading={false}
83
- />,
84
- );
85
- expect(mockTemplatesV2).toHaveBeenCalled();
86
- const passed = mockTemplatesV2.mock.calls[mockTemplatesV2.mock.calls.length - 1][0];
87
- expect(passed.localTemplatesConfig.useLocalTemplates).toBe(true);
88
- expect(passed.localTemplatesConfig.localTemplates).toEqual([{ _id: '1' }]);
89
- });
90
- });