@capillarytech/creatives-library 8.0.353-alpha.6 → 8.0.354
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 -29
- package/index.html +1 -0
- package/package.json +1 -1
- package/services/tests/api.test.js +20 -35
- package/utils/cdnTransformation.js +63 -3
- package/utils/commonUtils.js +1 -19
- package/utils/tests/cdnTransformation.test.js +111 -0
- package/v2Components/CapActionButton/constants.js +0 -7
- package/v2Components/CapActionButton/index.js +108 -166
- package/v2Components/CapActionButton/index.scss +6 -157
- package/v2Components/CapActionButton/messages.js +3 -19
- package/v2Components/CapActionButton/tests/index.test.js +17 -41
- package/v2Components/CapTagList/index.js +0 -10
- package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +49 -72
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -213
- 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 +5 -10
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +15 -157
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +76 -346
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +4 -133
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +0 -11
- package/v2Components/CommonTestAndPreview/constants.js +2 -38
- package/v2Components/CommonTestAndPreview/index.js +186 -691
- package/v2Components/CommonTestAndPreview/messages.js +3 -45
- package/v2Components/CommonTestAndPreview/sagas.js +6 -25
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +284 -308
- 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/PreviewSection.test.js +1 -8
- package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +13 -34
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +283 -281
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +1 -199
- package/v2Components/CommonTestAndPreview/tests/index.test.js +4 -132
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +26 -36
- package/v2Components/FormBuilder/index.js +6 -11
- package/v2Components/TemplatePreview/_templatePreview.scss +23 -38
- package/v2Components/TemplatePreview/index.js +31 -143
- package/v2Components/TemplatePreview/tests/index.test.js +0 -142
- 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 +103 -322
- 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 +15 -20
- package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
- package/v2Containers/MobilePush/Create/test/saga.test.js +2 -2
- package/v2Containers/Rcs/constants.js +10 -119
- package/v2Containers/Rcs/index.js +818 -2450
- package/v2Containers/Rcs/index.scss +8 -280
- package/v2Containers/Rcs/messages.js +3 -34
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +70073 -98018
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +5 -0
- package/v2Containers/Rcs/tests/index.test.js +121 -152
- package/v2Containers/Rcs/tests/mockData.js +0 -38
- package/v2Containers/Rcs/tests/utils.test.js +30 -646
- package/v2Containers/Rcs/utils.js +11 -478
- package/v2Containers/Sms/Create/index.js +40 -106
- package/v2Containers/SmsTrai/Create/index.js +4 -9
- package/v2Containers/SmsTrai/Edit/constants.js +0 -2
- package/v2Containers/SmsTrai/Edit/index.js +130 -640
- package/v2Containers/SmsTrai/Edit/messages.js +4 -14
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2296 -4249
- package/v2Containers/SmsWrapper/index.js +8 -37
- package/v2Containers/TagList/index.js +0 -6
- package/v2Containers/Templates/_templates.scss +9 -166
- package/v2Containers/Templates/actions.js +0 -11
- package/v2Containers/Templates/constants.js +0 -2
- package/v2Containers/Templates/index.js +52 -120
- package/v2Containers/Templates/sagas.js +18 -57
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1017 -1062
- package/v2Containers/Templates/tests/sagas.test.js +39 -205
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -72
- package/v2Containers/TemplatesV2/index.js +23 -86
- package/v2Containers/WeChat/MapTemplates/test/saga.test.js +9 -9
- package/v2Containers/Whatsapp/index.js +20 -3
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +34 -578
- package/utils/rcsPayloadUtils.js +0 -92
- package/utils/templateVarUtils.js +0 -201
- package/utils/tests/rcsPayloadUtils.test.js +0 -226
- package/utils/tests/templateVarUtils.test.js +0 -204
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +0 -67
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +0 -91
- package/v2Components/SmsFallback/constants.js +0 -73
- package/v2Components/SmsFallback/index.js +0 -956
- package/v2Components/SmsFallback/index.scss +0 -265
- package/v2Components/SmsFallback/messages.js +0 -78
- package/v2Components/SmsFallback/smsFallbackUtils.js +0 -119
- 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 -223
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -309
- package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +0 -422
- package/v2Components/SmsFallback/useLocalTemplateList.js +0 -92
- package/v2Components/TemplatePreview/constants.js +0 -2
- 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 -79
- 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
package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js
CHANGED
|
@@ -9,91 +9,29 @@
|
|
|
9
9
|
|
|
10
10
|
import get from 'lodash/get';
|
|
11
11
|
import { CHANNELS } from '../../constants';
|
|
12
|
-
import { RCS_CONTACT_INFO_GSM_TYPE_KEYS } from '../constants';
|
|
13
12
|
|
|
14
|
-
/** Match API contactInfo.type (some envs use different casing). */
|
|
15
|
-
const typeMatches = (itemType, expectedKey) => {
|
|
16
|
-
if (!itemType || !expectedKey) return false;
|
|
17
|
-
const normalizedItemType = String(itemType).toLowerCase().replace(/-/g, '_');
|
|
18
|
-
const normalizedExpectedType = String(expectedKey).toLowerCase().replace(/-/g, '_');
|
|
19
|
-
return normalizedItemType === normalizedExpectedType;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Include row unless explicitly invalid — many APIs omit `valid`, which would
|
|
24
|
-
* otherwise filter out every sender (RCS/SMS lists empty in UI).
|
|
25
|
-
*/
|
|
26
13
|
const getSenderOptions = (contactInfo, key) =>
|
|
27
14
|
(contactInfo || [])
|
|
28
|
-
.filter((contactInfoItem) =>
|
|
15
|
+
.filter((contactInfoItem) => contactInfoItem.type === key && contactInfoItem.valid)
|
|
29
16
|
.sort((contact) => (contact.default ? -1 : 0));
|
|
30
17
|
|
|
31
|
-
/** RCS APIs may label senders under several `contactInfo.type` keys — see `RCS_CONTACT_INFO_GSM_TYPE_KEYS`. */
|
|
32
|
-
const getRcsLikeGsmSenders = (contactInfo) => {
|
|
33
|
-
const seen = new Set();
|
|
34
|
-
const mergedSenderRows = [];
|
|
35
|
-
RCS_CONTACT_INFO_GSM_TYPE_KEYS.forEach((key) => {
|
|
36
|
-
getSenderOptions(contactInfo, key).forEach((row) => {
|
|
37
|
-
const senderValue = row?.value;
|
|
38
|
-
// Skip empty/whitespace sender values to avoid polluting the RCS sender dropdown.
|
|
39
|
-
if (senderValue == null || String(senderValue).trim() === '' || seen.has(senderValue)) return;
|
|
40
|
-
seen.add(senderValue);
|
|
41
|
-
mergedSenderRows.push(row);
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
return mergedSenderRows.sort((a, b) => (a.default ? -1 : 0) - (b.default ? -1 : 0));
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Campaigns domainProperties may return { entity } or { result: { entity } } / { data: { entity } }.
|
|
49
|
-
*/
|
|
50
|
-
function unwrapEntity(response) {
|
|
51
|
-
if (!response || typeof response !== 'object') return null;
|
|
52
|
-
if (response.entity != null) return response.entity;
|
|
53
|
-
const nested = get(response, 'result.entity') ?? get(response, 'data.entity');
|
|
54
|
-
if (nested != null) return nested;
|
|
55
|
-
if (response.entity === null) return null;
|
|
56
|
-
return response;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
18
|
/**
|
|
60
19
|
* Parse raw API response for one channel into { domains: [...] }
|
|
61
|
-
* @param {string} channel - SMS | EMAIL | WHATSAPP
|
|
20
|
+
* @param {string} channel - SMS | EMAIL | WHATSAPP
|
|
62
21
|
* @param {Object} response - API response (e.g. { entity: { SMS: [...] } } or { entity: [...] })
|
|
63
22
|
* @returns {{ domains: Array }} - domains array compatible with campaigns DeliverySettingsV2
|
|
64
23
|
*/
|
|
65
24
|
export function parseSenderDetailsResponse(channel, response) {
|
|
66
|
-
const entity =
|
|
67
|
-
if (entity
|
|
25
|
+
const entity = get(response, 'entity', response);
|
|
26
|
+
if (!entity) {
|
|
68
27
|
return { domains: [] };
|
|
69
28
|
}
|
|
70
29
|
|
|
71
|
-
//
|
|
72
|
-
|
|
73
|
-
channel == null || String(channel).trim() === ''
|
|
74
|
-
? ''
|
|
75
|
-
: String(channel).trim().toUpperCase();
|
|
76
|
-
|
|
77
|
-
// Single-channel API: entity may be { [channel]: [...] } or direct array.
|
|
78
|
-
// Some responses use different casing (e.g. rcs vs RCS) or a single domain object instead of an array.
|
|
79
|
-
let channelSenderDetails =
|
|
80
|
-
get(entity, channel, null)
|
|
81
|
-
?? (normalizedChannel ? get(entity, normalizedChannel, null) : null)
|
|
82
|
-
?? (normalizedChannel ? get(entity, normalizedChannel.toLowerCase(), null) : null);
|
|
83
|
-
|
|
30
|
+
// Single-channel API: entity may be { [channel]: [...] } or direct array
|
|
31
|
+
let channelSenderDetails = get(entity, channel, null);
|
|
84
32
|
if (channelSenderDetails == null && Array.isArray(entity)) {
|
|
85
33
|
channelSenderDetails = entity;
|
|
86
34
|
}
|
|
87
|
-
|
|
88
|
-
if (channelSenderDetails != null && !Array.isArray(channelSenderDetails)) {
|
|
89
|
-
const single = channelSenderDetails;
|
|
90
|
-
if (single && typeof single === 'object' && single.domainProperties) {
|
|
91
|
-
channelSenderDetails = [single];
|
|
92
|
-
} else {
|
|
93
|
-
return { domains: [] };
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
35
|
if (!Array.isArray(channelSenderDetails)) {
|
|
98
36
|
return { domains: [] };
|
|
99
37
|
}
|
|
@@ -104,7 +42,6 @@ export function parseSenderDetailsResponse(channel, response) {
|
|
|
104
42
|
const { id: dgmId, priority, domainProperties = {} } = element;
|
|
105
43
|
const {
|
|
106
44
|
domainName,
|
|
107
|
-
hostName,
|
|
108
45
|
id = -1,
|
|
109
46
|
contactInfo,
|
|
110
47
|
connectionProperties: {
|
|
@@ -114,25 +51,21 @@ export function parseSenderDetailsResponse(channel, response) {
|
|
|
114
51
|
} = {},
|
|
115
52
|
} = domainProperties;
|
|
116
53
|
|
|
117
|
-
const resolvedDomainName = domainName || hostName;
|
|
118
|
-
|
|
119
54
|
const domain = {
|
|
120
55
|
dgmId,
|
|
121
|
-
domainName
|
|
56
|
+
domainName,
|
|
122
57
|
domainId: id,
|
|
123
58
|
priority: priority != null ? priority : 0,
|
|
124
59
|
};
|
|
125
60
|
|
|
126
|
-
if ([CHANNELS.SMS, CHANNELS.WHATSAPP
|
|
61
|
+
if ([CHANNELS.SMS, CHANNELS.WHATSAPP].includes(channel)) {
|
|
127
62
|
domain.cdmaSenders = getSenderOptions(contactInfo, 'cdma_sender_id');
|
|
128
|
-
domain.gsmSenders =
|
|
129
|
-
? getRcsLikeGsmSenders(contactInfo)
|
|
130
|
-
: getSenderOptions(contactInfo, 'gsm_sender_id');
|
|
63
|
+
domain.gsmSenders = getSenderOptions(contactInfo, 'gsm_sender_id');
|
|
131
64
|
domain.sourceAccountIdentifier =
|
|
132
65
|
sourceAccountIdentifier || wabaId || userid || '';
|
|
133
66
|
}
|
|
134
67
|
|
|
135
|
-
if (
|
|
68
|
+
if (channel === CHANNELS.EMAIL) {
|
|
136
69
|
domain.emailSenders = getSenderOptions(contactInfo, 'sender_id');
|
|
137
70
|
domain.emailRepliers = getSenderOptions(contactInfo, 'reply_to_id');
|
|
138
71
|
}
|
|
@@ -143,8 +76,7 @@ export function parseSenderDetailsResponse(channel, response) {
|
|
|
143
76
|
// Sort by priority and dedupe by domainName (match campaigns behaviour)
|
|
144
77
|
domains.sort((a, b) => (a.priority || 0) - (b.priority || 0));
|
|
145
78
|
const deduped = domains.reduce((acc, domain) => {
|
|
146
|
-
|
|
147
|
-
if (!acc.find((existing) => (existing.domainName ?? existing.domainId) === key)) {
|
|
79
|
+
if (!acc.find((d) => d.domainName === domain.domainName)) {
|
|
148
80
|
acc.push(domain);
|
|
149
81
|
}
|
|
150
82
|
return acc;
|
|
@@ -6,13 +6,12 @@ import CapButton from '@capillarytech/cap-ui-library/CapButton';
|
|
|
6
6
|
import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
|
|
7
7
|
import CapStepsAccordian from '@capillarytech/cap-ui-library/CapStepsAccordian';
|
|
8
8
|
import CapTreeSelect from '@capillarytech/cap-ui-library/CapTreeSelect';
|
|
9
|
-
import CapSelect from '@capillarytech/cap-ui-library/CapSelect';
|
|
10
9
|
import isEmpty from 'lodash/isEmpty';
|
|
11
10
|
import messages from './messages';
|
|
12
11
|
import DeliverySettings from './DeliverySettings';
|
|
13
12
|
import { CHANNELS } from './constants';
|
|
14
13
|
|
|
15
|
-
const CHANNELS_WITH_DELIVERY_SETTINGS = [CHANNELS.SMS, CHANNELS.EMAIL, CHANNELS.WHATSAPP
|
|
14
|
+
const CHANNELS_WITH_DELIVERY_SETTINGS = [CHANNELS.SMS, CHANNELS.EMAIL, CHANNELS.WHATSAPP];
|
|
16
15
|
|
|
17
16
|
const SendTestMessage = ({
|
|
18
17
|
isFetchingTestCustomers,
|
|
@@ -29,13 +28,12 @@ const SendTestMessage = ({
|
|
|
29
28
|
searchValue,
|
|
30
29
|
setSearchValue,
|
|
31
30
|
deliverySettings,
|
|
32
|
-
|
|
31
|
+
senderDetailsOptions,
|
|
33
32
|
wecrmAccounts,
|
|
34
33
|
onSaveDeliverySettings,
|
|
35
34
|
isLoadingSenderDetails,
|
|
36
35
|
smsTraiDltEnabled,
|
|
37
36
|
registeredSenderIds,
|
|
38
|
-
isChannelSmsFallbackPreviewEnabled,
|
|
39
37
|
}) => {
|
|
40
38
|
const addCustomerContent = renderAddTestCustomerButton ? renderAddTestCustomerButton() : null;
|
|
41
39
|
return (
|
|
@@ -79,14 +77,13 @@ const SendTestMessage = ({
|
|
|
79
77
|
<DeliverySettings
|
|
80
78
|
channel={channel}
|
|
81
79
|
deliverySettings={deliverySettings || {}}
|
|
82
|
-
|
|
80
|
+
senderDetailsOptions={senderDetailsOptions}
|
|
83
81
|
wecrmAccounts={wecrmAccounts || []}
|
|
84
82
|
onSaveDeliverySettings={onSaveDeliverySettings}
|
|
85
83
|
isLoadingSenderDetails={isLoadingSenderDetails}
|
|
86
84
|
formatMessage={formatMessage}
|
|
87
85
|
smsTraiDltEnabled={smsTraiDltEnabled}
|
|
88
86
|
registeredSenderIds={registeredSenderIds}
|
|
89
|
-
isChannelSmsFallbackPreviewEnabled={isChannelSmsFallbackPreviewEnabled}
|
|
90
87
|
whatsappAccountFromForm={
|
|
91
88
|
channel === CHANNELS.WHATSAPP && formData?.accountName
|
|
92
89
|
? { accountName: formData.accountName }
|
|
@@ -124,13 +121,12 @@ SendTestMessage.propTypes = {
|
|
|
124
121
|
searchValue: PropTypes.string,
|
|
125
122
|
setSearchValue: PropTypes.func,
|
|
126
123
|
deliverySettings: PropTypes.object,
|
|
127
|
-
|
|
124
|
+
senderDetailsOptions: PropTypes.array,
|
|
128
125
|
wecrmAccounts: PropTypes.array,
|
|
129
126
|
onSaveDeliverySettings: PropTypes.func,
|
|
130
127
|
isLoadingSenderDetails: PropTypes.bool,
|
|
131
128
|
smsTraiDltEnabled: PropTypes.bool,
|
|
132
129
|
registeredSenderIds: PropTypes.array,
|
|
133
|
-
isChannelSmsFallbackPreviewEnabled: PropTypes.bool,
|
|
134
130
|
};
|
|
135
131
|
|
|
136
132
|
SendTestMessage.defaultProps = {
|
|
@@ -140,13 +136,12 @@ SendTestMessage.defaultProps = {
|
|
|
140
136
|
searchValue: '',
|
|
141
137
|
setSearchValue: () => {}, // no-op when not provided; required by TreeSelect when showSearch is true
|
|
142
138
|
deliverySettings: {},
|
|
143
|
-
|
|
139
|
+
senderDetailsOptions: [],
|
|
144
140
|
wecrmAccounts: [],
|
|
145
141
|
onSaveDeliverySettings: undefined,
|
|
146
142
|
isLoadingSenderDetails: false,
|
|
147
143
|
smsTraiDltEnabled: false,
|
|
148
144
|
registeredSenderIds: [],
|
|
149
|
-
isChannelSmsFallbackPreviewEnabled: false,
|
|
150
145
|
};
|
|
151
146
|
|
|
152
147
|
export default SendTestMessage;
|
|
@@ -25,7 +25,6 @@ import {
|
|
|
25
25
|
TIME_FORMAT_MINUTE_PADDING_THRESHOLD,
|
|
26
26
|
TIME_FORMAT_AM,
|
|
27
27
|
TIME_FORMAT_PM,
|
|
28
|
-
MEDIA_TYPE_VIDEO,
|
|
29
28
|
} from '../constants';
|
|
30
29
|
import messages from '../messages';
|
|
31
30
|
import { RCS_BUTTON_TYPES } from '../../../v2Containers/Rcs/constants';
|
|
@@ -51,57 +50,41 @@ const RcsPreviewContent = ({
|
|
|
51
50
|
const deviceName = device === ANDROID ? ANDROID_DEVICE_NAME : IOS_DEVICE_NAME;
|
|
52
51
|
|
|
53
52
|
// Render RCS suggestions (Quick Reply, CTA, Phone Number)
|
|
54
|
-
|
|
55
|
-
const renderRcsSuggestionsPreview = (suggestionsArg, options = {}) => {
|
|
56
|
-
const { isCarousel = false } = options;
|
|
53
|
+
const renderRcsSuggestionsPreview = () => {
|
|
57
54
|
const renderArray = [];
|
|
58
|
-
const suggestions =
|
|
59
|
-
? suggestionsArg
|
|
60
|
-
: (content?.suggestions || []);
|
|
55
|
+
const { suggestions = [] } = content || {};
|
|
61
56
|
|
|
62
57
|
if (suggestions.length === 0) {
|
|
63
58
|
return null;
|
|
64
59
|
}
|
|
65
60
|
|
|
66
|
-
const ctaClass = isCarousel ? 'rcs-cta-preview rcs-cta-preview--carousel-bar' : 'rcs-cta-preview';
|
|
67
|
-
|
|
68
61
|
suggestions.forEach((suggestion) => {
|
|
69
62
|
const { type, text } = suggestion || {};
|
|
70
63
|
const suggestionKey = `${type}-${text || Math.random()}`;
|
|
71
64
|
|
|
72
|
-
if (renderArray.length > 0
|
|
65
|
+
if (renderArray.length > 0) {
|
|
73
66
|
renderArray.push(<CapDivider key={`divider-${suggestionKey}`} className="whatsapp-divider" />);
|
|
74
67
|
}
|
|
75
68
|
|
|
76
69
|
if (type === RCS_BUTTON_TYPES.QUICK_REPLY) {
|
|
77
70
|
renderArray.push(
|
|
78
|
-
<CapLabel key={suggestionKey} type="label21" className=
|
|
71
|
+
<CapLabel key={suggestionKey} type="label21" className="rcs-cta-preview">
|
|
79
72
|
<CapIcon type="small-link" size="xs" />
|
|
80
73
|
{text}
|
|
81
74
|
</CapLabel>
|
|
82
75
|
);
|
|
83
76
|
} else if (type === RCS_BUTTON_TYPES.CTA) {
|
|
84
77
|
renderArray.push(
|
|
85
|
-
<CapLabel key={suggestionKey} type="label21" className=
|
|
78
|
+
<CapLabel key={suggestionKey} type="label21" className="rcs-cta-preview">
|
|
86
79
|
<CapIcon type="launch" size="xs" />
|
|
87
80
|
{text}
|
|
88
81
|
</CapLabel>
|
|
89
82
|
);
|
|
90
83
|
} else if (type === RCS_BUTTON_TYPES.PHONE_NUMBER) {
|
|
91
|
-
// Carousel: label text then phone icon (matches device-style RCS preview)
|
|
92
84
|
renderArray.push(
|
|
93
|
-
<CapLabel key={suggestionKey} type="label21" className=
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
{text}
|
|
97
|
-
<CapIcon type="call" size="xs" className="rcs-cta-preview-phone-icon-end" />
|
|
98
|
-
</>
|
|
99
|
-
) : (
|
|
100
|
-
<>
|
|
101
|
-
<CapIcon type="call" size="xs" />
|
|
102
|
-
{text}
|
|
103
|
-
</>
|
|
104
|
-
)}
|
|
85
|
+
<CapLabel key={suggestionKey} type="label21" className="rcs-cta-preview">
|
|
86
|
+
<CapIcon type="call" size="xs" />
|
|
87
|
+
{text}
|
|
105
88
|
</CapLabel>
|
|
106
89
|
);
|
|
107
90
|
}
|
|
@@ -110,104 +93,6 @@ const RcsPreviewContent = ({
|
|
|
110
93
|
return renderArray?.length > 0 ? renderArray : null;
|
|
111
94
|
};
|
|
112
95
|
|
|
113
|
-
// Carousel media box: aspect matches RCS editor card size (SHORT/MEDIUM × SMALL/MEDIUM).
|
|
114
|
-
const getCarouselMediaAspectStyle = (isVideo) => {
|
|
115
|
-
const d = content?.carouselPreviewDimensions;
|
|
116
|
-
if (!d) return undefined;
|
|
117
|
-
if (isVideo) {
|
|
118
|
-
const { videoThumbWidth, videoThumbHeight } = d;
|
|
119
|
-
if (!videoThumbWidth || !videoThumbHeight) return undefined;
|
|
120
|
-
return { aspectRatio: `${videoThumbWidth} / ${videoThumbHeight}` };
|
|
121
|
-
}
|
|
122
|
-
const { imageWidth, imageHeight } = d;
|
|
123
|
-
if (!imageWidth || !imageHeight) return undefined;
|
|
124
|
-
return { aspectRatio: `${imageWidth} / ${imageHeight}` };
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
// Carousel preview (WhatsApp-style static horizontal scroll).
|
|
128
|
-
// Caller passes a non-empty array only (see hasCarousel); avoids duplicate guards that Sonar
|
|
129
|
-
// flagged as partially covered because inner checks were unreachable when hasCarousel was true.
|
|
130
|
-
const renderCarouselPreviewContent = (carouselCards) => (
|
|
131
|
-
<CapRow className="msg-container-carousel">
|
|
132
|
-
<CapRow className="scroll-container">
|
|
133
|
-
{carouselCards.map((card, idx) => {
|
|
134
|
-
const key = `rcs-carousel-${idx}-${card?.bodyText || card?.imageSrc || card?.videoPreviewImg || ''}`;
|
|
135
|
-
const isVideo =
|
|
136
|
-
(card?.mediaType || '').toLowerCase() === String(MEDIA_TYPE_VIDEO).toLowerCase();
|
|
137
|
-
const cardSuggestions = Array.isArray(card?.suggestions) ? card.suggestions : [];
|
|
138
|
-
const suggestionsNode = cardSuggestions.length > 0
|
|
139
|
-
? renderRcsSuggestionsPreview(cardSuggestions, { isCarousel: true })
|
|
140
|
-
: null;
|
|
141
|
-
const titleTrimmed = String(card?.title ?? '').trim();
|
|
142
|
-
const bodyTrimmed = String(card?.bodyText ?? '').trim();
|
|
143
|
-
const titleShown = titleTrimmed || formatMessage(messages.rcsCarouselPreviewTitlePlaceholder);
|
|
144
|
-
const bodyShown = bodyTrimmed || formatMessage(messages.rcsCarouselPreviewBodyPlaceholder);
|
|
145
|
-
return (
|
|
146
|
-
<CapRow
|
|
147
|
-
key={key}
|
|
148
|
-
className="message-pop align-left message-pop-carousel"
|
|
149
|
-
>
|
|
150
|
-
<CapRow className="whatsapp-content">
|
|
151
|
-
{!isVideo && (
|
|
152
|
-
<CapRow
|
|
153
|
-
className="whatsapp-image rcs-carousel-media-wrap"
|
|
154
|
-
style={getCarouselMediaAspectStyle(false)}
|
|
155
|
-
>
|
|
156
|
-
<CapImage
|
|
157
|
-
src={card?.imageSrc ? card.imageSrc : rcsImageEmptyPreview}
|
|
158
|
-
className="rcs-carousel-img"
|
|
159
|
-
alt={formatMessage(messages.previewGenerated)}
|
|
160
|
-
/>
|
|
161
|
-
</CapRow>
|
|
162
|
-
)}
|
|
163
|
-
{isVideo && (
|
|
164
|
-
<CapTooltip title={formatMessage(messages.videoPreviewTooltip)}>
|
|
165
|
-
<CapRow className="video-preview">
|
|
166
|
-
<CapRow
|
|
167
|
-
className="whatsapp-image rcs-carousel-media-wrap"
|
|
168
|
-
style={getCarouselMediaAspectStyle(true)}
|
|
169
|
-
>
|
|
170
|
-
<CapImage
|
|
171
|
-
src={card?.videoPreviewImg ? card.videoPreviewImg : rcsVideoEmptyPreview}
|
|
172
|
-
className="rcs-carousel-img"
|
|
173
|
-
alt={formatMessage(messages.previewGenerated)}
|
|
174
|
-
/>
|
|
175
|
-
</CapRow>
|
|
176
|
-
<CapRow className="icon-position">
|
|
177
|
-
<CapImage className="video-icon" src={videoPlay} alt="Play" />
|
|
178
|
-
</CapRow>
|
|
179
|
-
</CapRow>
|
|
180
|
-
</CapTooltip>
|
|
181
|
-
)}
|
|
182
|
-
|
|
183
|
-
<CapRow className="carousel-content">
|
|
184
|
-
<CapLabel
|
|
185
|
-
type={card.titleLabelType || 'label1'}
|
|
186
|
-
className={`carousel-title${titleTrimmed ? '' : ' rcs-carousel-field-placeholder'}`}
|
|
187
|
-
>
|
|
188
|
-
{titleShown}
|
|
189
|
-
</CapLabel>
|
|
190
|
-
<CapLabel
|
|
191
|
-
type={card.bodyLabelType || 'label2'}
|
|
192
|
-
className={`carousel-message${bodyTrimmed ? '' : ' rcs-carousel-field-placeholder'}`}
|
|
193
|
-
>
|
|
194
|
-
{bodyShown}
|
|
195
|
-
</CapLabel>
|
|
196
|
-
</CapRow>
|
|
197
|
-
|
|
198
|
-
{!!suggestionsNode && (
|
|
199
|
-
<CapRow className="rcs-carousel-cta-stack" gutter={0}>
|
|
200
|
-
{suggestionsNode}
|
|
201
|
-
</CapRow>
|
|
202
|
-
)}
|
|
203
|
-
</CapRow>
|
|
204
|
-
</CapRow>
|
|
205
|
-
);
|
|
206
|
-
})}
|
|
207
|
-
</CapRow>
|
|
208
|
-
</CapRow>
|
|
209
|
-
);
|
|
210
|
-
|
|
211
96
|
// Render text preview content
|
|
212
97
|
const renderTextPreviewContent = () => {
|
|
213
98
|
const {
|
|
@@ -341,22 +226,11 @@ const RcsPreviewContent = ({
|
|
|
341
226
|
const timestamp = `${displayHours}:${displayMinutes} ${ampm}`;
|
|
342
227
|
|
|
343
228
|
// Render normal RCS preview (same structure as SMS up to sms-message-container)
|
|
344
|
-
const carouselCardsNormalized = Array.isArray(content?.carouselData) ? content?.carouselData : [];
|
|
345
|
-
const hasCarousel = carouselCardsNormalized?.length > 0;
|
|
346
229
|
const hasMedia = !!(content?.rcsImageSrc || content?.rcsVideoSrc);
|
|
347
|
-
|
|
348
|
-
if (hasCarousel) {
|
|
349
|
-
contentToRender = renderCarouselPreviewContent(carouselCardsNormalized);
|
|
350
|
-
} else if (hasMedia) {
|
|
351
|
-
contentToRender = renderMediaPreviewContent();
|
|
352
|
-
} else {
|
|
353
|
-
contentToRender = renderTextPreviewContent();
|
|
354
|
-
}
|
|
230
|
+
const contentToRender = hasMedia ? renderMediaPreviewContent() : renderTextPreviewContent();
|
|
355
231
|
|
|
356
232
|
return (
|
|
357
|
-
<CapRow
|
|
358
|
-
className={`sms-device-container rcs-device-container ${hasCarousel ? 'rcs-device-container-carousel' : ''}`}
|
|
359
|
-
>
|
|
233
|
+
<CapRow className="sms-device-container">
|
|
360
234
|
{/* Device Background Image */}
|
|
361
235
|
<CapImage
|
|
362
236
|
className="sms-device-image"
|
|
@@ -365,9 +239,7 @@ const RcsPreviewContent = ({
|
|
|
365
239
|
/>
|
|
366
240
|
|
|
367
241
|
{/* Content Overlay */}
|
|
368
|
-
<CapRow
|
|
369
|
-
className={`sms-content-overlay sms-content-overlay-${device} sms-preview sms-${device} rcs-content-overlay`}
|
|
370
|
-
>
|
|
242
|
+
<CapRow className={`sms-content-overlay sms-content-overlay-${device} sms-preview sms-${device}`}>
|
|
371
243
|
{/* Navigation Bar - Same as SMS */}
|
|
372
244
|
<CapRow className={`sms-navigation-bar ${!showHeader ? 'sms-navigation-bar-no-header' : ''}`}>
|
|
373
245
|
<CapIcon type="chevron-left" className="sms-back-arrow" />
|
|
@@ -383,8 +255,8 @@ const RcsPreviewContent = ({
|
|
|
383
255
|
</CapRow>
|
|
384
256
|
|
|
385
257
|
{/* Message Container - Same structure as SMS, only content inside is RCS-specific */}
|
|
386
|
-
|
|
387
|
-
<CapRow className=
|
|
258
|
+
<CapRow className="sms-message-container">
|
|
259
|
+
<CapRow className="sms-message-bubble">
|
|
388
260
|
<CapRow className="sms-message-text">
|
|
389
261
|
{/* RCS-specific content rendering */}
|
|
390
262
|
<CapRow className="message-pop sms">
|
|
@@ -398,10 +270,8 @@ const RcsPreviewContent = ({
|
|
|
398
270
|
</CapRow>
|
|
399
271
|
</CapRow>
|
|
400
272
|
</CapRow>
|
|
401
|
-
)
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
|
|
273
|
+
);
|
|
274
|
+
};
|
|
405
275
|
|
|
406
276
|
RcsPreviewContent.propTypes = {
|
|
407
277
|
content: PropTypes.shape({
|
|
@@ -412,18 +282,6 @@ RcsPreviewContent.propTypes = {
|
|
|
412
282
|
rcsImageSrc: PropTypes.string,
|
|
413
283
|
rcsVideoSrc: PropTypes.string,
|
|
414
284
|
rcsThumbnailSrc: PropTypes.string,
|
|
415
|
-
carouselData: PropTypes.arrayOf(
|
|
416
|
-
PropTypes.shape({
|
|
417
|
-
titleLabelType: PropTypes.string,
|
|
418
|
-
bodyLabelType: PropTypes.string,
|
|
419
|
-
})
|
|
420
|
-
),
|
|
421
|
-
carouselPreviewDimensions: PropTypes.shape({
|
|
422
|
-
imageWidth: PropTypes.number,
|
|
423
|
-
imageHeight: PropTypes.number,
|
|
424
|
-
videoThumbWidth: PropTypes.number,
|
|
425
|
-
videoThumbHeight: PropTypes.number,
|
|
426
|
-
}),
|
|
427
285
|
suggestions: PropTypes.arrayOf(
|
|
428
286
|
PropTypes.shape({
|
|
429
287
|
type: PropTypes.string,
|