@capillarytech/creatives-library 9.0.29 → 9.0.31
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 +261 -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 +774 -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 +322 -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/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 +1822 -946
- package/v2Containers/Rcs/index.scss +443 -8
- package/v2Containers/Rcs/messages.js +45 -22
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +494 -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 +74440 -39387
- 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 +275 -40
- package/v2Containers/Rcs/tests/mockData.js +38 -0
- package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +912 -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
|
@@ -8,6 +8,8 @@ import CapButton from '@capillarytech/cap-ui-library/CapButton';
|
|
|
8
8
|
import CapInput from '@capillarytech/cap-ui-library/CapInput';
|
|
9
9
|
import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
|
|
10
10
|
import messages from './messages';
|
|
11
|
+
import { CUSTOM_VALUES_EDITOR_SECTION_FALLBACK_KEY } from './constants';
|
|
12
|
+
import { getPersonalizationTagColumnLabel } from './utils';
|
|
11
13
|
|
|
12
14
|
const CustomValuesEditor = ({
|
|
13
15
|
isExtractingTags,
|
|
@@ -16,9 +18,7 @@ const CustomValuesEditor = ({
|
|
|
16
18
|
setShowJSON,
|
|
17
19
|
customValues,
|
|
18
20
|
handleJSONTextChange,
|
|
19
|
-
|
|
20
|
-
requiredTags,
|
|
21
|
-
optionalTags,
|
|
21
|
+
sections,
|
|
22
22
|
handleCustomValueChange,
|
|
23
23
|
handleDiscardCustomValues,
|
|
24
24
|
handleUpdatePreview,
|
|
@@ -77,51 +77,70 @@ const CustomValuesEditor = ({
|
|
|
77
77
|
</CapRow>
|
|
78
78
|
) : (
|
|
79
79
|
<>
|
|
80
|
-
{
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
{(sections || []).filter((tagsSection) =>
|
|
81
|
+
(tagsSection?.requiredTags?.length || 0) + (tagsSection?.optionalTags?.length || 0) > 0).map((section) => (
|
|
82
|
+
<React.Fragment key={section.key || section.title?.id || section.title || CUSTOM_VALUES_EDITOR_SECTION_FALLBACK_KEY}>
|
|
83
|
+
{section.title ? (
|
|
84
|
+
<CapLabel type="label2" className="tags-section-title">
|
|
85
|
+
{typeof section.title === 'string' ? section.title : <FormattedMessage {...section.title} />}
|
|
85
86
|
</CapLabel>
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
<
|
|
93
|
-
{
|
|
94
|
-
</
|
|
95
|
-
<CapRow className="tag-input">
|
|
96
|
-
<CapInput
|
|
97
|
-
type="text"
|
|
98
|
-
isRequired
|
|
99
|
-
className="tag-input-field"
|
|
100
|
-
value={customValues[tag.fullPath] || ''}
|
|
101
|
-
onChange={(e) => handleCustomValueChange(tag.fullPath, e.target.value)}
|
|
102
|
-
placeholder={formatMessage(messages.enterValue)}
|
|
103
|
-
size="small"
|
|
104
|
-
/>
|
|
105
|
-
</CapRow>
|
|
87
|
+
) : null}
|
|
88
|
+
<CapRow className="values-table">
|
|
89
|
+
<CapRow type="flex" className="table-header">
|
|
90
|
+
<CapLabel type="label31" className="header-cell">
|
|
91
|
+
<FormattedMessage {...messages.personalizationTags} />
|
|
92
|
+
</CapLabel>
|
|
93
|
+
<CapLabel type="label31" className="header-cell">
|
|
94
|
+
<FormattedMessage {...messages.customValues} />
|
|
95
|
+
</CapLabel>
|
|
106
96
|
</CapRow>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
<CapRow className="
|
|
112
|
-
<
|
|
113
|
-
|
|
114
|
-
className="tag-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
97
|
+
{(section?.requiredTags || []).map((tag, tagIndex) => {
|
|
98
|
+
const personalizationTagColumnText = getPersonalizationTagColumnLabel(tag);
|
|
99
|
+
const tagKey = tag?.fullPath ?? `required-${tagIndex}`;
|
|
100
|
+
return (
|
|
101
|
+
<CapRow key={tagKey} type="flex" noWrap className="value-row">
|
|
102
|
+
<CapRow type="flex" className="tag-name">
|
|
103
|
+
{personalizationTagColumnText}
|
|
104
|
+
<span className="required-tag-indicator" aria-hidden="true">*</span>
|
|
105
|
+
</CapRow>
|
|
106
|
+
<CapRow type="flex" className="tag-input">
|
|
107
|
+
<CapInput
|
|
108
|
+
type="text"
|
|
109
|
+
isRequired
|
|
110
|
+
className="tag-input-field"
|
|
111
|
+
value={customValues?.[tagKey] ?? ''}
|
|
112
|
+
onChange={(e) => handleCustomValueChange(tagKey, e.target.value)}
|
|
113
|
+
placeholder={formatMessage(messages.enterValue)}
|
|
114
|
+
size="small"
|
|
115
|
+
/>
|
|
116
|
+
</CapRow>
|
|
120
117
|
</CapRow>
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
118
|
+
);
|
|
119
|
+
})}
|
|
120
|
+
{(section?.optionalTags || []).map((tag, tagIndex) => {
|
|
121
|
+
const personalizationTagColumnText = getPersonalizationTagColumnLabel(tag);
|
|
122
|
+
const tagKey = tag?.fullPath ?? `optional-${tagIndex}`;
|
|
123
|
+
return (
|
|
124
|
+
<CapRow key={tagKey} type="flex" noWrap className="value-row">
|
|
125
|
+
<CapRow type="flex" className="tag-name">
|
|
126
|
+
{personalizationTagColumnText}
|
|
127
|
+
</CapRow>
|
|
128
|
+
<CapRow type="flex" className="tag-input">
|
|
129
|
+
<CapInput
|
|
130
|
+
type="text"
|
|
131
|
+
className="tag-input-field"
|
|
132
|
+
value={customValues?.[tagKey] ?? ''}
|
|
133
|
+
onChange={(e) => handleCustomValueChange(tagKey, e.target.value)}
|
|
134
|
+
placeholder={formatMessage(messages.enterValue)}
|
|
135
|
+
size="small"
|
|
136
|
+
/>
|
|
137
|
+
</CapRow>
|
|
138
|
+
</CapRow>
|
|
139
|
+
);
|
|
140
|
+
})}
|
|
141
|
+
</CapRow>
|
|
142
|
+
</React.Fragment>
|
|
143
|
+
))}
|
|
125
144
|
</>
|
|
126
145
|
)}
|
|
127
146
|
<CapRow type='flex' align='middle' justify='space-between' className="editor-actions">
|
|
@@ -155,9 +174,12 @@ CustomValuesEditor.propTypes = {
|
|
|
155
174
|
setShowJSON: PropTypes.func.isRequired,
|
|
156
175
|
customValues: PropTypes.object.isRequired,
|
|
157
176
|
handleJSONTextChange: PropTypes.func.isRequired,
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
177
|
+
sections: PropTypes.arrayOf(PropTypes.shape({
|
|
178
|
+
key: PropTypes.string,
|
|
179
|
+
title: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
|
180
|
+
requiredTags: PropTypes.array,
|
|
181
|
+
optionalTags: PropTypes.array,
|
|
182
|
+
})).isRequired,
|
|
161
183
|
handleCustomValueChange: PropTypes.func.isRequired,
|
|
162
184
|
handleDiscardCustomValues: PropTypes.func.isRequired,
|
|
163
185
|
handleUpdatePreview: PropTypes.func.isRequired,
|
|
@@ -18,11 +18,17 @@
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
&__summary-entry {
|
|
21
|
+
display: flex;
|
|
22
|
+
align-items: baseline;
|
|
23
|
+
gap: 0;
|
|
21
24
|
margin-right: $CAP_SPACE_18;
|
|
22
25
|
}
|
|
23
26
|
|
|
24
|
-
&__summary-key
|
|
25
|
-
|
|
27
|
+
&__summary-key,
|
|
28
|
+
&__summary-value {
|
|
29
|
+
line-height: 1.4;
|
|
30
|
+
margin-top: 0;
|
|
31
|
+
margin-bottom: 0;
|
|
26
32
|
}
|
|
27
33
|
|
|
28
34
|
&__edit-icon {
|
|
@@ -32,16 +32,37 @@ import {
|
|
|
32
32
|
DELIVERY_SETTING_KEY_SENDER_REPLY_TO,
|
|
33
33
|
DELIVERY_SETTING_KEY_SOURCE_ACCOUNT_IDENTIFIER,
|
|
34
34
|
DELIVERY_SETTING_KEY_SENDER_MOB_NUM,
|
|
35
|
+
DELIVERY_SETTING_KEY_SMS_FALLBACK_DOMAIN_ID,
|
|
35
36
|
} from './constants';
|
|
36
37
|
import './ModifyDeliverySettings.scss';
|
|
37
38
|
|
|
38
39
|
const findDefault = (array) => find(array, { default: true }) || (array && array[0]) || {};
|
|
39
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Drop empty GSM rows. Optionally drop rows whose value equals domain name — some APIs duplicate
|
|
43
|
+
* domain label as a bogus sender row; RCS/DLT often legitimately use the same string (e.g. DetailsForGW1).
|
|
44
|
+
*/
|
|
45
|
+
const filterUsableGsmSendersForDomain = (domain, gsmSenders, { skipDomainNameEchoFilter = false } = {}) => {
|
|
46
|
+
const normalizedDomainName =
|
|
47
|
+
domain?.domainName != null ? String(domain.domainName).trim().toLowerCase() : '';
|
|
48
|
+
return (gsmSenders || []).filter((gsmSenderRow) => {
|
|
49
|
+
const rawValue = gsmSenderRow?.value;
|
|
50
|
+
if (rawValue == null) return false;
|
|
51
|
+
const trimmedSenderValue = String(rawValue).trim();
|
|
52
|
+
if (!trimmedSenderValue) return false;
|
|
53
|
+
const senderMatchesDomainLabel =
|
|
54
|
+
normalizedDomainName && trimmedSenderValue.toLowerCase() === normalizedDomainName;
|
|
55
|
+
if (!skipDomainNameEchoFilter && senderMatchesDomainLabel) return false;
|
|
56
|
+
return true;
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
|
|
40
60
|
const ModifyDeliverySettings = (props) => {
|
|
41
61
|
const {
|
|
42
62
|
channel,
|
|
43
63
|
deliverySettings: initialSettings = {},
|
|
44
64
|
senderDetailsOptions = [],
|
|
65
|
+
smsFallbackSenderDetailsOptions = [],
|
|
45
66
|
wecrmAccounts = [],
|
|
46
67
|
onSaveDeliverySettings,
|
|
47
68
|
onClose,
|
|
@@ -102,17 +123,21 @@ const ModifyDeliverySettings = (props) => {
|
|
|
102
123
|
if (!(channel === CHANNELS.SMS && smsTraiDltEnabled)) {
|
|
103
124
|
return allDomainOptions;
|
|
104
125
|
}
|
|
126
|
+
// Without template registered sender IDs, strict DLT filter removes every domain — keep full list.
|
|
127
|
+
if (!registeredSenderIds?.length) {
|
|
128
|
+
return allDomainOptions;
|
|
129
|
+
}
|
|
105
130
|
|
|
106
|
-
return allDomainOptions.filter((domain) => (domain
|
|
107
|
-
(
|
|
131
|
+
return allDomainOptions.filter((domain) => (domain?.gsmSenders || []).some(
|
|
132
|
+
(gsmSenderOption) => registeredSenderIds?.includes(gsmSenderOption?.value),
|
|
108
133
|
));
|
|
109
134
|
}, [allDomainOptions, channel, registeredSenderIds, smsTraiDltEnabled]);
|
|
110
135
|
|
|
111
136
|
const selectedDomain = useMemo(
|
|
112
137
|
() => (senderDetailsOptions || []).find(
|
|
113
|
-
(
|
|
138
|
+
(senderDomain) => senderDomain.domainId === get(localSettings, DELIVERY_SETTING_KEY_DOMAIN_ID),
|
|
114
139
|
) || {},
|
|
115
|
-
[senderDetailsOptions, localSettings
|
|
140
|
+
[senderDetailsOptions, get(localSettings, DELIVERY_SETTING_KEY_DOMAIN_ID)],
|
|
116
141
|
);
|
|
117
142
|
const {
|
|
118
143
|
gsmSenders: selectedDomainGsmSenders = [],
|
|
@@ -120,25 +145,103 @@ const ModifyDeliverySettings = (props) => {
|
|
|
120
145
|
emailRepliers: selectedDomainEmailRepliers = [],
|
|
121
146
|
} = selectedDomain;
|
|
122
147
|
|
|
148
|
+
const rcsSenderOptions = useMemo(
|
|
149
|
+
() => {
|
|
150
|
+
if (channel !== CHANNELS.RCS) return [];
|
|
151
|
+
const rcsDomainRows = senderDetailsOptions || [];
|
|
152
|
+
const selectedRcsDomainId = get(localSettings, DELIVERY_SETTING_KEY_DOMAIN_ID);
|
|
153
|
+
const rcsDomainsForDropdown =
|
|
154
|
+
selectedRcsDomainId != null && selectedRcsDomainId !== ''
|
|
155
|
+
? rcsDomainRows.filter((senderDomain) => senderDomain?.domainId === selectedRcsDomainId)
|
|
156
|
+
: rcsDomainRows;
|
|
157
|
+
return rcsDomainsForDropdown.flatMap((senderDomain) =>
|
|
158
|
+
filterUsableGsmSendersForDomain(senderDomain, senderDomain?.gsmSenders, {
|
|
159
|
+
skipDomainNameEchoFilter: true,
|
|
160
|
+
}).map((gsmSenderRow) => ({
|
|
161
|
+
value: senderDomain?.domainId != null && gsmSenderRow?.value != null
|
|
162
|
+
? `${senderDomain.domainId}|${gsmSenderRow.value}`
|
|
163
|
+
: gsmSenderRow?.value,
|
|
164
|
+
label: String(gsmSenderRow?.value ?? ''),
|
|
165
|
+
})));
|
|
166
|
+
},
|
|
167
|
+
[channel, senderDetailsOptions, localSettings],
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
const rcsGsmSenderIdForSelect = useMemo(() => {
|
|
171
|
+
const raw = get(localSettings, DELIVERY_SETTING_KEY_GSM_SENDER_ID);
|
|
172
|
+
if (raw == null || raw === '') return undefined;
|
|
173
|
+
const allowed = new Set((rcsSenderOptions || []).map((senderOption) => senderOption.value));
|
|
174
|
+
return allowed.has(raw) ? raw : undefined;
|
|
175
|
+
}, [localSettings, rcsSenderOptions]);
|
|
176
|
+
|
|
177
|
+
const smsFallbackDomainOptions = useMemo(
|
|
178
|
+
() => {
|
|
179
|
+
const raw = (smsFallbackSenderDetailsOptions || []).map((senderDetails) => ({
|
|
180
|
+
label: senderDetails.domainName || senderDetails.domainId,
|
|
181
|
+
value: senderDetails.domainId,
|
|
182
|
+
...senderDetails,
|
|
183
|
+
}));
|
|
184
|
+
if (!(channel === CHANNELS.RCS && smsTraiDltEnabled && registeredSenderIds?.length)) {
|
|
185
|
+
return raw;
|
|
186
|
+
}
|
|
187
|
+
return raw.filter((domain) => (domain?.gsmSenders || []).some(
|
|
188
|
+
(gsmSenderOption) => registeredSenderIds?.includes(gsmSenderOption?.value),
|
|
189
|
+
));
|
|
190
|
+
},
|
|
191
|
+
[channel, smsFallbackSenderDetailsOptions, smsTraiDltEnabled, registeredSenderIds],
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
const smsSenderOptions = useMemo(
|
|
195
|
+
() => {
|
|
196
|
+
if (channel !== CHANNELS.RCS) return [];
|
|
197
|
+
const smsFallbackDomainRows = smsFallbackSenderDetailsOptions || [];
|
|
198
|
+
const selectedSmsFallbackDomainId = get(localSettings, DELIVERY_SETTING_KEY_SMS_FALLBACK_DOMAIN_ID);
|
|
199
|
+
const smsFallbackDomainsForDropdown =
|
|
200
|
+
selectedSmsFallbackDomainId != null && selectedSmsFallbackDomainId !== ''
|
|
201
|
+
? smsFallbackDomainRows.filter((senderDomain) => senderDomain?.domainId === selectedSmsFallbackDomainId)
|
|
202
|
+
: smsFallbackDomainRows;
|
|
203
|
+
const shouldFilterSmsSendersByDltRegistration = smsTraiDltEnabled && registeredSenderIds?.length;
|
|
204
|
+
return smsFallbackDomainsForDropdown.flatMap((senderDomain) =>
|
|
205
|
+
filterUsableGsmSendersForDomain(senderDomain, senderDomain?.gsmSenders, { skipDomainNameEchoFilter: true })
|
|
206
|
+
.filter((smsGsmSenderRow) =>
|
|
207
|
+
!shouldFilterSmsSendersByDltRegistration || registeredSenderIds?.includes(smsGsmSenderRow?.value))
|
|
208
|
+
.map((gsmSenderRow) => ({
|
|
209
|
+
value: senderDomain?.domainId != null && gsmSenderRow?.value != null
|
|
210
|
+
? `${senderDomain.domainId}|${gsmSenderRow.value}`
|
|
211
|
+
: gsmSenderRow?.value,
|
|
212
|
+
label: String(gsmSenderRow?.value ?? ''),
|
|
213
|
+
})));
|
|
214
|
+
},
|
|
215
|
+
[channel, smsFallbackSenderDetailsOptions, localSettings, smsTraiDltEnabled, registeredSenderIds],
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
const smsFallbackGsmIdForSelect = useMemo(() => {
|
|
219
|
+
const raw = get(localSettings, DELIVERY_SETTING_KEY_CDMA_SENDER_ID);
|
|
220
|
+
if (raw == null || raw === '') return undefined;
|
|
221
|
+
const allowed = new Set((smsSenderOptions || []).map((senderOption) => senderOption.value));
|
|
222
|
+
return allowed.has(raw) ? raw : undefined;
|
|
223
|
+
}, [localSettings, smsSenderOptions]);
|
|
224
|
+
|
|
123
225
|
const gsmOptions = useMemo(
|
|
124
226
|
() => {
|
|
125
|
-
const
|
|
126
|
-
? selectedDomainGsmSenders.filter((
|
|
227
|
+
const smsGsmSendersForSelect = channel === CHANNELS.SMS && smsTraiDltEnabled && registeredSenderIds?.length
|
|
228
|
+
? selectedDomainGsmSenders.filter((gsmSenderOption) =>
|
|
229
|
+
registeredSenderIds?.includes(gsmSenderOption?.value))
|
|
127
230
|
: selectedDomainGsmSenders;
|
|
128
231
|
|
|
129
|
-
return
|
|
130
|
-
label:
|
|
131
|
-
value:
|
|
232
|
+
return smsGsmSendersForSelect.map((gsmSenderRow) => ({
|
|
233
|
+
label: gsmSenderRow?.value || gsmSenderRow?.label,
|
|
234
|
+
value: gsmSenderRow?.value,
|
|
132
235
|
}));
|
|
133
236
|
},
|
|
134
237
|
[channel, registeredSenderIds, selectedDomainGsmSenders, smsTraiDltEnabled],
|
|
135
238
|
);
|
|
136
239
|
|
|
137
240
|
const emailSenderOptions = useMemo(
|
|
138
|
-
() => selectedDomainEmailSenders.map((
|
|
139
|
-
label:
|
|
140
|
-
value:
|
|
141
|
-
senderLabel:
|
|
241
|
+
() => selectedDomainEmailSenders.map((emailSenderRow) => ({
|
|
242
|
+
label: emailSenderRow.value || emailSenderRow.label,
|
|
243
|
+
value: emailSenderRow.value,
|
|
244
|
+
senderLabel: emailSenderRow.label,
|
|
142
245
|
})),
|
|
143
246
|
[selectedDomainEmailSenders],
|
|
144
247
|
);
|
|
@@ -204,13 +307,54 @@ const ModifyDeliverySettings = (props) => {
|
|
|
204
307
|
});
|
|
205
308
|
}, []);
|
|
206
309
|
|
|
310
|
+
const onSmsFallbackDomainChange = useCallback(
|
|
311
|
+
(value) => {
|
|
312
|
+
setLocalSettings((prev) => {
|
|
313
|
+
const next = cloneDeep(prev);
|
|
314
|
+
next[DELIVERY_SETTING_KEY_SMS_FALLBACK_DOMAIN_ID] = value;
|
|
315
|
+
const selectedSmsFallbackDomain = (smsFallbackSenderDetailsOptions || []).find(
|
|
316
|
+
(senderDomain) => senderDomain?.domainId === value,
|
|
317
|
+
);
|
|
318
|
+
const shouldFilterSmsFallbackSendersByDltRegistration =
|
|
319
|
+
channel === CHANNELS.RCS && smsTraiDltEnabled && registeredSenderIds?.length;
|
|
320
|
+
const usableSmsFallbackGsmSenders = filterUsableGsmSendersForDomain(
|
|
321
|
+
selectedSmsFallbackDomain,
|
|
322
|
+
selectedSmsFallbackDomain?.gsmSenders,
|
|
323
|
+
{ skipDomainNameEchoFilter: !!shouldFilterSmsFallbackSendersByDltRegistration },
|
|
324
|
+
);
|
|
325
|
+
const smsFallbackGsmSenders = shouldFilterSmsFallbackSendersByDltRegistration
|
|
326
|
+
? usableSmsFallbackGsmSenders.filter((smsGsmSenderRow) =>
|
|
327
|
+
registeredSenderIds?.includes(smsGsmSenderRow?.value))
|
|
328
|
+
: usableSmsFallbackGsmSenders;
|
|
329
|
+
const firstSmsFallbackGsmSender = smsFallbackGsmSenders[0];
|
|
330
|
+
const composite = selectedSmsFallbackDomain?.domainId != null && firstSmsFallbackGsmSender?.value != null
|
|
331
|
+
? `${selectedSmsFallbackDomain.domainId}|${firstSmsFallbackGsmSender.value}`
|
|
332
|
+
: (firstSmsFallbackGsmSender?.value || '');
|
|
333
|
+
next[DELIVERY_SETTING_KEY_CDMA_SENDER_ID] = composite;
|
|
334
|
+
return next;
|
|
335
|
+
});
|
|
336
|
+
},
|
|
337
|
+
[channel, smsFallbackSenderDetailsOptions, smsTraiDltEnabled, registeredSenderIds],
|
|
338
|
+
);
|
|
339
|
+
|
|
207
340
|
const onDomainChange = useCallback(
|
|
208
341
|
(value) => {
|
|
209
|
-
const domain = domainOptions.find((
|
|
342
|
+
const domain = domainOptions.find((domainOption) => domainOption.value === value);
|
|
210
343
|
updateSetting(DELIVERY_SETTING_KEY_DOMAIN_ID, value);
|
|
211
344
|
if (domain?.dgmId != null) updateSetting(DELIVERY_SETTING_KEY_DOMAIN_GATEWAY_MAP_ID, domain.dgmId);
|
|
345
|
+
if (channel === CHANNELS.RCS && domain) {
|
|
346
|
+
const usableRcsGsmSenders = filterUsableGsmSendersForDomain(domain, domain?.gsmSenders, {
|
|
347
|
+
skipDomainNameEchoFilter: true,
|
|
348
|
+
});
|
|
349
|
+
const firstRcsGsmSender = usableRcsGsmSenders[0];
|
|
350
|
+
const composite = domain?.domainId != null && firstRcsGsmSender?.value != null
|
|
351
|
+
? `${domain.domainId}|${firstRcsGsmSender.value}`
|
|
352
|
+
: (firstRcsGsmSender?.value || '');
|
|
353
|
+
updateSetting(DELIVERY_SETTING_KEY_GSM_SENDER_ID, composite);
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
212
356
|
if (channel === CHANNELS.SMS && domain) {
|
|
213
|
-
const smsGsmSenders = smsTraiDltEnabled
|
|
357
|
+
const smsGsmSenders = smsTraiDltEnabled && registeredSenderIds?.length
|
|
214
358
|
? (domain.gsmSenders || []).filter((gsmId) => registeredSenderIds.includes(gsmId.value))
|
|
215
359
|
: domain.gsmSenders;
|
|
216
360
|
const def = findDefault(smsGsmSenders);
|
|
@@ -230,9 +374,20 @@ const ModifyDeliverySettings = (props) => {
|
|
|
230
374
|
);
|
|
231
375
|
|
|
232
376
|
const handleDone = useCallback(() => {
|
|
233
|
-
|
|
377
|
+
const next = cloneDeep(localSettings);
|
|
378
|
+
if (channel === CHANNELS.RCS) {
|
|
379
|
+
const rawRcs = get(next, DELIVERY_SETTING_KEY_GSM_SENDER_ID);
|
|
380
|
+
if (rawRcs && !(rcsSenderOptions || []).some((senderOption) => senderOption.value === rawRcs)) {
|
|
381
|
+
next[DELIVERY_SETTING_KEY_GSM_SENDER_ID] = '';
|
|
382
|
+
}
|
|
383
|
+
const rawSms = get(next, DELIVERY_SETTING_KEY_CDMA_SENDER_ID);
|
|
384
|
+
if (rawSms && !(smsSenderOptions || []).some((senderOption) => senderOption.value === rawSms)) {
|
|
385
|
+
next[DELIVERY_SETTING_KEY_CDMA_SENDER_ID] = '';
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
onSaveDeliverySettings(next);
|
|
234
389
|
if (onClose) onClose();
|
|
235
|
-
}, [localSettings, onSaveDeliverySettings, onClose]);
|
|
390
|
+
}, [channel, localSettings, onSaveDeliverySettings, onClose, rcsSenderOptions, smsSenderOptions]);
|
|
236
391
|
|
|
237
392
|
const renderSelectRow = useCallback(
|
|
238
393
|
({
|
|
@@ -286,7 +441,7 @@ const ModifyDeliverySettings = (props) => {
|
|
|
286
441
|
value: get(localSettings, DELIVERY_SETTING_KEY_SENDER_EMAIL),
|
|
287
442
|
onChange: (val) => {
|
|
288
443
|
const sender = selectedDomainEmailSenders.find(
|
|
289
|
-
(
|
|
444
|
+
(emailSenderRow) => emailSenderRow.value === val,
|
|
290
445
|
);
|
|
291
446
|
updateSetting(DELIVERY_SETTING_KEY_SENDER_EMAIL, val);
|
|
292
447
|
updateSetting(DELIVERY_SETTING_KEY_SENDER_LABEL, sender?.label || val);
|
|
@@ -298,7 +453,7 @@ const ModifyDeliverySettings = (props) => {
|
|
|
298
453
|
value: get(localSettings, DELIVERY_SETTING_KEY_SENDER_LABEL) || '',
|
|
299
454
|
onChange: (val) => {
|
|
300
455
|
const sender = selectedDomainEmailSenders.find(
|
|
301
|
-
(
|
|
456
|
+
(emailSenderRow) => (emailSenderRow.label || emailSenderRow.value) === val,
|
|
302
457
|
);
|
|
303
458
|
if (sender) {
|
|
304
459
|
updateSetting(DELIVERY_SETTING_KEY_SENDER_EMAIL, sender.value);
|
|
@@ -326,7 +481,7 @@ const ModifyDeliverySettings = (props) => {
|
|
|
326
481
|
onChange: (val) => {
|
|
327
482
|
updateSetting(DELIVERY_SETTING_KEY_SOURCE_ACCOUNT_IDENTIFIER, val);
|
|
328
483
|
const domain = (senderDetailsOptions || []).find(
|
|
329
|
-
(
|
|
484
|
+
(whatsappAccountRow) => whatsappAccountRow.sourceAccountIdentifier === val,
|
|
330
485
|
);
|
|
331
486
|
const first = domain?.gsmSenders?.[0];
|
|
332
487
|
updateSetting(DELIVERY_SETTING_KEY_SENDER_MOB_NUM, first?.value || '');
|
|
@@ -340,10 +495,39 @@ const ModifyDeliverySettings = (props) => {
|
|
|
340
495
|
onChange: (val) => updateSetting(DELIVERY_SETTING_KEY_SENDER_MOB_NUM, val),
|
|
341
496
|
},
|
|
342
497
|
];
|
|
498
|
+
const rcsFields = [
|
|
499
|
+
{
|
|
500
|
+
titleMessage: messages.rcsDomainLabel,
|
|
501
|
+
options: domainOptions,
|
|
502
|
+
value: get(localSettings, DELIVERY_SETTING_KEY_DOMAIN_ID),
|
|
503
|
+
onChange: (val) => onDomainChange(val),
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
titleMessage: messages.rcsSenderIdLabel,
|
|
507
|
+
options: rcsSenderOptions,
|
|
508
|
+
value: rcsGsmSenderIdForSelect,
|
|
509
|
+
onChange: (val) => updateSetting(DELIVERY_SETTING_KEY_GSM_SENDER_ID, val),
|
|
510
|
+
},
|
|
511
|
+
...((smsFallbackSenderDetailsOptions || []).length > 0 ? [
|
|
512
|
+
{
|
|
513
|
+
titleMessage: messages.fallbackSmsDomainLabel,
|
|
514
|
+
options: smsFallbackDomainOptions,
|
|
515
|
+
value: get(localSettings, DELIVERY_SETTING_KEY_SMS_FALLBACK_DOMAIN_ID),
|
|
516
|
+
onChange: onSmsFallbackDomainChange,
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
titleMessage: messages.fallbackSmsSenderIdLabel,
|
|
520
|
+
options: smsSenderOptions,
|
|
521
|
+
value: smsFallbackGsmIdForSelect,
|
|
522
|
+
onChange: (val) => updateSetting(DELIVERY_SETTING_KEY_CDMA_SENDER_ID, val),
|
|
523
|
+
},
|
|
524
|
+
] : []),
|
|
525
|
+
];
|
|
343
526
|
const byChannel = {
|
|
344
527
|
[CHANNELS.SMS]: smsFields,
|
|
345
528
|
[CHANNELS.EMAIL]: emailFields,
|
|
346
529
|
[CHANNELS.WHATSAPP]: whatsappFields,
|
|
530
|
+
[CHANNELS.RCS]: rcsFields,
|
|
347
531
|
};
|
|
348
532
|
return byChannel[channel] || [];
|
|
349
533
|
}, [
|
|
@@ -356,6 +540,13 @@ const ModifyDeliverySettings = (props) => {
|
|
|
356
540
|
wecrmAccountOptions,
|
|
357
541
|
whatsappAccountOptionsForDisplay,
|
|
358
542
|
whatsappSenderOptions,
|
|
543
|
+
rcsSenderOptions,
|
|
544
|
+
rcsGsmSenderIdForSelect,
|
|
545
|
+
smsSenderOptions,
|
|
546
|
+
smsFallbackGsmIdForSelect,
|
|
547
|
+
smsFallbackDomainOptions,
|
|
548
|
+
smsFallbackSenderDetailsOptions,
|
|
549
|
+
onSmsFallbackDomainChange,
|
|
359
550
|
localSettings,
|
|
360
551
|
selectedDomainEmailSenders,
|
|
361
552
|
senderDetailsOptions,
|
|
@@ -390,9 +581,10 @@ const ModifyDeliverySettings = (props) => {
|
|
|
390
581
|
};
|
|
391
582
|
|
|
392
583
|
ModifyDeliverySettings.propTypes = {
|
|
393
|
-
channel: PropTypes.oneOf([CHANNELS.SMS, CHANNELS.EMAIL, CHANNELS.WHATSAPP]).isRequired,
|
|
584
|
+
channel: PropTypes.oneOf([CHANNELS.SMS, CHANNELS.EMAIL, CHANNELS.WHATSAPP, CHANNELS.RCS]).isRequired,
|
|
394
585
|
deliverySettings: PropTypes.object,
|
|
395
586
|
senderDetailsOptions: PropTypes.array,
|
|
587
|
+
smsFallbackSenderDetailsOptions: PropTypes.array,
|
|
396
588
|
wecrmAccounts: PropTypes.array,
|
|
397
589
|
onSaveDeliverySettings: PropTypes.func.isRequired,
|
|
398
590
|
onClose: PropTypes.func,
|
|
@@ -408,6 +600,7 @@ ModifyDeliverySettings.propTypes = {
|
|
|
408
600
|
ModifyDeliverySettings.defaultProps = {
|
|
409
601
|
deliverySettings: {},
|
|
410
602
|
senderDetailsOptions: [],
|
|
603
|
+
smsFallbackSenderDetailsOptions: [],
|
|
411
604
|
wecrmAccounts: [],
|
|
412
605
|
onClose: undefined,
|
|
413
606
|
isLoading: false,
|
|
@@ -21,6 +21,8 @@ export const DELIVERY_SETTING_KEY_SENDER_LABEL = 'senderLabel';
|
|
|
21
21
|
export const DELIVERY_SETTING_KEY_SENDER_REPLY_TO = 'senderReplyTo';
|
|
22
22
|
export const DELIVERY_SETTING_KEY_SOURCE_ACCOUNT_IDENTIFIER = 'sourceAccountIdentifier';
|
|
23
23
|
export const DELIVERY_SETTING_KEY_SENDER_MOB_NUM = 'senderMobNum';
|
|
24
|
+
/** RCS: SMS fallback domain (separate from primary RCS domainId) */
|
|
25
|
+
export const DELIVERY_SETTING_KEY_SMS_FALLBACK_DOMAIN_ID = 'smsFallbackDomainId';
|
|
24
26
|
|
|
25
27
|
/** data-testid for delivery settings edit icon */
|
|
26
28
|
export const TEST_ID_DELIVERY_SETTINGS_EDIT = 'delivery-settings-edit';
|
|
@@ -32,6 +34,7 @@ export const CHANNELS_WITH_DELIVERY_SETTINGS = [
|
|
|
32
34
|
CHANNELS.SMS,
|
|
33
35
|
CHANNELS.EMAIL,
|
|
34
36
|
CHANNELS.WHATSAPP,
|
|
37
|
+
CHANNELS.RCS,
|
|
35
38
|
];
|
|
36
39
|
|
|
37
40
|
/** Default empty delivery setting per channel (campaigns-style shape) */
|
|
@@ -56,8 +59,21 @@ export const DEFAULT_DELIVERY_SETTING_WHATSAPP = {
|
|
|
56
59
|
sourceAccountIdentifier: '',
|
|
57
60
|
};
|
|
58
61
|
|
|
62
|
+
/** RCS: gsmSenderId = RCS sender, cdmaSenderId = SMS fallback sender (reuse same keys) */
|
|
63
|
+
export const DEFAULT_DELIVERY_SETTING_RCS = {
|
|
64
|
+
domainId: null,
|
|
65
|
+
domainGatewayMapId: null,
|
|
66
|
+
gsmSenderId: '',
|
|
67
|
+
smsFallbackDomainId: null,
|
|
68
|
+
cdmaSenderId: '',
|
|
69
|
+
};
|
|
70
|
+
|
|
59
71
|
export const DEFAULT_DELIVERY_SETTINGS_BY_CHANNEL = {
|
|
60
72
|
[CHANNELS.SMS]: DEFAULT_DELIVERY_SETTING_SMS,
|
|
61
73
|
[CHANNELS.EMAIL]: DEFAULT_DELIVERY_SETTING_EMAIL,
|
|
62
74
|
[CHANNELS.WHATSAPP]: DEFAULT_DELIVERY_SETTING_WHATSAPP,
|
|
75
|
+
[CHANNELS.RCS]: DEFAULT_DELIVERY_SETTING_RCS,
|
|
63
76
|
};
|
|
77
|
+
|
|
78
|
+
/** API `contactInfo.type` keys that map to RCS-style GSM sender rows (env-specific naming). */
|
|
79
|
+
export const RCS_CONTACT_INFO_GSM_TYPE_KEYS = ['gsm_sender_id', 'rcs_sender_id', 'rcs_sender'];
|