@capillarytech/creatives-library 9.0.47 → 9.0.49-alpha.0
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 +1 -0
- package/package.json +1 -1
- package/v2Components/CommonTestAndPreview/UnifiedPreview/SmsPreviewContent.js +21 -1
- package/v2Components/CommonTestAndPreview/UnifiedPreview/ViberCarouselPreviewCards.js +127 -0
- package/v2Components/CommonTestAndPreview/UnifiedPreview/ViberPreviewContent.js +106 -15
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +144 -1
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_viberCarouselPreviewCards.scss +133 -0
- package/v2Components/CommonTestAndPreview/constants.js +2 -0
- package/v2Components/CommonTestAndPreview/index.js +240 -26
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/SmsPreviewContent.test.js +32 -0
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/ViberPreviewContent.test.js +364 -0
- package/v2Components/CommonTestAndPreview/tests/utils.test.js +49 -0
- package/v2Components/CommonTestAndPreview/utils.js +20 -0
- package/v2Components/SmsFallback/constants.js +19 -0
- package/v2Components/SmsFallback/index.js +0 -3
- package/v2Containers/SmsTrai/Edit/constants.js +2 -0
- package/v2Containers/SmsTrai/Edit/dltVarTypes.js +88 -0
- package/v2Containers/SmsTrai/Edit/index.js +198 -92
- package/v2Containers/SmsTrai/Edit/index.scss +117 -1
- package/v2Containers/SmsTrai/Edit/messages.js +40 -0
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +21164 -4559
- package/v2Containers/SmsTrai/Edit/tests/dltVarTypes.test.js +100 -0
- package/v2Containers/Templates/_templates.scss +202 -1
- package/v2Containers/Templates/index.js +210 -42
- package/v2Containers/Templates/messages.js +12 -0
- package/v2Containers/Viber/constants.js +21 -0
- package/v2Containers/Viber/index.js +711 -43
- package/v2Containers/Viber/index.scss +175 -0
- package/v2Containers/Viber/messages.js +121 -0
- package/v2Containers/Viber/tests/index.test.js +80 -0
|
@@ -73,6 +73,7 @@ import * as ebillActions from '../Ebill/actions';
|
|
|
73
73
|
import * as emailActions from '../Email/actions';
|
|
74
74
|
import * as lineActions from '../Line/Container/actions';
|
|
75
75
|
import * as viberActions from '../Viber/actions';
|
|
76
|
+
import { VIBER_MEDIA_TYPES } from '../Viber/constants';
|
|
76
77
|
import * as facebookActions from '../Facebook/actions';
|
|
77
78
|
import * as whatsappActions from '../Whatsapp/actions';
|
|
78
79
|
import * as rcsActions from '../Rcs/actions';
|
|
@@ -142,7 +143,10 @@ import {CREATIVE} from '../Facebook/constants';
|
|
|
142
143
|
import videoPlay from '../../assets/videoPlay.svg';
|
|
143
144
|
import whatsappImageEmptyPreview from '../../v2Components/TemplatePreview/assets/images/empty_image_preview.svg';
|
|
144
145
|
import whatsappVideoEmptyPreview from '../../v2Components/TemplatePreview/assets/images/empty_video_preview.svg';
|
|
145
|
-
import {
|
|
146
|
+
import {
|
|
147
|
+
CAP_SPACE_16, CAP_G08, CAP_G05, CAP_SPACE_08, CAP_SPACE_12, CAP_YELLOW01,
|
|
148
|
+
} from '@capillarytech/cap-ui-library/styled/variables';
|
|
149
|
+
import { SMS_CATEGORY_TAG_STYLES, SMS_CATEGORY_LABELS } from '../../v2Components/SmsFallback/constants';
|
|
146
150
|
import { GA } from '@capillarytech/cap-ui-utils';
|
|
147
151
|
import { MAPP_SDK } from '../InApp/constants';
|
|
148
152
|
import injectReducer from '../../utils/injectReducer';
|
|
@@ -158,6 +162,7 @@ import { v2MobilePushSagas } from '../MobilePushNew/sagas';
|
|
|
158
162
|
import { AUTO_CAROUSEL, BIG_PICTURE, FILMSTRIP_CAROUSEL, MANUAL_CAROUSEL } from '../MobilePushNew/constants';
|
|
159
163
|
import CapPageSpinner from '../../v2Components/CapPageSpinner';
|
|
160
164
|
import webPushSagas from '../WebPush/sagas';
|
|
165
|
+
import { DLT_LEGACY_VAR_REGEX } from '../SmsTrai/Edit/dltVarTypes';
|
|
161
166
|
const withMobilePushNewSaga = injectSaga({ key: 'mobilePushNew', saga: v2MobilePushSagas, mode: DAEMON });
|
|
162
167
|
const withWebPushSaga = injectSaga({ key: 'webPush', saga: webPushSagas, mode: DAEMON });
|
|
163
168
|
|
|
@@ -454,9 +459,11 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
454
459
|
}
|
|
455
460
|
|
|
456
461
|
checkDLTfeatureEnable() {
|
|
457
|
-
const {smsRegister, isFullMode} = this.props;
|
|
458
|
-
|
|
459
|
-
|
|
462
|
+
const { smsRegister, isFullMode, localTemplatesConfig } = this.props;
|
|
463
|
+
if (commonUtil.isTraiDLTEnable(isFullMode, smsRegister)) return true;
|
|
464
|
+
// Local-templates picker (RCS SMS fallback, campaigns): apply DLT UI whenever the org has
|
|
465
|
+
// the feature, even if the parent context wasn't marked `smsRegister === 'DLT'`.
|
|
466
|
+
return !!localTemplatesConfig?.useLocalTemplates && commonUtil.hasTraiDltFeature();
|
|
460
467
|
}
|
|
461
468
|
|
|
462
469
|
componentDidMount() {
|
|
@@ -1399,6 +1406,11 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1399
1406
|
const image = viberContent.image || {};
|
|
1400
1407
|
const video = viberContent.video || {};
|
|
1401
1408
|
const button = viberContent.button || {};
|
|
1409
|
+
const messageType = viberContent.type || '';
|
|
1410
|
+
const cardsRaw = viberContent.cards;
|
|
1411
|
+
const cards = Array.isArray(cardsRaw) ? cardsRaw : [];
|
|
1412
|
+
const isCarousel =
|
|
1413
|
+
messageType === VIBER_MEDIA_TYPES.CAROUSEL || cards.length > 0;
|
|
1402
1414
|
|
|
1403
1415
|
const viberPreview = {
|
|
1404
1416
|
messageContent: text,
|
|
@@ -1416,14 +1428,39 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1416
1428
|
};
|
|
1417
1429
|
}
|
|
1418
1430
|
|
|
1431
|
+
if (isCarousel) {
|
|
1432
|
+
viberPreview.type = VIBER_MEDIA_TYPES.CAROUSEL;
|
|
1433
|
+
viberPreview.cards = cards.map((card) => ({
|
|
1434
|
+
text: card?.text || '',
|
|
1435
|
+
mediaUrl: card?.mediaUrl || '',
|
|
1436
|
+
buttons: (card?.buttons || []).map((btn) => ({
|
|
1437
|
+
title: btn?.title || '',
|
|
1438
|
+
action: btn?.action || '',
|
|
1439
|
+
})),
|
|
1440
|
+
}));
|
|
1441
|
+
viberPreview.showCarouselEditorPreview = true;
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1419
1444
|
// Extract account name
|
|
1420
1445
|
const accountName = get(template, 'definition.accountName', '');
|
|
1421
1446
|
|
|
1422
1447
|
// Return Viber content object (same as Viber/index.js getTemplateContent)
|
|
1423
1448
|
return {
|
|
1424
1449
|
viberPreviewContent: viberPreview,
|
|
1425
|
-
accountName: accountName
|
|
1426
|
-
brandName: accountName
|
|
1450
|
+
accountName: accountName || '',
|
|
1451
|
+
brandName: accountName || '',
|
|
1452
|
+
messageContent: text,
|
|
1453
|
+
...(isCarousel && {
|
|
1454
|
+
type: VIBER_MEDIA_TYPES.CAROUSEL,
|
|
1455
|
+
cards: viberPreview.cards,
|
|
1456
|
+
}),
|
|
1457
|
+
...(!isCarousel && !isEmpty(button) && button.text && (button.url || viberContent.buttonURL) && {
|
|
1458
|
+
button: {
|
|
1459
|
+
text: button.text,
|
|
1460
|
+
url: button.url || viberContent.buttonURL || '',
|
|
1461
|
+
},
|
|
1462
|
+
}),
|
|
1463
|
+
buttonURL: button.url || viberContent.buttonURL || '',
|
|
1427
1464
|
};
|
|
1428
1465
|
}
|
|
1429
1466
|
|
|
@@ -2045,11 +2082,21 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2045
2082
|
const isCardArchiveEligible = isArchivalEnabled && this.isChannelArchiveEligible(currentChannel, cardWhatsappStatus, cardRcsStatus);
|
|
2046
2083
|
const isArchivedMode = isArchivalEnabled && get(this.props, 'Templates.isArchivedMode', false);
|
|
2047
2084
|
const isAnyArchiveInProgress = isArchivalEnabled && !!(get(this.props, 'Templates.archiveInProgress') || get(this.props, 'Templates.unarchiveInProgress') || get(this.props, 'Templates.bulkArchiveInProgress') || get(this.props, 'Templates.bulkUnarchiveInProgress'));
|
|
2085
|
+
const smsBaseForLegacyCheck = template?.versions?.base || {};
|
|
2086
|
+
const updatedSmsEditorForLegacy = smsBaseForLegacyCheck['updated-sms-editor'];
|
|
2087
|
+
const updatedSmsEditorForLegacyJoined = Array.isArray(updatedSmsEditorForLegacy)
|
|
2088
|
+
? updatedSmsEditorForLegacy.join('')
|
|
2089
|
+
: updatedSmsEditorForLegacy;
|
|
2090
|
+
const smsBodyForLegacyCheck = `${updatedSmsEditorForLegacyJoined || ''}${smsBaseForLegacyCheck['sms-editor'] || ''}`;
|
|
2091
|
+
const isDltLegacyTemplate = currentChannel === SMS
|
|
2092
|
+
&& isTraiDltFeature
|
|
2093
|
+
&& !this.props.isFullMode
|
|
2094
|
+
&& DLT_LEGACY_VAR_REGEX.test(smsBodyForLegacyCheck);
|
|
2048
2095
|
const templateData = {
|
|
2049
2096
|
key: `${currentChannel}-card-${template?.name}`,
|
|
2050
2097
|
title: (
|
|
2051
2098
|
<span className="template-card-title" title={template?.name}>
|
|
2052
|
-
{isCardArchiveEligible && this.renderCardSelectionCheckbox({ templateId: template._id, selectedIds: selectedIdsArrayForCard, isDisabled: isAnyArchiveInProgress })}
|
|
2099
|
+
{isCardArchiveEligible && this.renderCardSelectionCheckbox({ templateId: template._id, selectedIds: selectedIdsArrayForCard, isDisabled: isAnyArchiveInProgress || isDltLegacyTemplate })}
|
|
2053
2100
|
<CapLabel.CapLabelInline type="label1" title={template?.name} className="template-card-name">
|
|
2054
2101
|
{template?.name}
|
|
2055
2102
|
{currentChannel === INAPP && (
|
|
@@ -2109,20 +2156,39 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2109
2156
|
})()
|
|
2110
2157
|
],
|
|
2111
2158
|
hoverOption: isArchivedMode || !this.canPerform(PERMISSIONS.CREATIVE_EDIT) ? null : (
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
this.props.
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2159
|
+
isDltLegacyTemplate ? (
|
|
2160
|
+
<CapTooltip
|
|
2161
|
+
title={this.props.intl.formatMessage(messages.smsLegacyBlockedTooltip)}
|
|
2162
|
+
>
|
|
2163
|
+
<CapLabel.CapLabelInline>
|
|
2164
|
+
<CapButton
|
|
2165
|
+
className={
|
|
2166
|
+
this.props.isFullMode
|
|
2167
|
+
? `edit-${channelLowerCase}`
|
|
2168
|
+
: `select-${channelLowerCase}`
|
|
2169
|
+
}
|
|
2170
|
+
disabled
|
|
2171
|
+
>
|
|
2172
|
+
{hoverButtonText}
|
|
2173
|
+
</CapButton>
|
|
2174
|
+
</CapLabel.CapLabelInline>
|
|
2175
|
+
</CapTooltip>
|
|
2176
|
+
) : (
|
|
2177
|
+
<CapButton
|
|
2178
|
+
className={
|
|
2179
|
+
this.props.isFullMode
|
|
2180
|
+
? `edit-${channelLowerCase}`
|
|
2181
|
+
: `select-${channelLowerCase}`
|
|
2182
|
+
}
|
|
2183
|
+
onClick={e =>
|
|
2184
|
+
handlers.handleEditClick(e, template, undefined, undefined, {
|
|
2185
|
+
account: this.state.selectedAccount
|
|
2186
|
+
})
|
|
2187
|
+
}
|
|
2188
|
+
>
|
|
2189
|
+
{hoverButtonText}
|
|
2190
|
+
</CapButton>
|
|
2191
|
+
)
|
|
2126
2192
|
)
|
|
2127
2193
|
};
|
|
2128
2194
|
const {
|
|
@@ -2222,22 +2288,49 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2222
2288
|
);
|
|
2223
2289
|
}
|
|
2224
2290
|
switch (currentChannel) {
|
|
2225
|
-
case SMS:
|
|
2291
|
+
case SMS: {
|
|
2292
|
+
const smsBaseForCard = template.versions.base || {};
|
|
2293
|
+
const updatedSmsEditor = smsBaseForCard['updated-sms-editor'];
|
|
2294
|
+
const normalizedUpdatedSmsEditor = Array.isArray(updatedSmsEditor)
|
|
2295
|
+
? updatedSmsEditor.join('')
|
|
2296
|
+
: updatedSmsEditor;
|
|
2297
|
+
const smsBodyForCard = normalizedUpdatedSmsEditor || smsBaseForCard['sms-editor'] || '';
|
|
2298
|
+
const hasLegacyVarToken = DLT_LEGACY_VAR_REGEX.test(smsBodyForCard);
|
|
2299
|
+
const rawCategoryLabel = smsBaseForCard.type || '';
|
|
2300
|
+
const categoryLabel = rawCategoryLabel.toLowerCase() === SMS_CATEGORY_LABELS.SERVICE_EXPLICIT
|
|
2301
|
+
? this.props.intl.formatMessage(messages.promotional)
|
|
2302
|
+
: rawCategoryLabel;
|
|
2303
|
+
const categoryTagStyle = SMS_CATEGORY_TAG_STYLES[categoryLabel.toLowerCase()] || {};
|
|
2226
2304
|
templateData.content = isTraiDltFeature ? (
|
|
2227
2305
|
<>
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2306
|
+
{hasLegacyVarToken ? (
|
|
2307
|
+
<CapColoredTag
|
|
2308
|
+
tagColor="rgba(254, 197, 46, 0.15)"
|
|
2309
|
+
tagTextColor={CAP_YELLOW01}
|
|
2310
|
+
tagHeight="1.25rem"
|
|
2311
|
+
tagFontSize="0.75rem"
|
|
2312
|
+
className="sms-template-category-tag"
|
|
2313
|
+
>
|
|
2314
|
+
{this.props.intl.formatMessage(messages.smsLegacyFormatBadge)}
|
|
2315
|
+
</CapColoredTag>
|
|
2316
|
+
) : categoryLabel ? (
|
|
2317
|
+
<CapColoredTag
|
|
2318
|
+
tagColor={categoryTagStyle.tagColor}
|
|
2319
|
+
tagTextColor={categoryTagStyle.tagTextColor}
|
|
2320
|
+
tagHeight="1.25rem"
|
|
2321
|
+
tagFontSize="0.75rem"
|
|
2322
|
+
className="sms-template-category-tag"
|
|
2323
|
+
>
|
|
2324
|
+
{categoryLabel}
|
|
2325
|
+
</CapColoredTag>
|
|
2326
|
+
) : null}
|
|
2327
|
+
<CapLabel type="label1">{smsBodyForCard}</CapLabel>
|
|
2236
2328
|
</>
|
|
2237
2329
|
) : (
|
|
2238
2330
|
template.versions.base['sms-editor']
|
|
2239
2331
|
);
|
|
2240
2332
|
break;
|
|
2333
|
+
}
|
|
2241
2334
|
case EMAIL: {
|
|
2242
2335
|
const url = template.versions.base.preview_http_url;
|
|
2243
2336
|
if (url) {
|
|
@@ -2436,10 +2529,59 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2436
2529
|
image = {},
|
|
2437
2530
|
button = {},
|
|
2438
2531
|
video = {},
|
|
2532
|
+
type = '',
|
|
2533
|
+
cards = [],
|
|
2439
2534
|
} = {},
|
|
2440
2535
|
} = {},
|
|
2441
2536
|
} = template.versions.base;
|
|
2537
|
+
const isViberCarousel = type === VIBER_MEDIA_TYPES.CAROUSEL;
|
|
2442
2538
|
templateData.content = text;
|
|
2539
|
+
if (isViberCarousel) {
|
|
2540
|
+
const previewCards = Array.isArray(cards) ? cards.slice(0, 1) : [];
|
|
2541
|
+
// Bypass CapCustomCard Viber Meta + line-clamp (clips title/buttons for tall images).
|
|
2542
|
+
// Parent class `viber-carousel-static` scopes listing styles in _templates.scss.
|
|
2543
|
+
// cardType hits the default content path; keep VIBER for channel card styles.
|
|
2544
|
+
templateData.cardType = 'VIBER_CAROUSEL_PREVIEW';
|
|
2545
|
+
templateData.className = 'viber-carousel-static VIBER';
|
|
2546
|
+
templateData.content = (
|
|
2547
|
+
<CapRow vertical className="content">
|
|
2548
|
+
<CapRow className="message-box">
|
|
2549
|
+
<CapLabel type="label1" className="message">
|
|
2550
|
+
{text}
|
|
2551
|
+
</CapLabel>
|
|
2552
|
+
</CapRow>
|
|
2553
|
+
<CapRow className="cards">
|
|
2554
|
+
{previewCards?.map((card, cardIdx) => (
|
|
2555
|
+
<CapRow vertical className="card" key={`viber-carousel-static-card-${cardIdx}`}>
|
|
2556
|
+
{card?.mediaUrl ? (
|
|
2557
|
+
<CapImage src={card.mediaUrl} className="image" />
|
|
2558
|
+
) : (
|
|
2559
|
+
<CapRow className="image-placeholder" />
|
|
2560
|
+
)}
|
|
2561
|
+
<CapLabel type="label1" className="text">
|
|
2562
|
+
{card?.text}
|
|
2563
|
+
</CapLabel>
|
|
2564
|
+
<CapRow vertical className="buttons">
|
|
2565
|
+
{(Array.isArray(card?.buttons) && card.buttons.length
|
|
2566
|
+
? card.buttons
|
|
2567
|
+
: [{}, {}]
|
|
2568
|
+
).slice(0, 2).map((carouselButton, btnIdx) => (
|
|
2569
|
+
<CapLabel
|
|
2570
|
+
key={`viber-carousel-static-btn-${cardIdx}-${btnIdx}`}
|
|
2571
|
+
type="label1"
|
|
2572
|
+
className={`button${btnIdx === 1 ? ' button-secondary' : ''}`}
|
|
2573
|
+
>
|
|
2574
|
+
{(carouselButton?.title || '').trim()}
|
|
2575
|
+
</CapLabel>
|
|
2576
|
+
))}
|
|
2577
|
+
</CapRow>
|
|
2578
|
+
</CapRow>
|
|
2579
|
+
))}
|
|
2580
|
+
</CapRow>
|
|
2581
|
+
</CapRow>
|
|
2582
|
+
);
|
|
2583
|
+
break;
|
|
2584
|
+
}
|
|
2443
2585
|
if (!isEmpty(image)) {
|
|
2444
2586
|
const { url = '' } = image;
|
|
2445
2587
|
templateData.url = url;
|
|
@@ -2761,6 +2903,12 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2761
2903
|
)}
|
|
2762
2904
|
</CapRow>
|
|
2763
2905
|
{[WHATSAPP, ZALO, INAPP,RCS].includes(currentChannel) && this.selectedFilters()}
|
|
2906
|
+
{currentChannel === SMS && this.checkDLTfeatureEnable() && (
|
|
2907
|
+
<CapInfoNote
|
|
2908
|
+
className="sms-service-explicit-retired-banner"
|
|
2909
|
+
message={this.props.intl.formatMessage(messages.smsServiceExplicitRetiredBanner)}
|
|
2910
|
+
/>
|
|
2911
|
+
)}
|
|
2764
2912
|
{<div>
|
|
2765
2913
|
{!isEmpty(filteredTemplates) || !isEmpty(this.state.searchText) || !isEmpty(this.props.Templates.templateError) ? (
|
|
2766
2914
|
<div className={!isEmpty(this.state.searchText) && isEmpty(cardDataList) ? '' : this.isFullMode() ? "v2-pagination-container" : "v2-pagination-container-half"}>
|
|
@@ -3535,6 +3683,22 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
3535
3683
|
CapNotification.error({ message: this.props.intl.formatMessage(messages.cannotEditArchivedTemplate) });
|
|
3536
3684
|
return;
|
|
3537
3685
|
}
|
|
3686
|
+
if (!this.props.isFullMode
|
|
3687
|
+
&& this.checkDLTfeatureEnable()
|
|
3688
|
+
&& (this.state.channel || '').toLowerCase() === SMS_LOWERCASE) {
|
|
3689
|
+
const smsBase = template?.versions?.base || {};
|
|
3690
|
+
const updatedSms = smsBase['updated-sms-editor'];
|
|
3691
|
+
const updatedSmsJoined = Array.isArray(updatedSms) ? updatedSms.join('') : updatedSms;
|
|
3692
|
+
// Check BOTH candidate fields — some legacy templates keep the body only in `sms-editor`
|
|
3693
|
+
// while others have it in `updated-sms-editor`. Concatenating catches either.
|
|
3694
|
+
const smsBody = `${updatedSmsJoined || ''}${smsBase['sms-editor'] || ''}`;
|
|
3695
|
+
if (DLT_LEGACY_VAR_REGEX.test(smsBody)) {
|
|
3696
|
+
CapNotification.error({
|
|
3697
|
+
message: this.props.intl.formatMessage(messages.smsLegacyBlockedTooltip),
|
|
3698
|
+
});
|
|
3699
|
+
return;
|
|
3700
|
+
}
|
|
3701
|
+
}
|
|
3538
3702
|
if (modeType && modeType !== undefined) {
|
|
3539
3703
|
this.setState({modeType});
|
|
3540
3704
|
}
|
|
@@ -4788,7 +4952,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
4788
4952
|
<CapRadio.CapRadioGroup className="line-filters" defaultValue={smsFilter} onChange={this.setSMSFilter}>
|
|
4789
4953
|
{
|
|
4790
4954
|
(() => {
|
|
4791
|
-
const { ALL, SERVICE_IMPLICIT,
|
|
4955
|
+
const { ALL, SERVICE_IMPLICIT, PROMOTIONAL } = SMS_FILTERS;
|
|
4792
4956
|
return (
|
|
4793
4957
|
<>
|
|
4794
4958
|
<CapRadio.Button value={ALL}><CapLabel type="label2">
|
|
@@ -4797,9 +4961,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
4797
4961
|
<CapRadio.Button value={PROMOTIONAL}><CapLabel type="label2">
|
|
4798
4962
|
<FormattedMessage {...messages.promotional} />
|
|
4799
4963
|
</CapLabel></CapRadio.Button>
|
|
4800
|
-
<CapRadio.Button value={SERVICE_EXPLICIT}><CapLabel type="label2">
|
|
4801
|
-
<FormattedMessage {...messages.serviceExplicit} />
|
|
4802
|
-
</CapLabel></CapRadio.Button>
|
|
4803
4964
|
<CapRadio.Button value={SERVICE_IMPLICIT}><CapLabel type="label2">
|
|
4804
4965
|
<FormattedMessage {...messages.serviceImplicit} />
|
|
4805
4966
|
</CapLabel></CapRadio.Button>
|
|
@@ -5107,15 +5268,22 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
5107
5268
|
? this.props.Templates.selectedWhatsappAccount.name
|
|
5108
5269
|
: null
|
|
5109
5270
|
}
|
|
5110
|
-
// Pass formData for
|
|
5271
|
+
// Pass formData for tag extraction (EMAIL/SMS use nested formData; VIBER uses content object)
|
|
5111
5272
|
formData={
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5273
|
+
(() => {
|
|
5274
|
+
const previewContent = this.state.testAndPreviewContent;
|
|
5275
|
+
const channelUpper = this.state.channel?.toUpperCase();
|
|
5276
|
+
if (!previewContent || typeof previewContent !== 'object') {
|
|
5277
|
+
return null;
|
|
5278
|
+
}
|
|
5279
|
+
if ([EMAIL, SMS].includes(channelUpper)) {
|
|
5280
|
+
return previewContent.formData || null;
|
|
5281
|
+
}
|
|
5282
|
+
if (channelUpper === VIBER) {
|
|
5283
|
+
return previewContent;
|
|
5284
|
+
}
|
|
5285
|
+
return null;
|
|
5286
|
+
})()
|
|
5119
5287
|
}
|
|
5120
5288
|
/>
|
|
5121
5289
|
)}
|
|
@@ -538,6 +538,18 @@ export default defineMessages({
|
|
|
538
538
|
id: `${scope}.serviceImplicit`,
|
|
539
539
|
defaultMessage: 'Service implicit',
|
|
540
540
|
},
|
|
541
|
+
"smsServiceExplicitRetiredBanner": {
|
|
542
|
+
id: `${scope}.smsServiceExplicitRetiredBanner`,
|
|
543
|
+
defaultMessage: 'Service Explicit is retired. Existing Service Explicit templates have been moved under the Promotional category.',
|
|
544
|
+
},
|
|
545
|
+
"smsLegacyFormatBadge": {
|
|
546
|
+
id: `${scope}.smsLegacyFormatBadge`,
|
|
547
|
+
defaultMessage: 'Legacy format',
|
|
548
|
+
},
|
|
549
|
+
"smsLegacyBlockedTooltip": {
|
|
550
|
+
id: `${scope}.smsLegacyBlockedTooltip`,
|
|
551
|
+
defaultMessage: "This template can't be used until re-registered with typed variables on the DLT portal.",
|
|
552
|
+
},
|
|
541
553
|
"uploadTemplate": {
|
|
542
554
|
id: `${scope}.uploadTemplate`,
|
|
543
555
|
defaultMessage: 'Upload template',
|
|
@@ -47,7 +47,24 @@ export const VIBER_MEDIA_TYPES = {
|
|
|
47
47
|
TEXT: 'TEXT',
|
|
48
48
|
IMAGE: 'IMAGE',
|
|
49
49
|
VIDEO: 'VIDEO',
|
|
50
|
+
CAROUSEL: 'CAROUSEL',
|
|
50
51
|
};
|
|
52
|
+
export const VIBER_CAROUSEL_MIN_CARDS = 2;
|
|
53
|
+
export const VIBER_CAROUSEL_MAX_CARDS = 5;
|
|
54
|
+
export const VIBER_CAROUSEL_MAX_BUTTONS = 2;
|
|
55
|
+
export const VIBER_CAROUSEL_CARD_TITLE_MIN_LENGTH = 2;
|
|
56
|
+
export const VIBER_CAROUSEL_CARD_TITLE_MAX_LENGTH = 38;
|
|
57
|
+
export const VIBER_CAROUSEL_FIRST_BUTTON_TITLE_MAX_LENGTH = 10;
|
|
58
|
+
export const VIBER_CAROUSEL_SECOND_BUTTON_TITLE_MAX_LENGTH = 12;
|
|
59
|
+
export const VIBER_CAROUSEL_BUTTON_URL_MAX_LENGTH = 1000;
|
|
60
|
+
export const STATIC_URL = 'STATIC_URL';
|
|
61
|
+
export const DYNAMIC_URL = 'DYNAMIC_URL';
|
|
62
|
+
/** Recommended / validated carousel image height in pixels (passed to image upload). */
|
|
63
|
+
export const VIBER_CAROUSEL_IMG_HEIGHT = 600;
|
|
64
|
+
/** Recommended / validated carousel image width in pixels (passed to image upload). */
|
|
65
|
+
export const VIBER_CAROUSEL_IMG_WIDTH = 696;
|
|
66
|
+
/** Maximum carousel image file size (bytes). 10_000_000 ≈ 10 MB (decimal). */
|
|
67
|
+
export const VIBER_CAROUSEL_IMG_SIZE = 10000000;
|
|
51
68
|
export const ALLOWED_IMAGE_EXTENSIONS_REGEX_VIBER = /\.(jpe?g|png)$/i;
|
|
52
69
|
export const ALLOWED_EXTENSIONS_VIDEO_REGEX_VIBER = /\.(mp4|3gp|m4v|mov)$/i;
|
|
53
70
|
export const NONE = 'NONE';
|
|
@@ -69,6 +86,10 @@ export const mediaRadioOptions = [
|
|
|
69
86
|
value: VIBER_MEDIA_TYPES.VIDEO,
|
|
70
87
|
label: <FormattedMessage {...messages.mediaVideo} />,
|
|
71
88
|
},
|
|
89
|
+
{
|
|
90
|
+
value: VIBER_MEDIA_TYPES.CAROUSEL,
|
|
91
|
+
label: <FormattedMessage {...messages.mediaCarousel} />,
|
|
92
|
+
},
|
|
72
93
|
];
|
|
73
94
|
|
|
74
95
|
export const buttonRadioOptions = [
|