@capillarytech/creatives-library 8.0.345-alpha.12 → 8.0.345-alpha.14
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/package.json +1 -1
- package/services/tests/api.test.js +0 -13
- package/utils/commonUtils.js +1 -19
- package/v2Components/CapActionButton/constants.js +0 -7
- package/v2Components/CapActionButton/index.js +109 -167
- 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 -70
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -207
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +0 -16
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +10 -85
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +0 -30
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +11 -79
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +5 -10
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +15 -160
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +76 -341
- 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 -676
- package/v2Components/CommonTestAndPreview/messages.js +3 -49
- package/v2Components/CommonTestAndPreview/sagas.js +6 -15
- 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 +2 -2
- package/v2Components/FormBuilder/index.js +10 -8
- package/v2Components/TemplatePreview/_templatePreview.scss +23 -33
- package/v2Components/TemplatePreview/index.js +28 -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 -300
- 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/Email/reducer.js +11 -3
- package/v2Containers/Email/sagas.js +9 -5
- package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +4 -0
- package/v2Containers/Email/tests/sagas.test.js +21 -3
- package/v2Containers/Rcs/constants.js +8 -119
- package/v2Containers/Rcs/index.js +812 -2375
- package/v2Containers/Rcs/index.scss +6 -276
- package/v2Containers/Rcs/messages.js +3 -38
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +70345 -98302
- 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 -100
- package/v2Containers/SmsTrai/Create/index.js +4 -9
- package/v2Containers/SmsTrai/Edit/constants.js +0 -2
- package/v2Containers/SmsTrai/Edit/index.js +130 -636
- 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 +2 -163
- package/v2Containers/Templates/actions.js +0 -11
- package/v2Containers/Templates/constants.js +0 -2
- package/v2Containers/Templates/index.js +54 -119
- package/v2Containers/Templates/sagas.js +12 -57
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1079 -1043
- package/v2Containers/Templates/tests/sagas.test.js +123 -193
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -72
- package/v2Containers/TemplatesV2/index.js +23 -86
- package/v2Containers/Whatsapp/index.js +20 -3
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +34 -578
- package/utils/rcsPayloadUtils.js +0 -92
- package/utils/templateVarUtils.js +0 -201
- package/utils/tests/templateVarUtils.test.js +0 -204
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js.rej +0 -18
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +0 -67
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +0 -87
- package/v2Components/SmsFallback/constants.js +0 -73
- package/v2Components/SmsFallback/index.js +0 -955
- package/v2Components/SmsFallback/index.scss +0 -265
- package/v2Components/SmsFallback/messages.js +0 -78
- package/v2Components/SmsFallback/smsFallbackUtils.js +0 -118
- package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +0 -50
- package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +0 -147
- package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +0 -304
- package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +0 -197
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -277
- package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +0 -422
- package/v2Components/SmsFallback/useLocalTemplateList.js +0 -92
- package/v2Components/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 -67
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +0 -90
- package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +0 -258
- package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +0 -125
- package/v2Containers/Rcs/index.js.rej +0 -1336
- package/v2Containers/Rcs/index.scss.rej +0 -74
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +0 -225
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap.rej +0 -128
- 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 a = String(itemType).toLowerCase().replace(/-/g, '_');
|
|
18
|
-
const b = String(expectedKey).toLowerCase().replace(/-/g, '_');
|
|
19
|
-
return a === b;
|
|
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 merged = [];
|
|
35
|
-
RCS_CONTACT_INFO_GSM_TYPE_KEYS.forEach((key) => {
|
|
36
|
-
getSenderOptions(contactInfo, key).forEach((row) => {
|
|
37
|
-
const v = row?.value;
|
|
38
|
-
// Skip empty/whitespace — they still pass `v != null` for "" and pollute RCS sender dropdowns.
|
|
39
|
-
if (v == null || String(v).trim() === '' || seen.has(v)) return;
|
|
40
|
-
seen.add(v);
|
|
41
|
-
merged.push(row);
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
return merged.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 {
|
|
@@ -242,9 +127,6 @@ const RcsPreviewContent = ({
|
|
|
242
127
|
{description}
|
|
243
128
|
</CapLabel>
|
|
244
129
|
)}
|
|
245
|
-
{Array.isArray(content?.suggestions) && content.suggestions.length > 0 && (
|
|
246
|
-
<CapDivider className="whatsapp-divider" />
|
|
247
|
-
)}
|
|
248
130
|
{renderRcsSuggestionsPreview()}
|
|
249
131
|
</>
|
|
250
132
|
);
|
|
@@ -344,22 +226,11 @@ const RcsPreviewContent = ({
|
|
|
344
226
|
const timestamp = `${displayHours}:${displayMinutes} ${ampm}`;
|
|
345
227
|
|
|
346
228
|
// Render normal RCS preview (same structure as SMS up to sms-message-container)
|
|
347
|
-
const carouselCardsNormalized = Array.isArray(content?.carouselData) ? content?.carouselData : [];
|
|
348
|
-
const hasCarousel = carouselCardsNormalized?.length > 0;
|
|
349
229
|
const hasMedia = !!(content?.rcsImageSrc || content?.rcsVideoSrc);
|
|
350
|
-
|
|
351
|
-
if (hasCarousel) {
|
|
352
|
-
contentToRender = renderCarouselPreviewContent(carouselCardsNormalized);
|
|
353
|
-
} else if (hasMedia) {
|
|
354
|
-
contentToRender = renderMediaPreviewContent();
|
|
355
|
-
} else {
|
|
356
|
-
contentToRender = renderTextPreviewContent();
|
|
357
|
-
}
|
|
230
|
+
const contentToRender = hasMedia ? renderMediaPreviewContent() : renderTextPreviewContent();
|
|
358
231
|
|
|
359
232
|
return (
|
|
360
|
-
<CapRow
|
|
361
|
-
className={`sms-device-container rcs-device-container ${hasCarousel ? 'rcs-device-container-carousel' : ''}`}
|
|
362
|
-
>
|
|
233
|
+
<CapRow className="sms-device-container">
|
|
363
234
|
{/* Device Background Image */}
|
|
364
235
|
<CapImage
|
|
365
236
|
className="sms-device-image"
|
|
@@ -368,9 +239,7 @@ const RcsPreviewContent = ({
|
|
|
368
239
|
/>
|
|
369
240
|
|
|
370
241
|
{/* Content Overlay */}
|
|
371
|
-
<CapRow
|
|
372
|
-
className={`sms-content-overlay sms-content-overlay-${device} sms-preview sms-${device} rcs-content-overlay`}
|
|
373
|
-
>
|
|
242
|
+
<CapRow className={`sms-content-overlay sms-content-overlay-${device} sms-preview sms-${device}`}>
|
|
374
243
|
{/* Navigation Bar - Same as SMS */}
|
|
375
244
|
<CapRow className={`sms-navigation-bar ${!showHeader ? 'sms-navigation-bar-no-header' : ''}`}>
|
|
376
245
|
<CapIcon type="chevron-left" className="sms-back-arrow" />
|
|
@@ -386,8 +255,8 @@ const RcsPreviewContent = ({
|
|
|
386
255
|
</CapRow>
|
|
387
256
|
|
|
388
257
|
{/* Message Container - Same structure as SMS, only content inside is RCS-specific */}
|
|
389
|
-
|
|
390
|
-
<CapRow className=
|
|
258
|
+
<CapRow className="sms-message-container">
|
|
259
|
+
<CapRow className="sms-message-bubble">
|
|
391
260
|
<CapRow className="sms-message-text">
|
|
392
261
|
{/* RCS-specific content rendering */}
|
|
393
262
|
<CapRow className="message-pop sms">
|
|
@@ -401,10 +270,8 @@ const RcsPreviewContent = ({
|
|
|
401
270
|
</CapRow>
|
|
402
271
|
</CapRow>
|
|
403
272
|
</CapRow>
|
|
404
|
-
)
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
|
|
273
|
+
);
|
|
274
|
+
};
|
|
408
275
|
|
|
409
276
|
RcsPreviewContent.propTypes = {
|
|
410
277
|
content: PropTypes.shape({
|
|
@@ -415,18 +282,6 @@ RcsPreviewContent.propTypes = {
|
|
|
415
282
|
rcsImageSrc: PropTypes.string,
|
|
416
283
|
rcsVideoSrc: PropTypes.string,
|
|
417
284
|
rcsThumbnailSrc: PropTypes.string,
|
|
418
|
-
carouselData: PropTypes.arrayOf(
|
|
419
|
-
PropTypes.shape({
|
|
420
|
-
titleLabelType: PropTypes.string,
|
|
421
|
-
bodyLabelType: PropTypes.string,
|
|
422
|
-
})
|
|
423
|
-
),
|
|
424
|
-
carouselPreviewDimensions: PropTypes.shape({
|
|
425
|
-
imageWidth: PropTypes.number,
|
|
426
|
-
imageHeight: PropTypes.number,
|
|
427
|
-
videoThumbWidth: PropTypes.number,
|
|
428
|
-
videoThumbHeight: PropTypes.number,
|
|
429
|
-
}),
|
|
430
285
|
suggestions: PropTypes.arrayOf(
|
|
431
286
|
PropTypes.shape({
|
|
432
287
|
type: PropTypes.string,
|