@capillarytech/creatives-library 8.0.353-alpha.5 → 8.0.353-alpha.6

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.
Files changed (136) hide show
  1. package/constants/unified.js +29 -0
  2. package/package.json +1 -1
  3. package/services/tests/api.test.js +35 -20
  4. package/utils/commonUtils.js +19 -1
  5. package/utils/rcsPayloadUtils.js +92 -0
  6. package/utils/templateVarUtils.js +201 -0
  7. package/utils/tests/rcsPayloadUtils.test.js +226 -0
  8. package/utils/tests/templateVarUtils.test.js +204 -0
  9. package/v2Components/CapActionButton/constants.js +7 -0
  10. package/v2Components/CapActionButton/index.js +166 -108
  11. package/v2Components/CapActionButton/index.scss +157 -6
  12. package/v2Components/CapActionButton/messages.js +19 -3
  13. package/v2Components/CapActionButton/tests/index.test.js +41 -17
  14. package/v2Components/CapTagList/index.js +10 -0
  15. package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +72 -49
  16. package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +8 -2
  17. package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +213 -21
  18. package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +16 -0
  19. package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +85 -10
  20. package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +30 -0
  21. package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +79 -11
  22. package/v2Components/CommonTestAndPreview/SendTestMessage.js +10 -5
  23. package/v2Components/CommonTestAndPreview/UnifiedPreview/PreviewHeader.js +0 -17
  24. package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +157 -15
  25. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +346 -146
  26. package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +138 -48
  27. package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +11 -0
  28. package/v2Components/CommonTestAndPreview/constants.js +38 -4
  29. package/v2Components/CommonTestAndPreview/index.js +691 -235
  30. package/v2Components/CommonTestAndPreview/messages.js +45 -3
  31. package/v2Components/CommonTestAndPreview/previewApiUtils.js +59 -0
  32. package/v2Components/CommonTestAndPreview/sagas.js +25 -6
  33. package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +308 -284
  34. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +231 -65
  35. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +118 -5
  36. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +341 -0
  37. package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +8 -1
  38. package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +34 -13
  39. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/PreviewHeader.test.js +0 -159
  40. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +281 -283
  41. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +199 -256
  42. package/v2Components/CommonTestAndPreview/tests/constants.test.js +1 -2
  43. package/v2Components/CommonTestAndPreview/tests/index.test.js +132 -198
  44. package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +67 -0
  45. package/v2Components/CommonTestAndPreview/tests/sagas.test.js +36 -26
  46. package/v2Components/FormBuilder/index.js +11 -6
  47. package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +91 -0
  48. package/v2Components/SmsFallback/constants.js +73 -0
  49. package/v2Components/SmsFallback/index.js +956 -0
  50. package/v2Components/SmsFallback/index.scss +265 -0
  51. package/v2Components/SmsFallback/messages.js +78 -0
  52. package/v2Components/SmsFallback/smsFallbackUtils.js +119 -0
  53. package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +50 -0
  54. package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +147 -0
  55. package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +304 -0
  56. package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +223 -0
  57. package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +309 -0
  58. package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +422 -0
  59. package/v2Components/SmsFallback/useLocalTemplateList.js +92 -0
  60. package/v2Components/TemplatePreview/_templatePreview.scss +38 -23
  61. package/v2Components/TemplatePreview/constants.js +2 -0
  62. package/v2Components/TemplatePreview/index.js +143 -31
  63. package/v2Components/TemplatePreview/tests/index.test.js +142 -0
  64. package/v2Components/TestAndPreviewSlidebox/index.js +15 -3
  65. package/v2Components/TestAndPreviewSlidebox/sagas.js +11 -4
  66. package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +3 -1
  67. package/v2Components/VarSegmentMessageEditor/constants.js +2 -0
  68. package/v2Components/VarSegmentMessageEditor/index.js +125 -0
  69. package/v2Components/VarSegmentMessageEditor/index.scss +46 -0
  70. package/v2Containers/App/constants.js +0 -3
  71. package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +43 -0
  72. package/v2Containers/CreativesContainer/SlideBoxContent.js +36 -4
  73. package/v2Containers/CreativesContainer/SlideBoxFooter.js +10 -1
  74. package/v2Containers/CreativesContainer/SlideBoxHeader.js +29 -4
  75. package/v2Containers/CreativesContainer/constants.js +9 -0
  76. package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +79 -0
  77. package/v2Containers/CreativesContainer/index.js +322 -103
  78. package/v2Containers/CreativesContainer/index.scss +51 -1
  79. package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +90 -0
  80. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +78 -34
  81. package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +79 -16
  82. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +8 -0
  83. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +357 -98
  84. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +20 -15
  85. package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +258 -0
  86. package/v2Containers/CreativesContainer/tests/index.test.js +71 -9
  87. package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +125 -0
  88. package/v2Containers/MobilePush/Create/test/saga.test.js +2 -2
  89. package/v2Containers/Rcs/constants.js +119 -10
  90. package/v2Containers/Rcs/index.js +2445 -813
  91. package/v2Containers/Rcs/index.scss +280 -8
  92. package/v2Containers/Rcs/messages.js +34 -3
  93. package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +225 -0
  94. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +98018 -70073
  95. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +0 -5
  96. package/v2Containers/Rcs/tests/index.test.js +152 -121
  97. package/v2Containers/Rcs/tests/mockData.js +38 -0
  98. package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +318 -0
  99. package/v2Containers/Rcs/tests/utils.test.js +646 -30
  100. package/v2Containers/Rcs/utils.js +478 -11
  101. package/v2Containers/Sms/Create/index.js +106 -40
  102. package/v2Containers/Sms/smsFormDataHelpers.js +67 -0
  103. package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +253 -0
  104. package/v2Containers/SmsTrai/Create/index.js +9 -4
  105. package/v2Containers/SmsTrai/Edit/constants.js +2 -0
  106. package/v2Containers/SmsTrai/Edit/index.js +640 -130
  107. package/v2Containers/SmsTrai/Edit/index.scss +121 -0
  108. package/v2Containers/SmsTrai/Edit/messages.js +14 -4
  109. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4328 -2375
  110. package/v2Containers/SmsWrapper/index.js +37 -8
  111. package/v2Containers/TagList/index.js +6 -0
  112. package/v2Containers/Templates/TemplatesActionBar.js +101 -0
  113. package/v2Containers/Templates/_templates.scss +166 -9
  114. package/v2Containers/Templates/actions.js +11 -0
  115. package/v2Containers/Templates/constants.js +2 -0
  116. package/v2Containers/Templates/index.js +122 -120
  117. package/v2Containers/Templates/sagas.js +56 -12
  118. package/v2Containers/Templates/tests/TemplatesActionBar.test.js +120 -0
  119. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1062 -1017
  120. package/v2Containers/Templates/tests/sagas.test.js +199 -16
  121. package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +180 -0
  122. package/v2Containers/Templates/utils/smsTemplatesListApi.js +79 -0
  123. package/v2Containers/TemplatesV2/TemplatesV2.style.js +72 -1
  124. package/v2Containers/TemplatesV2/index.js +86 -23
  125. package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +131 -0
  126. package/v2Containers/WeChat/MapTemplates/test/saga.test.js +9 -9
  127. package/v2Containers/WebPush/Create/index.js +8 -91
  128. package/v2Containers/WebPush/Create/index.scss +0 -7
  129. package/v2Containers/Whatsapp/index.js +3 -20
  130. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +578 -34
  131. package/v2Components/CommonTestAndPreview/UnifiedPreview/WebPushPreviewContent.js +0 -169
  132. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/WebPushPreviewContent.test.js +0 -522
  133. package/v2Containers/App/tests/constants.test.js +0 -61
  134. package/v2Containers/Templates/tests/webpush.test.js +0 -375
  135. package/v2Containers/WebPush/Create/tests/getTemplateContent.test.js +0 -338
  136. package/v2Containers/WebPush/Create/tests/testAndPreviewIntegration.test.js +0 -325
@@ -6,7 +6,7 @@
6
6
  * Routes to channel-specific preview content components
7
7
  */
8
8
 
9
- import React, { useState } from 'react';
9
+ import React from 'react';
10
10
  import PropTypes from 'prop-types';
11
11
  import CapRow from '@capillarytech/cap-ui-library/CapRow';
12
12
  import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
@@ -21,9 +21,21 @@ import InAppPreviewContent from './InAppPreviewContent';
21
21
  import MobilePushPreviewContent from './MobilePushPreviewContent';
22
22
  import ViberPreviewContent from './ViberPreviewContent';
23
23
  import ZaloPreviewContent from './ZaloPreviewContent';
24
- import WebPushPreviewContent from './WebPushPreviewContent';
25
- import { CHANNELS, DESKTOP, TABLET, MOBILE, ANDROID, IOS } from '../constants';
24
+ import CapTab from '@capillarytech/cap-ui-library/CapTab';
25
+ import {
26
+ CHANNELS,
27
+ DESKTOP,
28
+ TABLET,
29
+ MOBILE,
30
+ ANDROID,
31
+ IOS,
32
+ PREVIEW_TAB_RCS,
33
+ PREVIEW_TAB_SMS_FALLBACK,
34
+ PREVIEW_TAB_KEYS,
35
+ RCS_SMS_FALLBACK_VAR_MAPPED_PROP,
36
+ } from '../constants';
26
37
  import messages from '../messages';
38
+ import { getFallbackResolvedContent } from '../../../utils/templateVarUtils';
27
39
  import './_unifiedPreview.scss';
28
40
 
29
41
  const UnifiedPreview = ({
@@ -39,13 +51,29 @@ const UnifiedPreview = ({
39
51
  lastModified,
40
52
  updatedByName,
41
53
  showHeader, // Default to true for Test and Preview flow, false for channel component previews
54
+ smsFallbackContent,
55
+ smsFallbackResolvedText,
56
+ activePreviewTab,
57
+ onPreviewTabChange,
42
58
  }) => {
59
+ const hasFallbackSmsTemplate = !!(smsFallbackContent?.templateContent || smsFallbackContent?.content);
60
+ const showRcsSmsFallbackTabs = channel === CHANNELS.RCS && hasFallbackSmsTemplate;
61
+ const rawFallbackTemplate = smsFallbackContent?.templateContent ?? smsFallbackContent?.content ?? '';
62
+ const rcsFallbackVarMapped = smsFallbackContent?.[RCS_SMS_FALLBACK_VAR_MAPPED_PROP] ?? {};
63
+ const hasRcsFallbackVarMapped = Object.keys(rcsFallbackVarMapped).length > 0;
64
+ // When no varmap is present, show raw template so {{tags}} remain visible in the preview.
65
+ // Only apply slot substitution when varmap entries exist or a resolved text is available.
66
+ const smsFallbackDisplayContent =
67
+ smsFallbackResolvedText != null && smsFallbackResolvedText !== ''
68
+ ? smsFallbackResolvedText
69
+ : hasRcsFallbackVarMapped
70
+ ? getFallbackResolvedContent(rawFallbackTemplate, rcsFallbackVarMapped)
71
+ : rawFallbackTemplate;
43
72
  /**
44
73
  * Render channel-specific preview content
45
74
  * For Phase 5, we'll render placeholders
46
75
  * Phase 6+ will implement actual content components
47
76
  */
48
- const [isFullscreenOpen, setIsFullscreenOpen] = useState(false);
49
77
  const renderChannelContent = () => {
50
78
  // Phase 5: Placeholder content for all channels
51
79
  // Phase 6+: Import and render actual channel-specific components
@@ -126,6 +154,21 @@ const UnifiedPreview = ({
126
154
  case CHANNELS.RCS: {
127
155
  // RCS content is an object with rcsTitle, rcsDesc, rcsImageSrc, suggestions, etc.
128
156
  const rcsContent = typeof content === 'object' ? content : {};
157
+
158
+ if (showRcsSmsFallbackTabs && activePreviewTab === PREVIEW_TAB_SMS_FALLBACK) {
159
+ return (
160
+ <SmsPreviewContent
161
+ content={smsFallbackDisplayContent}
162
+ device={ANDROID}
163
+ isUpdating={isUpdating}
164
+ error={error}
165
+ formatMessage={formatMessage}
166
+ senderId={smsFallbackContent?.senderId}
167
+ showHeader={showHeader}
168
+ />
169
+ );
170
+ }
171
+
129
172
  return (
130
173
  <RcsPreviewContent
131
174
  content={rcsContent}
@@ -199,40 +242,6 @@ const UnifiedPreview = ({
199
242
  );
200
243
  }
201
244
 
202
- case CHANNELS.WEBPUSH: {
203
- // WebPush content arrives as a JSON string (from getCurrentContent or preview API response)
204
- let webPushOuter = {};
205
- try {
206
- webPushOuter = typeof content === 'string' ? JSON.parse(content) : (typeof content === 'object' && content !== null ? content : {});
207
- } catch (e) {
208
- webPushOuter = {};
209
- }
210
- const webPushInner = webPushOuter?.content || {};
211
- const webPushExpandable = webPushInner?.expandableDetails || {};
212
- const webPushMedia = webPushExpandable?.media || [];
213
- const webPushCtas = webPushExpandable?.ctas || [];
214
- const webPushButtons = webPushCtas.map((cta) => ({
215
- text: cta?.title || '',
216
- url: cta?.actionLink || '',
217
- type: cta?.type || '',
218
- }));
219
- return (
220
- <WebPushPreviewContent
221
- notificationTitle={webPushInner?.title || ''}
222
- notificationBody={webPushInner?.message || ''}
223
- imageSrc={webPushMedia[0]?.url || ''}
224
- brandIconSrc={webPushInner?.iconImageUrl || ''}
225
- buttons={webPushButtons}
226
- url={webPushInner?.cta?.actionLink || ''}
227
- isUpdating={isUpdating}
228
- error={error}
229
- isFullscreenOpen={isFullscreenOpen}
230
- setIsFullscreenOpen={setIsFullscreenOpen}
231
- selectedCustomer={selectedCustomer}
232
- />
233
- );
234
- }
235
-
236
245
  default:
237
246
  return (
238
247
  <div className="channel-preview-placeholder">
@@ -258,10 +267,9 @@ const UnifiedPreview = ({
258
267
  <PreviewHeader
259
268
  selectedCustomer={selectedCustomer}
260
269
  device={device}
261
- showDeviceToggle={channel !== CHANNELS.WEBPUSH && showDeviceToggle}
270
+ showDeviceToggle={showDeviceToggle}
262
271
  onDeviceChange={onDeviceChange}
263
272
  channel={channel}
264
- setIsFullscreenOpen={setIsFullscreenOpen}
265
273
  />
266
274
  )}
267
275
  <CapRow className="preview-loading-container">
@@ -284,10 +292,9 @@ const UnifiedPreview = ({
284
292
  <PreviewHeader
285
293
  selectedCustomer={selectedCustomer}
286
294
  device={device}
287
- showDeviceToggle={channel !== CHANNELS.WEBPUSH && showDeviceToggle}
295
+ showDeviceToggle={showDeviceToggle}
288
296
  onDeviceChange={onDeviceChange}
289
297
  channel={channel}
290
- setIsFullscreenOpen={setIsFullscreenOpen}
291
298
  />
292
299
  )}
293
300
  <CapRow className="preview-error-container">
@@ -306,6 +313,79 @@ const UnifiedPreview = ({
306
313
  * PreviewHeader is shown only when showHeader is true (for Test and Preview flow)
307
314
  * Channel-specific content will be in separate files in future phases
308
315
  */
316
+ if (showRcsSmsFallbackTabs) {
317
+ const renderPane = ({ paneChannel, paneDevice, paneShowDeviceToggle, paneContent }) => (
318
+ <CapRow className="unified-preview-tab-pane">
319
+ {showHeader && (
320
+ <PreviewHeader
321
+ selectedCustomer={selectedCustomer}
322
+ device={paneDevice}
323
+ showDeviceToggle={paneShowDeviceToggle}
324
+ onDeviceChange={onDeviceChange}
325
+ channel={paneChannel}
326
+ />
327
+ )}
328
+
329
+ <CapRow className={`preview-content-container ${!showHeader ? 'preview-content-container-no-header' : ''}`}>
330
+ {paneContent}
331
+ </CapRow>
332
+
333
+
334
+ </CapRow>
335
+ );
336
+
337
+ return (
338
+ <CapRow className="unified-preview unified-preview-rcs-tabs">
339
+ <CapTab
340
+ activeKey={activePreviewTab}
341
+ onChange={onPreviewTabChange}
342
+ panes={[
343
+ {
344
+ tab: formatMessage(messages.rcsTab),
345
+ key: PREVIEW_TAB_RCS,
346
+ content: renderPane({
347
+ paneChannel: CHANNELS.RCS,
348
+ paneDevice: device,
349
+ paneShowDeviceToggle: showDeviceToggle,
350
+ paneContent: (
351
+ <RcsPreviewContent
352
+ content={typeof content === 'object' ? content : {}}
353
+ device={device}
354
+ isUpdating={isUpdating}
355
+ error={error}
356
+ formatMessage={formatMessage}
357
+ senderId={content?.senderId}
358
+ showHeader={showHeader}
359
+ />
360
+ ),
361
+ }),
362
+ },
363
+ {
364
+ tab: formatMessage(messages.smsFallbackTab),
365
+ key: PREVIEW_TAB_SMS_FALLBACK,
366
+ content: renderPane({
367
+ paneChannel: CHANNELS.SMS,
368
+ paneDevice: device,
369
+ paneShowDeviceToggle: showDeviceToggle,
370
+ paneContent: (
371
+ <SmsPreviewContent
372
+ content={smsFallbackDisplayContent}
373
+ device={device}
374
+ isUpdating={isUpdating}
375
+ error={error}
376
+ formatMessage={formatMessage}
377
+ senderId={smsFallbackContent?.senderId}
378
+ showHeader={showHeader}
379
+ />
380
+ ),
381
+ }),
382
+ },
383
+ ]}
384
+ />
385
+ </CapRow>
386
+ );
387
+ }
388
+
309
389
  return (
310
390
  <CapRow className="unified-preview">
311
391
  {/* PreviewHeader - shown only in Test and Preview flow, hidden in channel component previews */}
@@ -313,16 +393,15 @@ const UnifiedPreview = ({
313
393
  <PreviewHeader
314
394
  selectedCustomer={selectedCustomer}
315
395
  device={device}
316
- showDeviceToggle={channel !== CHANNELS.WEBPUSH && showDeviceToggle}
396
+ showDeviceToggle={showDeviceToggle}
317
397
  onDeviceChange={onDeviceChange}
318
398
  channel={channel}
319
- setIsFullscreenOpen={setIsFullscreenOpen}
320
399
  />
321
400
  )}
322
401
 
323
402
  {/* Channel-specific preview content */}
324
403
  <CapRow className={`preview-content-container ${!showHeader ? 'preview-content-container-no-header' : ''}`}>
325
- {[CHANNELS.EMAIL, CHANNELS.SMS, CHANNELS.WHATSAPP, CHANNELS.RCS, CHANNELS.INAPP, CHANNELS.MOBILEPUSH, CHANNELS.VIBER, CHANNELS.WEBPUSH].includes(channel) ? (
404
+ {[CHANNELS.EMAIL, CHANNELS.SMS, CHANNELS.WHATSAPP, CHANNELS.RCS, CHANNELS.INAPP, CHANNELS.MOBILEPUSH, CHANNELS.VIBER].includes(channel) ? (
326
405
  renderChannelContent()
327
406
  ) : (
328
407
  <DeviceFrame device={device || DESKTOP}>
@@ -344,9 +423,7 @@ const UnifiedPreview = ({
344
423
  )}
345
424
  {updatedByName && (
346
425
  <span className="metadata-item">
347
- {formatMessage(messages.by)}
348
- {' '}
349
- {updatedByName}
426
+ {formatMessage(messages.byAuthor, { name: updatedByName })}
350
427
  </span>
351
428
  )}
352
429
  </CapRow>
@@ -387,6 +464,15 @@ UnifiedPreview.propTypes = {
387
464
 
388
465
  // Header display
389
466
  showHeader: PropTypes.bool, // Show PreviewHeader (true for Test and Preview flow, false for channel component previews)
467
+
468
+ // RCS: SMS fallback preview support (same shape as SmsFallback / RCS smsFallbackData)
469
+ smsFallbackContent: PropTypes.shape({
470
+ templateContent: PropTypes.string,
471
+ senderId: PropTypes.string,
472
+ templateName: PropTypes.string,
473
+ }),
474
+ activePreviewTab: PropTypes.oneOf(PREVIEW_TAB_KEYS),
475
+ onPreviewTabChange: PropTypes.func,
390
476
  };
391
477
 
392
478
  UnifiedPreview.defaultProps = {
@@ -399,6 +485,10 @@ UnifiedPreview.defaultProps = {
399
485
  lastModified: null,
400
486
  updatedByName: null,
401
487
  showHeader: true, // Default to true for Test and Preview flow
488
+ smsFallbackContent: null,
489
+ smsFallbackResolvedText: undefined,
490
+ activePreviewTab: PREVIEW_TAB_RCS,
491
+ onPreviewTabChange: () => {},
402
492
  };
403
493
 
404
494
  export default UnifiedPreview;
@@ -213,6 +213,10 @@
213
213
  margin-right: 0.5rem;
214
214
  }
215
215
 
216
+ .cap-slide-box-v2.common-test-and-preview-slidebox .cap-slide-box-v2-container {
217
+ z-index: 10030;
218
+ }
219
+
216
220
  .common-test-and-preview-slidebox {
217
221
 
218
222
  .ant-modal-mask,
@@ -486,6 +490,13 @@
486
490
  }
487
491
  }
488
492
 
493
+ .tags-section-title {
494
+ margin: $CAP_SPACE_12 0;
495
+ display: block;
496
+ color: $CAP_G01;
497
+ font-weight: $FONT_WEIGHT_MEDIUM;
498
+ }
499
+
489
500
  .values-table {
490
501
  margin-bottom: $CAP_SPACE_16;
491
502
  border: $CAP_SPACE_01 solid $CAP_G12;
@@ -66,7 +66,6 @@ export const GET_WECRM_ACCOUNTS_REQUESTED = 'app/CommonTestAndPreview/GET_WECRM_
66
66
  export const GET_WECRM_ACCOUNTS_SUCCESS = 'app/CommonTestAndPreview/GET_WECRM_ACCOUNTS_SUCCESS';
67
67
  export const GET_WECRM_ACCOUNTS_FAILURE = 'app/CommonTestAndPreview/GET_WECRM_ACCOUNTS_FAILURE';
68
68
 
69
-
70
69
  // ============================================
71
70
  // CUSTOMER MODAL TYPE (test customer addition)
72
71
  // ============================================
@@ -85,9 +84,45 @@ export const CHANNELS = {
85
84
  MOBILEPUSH: 'MOBILEPUSH',
86
85
  VIBER: 'VIBER',
87
86
  ZALO: 'ZALO',
88
- WEBPUSH: 'WEBPUSH',
89
87
  };
90
- export const CHANNELS_USING_ANDROID_PREVIEW_DEVICE = [CHANNELS.SMS, CHANNELS.RCS, CHANNELS.WHATSAPP, CHANNELS.VIBER, CHANNELS.ZALO, CHANNELS.INAPP, CHANNELS.MOBILEPUSH];
88
+
89
+ /** Unified preview tab keys when RCS shows RCS + SMS fallback panes. */
90
+ export const PREVIEW_TAB_RCS = 'rcs';
91
+ export const PREVIEW_TAB_SMS_FALLBACK = 'smsFallback';
92
+ export const PREVIEW_TAB_KEYS = [PREVIEW_TAB_RCS, PREVIEW_TAB_SMS_FALLBACK];
93
+
94
+ /** Channels whose Test & Preview defaults to Android/iOS device frame (not desktop). */
95
+ export const CHANNELS_USING_ANDROID_PREVIEW_DEVICE = [
96
+ CHANNELS.SMS,
97
+ CHANNELS.WHATSAPP,
98
+ CHANNELS.RCS,
99
+ CHANNELS.INAPP,
100
+ CHANNELS.MOBILEPUSH,
101
+ CHANNELS.VIBER,
102
+ ];
103
+
104
+ /** RCS createMessageMeta test payload — rich card envelope literals. */
105
+ export const RCS_TEST_META_CONTENT_TYPE_RICHCARD = 'RICHCARD';
106
+ export const RCS_TEST_META_CARD_TYPE_STANDALONE = 'STANDALONE';
107
+ export const RCS_TEST_META_CARD_ORIENTATION_VERTICAL = 'VERTICAL';
108
+ export const RCS_TEST_META_CARD_WIDTH_SMALL = 'SMALL';
109
+
110
+ /** React key fallback when a custom-values section has no `key` or title id. */
111
+ export const CUSTOM_VALUES_EDITOR_SECTION_FALLBACK_KEY = 'section';
112
+
113
+ /**
114
+ * Matches at least one `{{variableName}}` token in SMS / RCS fallback template text.
115
+ */
116
+ export const SMS_MUSTACHE_TAG_PATTERN = /\{\{[^}]+\}\}/;
117
+
118
+ /** TRAI DLT `{#…#}` placeholders (same idea as `COMBINED_SMS_TEMPLATE_VAR_REGEX` in unified constants). */
119
+ export const SMS_DLT_HASH_TAG_PATTERN = /\{\#[^#]*\#\}/;
120
+
121
+ /**
122
+ * Key on `smsFallbackContent` passed into Test & Preview — RCS slot map from SmsTraiEdit
123
+ * (`onRcsFallbackEditorStateChange`), merged before tag extraction like the embedded SMS editor.
124
+ */
125
+ export const RCS_SMS_FALLBACK_VAR_MAPPED_PROP = 'rcsSmsFallbackVarMapped';
91
126
 
92
127
  // ============================================
93
128
  // DEVICE CONSTANTS
@@ -204,7 +239,6 @@ export const DYNAMIC_URL = 'DYNAMIC_URL';
204
239
  export const IMAGE = 'IMAGE';
205
240
  export const VIDEO = 'VIDEO';
206
241
  export const URL = 'URL';
207
- export const DAYS = 'DAYS';
208
242
 
209
243
  // Initial Payload Template (for reference)
210
244
  export const INITIAL_PAYLOAD = {