cap-creatives-ui 8.0.280 → 8.0.321

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 (247) hide show
  1. package/.github/workflows/pr-title-check.yml +88 -0
  2. package/app/constants/unified.js +21 -1
  3. package/app/containers/App/constants.js +0 -1
  4. package/app/containers/Login/test/index.test.js +123 -0
  5. package/app/containers/Login/test/selectors.test.js +165 -0
  6. package/app/initialState.js +0 -2
  7. package/app/services/api.js +6 -0
  8. package/app/services/tests/api.test.js +7 -0
  9. package/app/services/tests/getSchema.test.js +95 -0
  10. package/app/utils/common.js +23 -9
  11. package/app/utils/commonUtils.js +64 -93
  12. package/app/utils/tagValidations.js +83 -219
  13. package/app/utils/templateVarUtils.js +172 -0
  14. package/app/utils/tests/common.test.js +265 -323
  15. package/app/utils/tests/commonUtil.test.js +461 -118
  16. package/app/utils/tests/commonUtils.test.js +581 -0
  17. package/app/utils/tests/messageUtils.test.js +95 -0
  18. package/app/utils/tests/smsCharCount.test.js +304 -0
  19. package/app/utils/tests/smsCharCountV2.test.js +213 -10
  20. package/app/utils/tests/tagValidations.test.js +474 -357
  21. package/app/utils/tests/templateVarUtils.test.js +160 -0
  22. package/app/v2Components/CapDeviceContent/index.js +10 -7
  23. package/app/v2Components/CapTagList/index.js +32 -24
  24. package/app/v2Components/CapTagList/style.scss +48 -0
  25. package/app/v2Components/CapTagListWithInput/__tests__/CapTagListWithInput.test.js +63 -0
  26. package/app/v2Components/CapTagListWithInput/index.js +8 -0
  27. package/app/v2Components/CapWhatsappCTA/index.js +2 -0
  28. package/app/v2Components/CapWhatsappCarouselButton/index.js +32 -14
  29. package/app/v2Components/CapWhatsappCarouselButton/tests/index.test.js +120 -2
  30. package/app/v2Components/CommonTestAndPreview/CustomValuesEditor.js +70 -49
  31. package/app/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +39 -0
  32. package/app/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +606 -0
  33. package/app/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.scss +36 -0
  34. package/app/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +79 -0
  35. package/app/v2Components/CommonTestAndPreview/DeliverySettings/index.js +314 -0
  36. package/app/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +141 -0
  37. package/app/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +156 -0
  38. package/app/v2Components/CommonTestAndPreview/SendTestMessage.js +57 -1
  39. package/app/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +20 -1
  40. package/app/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +133 -4
  41. package/app/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +210 -4
  42. package/app/v2Components/CommonTestAndPreview/actions.js +20 -0
  43. package/app/v2Components/CommonTestAndPreview/constants.js +57 -1
  44. package/app/v2Components/CommonTestAndPreview/index.js +878 -156
  45. package/app/v2Components/CommonTestAndPreview/messages.js +41 -3
  46. package/app/v2Components/CommonTestAndPreview/previewApiUtils.js +59 -0
  47. package/app/v2Components/CommonTestAndPreview/reducer.js +47 -0
  48. package/app/v2Components/CommonTestAndPreview/sagas.js +75 -5
  49. package/app/v2Components/CommonTestAndPreview/selectors.js +51 -0
  50. package/app/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +352 -0
  51. package/app/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +1156 -0
  52. package/app/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +334 -0
  53. package/app/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +576 -0
  54. package/app/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +156 -0
  55. package/app/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +199 -1
  56. package/app/v2Components/CommonTestAndPreview/tests/actions.test.js +50 -0
  57. package/app/v2Components/CommonTestAndPreview/tests/constants.test.js +18 -7
  58. package/app/v2Components/CommonTestAndPreview/tests/index.test.js +914 -5
  59. package/app/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +67 -0
  60. package/app/v2Components/CommonTestAndPreview/tests/reducer.test.js +118 -0
  61. package/app/v2Components/CommonTestAndPreview/tests/sagas.test.js +146 -378
  62. package/app/v2Components/CommonTestAndPreview/tests/selectors.test.js +146 -0
  63. package/app/v2Components/ErrorInfoNote/index.js +24 -26
  64. package/app/v2Components/FormBuilder/index.js +182 -204
  65. package/app/v2Components/FormBuilder/messages.js +4 -8
  66. package/app/v2Components/HtmlEditor/HTMLEditor.js +7 -6
  67. package/app/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +1 -1
  68. package/app/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +928 -17
  69. package/app/v2Components/HtmlEditor/components/CodeEditorPane/index.js +4 -2
  70. package/app/v2Components/HtmlEditor/hooks/__tests__/useValidation.test.js +452 -3
  71. package/app/v2Components/HtmlEditor/hooks/useValidation.js +12 -9
  72. package/app/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +132 -0
  73. package/app/v2Components/HtmlEditor/utils/htmlValidator.js +4 -2
  74. package/app/v2Components/SmsFallback/SmsFallbackLocalSelector.js +87 -0
  75. package/app/v2Components/SmsFallback/constants.js +73 -0
  76. package/app/v2Components/SmsFallback/index.js +956 -0
  77. package/app/v2Components/SmsFallback/index.scss +265 -0
  78. package/app/v2Components/SmsFallback/messages.js +78 -0
  79. package/app/v2Components/SmsFallback/smsFallbackUtils.js +107 -0
  80. package/app/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +50 -0
  81. package/app/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +147 -0
  82. package/app/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +304 -0
  83. package/app/v2Components/SmsFallback/tests/smsFallbackUi.test.js +197 -0
  84. package/app/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +261 -0
  85. package/app/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +422 -0
  86. package/app/v2Components/SmsFallback/useLocalTemplateList.js +92 -0
  87. package/app/v2Components/TestAndPreviewSlidebox/index.js +22 -1
  88. package/app/v2Components/TestAndPreviewSlidebox/sagas.js +11 -4
  89. package/app/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +3 -1
  90. package/app/v2Components/VarSegmentMessageEditor/constants.js +2 -0
  91. package/app/v2Components/VarSegmentMessageEditor/index.js +125 -0
  92. package/app/v2Components/VarSegmentMessageEditor/index.scss +46 -0
  93. package/app/v2Containers/BeeEditor/index.js +3 -0
  94. package/app/v2Containers/BeePopupEditor/index.js +9 -2
  95. package/app/v2Containers/Cap/mockData.js +0 -14
  96. package/app/v2Containers/Cap/reducer.js +3 -55
  97. package/app/v2Containers/Cap/tests/reducer.test.js +0 -102
  98. package/app/v2Containers/CommunicationFlow/CommunicationFlow.js +291 -0
  99. package/app/v2Containers/CommunicationFlow/CommunicationFlow.scss +25 -0
  100. package/app/v2Containers/CommunicationFlow/Tests/CommunicationFlow.test.js +255 -0
  101. package/app/v2Containers/CommunicationFlow/constants.js +200 -0
  102. package/app/v2Containers/CommunicationFlow/index.js +102 -0
  103. package/app/v2Containers/CommunicationFlow/messages.js +346 -0
  104. package/app/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/ChannelSelectionStep.js +522 -0
  105. package/app/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/ChannelSelectionStep.scss +170 -0
  106. package/app/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/Tests/ChannelSelectionStep.test.js +796 -0
  107. package/app/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/index.js +5 -0
  108. package/app/v2Containers/CommunicationFlow/steps/CommunicationStrategyStep/CommunicationStrategyStep.js +95 -0
  109. package/app/v2Containers/CommunicationFlow/steps/CommunicationStrategyStep/Tests/CommunicationStrategyStep.test.js +133 -0
  110. package/app/v2Containers/CommunicationFlow/steps/CommunicationStrategyStep/index.js +5 -0
  111. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/DeliverySettingsSection.js +289 -0
  112. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/DeliverySettingsSection.scss +70 -0
  113. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/SenderDetails.js +319 -0
  114. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/SenderDetails.scss +69 -0
  115. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/DeliverySettingsSection.test.js +616 -0
  116. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +577 -0
  117. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/deliverySettingsConfig.test.js +1111 -0
  118. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/deliverySettingsConfig.js +696 -0
  119. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/index.js +7 -0
  120. package/app/v2Containers/CommunicationFlow/steps/DynamicControlsStep/DynamicControlsStep.js +102 -0
  121. package/app/v2Containers/CommunicationFlow/steps/DynamicControlsStep/DynamicControlsStep.scss +36 -0
  122. package/app/v2Containers/CommunicationFlow/steps/DynamicControlsStep/Tests/DynamicControlsStep.test.js +91 -0
  123. package/app/v2Containers/CommunicationFlow/steps/DynamicControlsStep/index.js +5 -0
  124. package/app/v2Containers/CommunicationFlow/steps/MessageTypeStep/MessageTypeStep.js +86 -0
  125. package/app/v2Containers/CommunicationFlow/steps/MessageTypeStep/Tests/MessageTypeStep.test.js +100 -0
  126. package/app/v2Containers/CommunicationFlow/steps/MessageTypeStep/index.js +5 -0
  127. package/app/v2Containers/CommunicationFlow/utils/getEnabledSteps.js +30 -0
  128. package/app/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +43 -0
  129. package/app/v2Containers/CreativesContainer/SlideBoxContent.js +127 -11
  130. package/app/v2Containers/CreativesContainer/SlideBoxFooter.js +62 -9
  131. package/app/v2Containers/CreativesContainer/SlideBoxHeader.js +29 -4
  132. package/app/v2Containers/CreativesContainer/constants.js +24 -0
  133. package/app/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +67 -0
  134. package/app/v2Containers/CreativesContainer/index.js +346 -71
  135. package/app/v2Containers/CreativesContainer/index.scss +51 -1
  136. package/app/v2Containers/CreativesContainer/messages.js +12 -0
  137. package/app/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +90 -0
  138. package/app/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +69 -1
  139. package/app/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +443 -0
  140. package/app/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +110 -0
  141. package/app/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +147 -4
  142. package/app/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +363 -0
  143. package/app/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +57 -10
  144. package/app/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +258 -0
  145. package/app/v2Containers/CreativesContainer/tests/index.test.js +71 -9
  146. package/app/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +125 -0
  147. package/app/v2Containers/Email/index.js +2 -5
  148. package/app/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +58 -77
  149. package/app/v2Containers/EmailWrapper/components/EmailWrapperView.js +3 -0
  150. package/app/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +158 -89
  151. package/app/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +16 -1
  152. package/app/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +17 -12
  153. package/app/v2Containers/EmailWrapper/index.js +4 -0
  154. package/app/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +1 -0
  155. package/app/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +133 -0
  156. package/app/v2Containers/FTP/index.js +2 -51
  157. package/app/v2Containers/FTP/messages.js +0 -4
  158. package/app/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +110 -155
  159. package/app/v2Containers/InApp/index.js +297 -118
  160. package/app/v2Containers/InApp/tests/index.test.js +17 -6
  161. package/app/v2Containers/InApp/tests/mockData.js +1 -1
  162. package/app/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +19 -0
  163. package/app/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +3 -0
  164. package/app/v2Containers/InAppWrapper/index.js +3 -0
  165. package/app/v2Containers/InappAdvance/index.js +5 -104
  166. package/app/v2Containers/InappAdvance/tests/index.test.js +2 -0
  167. package/app/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +24 -3
  168. package/app/v2Containers/Line/Container/Text/index.js +0 -1
  169. package/app/v2Containers/MobilePush/Create/index.js +105 -28
  170. package/app/v2Containers/MobilePush/Create/messages.js +4 -0
  171. package/app/v2Containers/MobilePush/Edit/index.js +250 -68
  172. package/app/v2Containers/MobilePush/Edit/messages.js +4 -0
  173. package/app/v2Containers/MobilePushNew/components/PlatformContentFields.js +36 -12
  174. package/app/v2Containers/MobilePushNew/components/tests/PlatformContentFields.test.js +68 -27
  175. package/app/v2Containers/MobilePushNew/index.js +78 -35
  176. package/app/v2Containers/MobilePushNew/messages.js +8 -0
  177. package/app/v2Containers/MobilepushWrapper/index.js +11 -1
  178. package/app/v2Containers/Rcs/constants.js +32 -1
  179. package/app/v2Containers/Rcs/index.js +963 -916
  180. package/app/v2Containers/Rcs/index.scss +85 -6
  181. package/app/v2Containers/Rcs/messages.js +10 -1
  182. package/app/v2Containers/Rcs/rcsLibraryHydrationUtils.js +205 -0
  183. package/app/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +41136 -1566
  184. package/app/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +0 -5
  185. package/app/v2Containers/Rcs/tests/index.test.js +41 -38
  186. package/app/v2Containers/Rcs/tests/mockData.js +38 -0
  187. package/app/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +251 -0
  188. package/app/v2Containers/Rcs/tests/utils.test.js +379 -1
  189. package/app/v2Containers/Rcs/utils.js +358 -10
  190. package/app/v2Containers/Sms/Create/index.js +122 -39
  191. package/app/v2Containers/Sms/Create/messages.js +4 -0
  192. package/app/v2Containers/Sms/Edit/index.js +37 -3
  193. package/app/v2Containers/Sms/commonMethods.js +3 -6
  194. package/app/v2Containers/Sms/smsFormDataHelpers.js +67 -0
  195. package/app/v2Containers/Sms/tests/commonMethods.test.js +122 -0
  196. package/app/v2Containers/Sms/tests/smsFormDataHelpers.test.js +253 -0
  197. package/app/v2Containers/SmsTrai/Create/index.js +9 -4
  198. package/app/v2Containers/SmsTrai/Create/index.scss +1 -1
  199. package/app/v2Containers/SmsTrai/Edit/constants.js +2 -0
  200. package/app/v2Containers/SmsTrai/Edit/index.js +667 -160
  201. package/app/v2Containers/SmsTrai/Edit/index.scss +121 -0
  202. package/app/v2Containers/SmsTrai/Edit/messages.js +9 -4
  203. package/app/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4590 -2436
  204. package/app/v2Containers/SmsWrapper/index.js +41 -8
  205. package/app/v2Containers/TagList/index.js +63 -2
  206. package/app/v2Containers/TagList/messages.js +8 -0
  207. package/app/v2Containers/TagList/tests/TagList.test.js +122 -20
  208. package/app/v2Containers/TagList/tests/mockdata.js +17 -0
  209. package/app/v2Containers/Templates/TemplatesActionBar.js +101 -0
  210. package/app/v2Containers/Templates/_templates.scss +61 -2
  211. package/app/v2Containers/Templates/actions.js +11 -0
  212. package/app/v2Containers/Templates/constants.js +2 -0
  213. package/app/v2Containers/Templates/index.js +90 -40
  214. package/app/v2Containers/Templates/reducer.js +3 -1
  215. package/app/v2Containers/Templates/sagas.js +57 -12
  216. package/app/v2Containers/Templates/tests/TemplatesActionBar.test.js +120 -0
  217. package/app/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1043 -1079
  218. package/app/v2Containers/Templates/tests/reducer.test.js +12 -0
  219. package/app/v2Containers/Templates/tests/sagas.test.js +193 -12
  220. package/app/v2Containers/Templates/tests/smsTemplatesListApi.test.js +180 -0
  221. package/app/v2Containers/Templates/utils/smsTemplatesListApi.js +79 -0
  222. package/app/v2Containers/TemplatesV2/TemplatesV2.style.js +72 -1
  223. package/app/v2Containers/TemplatesV2/index.js +147 -49
  224. package/app/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +131 -0
  225. package/app/v2Containers/Viber/index.js +9 -10
  226. package/app/v2Containers/Viber/index.scss +1 -1
  227. package/app/v2Containers/WebPush/Create/components/BrandIconSection.test.js +264 -0
  228. package/app/v2Containers/WebPush/Create/components/MessageSection.js +78 -19
  229. package/app/v2Containers/WebPush/Create/components/MessageSection.test.js +82 -0
  230. package/app/v2Containers/WebPush/Create/components/__snapshots__/BrandIconSection.test.js.snap +187 -0
  231. package/app/v2Containers/WebPush/Create/components/__snapshots__/MessageSection.test.js.snap +25 -17
  232. package/app/v2Containers/WebPush/Create/hooks/useAiraTriggerPosition.js +80 -0
  233. package/app/v2Containers/WebPush/Create/hooks/useAiraTriggerPosition.test.js +210 -0
  234. package/app/v2Containers/WebPush/Create/hooks/useTagManagement.js +1 -5
  235. package/app/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +0 -7
  236. package/app/v2Containers/WebPush/Create/index.js +36 -6
  237. package/app/v2Containers/WebPush/Create/index.scss +5 -0
  238. package/app/v2Containers/WebPush/Create/messages.js +8 -1
  239. package/app/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +269 -0
  240. package/app/v2Containers/WebPush/Create/utils/validation.js +31 -15
  241. package/app/v2Containers/WebPush/Create/utils/validation.test.js +72 -24
  242. package/app/v2Containers/Whatsapp/index.js +28 -53
  243. package/app/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +26939 -3982
  244. package/app/v2Containers/Whatsapp/tests/index.test.js +172 -0
  245. package/app/v2Containers/Zalo/index.js +5 -11
  246. package/package.json +2 -2
  247. package/version +9 -0
@@ -6,8 +6,13 @@ 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';
9
10
  import isEmpty from 'lodash/isEmpty';
10
11
  import messages from './messages';
12
+ import DeliverySettings from './DeliverySettings';
13
+ import { CHANNELS } from './constants';
14
+
15
+ const CHANNELS_WITH_DELIVERY_SETTINGS = [CHANNELS.SMS, CHANNELS.EMAIL, CHANNELS.WHATSAPP, CHANNELS.RCS];
11
16
 
12
17
  const SendTestMessage = ({
13
18
  isFetchingTestCustomers,
@@ -17,8 +22,17 @@ const SendTestMessage = ({
17
22
  selectedTestEntities,
18
23
  handleSendTestMessage,
19
24
  formData,
25
+ channel,
20
26
  isSendingTestMessage,
21
27
  formatMessage,
28
+ deliverySettings,
29
+ senderDetailsByChannel = {},
30
+ wecrmAccounts,
31
+ onSaveDeliverySettings,
32
+ isLoadingSenderDetails,
33
+ smsTraiDltEnabled,
34
+ registeredSenderIds,
35
+ isChannelSmsFallbackPreviewEnabled,
22
36
  }) => (
23
37
  <CapStepsAccordian
24
38
  showNumberSteps={false}
@@ -42,7 +56,27 @@ const SendTestMessage = ({
42
56
  value={selectedTestEntities}
43
57
  multiple
44
58
  placeholder={formatMessage(messages.testCustomersPlaceholder)}
59
+ getPopupContainer={(triggerNode) => triggerNode.parentNode}
45
60
  />
61
+ {CHANNELS_WITH_DELIVERY_SETTINGS.includes(channel) && (
62
+ <DeliverySettings
63
+ channel={channel}
64
+ deliverySettings={deliverySettings || {}}
65
+ senderDetailsByChannel={senderDetailsByChannel}
66
+ wecrmAccounts={wecrmAccounts || []}
67
+ onSaveDeliverySettings={onSaveDeliverySettings}
68
+ isLoadingSenderDetails={isLoadingSenderDetails}
69
+ formatMessage={formatMessage}
70
+ smsTraiDltEnabled={smsTraiDltEnabled}
71
+ registeredSenderIds={registeredSenderIds}
72
+ isChannelSmsFallbackPreviewEnabled={isChannelSmsFallbackPreviewEnabled}
73
+ whatsappAccountFromForm={
74
+ channel === CHANNELS.WHATSAPP && formData?.accountName
75
+ ? { accountName: formData.accountName }
76
+ : undefined
77
+ }
78
+ />
79
+ )}
46
80
  <CapButton onClick={handleSendTestMessage} disabled={isEmpty(selectedTestEntities) || isSendingTestMessage}>
47
81
  <FormattedMessage {...messages.sendTestButton} />
48
82
  </CapButton>
@@ -60,9 +94,31 @@ SendTestMessage.propTypes = {
60
94
  handleTestEntitiesChange: PropTypes.func.isRequired,
61
95
  selectedTestEntities: PropTypes.array.isRequired,
62
96
  handleSendTestMessage: PropTypes.func.isRequired,
63
- formData: PropTypes.object.isRequired,
97
+ formData: PropTypes.object,
98
+ channel: PropTypes.string,
64
99
  isSendingTestMessage: PropTypes.bool.isRequired,
65
100
  formatMessage: PropTypes.func.isRequired,
101
+ deliverySettings: PropTypes.object,
102
+ senderDetailsByChannel: PropTypes.object,
103
+ wecrmAccounts: PropTypes.array,
104
+ onSaveDeliverySettings: PropTypes.func,
105
+ isLoadingSenderDetails: PropTypes.bool,
106
+ smsTraiDltEnabled: PropTypes.bool,
107
+ registeredSenderIds: PropTypes.array,
108
+ isChannelSmsFallbackPreviewEnabled: PropTypes.bool,
109
+ };
110
+
111
+ SendTestMessage.defaultProps = {
112
+ formData: undefined,
113
+ channel: undefined,
114
+ deliverySettings: {},
115
+ senderDetailsByChannel: {},
116
+ wecrmAccounts: [],
117
+ onSaveDeliverySettings: undefined,
118
+ isLoadingSenderDetails: false,
119
+ smsTraiDltEnabled: false,
120
+ registeredSenderIds: [],
121
+ isChannelSmsFallbackPreviewEnabled: false,
66
122
  };
67
123
 
68
124
  export default SendTestMessage;
@@ -11,7 +11,6 @@
11
11
  height: 100%;
12
12
  display: flex;
13
13
  flex-direction: column;
14
- background: $CAP_WHITE;
15
14
  overflow: hidden;
16
15
 
17
16
  // Preview Chrome wrapper (matches old TestAndPreviewSlidebox design)
@@ -62,7 +61,27 @@
62
61
  }
63
62
  }
64
63
  }
64
+
65
+ .unified-preview.unified-preview-rcs-tabs {
66
+ .ant-tabs-nav {
67
+ margin: 0;
68
+ padding: 0 $CAP_SPACE_16;
69
+ }
65
70
 
71
+ // Prevent white hover/active backgrounds from default antd styles
72
+ .ant-tabs-tab,
73
+ .ant-tabs-tab:hover,
74
+ .ant-tabs-tab-active {
75
+ background: transparent;
76
+ }
77
+
78
+ .ant-tabs-tab-btn,
79
+ .ant-tabs-tab-btn:hover,
80
+ .ant-tabs-tab-btn:active {
81
+ background: transparent;
82
+ }
83
+ }
84
+
66
85
  // Preview Content Container
67
86
  .preview-content-container {
68
87
  flex: 1;
@@ -21,8 +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 { 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';
25
37
  import messages from '../messages';
38
+ import { getFallbackResolvedContent } from '../../../utils/templateVarUtils';
26
39
  import './_unifiedPreview.scss';
27
40
 
28
41
  const UnifiedPreview = ({
@@ -38,7 +51,24 @@ const UnifiedPreview = ({
38
51
  lastModified,
39
52
  updatedByName,
40
53
  showHeader, // Default to true for Test and Preview flow, false for channel component previews
54
+ smsFallbackContent,
55
+ smsFallbackResolvedText,
56
+ activePreviewTab,
57
+ onPreviewTabChange,
41
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;
42
72
  /**
43
73
  * Render channel-specific preview content
44
74
  * For Phase 5, we'll render placeholders
@@ -124,6 +154,21 @@ const UnifiedPreview = ({
124
154
  case CHANNELS.RCS: {
125
155
  // RCS content is an object with rcsTitle, rcsDesc, rcsImageSrc, suggestions, etc.
126
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
+
127
172
  return (
128
173
  <RcsPreviewContent
129
174
  content={rcsContent}
@@ -268,6 +313,79 @@ const UnifiedPreview = ({
268
313
  * PreviewHeader is shown only when showHeader is true (for Test and Preview flow)
269
314
  * Channel-specific content will be in separate files in future phases
270
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
+
271
389
  return (
272
390
  <CapRow className="unified-preview">
273
391
  {/* PreviewHeader - shown only in Test and Preview flow, hidden in channel component previews */}
@@ -305,9 +423,7 @@ const UnifiedPreview = ({
305
423
  )}
306
424
  {updatedByName && (
307
425
  <span className="metadata-item">
308
- {formatMessage(messages.by)}
309
- {' '}
310
- {updatedByName}
426
+ {formatMessage(messages.byAuthor, { name: updatedByName })}
311
427
  </span>
312
428
  )}
313
429
  </CapRow>
@@ -348,6 +464,15 @@ UnifiedPreview.propTypes = {
348
464
 
349
465
  // Header display
350
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,
351
476
  };
352
477
 
353
478
  UnifiedPreview.defaultProps = {
@@ -360,6 +485,10 @@ UnifiedPreview.defaultProps = {
360
485
  lastModified: null,
361
486
  updatedByName: null,
362
487
  showHeader: true, // Default to true for Test and Preview flow
488
+ smsFallbackContent: null,
489
+ smsFallbackResolvedText: undefined,
490
+ activePreviewTab: PREVIEW_TAB_RCS,
491
+ onPreviewTabChange: () => {},
363
492
  };
364
493
 
365
494
  export default UnifiedPreview;
@@ -5,7 +5,166 @@
5
5
  */
6
6
  @import '~@capillarytech/cap-ui-library/styles/_variables.scss';
7
7
 
8
+ /* All ant overrides scoped under wrapper to avoid affecting other modals. */
9
+ .common-test-preview-modal-wrap {
10
+ z-index: 10000 !important;
11
+ }
12
+
13
+ /* Lookup spinner overlay above test-customers dropdown. */
14
+ .common-test-preview-lookup-spin {
15
+ position: relative;
16
+ z-index: 1000;
17
+
18
+ .ant-spin-container::after {
19
+ z-index: 1;
20
+ }
21
+ }
22
+
23
+ /* When customer lookup is loading, dropdown renders inside .send-test-section; lower it so spinner is on top. */
24
+ .common-test-preview-customer-loading .test-customers-tree-select-dropdown {
25
+ z-index: 0 !important;
26
+ }
27
+
28
+ /* Customer creation modal content – avoid inline styles */
29
+ .common-test-preview-modal {
30
+ color: $CAP_G01 !important;
31
+ .ant-modal-content {
32
+ width: 28.5rem; /* 456px at 16px root */
33
+ }
34
+ .ant-modal-footer {
35
+ text-align: left;
36
+ margin-left: 0.625rem; /* 10px at 16px root */
37
+ margin-top: 0.9375rem; /* 15px at 16px root */
38
+ }
39
+
40
+ .customer-creation-modal-row {
41
+ margin-bottom: $CAP_SPACE_16;
42
+
43
+ &--last {
44
+ margin-bottom: $CAP_SPACE_24;
45
+ }
46
+ }
47
+
48
+ .customer-creation-modal-description {
49
+ color: $CAP_G01;
50
+ font-size: $FONT_SIZE_M;
51
+ }
52
+
53
+ .customer-creation-modal-label {
54
+ margin-bottom: $CAP_SPACE_04;
55
+ display: block;
56
+ font-size: $FONT_SIZE_M;
57
+ font-weight: bold;
58
+ color: $CAP_G01;
59
+ }
60
+
61
+ .customer-creation-modal-optional {
62
+ color: $CAP_G06;
63
+ font-weight: normal;
64
+ }
65
+
66
+ .customer-creation-modal-input {
67
+ width: 100%;
68
+ color: $CAP_G01;
69
+
70
+ &.has-error {
71
+ color: $CAP_COLOR_03 !important;
72
+ .ant-input {
73
+ border-color: $CAP_COLOR_03 !important;
74
+ }
75
+ }
76
+ }
77
+
78
+ .customer-creation-modal-validation-error {
79
+ color: $CAP_COLOR_03;
80
+ font-size: $FONT_SIZE_S;
81
+ margin-top: $CAP_SPACE_04;
82
+ }
83
+
84
+ /* Existing customer modal content */
85
+ .existing-customer-modal {
86
+ &-intro-row {
87
+ margin-bottom: $CAP_SPACE_16;
88
+ }
89
+
90
+ .ant-card-body {
91
+ padding: 1rem;
92
+ }
93
+
94
+ &-card {
95
+ border-radius: $CAP_SPACE_08;
96
+ border: $CAP_SPACE_01 solid $CAP_G06;
97
+ padding: 0;
98
+ }
99
+
100
+ &-card-row {
101
+ display: flex;
102
+ align-items: flex-start;
103
+ padding: 0;
104
+ }
105
+
106
+ &-avatar {
107
+ width: 3rem; /* 48px at 16px root */
108
+ height: 3rem;
109
+ border-radius: 1.25rem; /* 20px at 16px root */
110
+ background-color: $CAP_G07;
111
+ display: flex;
112
+ align-items: center;
113
+ justify-content: center;
114
+ margin-top: $CAP_SPACE_04;
115
+ margin-right: $CAP_SPACE_16;
116
+ flex-shrink: 0;
117
+ }
118
+
119
+ &-avatar-icon {
120
+ font-size: $CAP_SPACE_24;
121
+ color: $CAP_G01;
122
+ }
123
+
124
+ &-details {
125
+ flex: 1;
126
+ }
127
+
128
+ &-name {
129
+ font-size: $FONT_SIZE_L;
130
+ font-weight: 500;
131
+ color: $CAP_G01;
132
+ margin-bottom: $CAP_SPACE_04;
133
+ }
134
+
135
+ &-meta {
136
+ font-size: $FONT_SIZE_M;
137
+ color: $CAP_G01;
138
+ line-height: 1.4;
139
+ }
140
+
141
+ &-meta-label {
142
+ color: $CAP_G04;
143
+ }
144
+ }
145
+ }
146
+
147
+
148
+ .add-test-customer-icon {
149
+ margin-top: 0.3rem;
150
+ margin-right: 0.5rem;
151
+ }
152
+
153
+ /* CapSlideBox defaults to z-index 100; RCS SMS fallback slidebox + tag popovers use 10010–10020 — must stack above or close control is not clickable. */
154
+ .cap-slide-box-v2.common-test-and-preview-slidebox {
155
+ z-index: 10030;
156
+ }
157
+
8
158
  .common-test-and-preview-slidebox {
159
+ .common-test-preview-modal-wrap {
160
+ z-index: 10003;
161
+ }
162
+
163
+ .ant-modal-mask,
164
+ .ant-modal-wrap {
165
+ z-index: 10003;
166
+ }
167
+
9
168
  .test-preview-header {
10
169
  display: flex;
11
170
  align-items: center;
@@ -265,6 +424,13 @@
265
424
  }
266
425
  }
267
426
 
427
+ .tags-section-title {
428
+ margin: $CAP_SPACE_12 0;
429
+ display: block;
430
+ color: $CAP_G01;
431
+ font-weight: $FONT_WEIGHT_MEDIUM;
432
+ }
433
+
268
434
  .values-table {
269
435
  margin-bottom: $CAP_SPACE_16;
270
436
  border: $CAP_SPACE_01 solid $CAP_G12;
@@ -363,14 +529,25 @@
363
529
  .ant-collapse-content-box {
364
530
  padding-left: 0 !important;
365
531
  }
532
+ .send-test-content {
533
+ flex-direction: column;
534
+ align-items: stretch;
535
+ gap: 0;
536
+ }
366
537
  .test-customers-tree-select {
367
538
  width: 100%;
368
- height: $CAP_SPACE_40;
369
- margin: $CAP_SPACE_12 0;
370
- .ant-select-selection {
371
- height: inherit;
539
+ min-height: $CAP_SPACE_40;
540
+ margin: $CAP_SPACE_12 0 $CAP_SPACE_08;
541
+ .ant-select-selection,
542
+ .ant-select-selector {
543
+ min-height: $CAP_SPACE_40;
544
+ height: auto !important;
372
545
  }
373
546
  }
547
+ .send-test-content .ant-btn {
548
+ margin-top: $CAP_SPACE_04;
549
+ flex-shrink: 0;
550
+ }
374
551
  .ant-select-selection__choice {
375
552
  background-color: $CAP_G08;
376
553
  border-radius: $CAP_SPACE_04;
@@ -378,6 +555,35 @@
378
555
  }
379
556
  }
380
557
 
558
+ // Test customers TreeSelect dropdown: limit height and make scrollable (dropdown renders in portal)
559
+ .test-customers-tree-select-dropdown {
560
+ max-height: 20rem !important; /* 320px */
561
+ overflow-y: auto !important;
562
+ .ant-select-tree-list-holder-inner {
563
+ overflow: visible;
564
+ }
565
+ }
566
+
567
+ .test-customer-add-btn {
568
+ width: 100%;
569
+ background-color: transparent !important;
570
+ color: $FONT_COLOR_05 !important;
571
+ white-space: normal;
572
+ word-break: normal;
573
+ overflow-wrap: break-word;
574
+ height: auto;
575
+
576
+ /* Truncate long email/phone in label so it doesn't break mid-string */
577
+ .test-customer-add-btn-value {
578
+ display: inline-block;
579
+ max-width: 12rem;
580
+ overflow: hidden;
581
+ text-overflow: ellipsis;
582
+ white-space: nowrap;
583
+ vertical-align: bottom;
584
+ }
585
+ }
586
+
381
587
  // Responsive design for smaller screens
382
588
  @media (max-width: 54.857rem) {
383
589
  .common-test-and-preview-slidebox {
@@ -18,6 +18,8 @@ import {
18
18
  GET_PREFILLED_VALUES_REQUESTED,
19
19
  CLEAR_PREFILLED_VALUES,
20
20
  CLEAR_PREVIEW_ERRORS,
21
+ GET_SENDER_DETAILS_REQUESTED,
22
+ GET_WECRM_ACCOUNTS_REQUESTED,
21
23
  } from './constants';
22
24
 
23
25
  // ============================================
@@ -125,3 +127,21 @@ export const clearPrefilledValues = () => ({
125
127
  export const clearPreviewErrors = () => ({
126
128
  type: CLEAR_PREVIEW_ERRORS,
127
129
  });
130
+
131
+ /**
132
+ * Request sender details for a channel (SMS, EMAIL, WHATSAPP) for delivery settings
133
+ * @param {Object} payload - { channel, orgUnitId }
134
+ */
135
+ export const getSenderDetailsRequested = (payload) => ({
136
+ type: GET_SENDER_DETAILS_REQUESTED,
137
+ payload,
138
+ });
139
+
140
+ /**
141
+ * Request WeCRM accounts (e.g. for WhatsApp account dropdown)
142
+ * @param {Object} payload - { sourceName } e.g. { sourceName: 'WHATSAPP' }
143
+ */
144
+ export const getWeCrmAccountsRequested = (payload) => ({
145
+ type: GET_WECRM_ACCOUNTS_REQUESTED,
146
+ payload,
147
+ });
@@ -55,6 +55,16 @@ export const CLEAR_SEARCH_RESULTS = 'app/CommonTestAndPreview/CLEAR_SEARCH_RESUL
55
55
  export const CLEAR_PREFILLED_VALUES = 'app/CommonTestAndPreview/CLEAR_PREFILLED_VALUES';
56
56
  export const CLEAR_PREVIEW_ERRORS = 'app/CommonTestAndPreview/CLEAR_PREVIEW_ERRORS';
57
57
 
58
+ // Get Sender Details (delivery settings for Test and Preview)
59
+ export const GET_SENDER_DETAILS_REQUESTED = 'app/CommonTestAndPreview/GET_SENDER_DETAILS_REQUESTED';
60
+ export const GET_SENDER_DETAILS_SUCCESS = 'app/CommonTestAndPreview/GET_SENDER_DETAILS_SUCCESS';
61
+ export const GET_SENDER_DETAILS_FAILURE = 'app/CommonTestAndPreview/GET_SENDER_DETAILS_FAILURE';
62
+
63
+ // Get WeCRM Accounts (WhatsApp account list)
64
+ export const GET_WECRM_ACCOUNTS_REQUESTED = 'app/CommonTestAndPreview/GET_WECRM_ACCOUNTS_REQUESTED';
65
+ export const GET_WECRM_ACCOUNTS_SUCCESS = 'app/CommonTestAndPreview/GET_WECRM_ACCOUNTS_SUCCESS';
66
+ export const GET_WECRM_ACCOUNTS_FAILURE = 'app/CommonTestAndPreview/GET_WECRM_ACCOUNTS_FAILURE';
67
+
58
68
  // ============================================
59
69
  // CHANNEL CONSTANTS
60
70
  // ============================================
@@ -69,6 +79,44 @@ export const CHANNELS = {
69
79
  ZALO: 'ZALO',
70
80
  };
71
81
 
82
+ /** Unified preview tab keys when RCS shows RCS + SMS fallback panes. */
83
+ export const PREVIEW_TAB_RCS = 'rcs';
84
+ export const PREVIEW_TAB_SMS_FALLBACK = 'smsFallback';
85
+ export const PREVIEW_TAB_KEYS = [PREVIEW_TAB_RCS, PREVIEW_TAB_SMS_FALLBACK];
86
+
87
+ /** Channels whose Test & Preview defaults to Android/iOS device frame (not desktop). */
88
+ export const CHANNELS_USING_ANDROID_PREVIEW_DEVICE = [
89
+ CHANNELS.SMS,
90
+ CHANNELS.WHATSAPP,
91
+ CHANNELS.RCS,
92
+ CHANNELS.INAPP,
93
+ CHANNELS.MOBILEPUSH,
94
+ CHANNELS.VIBER,
95
+ ];
96
+
97
+ /** RCS createMessageMeta test payload — rich card envelope literals. */
98
+ export const RCS_TEST_META_CONTENT_TYPE_RICHCARD = 'RICHCARD';
99
+ export const RCS_TEST_META_CARD_TYPE_STANDALONE = 'STANDALONE';
100
+ export const RCS_TEST_META_CARD_ORIENTATION_VERTICAL = 'VERTICAL';
101
+ export const RCS_TEST_META_CARD_WIDTH_SMALL = 'SMALL';
102
+
103
+ /** React key fallback when a custom-values section has no `key` or title id. */
104
+ export const CUSTOM_VALUES_EDITOR_SECTION_FALLBACK_KEY = 'section';
105
+
106
+ /**
107
+ * Matches at least one `{{variableName}}` token in SMS / RCS fallback template text.
108
+ */
109
+ export const SMS_MUSTACHE_TAG_PATTERN = /\{\{[^}]+\}\}/;
110
+
111
+ /** TRAI DLT `{#…#}` placeholders (same idea as `COMBINED_SMS_TEMPLATE_VAR_REGEX` in unified constants). */
112
+ export const SMS_DLT_HASH_TAG_PATTERN = /\{\#[^#]*\#\}/;
113
+
114
+ /**
115
+ * Key on `smsFallbackContent` passed into Test & Preview — RCS slot map from SmsTraiEdit
116
+ * (`onRcsFallbackEditorStateChange`), merged before tag extraction like the embedded SMS editor.
117
+ */
118
+ export const RCS_SMS_FALLBACK_VAR_MAPPED_PROP = 'rcsSmsFallbackVarMapped';
119
+
72
120
  // ============================================
73
121
  // DEVICE CONSTANTS
74
122
  // ============================================
@@ -94,7 +142,10 @@ export const API_CHANNEL_PUSH = 'PUSH';
94
142
  // IDENTIFIER TYPE CONSTANTS
95
143
  // ============================================
96
144
  export const IDENTIFIER_TYPE_MOBILE = 'mobile';
97
- export const IDENTIFIER_TYPE_EMAIL = 'email';
145
+ export const IDENTIFIER_TYPE_PHONE = 'phone';
146
+
147
+ // Customer creation modal – input error state class suffix (used with customer-creation-modal-input)
148
+ export const INPUT_HAS_ERROR_CLASS = ' has-error';
98
149
 
99
150
  // ============================================
100
151
  // CHANNEL NAME CONSTANTS (for CDN and other utilities)
@@ -169,6 +220,11 @@ export const UNSUBSCRIBE_TAG_NAME = 'unsubscribe';
169
220
  export const IN_APP_CHANNEL_NAME = 'in-app';
170
221
  export const MOBILE_PUSH_CHANNEL_NAME = 'mobile push';
171
222
  export const CHANNEL = 'channel';
223
+ export const PHONE_NUMBER = 'PHONE_NUMBER';
224
+ export const DYNAMIC_URL = 'DYNAMIC_URL';
225
+ export const IMAGE = 'IMAGE';
226
+ export const VIDEO = 'VIDEO';
227
+ export const URL = 'URL';
172
228
 
173
229
  // Initial Payload Template (for reference)
174
230
  export const INITIAL_PAYLOAD = {