@capillarytech/creatives-library 9.0.26 → 9.0.29-alpha.1
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 +29 -0
- package/global-styles.js +1 -1
- package/package.json +1 -1
- package/services/tests/api.test.js +35 -20
- package/utils/commonUtils.js +22 -1
- package/utils/rcsPayloadUtils.js +102 -0
- package/utils/templateVarUtils.js +198 -0
- package/utils/tests/rcsPayloadUtils.test.js +295 -0
- package/utils/tests/templateVarUtils.test.js +204 -0
- package/v2Components/CapActionButton/constants.js +21 -1
- package/v2Components/CapActionButton/index.js +260 -144
- package/v2Components/CapActionButton/index.scss +245 -14
- package/v2Components/CapActionButton/messages.js +32 -3
- package/v2Components/CapActionButton/tests/index.test.js +74 -19
- package/v2Components/CapImageUpload/index.js +2 -2
- package/v2Components/CapTagList/index.js +9 -0
- package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +70 -48
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +8 -2
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +214 -21
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +16 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +83 -9
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +30 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +58 -11
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +10 -5
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +186 -22
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +381 -80
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +155 -8
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +11 -0
- package/v2Components/CommonTestAndPreview/constants.js +35 -2
- package/v2Components/CommonTestAndPreview/index.js +770 -231
- package/v2Components/CommonTestAndPreview/messages.js +45 -3
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +59 -0
- package/v2Components/CommonTestAndPreview/sagas.js +25 -6
- package/v2Components/CommonTestAndPreview/tests/CommonTestAndPreview.addTestCustomer.test.js +1 -0
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +412 -257
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +337 -63
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +118 -5
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +341 -0
- package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +8 -1
- package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +108 -15
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +281 -283
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +199 -1
- package/v2Components/CommonTestAndPreview/tests/index.test.js +133 -4
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +67 -0
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +31 -24
- package/v2Components/CommonTestAndPreview/tests/utils.test.js +151 -0
- package/v2Components/CommonTestAndPreview/utils.js +84 -0
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +91 -0
- package/v2Components/SmsFallback/constants.js +94 -0
- package/v2Components/SmsFallback/index.js +958 -0
- package/v2Components/SmsFallback/index.scss +266 -0
- package/v2Components/SmsFallback/messages.js +78 -0
- package/v2Components/SmsFallback/smsFallbackUtils.js +120 -0
- package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +50 -0
- package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +147 -0
- package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +304 -0
- package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +208 -0
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +309 -0
- package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +471 -0
- package/v2Components/SmsFallback/useLocalTemplateList.js +92 -0
- package/v2Components/TemplatePreview/_templatePreview.scss +45 -25
- package/v2Components/TemplatePreview/constants.js +2 -0
- package/v2Components/TemplatePreview/index.js +147 -32
- package/v2Components/TemplatePreview/tests/index.test.js +142 -0
- package/v2Components/TestAndPreviewSlidebox/CustomValuesEditor.js +6 -6
- package/v2Components/TestAndPreviewSlidebox/index.js +13 -1
- package/v2Components/TestAndPreviewSlidebox/sagas.js +11 -4
- package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +3 -1
- package/v2Components/VarSegmentMessageEditor/constants.js +2 -0
- package/v2Components/VarSegmentMessageEditor/index.js +125 -0
- package/v2Components/VarSegmentMessageEditor/index.scss +46 -0
- package/v2Containers/CommunicationFlow/Tests/CommunicationFlow.test.js +4 -1
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/DeliverySettingsSection.test.js +4 -0
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +20 -20
- package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +27 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +37 -4
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +14 -5
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +36 -5
- package/v2Containers/CreativesContainer/constants.js +11 -0
- package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +77 -0
- package/v2Containers/CreativesContainer/index.js +328 -106
- package/v2Containers/CreativesContainer/index.scss +102 -1
- package/v2Containers/CreativesContainer/tests/CreativesSlideBoxWrapper.test.js +58 -0
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +90 -0
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.smsDltPreview.test.js +73 -0
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +37 -0
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +103 -34
- package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +193 -15
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +88 -0
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +549 -57
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +20 -15
- package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +258 -0
- package/v2Containers/CreativesContainer/tests/index.test.js +71 -9
- package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +125 -0
- package/v2Containers/Email/index.js +3 -54
- package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +4 -9
- package/v2Containers/MobilePush/Create/test/saga.test.js +2 -2
- package/v2Containers/Rcs/carouselUtils.js +224 -0
- package/v2Containers/Rcs/components/CarouselCard.js +317 -0
- package/v2Containers/Rcs/components/CarouselCardButtons.js +113 -0
- package/v2Containers/Rcs/components/CarouselCardMedia.js +136 -0
- package/v2Containers/Rcs/components/CarouselCharacterCount.js +31 -0
- package/v2Containers/Rcs/components/CarouselDimensionSelection.js +80 -0
- package/v2Containers/Rcs/constants.js +132 -16
- package/v2Containers/Rcs/index.js +1808 -949
- package/v2Containers/Rcs/index.scss +443 -8
- package/v2Containers/Rcs/messages.js +45 -22
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +484 -0
- package/v2Containers/Rcs/tests/CarouselCard.test.js +464 -0
- package/v2Containers/Rcs/tests/CarouselCardButtons.test.js +211 -0
- package/v2Containers/Rcs/tests/CarouselCardMedia.test.js +160 -0
- package/v2Containers/Rcs/tests/CarouselCharacterCount.test.js +50 -0
- package/v2Containers/Rcs/tests/CarouselDimensionSelection.test.js +119 -0
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +74176 -39409
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +10 -74
- package/v2Containers/Rcs/tests/carouselUtils.test.js +916 -0
- package/v2Containers/Rcs/tests/index.test.js +219 -40
- package/v2Containers/Rcs/tests/mockData.js +38 -0
- package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +873 -0
- package/v2Containers/Rcs/tests/utils.test.js +682 -30
- package/v2Containers/Rcs/utils.js +514 -12
- package/v2Containers/Sms/Create/index.js +115 -48
- package/v2Containers/Sms/smsFormDataHelpers.js +67 -0
- package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +253 -0
- package/v2Containers/SmsTrai/Create/index.js +9 -4
- package/v2Containers/SmsTrai/Edit/constants.js +2 -0
- package/v2Containers/SmsTrai/Edit/index.js +678 -169
- package/v2Containers/SmsTrai/Edit/index.scss +126 -0
- package/v2Containers/SmsTrai/Edit/messages.js +14 -4
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +5615 -3014
- package/v2Containers/SmsWrapper/index.js +37 -8
- package/v2Containers/TagList/index.js +5 -0
- package/v2Containers/Templates/TemplatesActionBar.js +101 -0
- package/v2Containers/Templates/_templates.scss +196 -12
- package/v2Containers/Templates/actions.js +11 -0
- package/v2Containers/Templates/constants.js +2 -0
- package/v2Containers/Templates/index.js +131 -59
- package/v2Containers/Templates/sagas.js +57 -13
- package/v2Containers/Templates/tests/TemplatesActionBar.test.js +129 -0
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1060 -1015
- package/v2Containers/Templates/tests/sagas.test.js +199 -16
- package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +180 -0
- package/v2Containers/Templates/utils/smsTemplatesListApi.js +79 -0
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +72 -1
- package/v2Containers/TemplatesV2/index.js +88 -25
- package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +131 -0
- package/v2Containers/WeChat/MapTemplates/test/saga.test.js +9 -9
- package/v2Containers/Whatsapp/index.js +3 -20
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +578 -34
|
@@ -0,0 +1,125 @@
|
|
|
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;
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
}
|
|
@@ -30,7 +30,7 @@ jest.mock('../../CreativesContainer', () => function MockCreativesContainer({
|
|
|
30
30
|
import { Provider } from 'react-redux';
|
|
31
31
|
import { configureStore } from '@capillarytech/vulcan-react-sdk/utils';
|
|
32
32
|
import {
|
|
33
|
-
render as rtlRender, screen, waitFor, within,
|
|
33
|
+
render as rtlRender, screen, waitFor, within, fireEvent,
|
|
34
34
|
} from '@testing-library/react';
|
|
35
35
|
import userEvent from '@testing-library/user-event';
|
|
36
36
|
import '@testing-library/jest-dom';
|
|
@@ -47,6 +47,9 @@ import {
|
|
|
47
47
|
STEPS,
|
|
48
48
|
} from '../constants';
|
|
49
49
|
|
|
50
|
+
// antd Select/Dropdown interactions are slow under the parallel jest suite
|
|
51
|
+
jest.setTimeout(15000);
|
|
52
|
+
|
|
50
53
|
let store;
|
|
51
54
|
|
|
52
55
|
beforeAll(() => {
|
|
@@ -24,6 +24,10 @@ jest.mock('../../../../../services/localStorageApi', () => ({
|
|
|
24
24
|
loadItem: jest.fn(),
|
|
25
25
|
}));
|
|
26
26
|
|
|
27
|
+
// SenderDetails uses antd Select whose click→open→select chains are slow in the
|
|
28
|
+
// parallel jest suite; mirror the timeout used in SenderDetails.test.js.
|
|
29
|
+
jest.setTimeout(15000);
|
|
30
|
+
|
|
27
31
|
const WABA_ID = 'waba-test-1';
|
|
28
32
|
|
|
29
33
|
/** Typical `getDomainProperties` payloads per channel (merged when testing multi-channel). */
|
package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import {
|
|
3
|
-
render, screen, waitFor, within,
|
|
3
|
+
render, screen, waitFor, within, fireEvent,
|
|
4
4
|
} from '@testing-library/react';
|
|
5
5
|
import userEvent from '@testing-library/user-event';
|
|
6
6
|
import '@testing-library/jest-dom';
|
|
@@ -183,9 +183,9 @@ const WAIT_OPTIONS = { timeout: 10000 };
|
|
|
183
183
|
|
|
184
184
|
async function openSelectAndChoose(root, comboIndex, optionText) {
|
|
185
185
|
const combos = within(root).getAllByRole('combobox');
|
|
186
|
-
|
|
186
|
+
fireEvent.mouseDown(combos[comboIndex]);
|
|
187
187
|
await waitFor(() => expect(screen.getByRole('listbox')).toBeInTheDocument(), WAIT_OPTIONS);
|
|
188
|
-
|
|
188
|
+
fireEvent.click(await findVisibleSelectOption(optionText, WAIT_OPTIONS));
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
describe('SenderDetails', () => {
|
|
@@ -334,7 +334,7 @@ describe('SenderDetails', () => {
|
|
|
334
334
|
await waitFor(() => expect(within(root).getByText('beta@other.com')).toBeInTheDocument());
|
|
335
335
|
|
|
336
336
|
const resetLinks = within(root).getAllByText('Reset');
|
|
337
|
-
|
|
337
|
+
fireEvent.click(resetLinks[0]);
|
|
338
338
|
|
|
339
339
|
await waitFor(() => {
|
|
340
340
|
expect(within(root).getByText('alpha@brand.com')).toBeInTheDocument();
|
|
@@ -349,12 +349,12 @@ describe('SenderDetails', () => {
|
|
|
349
349
|
await waitFor(() => expect(within(root).getByText('+1002003001')).toBeInTheDocument());
|
|
350
350
|
|
|
351
351
|
const combos = within(root).getAllByRole('combobox');
|
|
352
|
-
|
|
352
|
+
fireEvent.mouseDown(combos[1]);
|
|
353
353
|
await waitFor(() => expect(screen.getByRole('listbox')).toBeInTheDocument(), WAIT_OPTIONS);
|
|
354
|
-
|
|
354
|
+
fireEvent.click(await findVisibleSelectOption('+1002003002', WAIT_OPTIONS));
|
|
355
355
|
|
|
356
356
|
const resetLinks = within(root).getAllByText('Reset');
|
|
357
|
-
|
|
357
|
+
fireEvent.click(resetLinks[1]);
|
|
358
358
|
|
|
359
359
|
await waitFor(() => expect(within(root).getByText('+1002003001')).toBeInTheDocument());
|
|
360
360
|
});
|
|
@@ -370,13 +370,13 @@ describe('SenderDetails', () => {
|
|
|
370
370
|
await waitFor(() => expect(within(root).getByText('My Business')).toBeInTheDocument());
|
|
371
371
|
|
|
372
372
|
const combos = within(root).getAllByRole('combobox');
|
|
373
|
-
|
|
373
|
+
fireEvent.mouseDown(combos[combos.length - 1]);
|
|
374
374
|
await waitFor(() => expect(screen.getByRole('listbox')).toBeInTheDocument(), WAIT_OPTIONS);
|
|
375
|
-
|
|
375
|
+
fireEvent.click(await findVisibleSelectOption('+91900111333', WAIT_OPTIONS));
|
|
376
376
|
|
|
377
377
|
const saveBtn = within(root).getByRole('button', { name: /save changes/i });
|
|
378
378
|
await waitFor(() => expect(saveBtn).not.toBeDisabled());
|
|
379
|
-
|
|
379
|
+
fireEvent.click(saveBtn);
|
|
380
380
|
|
|
381
381
|
expect(onSave).toHaveBeenCalledWith(
|
|
382
382
|
expect.objectContaining({
|
|
@@ -425,9 +425,9 @@ describe('SenderDetails', () => {
|
|
|
425
425
|
await waitFor(() => expect(within(root).getByText('Gateway A')).toBeInTheDocument());
|
|
426
426
|
|
|
427
427
|
const combos = within(root).getAllByRole('combobox');
|
|
428
|
-
|
|
428
|
+
fireEvent.mouseDown(combos[0]);
|
|
429
429
|
await waitFor(() => expect(screen.getByRole('listbox')).toBeInTheDocument(), WAIT_OPTIONS);
|
|
430
|
-
|
|
430
|
+
fireEvent.click(await findVisibleSelectOption('Gateway B', WAIT_OPTIONS));
|
|
431
431
|
|
|
432
432
|
// The sender ID should now auto-update to Gateway B's sender
|
|
433
433
|
await waitFor(() => expect(within(root).getByText('+222')).toBeInTheDocument());
|
|
@@ -444,9 +444,9 @@ describe('SenderDetails', () => {
|
|
|
444
444
|
|
|
445
445
|
// Switch to Mail Beta domain
|
|
446
446
|
const combos = within(root).getAllByRole('combobox');
|
|
447
|
-
|
|
447
|
+
fireEvent.mouseDown(combos[0]);
|
|
448
448
|
await waitFor(() => expect(screen.getByRole('listbox')).toBeInTheDocument(), WAIT_OPTIONS);
|
|
449
|
-
|
|
449
|
+
fireEvent.click(await findVisibleSelectOption('Mail Beta', WAIT_OPTIONS));
|
|
450
450
|
|
|
451
451
|
// Sender ID should auto-update to beta@other.com
|
|
452
452
|
await waitFor(() => expect(within(root).getByText('beta@other.com')).toBeInTheDocument());
|
|
@@ -468,13 +468,13 @@ describe('SenderDetails', () => {
|
|
|
468
468
|
// Change sender to enable save
|
|
469
469
|
const combos = within(root).getAllByRole('combobox');
|
|
470
470
|
const senderCombo = combos[combos.length - 1];
|
|
471
|
-
|
|
471
|
+
fireEvent.mouseDown(senderCombo);
|
|
472
472
|
await waitFor(() => expect(screen.getByRole('listbox')).toBeInTheDocument(), WAIT_OPTIONS);
|
|
473
|
-
|
|
473
|
+
fireEvent.click(await findVisibleSelectOption('+91900111333', WAIT_OPTIONS));
|
|
474
474
|
|
|
475
475
|
const saveBtn = within(root).getByRole('button', { name: /save changes/i });
|
|
476
476
|
await waitFor(() => expect(saveBtn).not.toBeDisabled());
|
|
477
|
-
|
|
477
|
+
fireEvent.click(saveBtn);
|
|
478
478
|
|
|
479
479
|
// Should have called onSave with whatsappDomainId derived from the matched WABA domain
|
|
480
480
|
expect(onSave).toHaveBeenCalledWith(
|
|
@@ -507,9 +507,9 @@ describe('SenderDetails', () => {
|
|
|
507
507
|
// Change to an alternate sender
|
|
508
508
|
const combos = within(root).getAllByRole('combobox');
|
|
509
509
|
const senderCombo = combos[combos.length - 1];
|
|
510
|
-
|
|
510
|
+
fireEvent.mouseDown(senderCombo);
|
|
511
511
|
await waitFor(() => expect(screen.getByRole('listbox')).toBeInTheDocument(), WAIT_OPTIONS);
|
|
512
|
-
|
|
512
|
+
fireEvent.click(await findVisibleSelectOption('+viber-alt', WAIT_OPTIONS));
|
|
513
513
|
|
|
514
514
|
// antd v6 also renders selected option in an aria-live polite region for
|
|
515
515
|
// screen readers, so the text appears twice. Match only the visible select
|
|
@@ -521,7 +521,7 @@ describe('SenderDetails', () => {
|
|
|
521
521
|
// Now click reset — for viberSenderId the else branch in handleReset is hit
|
|
522
522
|
// (viberSenderId is not smsDomain/emailDomain, so getDefaultValueForField returns '')
|
|
523
523
|
const resetLinks = within(root).getAllByText('Reset');
|
|
524
|
-
|
|
524
|
+
fireEvent.click(resetLinks[resetLinks.length - 1]);
|
|
525
525
|
// After reset, the field goes to the default value returned by getDefaultValueForField
|
|
526
526
|
// For viberSenderId this is '' (no specific default handler). The visible
|
|
527
527
|
// select tile no longer shows +viber-alt; the aria-live polite span may
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import classnames from 'classnames';
|
|
3
|
+
import { CAP_SPACE_32, CAP_SPACE_56, CAP_SPACE_64 } from '@capillarytech/cap-ui-library/styled/variables';
|
|
4
|
+
|
|
5
|
+
/* getSlideBoxWrapperMarginFromLiquidErrors only ever returns 0 or one of these three tokens
|
|
6
|
+
* (see embeddedSlideboxUtils.js) — mapped to static modifier classes so no inline style is needed. */
|
|
7
|
+
const WRAPPER_MARGIN_CLASS_BY_VALUE = {
|
|
8
|
+
[CAP_SPACE_32]: 'creatives-slide-box-wrapper--margin-32',
|
|
9
|
+
[CAP_SPACE_56]: 'creatives-slide-box-wrapper--margin-56',
|
|
10
|
+
[CAP_SPACE_64]: 'creatives-slide-box-wrapper--margin-64',
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const CreativesSlideBoxWrapper = ({ slideBoxWrapperMargin, shouldApplyFooterMargin, children, className, ...rest }) => (
|
|
14
|
+
<section
|
|
15
|
+
className={classnames(
|
|
16
|
+
'creatives-slide-box-wrapper',
|
|
17
|
+
WRAPPER_MARGIN_CLASS_BY_VALUE[slideBoxWrapperMargin],
|
|
18
|
+
{ 'creatives-slide-box-wrapper--footer-margin': shouldApplyFooterMargin },
|
|
19
|
+
className,
|
|
20
|
+
)}
|
|
21
|
+
{...rest}
|
|
22
|
+
>
|
|
23
|
+
{children}
|
|
24
|
+
</section>
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
export default CreativesSlideBoxWrapper;
|
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import styled from 'styled-components';
|
|
4
4
|
import get from 'lodash/get';
|
|
5
5
|
import isEmpty from 'lodash/isEmpty';
|
|
6
|
+
import pick from 'lodash/pick';
|
|
6
7
|
import cloneDeep from 'lodash/cloneDeep';
|
|
7
8
|
import TemplatesV2 from '../TemplatesV2';
|
|
8
9
|
import TemplatePreview from '../../v2Components/TemplatePreview';
|
|
@@ -25,6 +26,7 @@ import Viber from '../Viber';
|
|
|
25
26
|
import Whatsapp from '../Whatsapp';
|
|
26
27
|
import InApp from '../InApp';
|
|
27
28
|
import Rcs from '../Rcs';
|
|
29
|
+
import { isRcsTextOnlyCardMediaType, resolveRcsCardPreviewStrings } from '../Rcs/utils';
|
|
28
30
|
import { getWhatsappContent } from '../Whatsapp/utils';
|
|
29
31
|
import * as commonUtil from '../../utils/common';
|
|
30
32
|
import Zalo from '../Zalo';
|
|
@@ -180,6 +182,8 @@ export function SlideBoxContent(props) {
|
|
|
180
182
|
isTestAndPreviewMode,
|
|
181
183
|
onHtmlEditorValidationStateChange,
|
|
182
184
|
} = props;
|
|
185
|
+
const localTemplatesConfig = props.localTemplatesConfig || pick(props, constants.LOCAL_TEMPLATE_CONFIG_KEYS);
|
|
186
|
+
const useLocalTemplates = !!get(localTemplatesConfig, 'useLocalTemplates');
|
|
183
187
|
const type = (messageDetails.type || '').toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
|
|
184
188
|
const query = { type: !isFullMode && 'embedded', module: isFullMode ? 'default' : 'library', isEditFromCampaigns: (templateData || {}).isEditFromCampaigns};
|
|
185
189
|
const creativesLocationProps = {
|
|
@@ -399,12 +403,37 @@ export function SlideBoxContent(props) {
|
|
|
399
403
|
}
|
|
400
404
|
case constants.RCS: {
|
|
401
405
|
const template = cloneDeep(templateDataObject);
|
|
402
|
-
const
|
|
406
|
+
const cardPath = 'versions.base.content.RCS.rcsContent.cardContent[0]';
|
|
407
|
+
const card = get(template, cardPath, {}) || {};
|
|
408
|
+
const {
|
|
409
|
+
description = '',
|
|
410
|
+
media: { mediaUrl = '' } = {},
|
|
411
|
+
title = '',
|
|
412
|
+
mediaType: cardMediaType,
|
|
413
|
+
suggestions = [],
|
|
414
|
+
cardVarMapped: nestedCardVarMapped,
|
|
415
|
+
} = card;
|
|
416
|
+
const rootMirror = templateDataObject?.rcsCardVarMapped;
|
|
417
|
+
const nestedRecord =
|
|
418
|
+
nestedCardVarMapped != null && typeof nestedCardVarMapped === 'object'
|
|
419
|
+
? nestedCardVarMapped
|
|
420
|
+
: {};
|
|
421
|
+
const rootRecord =
|
|
422
|
+
rootMirror != null && typeof rootMirror === 'object' ? rootMirror : {};
|
|
423
|
+
const mergedCardVarMapped = { ...rootRecord, ...nestedRecord };
|
|
424
|
+
const textOnlyCard = isRcsTextOnlyCardMediaType(cardMediaType);
|
|
425
|
+
const { rcsTitle, rcsDesc } = resolveRcsCardPreviewStrings(
|
|
426
|
+
title,
|
|
427
|
+
description,
|
|
428
|
+
mergedCardVarMapped,
|
|
429
|
+
!isFullMode,
|
|
430
|
+
textOnlyCard,
|
|
431
|
+
);
|
|
403
432
|
return {
|
|
404
433
|
rcsPreviewContent: {
|
|
405
434
|
rcsImageSrc: mediaUrl,
|
|
406
|
-
rcsTitle
|
|
407
|
-
rcsDesc
|
|
435
|
+
rcsTitle,
|
|
436
|
+
rcsDesc,
|
|
408
437
|
...(suggestions.length > 0 && {
|
|
409
438
|
buttonText: suggestions[0]?.text,
|
|
410
439
|
}),
|
|
@@ -426,11 +455,12 @@ export function SlideBoxContent(props) {
|
|
|
426
455
|
getFormData,
|
|
427
456
|
eventContextTags,
|
|
428
457
|
waitEventContextTags,
|
|
458
|
+
handleClose,
|
|
429
459
|
};
|
|
430
460
|
|
|
431
461
|
return (
|
|
432
462
|
<CreativesWrapper>
|
|
433
|
-
{
|
|
463
|
+
{slidBoxContent === 'templates' && (!isFullMode || useLocalTemplates) && (
|
|
434
464
|
<TemplatesV2
|
|
435
465
|
isFullMode={isFullMode}
|
|
436
466
|
onSelectTemplate={onSelectTemplate}
|
|
@@ -463,6 +493,7 @@ export function SlideBoxContent(props) {
|
|
|
463
493
|
waitEventContextTags={waitEventContextTags}
|
|
464
494
|
loyaltyMetaData={loyaltyMetaData}
|
|
465
495
|
isLoyaltyModule={isLoyaltyModule}
|
|
496
|
+
localTemplatesConfig={localTemplatesConfig}
|
|
466
497
|
/>
|
|
467
498
|
)}
|
|
468
499
|
{isPreview && (
|
|
@@ -633,6 +664,7 @@ export function SlideBoxContent(props) {
|
|
|
633
664
|
route={{ name: 'sms' }}
|
|
634
665
|
isCreateSms={isCreateSms}
|
|
635
666
|
isComponent
|
|
667
|
+
templateData={templateData}
|
|
636
668
|
isGetFormData={isGetFormData}
|
|
637
669
|
getFormSubscriptionData={getFormData}
|
|
638
670
|
getLiquidTags={getLiquidTags}
|
|
@@ -1242,6 +1274,7 @@ export function SlideBoxContent(props) {
|
|
|
1242
1274
|
)}
|
|
1243
1275
|
{isCreateRcs && (<Rcs
|
|
1244
1276
|
{...rcsCommonProps}
|
|
1277
|
+
templateData={templateData}
|
|
1245
1278
|
showLiquidErrorInFooter={showLiquidErrorInFooter}
|
|
1246
1279
|
showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
|
|
1247
1280
|
handleTestAndPreview={handleTestAndPreview}
|
|
@@ -49,6 +49,8 @@ function SlideBoxFooter(props) {
|
|
|
49
49
|
isAnonymousType = false,
|
|
50
50
|
templateData = {},
|
|
51
51
|
hasPersonalizationTokenError: hasPersonalizationTokenErrorProp = false,
|
|
52
|
+
/** When set (e.g. SMS library create), overrides `creativesTemplatesSave` (“Done”) for the primary button */
|
|
53
|
+
primarySaveButtonMessage,
|
|
52
54
|
} = props;
|
|
53
55
|
// Calculate if buttons should be disabled
|
|
54
56
|
// Only apply validation state checks for EMAIL channel in HTML Editor mode (not BEE/DragDrop)
|
|
@@ -165,6 +167,12 @@ function SlideBoxFooter(props) {
|
|
|
165
167
|
// Use prop from parent (FormBuilder flow) when available; else fall back to templateData check
|
|
166
168
|
const hasPersonalizationTokenError = hasPersonalizationTokenErrorProp === true || (restrictPersonalization && hasPersonalizationTokens());
|
|
167
169
|
|
|
170
|
+
function getSaveButtonLabel() {
|
|
171
|
+
if (primarySaveButtonMessage) return <FormattedMessage {...primarySaveButtonMessage} />;
|
|
172
|
+
if (isFullMode) return getFullModeSaveBtn(slidBoxContent, isCreatingTemplate);
|
|
173
|
+
return <FormattedMessage {...messages.creativesTemplatesSave} />;
|
|
174
|
+
}
|
|
175
|
+
|
|
168
176
|
return (
|
|
169
177
|
<div className="template-footer-width">
|
|
170
178
|
{shouldShowErrorInfoNote && (
|
|
@@ -187,11 +195,7 @@ function SlideBoxFooter(props) {
|
|
|
187
195
|
onClick={onSave}
|
|
188
196
|
disabled={isTemplateNameEmpty || fetchingCmsData || shouldDisableButtons || hasPersonalizationTokenError}
|
|
189
197
|
>
|
|
190
|
-
{
|
|
191
|
-
getFullModeSaveBtn(slidBoxContent, isCreatingTemplate)
|
|
192
|
-
) : (
|
|
193
|
-
<FormattedMessage {...messages.creativesTemplatesSave} />
|
|
194
|
-
)}
|
|
198
|
+
{getSaveButtonLabel()}
|
|
195
199
|
</CapButton>
|
|
196
200
|
{showTestAndPreviewButton && (
|
|
197
201
|
<CapButton
|
|
@@ -264,6 +268,10 @@ SlideBoxFooter.propTypes = {
|
|
|
264
268
|
templateData: PropTypes.object,
|
|
265
269
|
formData: PropTypes.array,
|
|
266
270
|
hasPersonalizationTokenError: PropTypes.bool,
|
|
271
|
+
primarySaveButtonMessage: PropTypes.shape({
|
|
272
|
+
id: PropTypes.string,
|
|
273
|
+
defaultMessage: PropTypes.string,
|
|
274
|
+
}),
|
|
267
275
|
};
|
|
268
276
|
|
|
269
277
|
SlideBoxFooter.defaultProps = {
|
|
@@ -291,5 +299,6 @@ SlideBoxFooter.defaultProps = {
|
|
|
291
299
|
selectedEmailCreateMode: '',
|
|
292
300
|
formData: [],
|
|
293
301
|
hasPersonalizationTokenError: false,
|
|
302
|
+
primarySaveButtonMessage: undefined,
|
|
294
303
|
};
|
|
295
304
|
export default SlideBoxFooter;
|
|
@@ -16,6 +16,7 @@ import { isTraiDLTEnable } from '../../utils/common';
|
|
|
16
16
|
import { formatString } from '../../utils/Formatter';
|
|
17
17
|
import {
|
|
18
18
|
CAP_SPACE_12,
|
|
19
|
+
CAP_SPACE_16,
|
|
19
20
|
ICON_SIZE_M,
|
|
20
21
|
} from '@capillarytech/cap-ui-library/styled/variables';
|
|
21
22
|
import { WHATSAPP_HELP_DOC_LINK, JOURNEY } from './constants';
|
|
@@ -28,7 +29,7 @@ const StyledLabel = styled(CapLabelInline)`
|
|
|
28
29
|
// the inherited font-size. Pin it to the medium icon size (24px) and center it so
|
|
29
30
|
// the back arrow matches the header title instead of collapsing to a tiny glyph.
|
|
30
31
|
const PrefixWrapper = styled.div`
|
|
31
|
-
margin-right:
|
|
32
|
+
margin-right: ${CAP_SPACE_16};
|
|
32
33
|
display: inline-flex;
|
|
33
34
|
align-items: center;
|
|
34
35
|
font-size: ${ICON_SIZE_M};
|
|
@@ -40,7 +41,25 @@ const renderData = (type, value, channel) => (
|
|
|
40
41
|
);
|
|
41
42
|
|
|
42
43
|
export function SlideBoxHeader(props) {
|
|
43
|
-
const {
|
|
44
|
+
const {
|
|
45
|
+
slidBoxContent,
|
|
46
|
+
templateData,
|
|
47
|
+
onShowTemplates,
|
|
48
|
+
creativesMode,
|
|
49
|
+
isFullMode,
|
|
50
|
+
showPrefix,
|
|
51
|
+
shouldShowTemplateName,
|
|
52
|
+
channel,
|
|
53
|
+
templateNameRenderProp,
|
|
54
|
+
weChatTemplateType,
|
|
55
|
+
onWeChatMaptemplateStepChange,
|
|
56
|
+
weChatMaptemplateStep,
|
|
57
|
+
templateStep,
|
|
58
|
+
smsRegister,
|
|
59
|
+
handleClose,
|
|
60
|
+
moduleType,
|
|
61
|
+
useLocalTemplates = false,
|
|
62
|
+
} = props;
|
|
44
63
|
const showTemplateNameHeader = isFullMode && shouldShowTemplateName;
|
|
45
64
|
const mapTemplateCreate = !showTemplateNameHeader && slidBoxContent === 'createTemplate' && weChatTemplateType === MAP_TEMPLATE && templateStep !== 'modeSelection';
|
|
46
65
|
const isTraiDlt = isTraiDLTEnable(isFullMode, smsRegister);
|
|
@@ -61,7 +80,7 @@ export function SlideBoxHeader(props) {
|
|
|
61
80
|
} = templateData || {};
|
|
62
81
|
const templateName = whatsappTemplateName || templateData?.name;
|
|
63
82
|
const showRcsTemplateName = channel.toLowerCase() === RCS && slidBoxContent === 'editTemplate' && !isFullMode && templateName;
|
|
64
|
-
const showTemplateName = isWhatsappEdit ||
|
|
83
|
+
const showTemplateName = isWhatsappEdit || isZaloEdit;
|
|
65
84
|
const whatsappCategory = whatsappTemplateCategory || get(templateData, `versions.base.content.whatsapp.category`, '');
|
|
66
85
|
const whatsappLanguageCode = whatsappTemplateLanguageCode || get(templateData, `versions.base.content.whatsapp.languages[0].language`, '');
|
|
67
86
|
|
|
@@ -88,6 +107,9 @@ export function SlideBoxHeader(props) {
|
|
|
88
107
|
window.open(WHATSAPP_HELP_DOC_LINK, '_blank');
|
|
89
108
|
};
|
|
90
109
|
|
|
110
|
+
const showCreativesTemplatesBackButton =
|
|
111
|
+
!isFullMode && (moduleType === JOURNEY || useLocalTemplates);
|
|
112
|
+
|
|
91
113
|
return (
|
|
92
114
|
<div key="creatives-container-slidebox-header-content">
|
|
93
115
|
{slidBoxContent === 'templates' && !showTemplateNameHeader && (
|
|
@@ -96,7 +118,7 @@ export function SlideBoxHeader(props) {
|
|
|
96
118
|
description={![NO_COMMUNICATION, FTP].includes(channel) &&
|
|
97
119
|
<FormattedMessage {...messages.creativeTemplatesDesc} />
|
|
98
120
|
}
|
|
99
|
-
prefix={
|
|
121
|
+
prefix={showCreativesTemplatesBackButton &&
|
|
100
122
|
<PrefixWrapper>
|
|
101
123
|
<CapIcons.BackIcon onClick={handleClose} />
|
|
102
124
|
</PrefixWrapper>
|
|
@@ -130,6 +152,12 @@ export function SlideBoxHeader(props) {
|
|
|
130
152
|
<StyledLabel className='whatsapp-rcs-slidebox-template-name' type="label2">{templateName}</StyledLabel>
|
|
131
153
|
</>
|
|
132
154
|
) : ""}
|
|
155
|
+
{showRcsTemplateName && (
|
|
156
|
+
<>
|
|
157
|
+
{renderData("label1", <FormattedMessage {...globalMessages.creativeNameLabel} />, channel)}
|
|
158
|
+
<StyledLabel className='whatsapp-rcs-slidebox-template-name' type="label2">{templateName}</StyledLabel>
|
|
159
|
+
</>
|
|
160
|
+
)}
|
|
133
161
|
{isWhatsappEdit && (
|
|
134
162
|
<>
|
|
135
163
|
{renderData("label3", <FormattedMessage {...whatsppMsg.labelSeperator} />)}
|
|
@@ -142,7 +170,7 @@ export function SlideBoxHeader(props) {
|
|
|
142
170
|
}
|
|
143
171
|
</>
|
|
144
172
|
}
|
|
145
|
-
prefix={
|
|
173
|
+
prefix={!isFullMode && showPrefix &&
|
|
146
174
|
<PrefixWrapper>
|
|
147
175
|
<CapIcons.BackIcon onClick={onShowTemplates} />
|
|
148
176
|
</PrefixWrapper>
|
|
@@ -198,5 +226,8 @@ SlideBoxHeader.propTypes = {
|
|
|
198
226
|
shouldShowTemplateName: PropTypes.bool,
|
|
199
227
|
templateNameRenderProp: PropTypes.func,
|
|
200
228
|
smsRegister: PropTypes.any,
|
|
229
|
+
handleClose: PropTypes.func,
|
|
230
|
+
moduleType: PropTypes.string,
|
|
231
|
+
useLocalTemplates: PropTypes.bool,
|
|
201
232
|
};
|
|
202
233
|
export default SlideBoxHeader;
|
|
@@ -73,3 +73,14 @@ export const ALLOWED_CHANNELS_FOR_ANONYMOUS = ['mobilepush', 'webpush'];
|
|
|
73
73
|
export const ALL_CHANNELS_NEW = [
|
|
74
74
|
'sms', 'email', 'whatsapp', 'facebook', 'line', 'viber', 'rcs', 'zalo', 'inapp', 'call_task', 'ftp',
|
|
75
75
|
];
|
|
76
|
+
|
|
77
|
+
export const LOCAL_TEMPLATE_CONFIG_KEYS = ['useLocalTemplates', 'localTemplates', 'localTemplatesLoading', 'localTemplatesFilterContent', 'localTemplatesUseSkeleton', 'localTemplatesOnPageChange'];
|
|
78
|
+
|
|
79
|
+
/** Keys passed from parents into `Templates` when using local SMS template list (extends `LOCAL_TEMPLATE_CONFIG_KEYS`). */
|
|
80
|
+
export const LOCAL_TEMPLATE_CONFIG_KEYS_FOR_PICK = [
|
|
81
|
+
...LOCAL_TEMPLATE_CONFIG_KEYS,
|
|
82
|
+
'localTemplatesLoadingTip',
|
|
83
|
+
'localTemplatesFooterContent',
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
export const DEFAULT_SMS_TEMPLATE_NAME = 'Campaign message SMS content';
|