@capillarytech/creatives-library 8.0.330-alpha.0 → 8.0.330
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 +0 -18
- package/package.json +1 -1
- package/services/api.js +0 -17
- package/services/tests/api.test.js +0 -85
- package/utils/commonUtils.js +0 -28
- package/utils/tests/commonUtil.test.js +0 -169
- package/v2Components/CapTagList/index.js +0 -10
- package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +49 -70
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -207
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +0 -16
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +10 -85
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +0 -30
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +11 -79
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +53 -87
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +1 -20
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +4 -133
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +34 -145
- package/v2Components/CommonTestAndPreview/actions.js +0 -10
- package/v2Components/CommonTestAndPreview/constants.js +1 -53
- package/v2Components/CommonTestAndPreview/index.js +168 -998
- package/v2Components/CommonTestAndPreview/messages.js +3 -147
- package/v2Components/CommonTestAndPreview/reducer.js +0 -10
- package/v2Components/CommonTestAndPreview/sagas.js +6 -15
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +286 -328
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +65 -231
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +5 -118
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +0 -341
- package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +24 -65
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +1 -199
- package/v2Components/CommonTestAndPreview/tests/constants.test.js +1 -31
- package/v2Components/CommonTestAndPreview/tests/index.test.js +4 -168
- package/v2Components/CommonTestAndPreview/tests/reducer.test.js +0 -71
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
- package/v2Components/CommonTestAndPreview/tests/selectors.test.js +0 -17
- package/v2Components/FormBuilder/index.js +1 -7
- package/v2Components/TestAndPreviewSlidebox/index.js +1 -13
- package/v2Components/TestAndPreviewSlidebox/sagas.js +4 -11
- package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +1 -3
- package/v2Containers/CreativesContainer/SlideBoxContent.js +4 -36
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +1 -10
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -29
- package/v2Containers/CreativesContainer/constants.js +0 -9
- package/v2Containers/CreativesContainer/index.js +93 -292
- package/v2Containers/CreativesContainer/index.scss +1 -51
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +34 -78
- package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +16 -79
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -8
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +98 -357
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +10 -20
- package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
- package/v2Containers/Rcs/constants.js +3 -40
- package/v2Containers/Rcs/index.js +895 -1145
- package/v2Containers/Rcs/index.scss +6 -85
- package/v2Containers/Rcs/messages.js +2 -12
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +2236 -41719
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +5 -0
- package/v2Containers/Rcs/tests/index.test.js +38 -41
- package/v2Containers/Rcs/tests/mockData.js +0 -38
- package/v2Containers/Rcs/tests/utils.test.js +1 -435
- package/v2Containers/Rcs/utils.js +10 -405
- package/v2Containers/Sms/Create/index.js +38 -100
- package/v2Containers/SmsTrai/Create/index.js +4 -9
- package/v2Containers/SmsTrai/Edit/constants.js +0 -2
- package/v2Containers/SmsTrai/Edit/index.js +128 -636
- package/v2Containers/SmsTrai/Edit/messages.js +4 -14
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2604 -4590
- package/v2Containers/SmsWrapper/index.js +8 -37
- package/v2Containers/TagList/index.js +0 -6
- package/v2Containers/Templates/_templates.scss +2 -63
- package/v2Containers/Templates/actions.js +0 -11
- package/v2Containers/Templates/constants.js +0 -2
- package/v2Containers/Templates/index.js +40 -90
- package/v2Containers/Templates/sagas.js +12 -57
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1079 -1043
- package/v2Containers/Templates/tests/sagas.test.js +123 -193
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -72
- package/v2Containers/TemplatesV2/index.js +23 -86
- package/v2Containers/Whatsapp/index.js +20 -3
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +4872 -5790
- package/utils/templateVarUtils.js +0 -201
- package/utils/tests/templateVarUtils.test.js +0 -204
- package/v2Components/CommonTestAndPreview/AddTestCustomer.js +0 -42
- package/v2Components/CommonTestAndPreview/CustomerCreationModal.js +0 -155
- package/v2Components/CommonTestAndPreview/ExistingCustomerModal.js +0 -93
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
- package/v2Components/CommonTestAndPreview/tests/AddTestCustomer.test.js +0 -66
- package/v2Components/CommonTestAndPreview/tests/CommonTestAndPreview.addTestCustomer.test.js +0 -648
- package/v2Components/CommonTestAndPreview/tests/CustomerCreationModal.test.js +0 -174
- package/v2Components/CommonTestAndPreview/tests/ExistingCustomerModal.test.js +0 -114
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +0 -67
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +0 -87
- package/v2Components/SmsFallback/constants.js +0 -73
- package/v2Components/SmsFallback/index.js +0 -955
- package/v2Components/SmsFallback/index.scss +0 -265
- package/v2Components/SmsFallback/messages.js +0 -78
- package/v2Components/SmsFallback/smsFallbackUtils.js +0 -118
- package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +0 -50
- package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +0 -147
- package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +0 -304
- package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +0 -197
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -277
- package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +0 -422
- package/v2Components/SmsFallback/useLocalTemplateList.js +0 -92
- package/v2Components/VarSegmentMessageEditor/constants.js +0 -2
- package/v2Components/VarSegmentMessageEditor/index.js +0 -125
- package/v2Components/VarSegmentMessageEditor/index.scss +0 -46
- package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +0 -43
- package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +0 -67
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +0 -90
- package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +0 -258
- package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +0 -125
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +0 -225
- package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +0 -318
- package/v2Containers/Sms/smsFormDataHelpers.js +0 -67
- package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +0 -253
- package/v2Containers/SmsTrai/Edit/index.scss +0 -121
- package/v2Containers/Templates/TemplatesActionBar.js +0 -101
- package/v2Containers/Templates/tests/TemplatesActionBar.test.js +0 -120
- package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +0 -180
- package/v2Containers/Templates/utils/smsTemplatesListApi.js +0 -79
- 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,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
|
-
});
|