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
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
3
3
  import styled from 'styled-components';
4
4
  import get from 'lodash/get';
5
5
  import isEmpty from 'lodash/isEmpty';
6
+ import pick from 'lodash/pick';
6
7
  import cloneDeep from 'lodash/cloneDeep';
7
8
  import TemplatesV2 from '../TemplatesV2';
8
9
  import TemplatePreview from '../../v2Components/TemplatePreview';
@@ -25,6 +26,7 @@ import Viber from '../Viber';
25
26
  import Whatsapp from '../Whatsapp';
26
27
  import InApp from '../InApp';
27
28
  import Rcs from '../Rcs';
29
+ import { isRcsTextOnlyCardMediaType, resolveRcsCardPreviewStrings } from '../Rcs/utils';
28
30
  import { getWhatsappContent } from '../Whatsapp/utils';
29
31
  import * as commonUtil from '../../utils/common';
30
32
  import Zalo from '../Zalo';
@@ -168,14 +170,20 @@ export function SlideBoxContent(props) {
168
170
  creativesMode,
169
171
  hostName = '',
170
172
  eventContextTags,
173
+ waitEventContextTags,
171
174
  isLoyaltyModule,
172
175
  loyaltyMetaData = {},
173
176
  showTestAndPreviewSlidebox,
174
177
  handleTestAndPreview,
175
178
  handleCloseTestAndPreview,
179
+ restrictPersonalization = false,
180
+ isAnonymousType = false,
181
+ onPersonalizationTokensChange,
176
182
  isTestAndPreviewMode,
177
183
  onHtmlEditorValidationStateChange,
178
184
  } = props;
185
+ const localTemplatesConfig = props.localTemplatesConfig || pick(props, constants.LOCAL_TEMPLATE_CONFIG_KEYS);
186
+ const useLocalTemplates = !!get(localTemplatesConfig, 'useLocalTemplates');
179
187
  const type = (messageDetails.type || '').toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
180
188
  const query = { type: !isFullMode && 'embedded', module: isFullMode ? 'default' : 'library', isEditFromCampaigns: (templateData || {}).isEditFromCampaigns};
181
189
  const creativesLocationProps = {
@@ -395,12 +403,37 @@ export function SlideBoxContent(props) {
395
403
  }
396
404
  case constants.RCS: {
397
405
  const template = cloneDeep(templateDataObject);
398
- const { description = "", media: { mediaUrl = "" } = {}, title = "", suggestions = [] } = get(template, 'versions.base.content.RCS.rcsContent.cardContent[0]', {});
406
+ const cardPath = 'versions.base.content.RCS.rcsContent.cardContent[0]';
407
+ const card = get(template, cardPath, {}) || {};
408
+ const {
409
+ description = '',
410
+ media: { mediaUrl = '' } = {},
411
+ title = '',
412
+ mediaType: cardMediaType,
413
+ suggestions = [],
414
+ cardVarMapped: nestedCardVarMapped,
415
+ } = card;
416
+ const rootMirror = templateDataObject?.rcsCardVarMapped;
417
+ const nestedRecord =
418
+ nestedCardVarMapped != null && typeof nestedCardVarMapped === 'object'
419
+ ? nestedCardVarMapped
420
+ : {};
421
+ const rootRecord =
422
+ rootMirror != null && typeof rootMirror === 'object' ? rootMirror : {};
423
+ const mergedCardVarMapped = { ...rootRecord, ...nestedRecord };
424
+ const textOnlyCard = isRcsTextOnlyCardMediaType(cardMediaType);
425
+ const { rcsTitle, rcsDesc } = resolveRcsCardPreviewStrings(
426
+ title,
427
+ description,
428
+ mergedCardVarMapped,
429
+ !isFullMode,
430
+ textOnlyCard,
431
+ );
399
432
  return {
400
433
  rcsPreviewContent: {
401
434
  rcsImageSrc: mediaUrl,
402
- rcsTitle: title,
403
- rcsDesc: description,
435
+ rcsTitle,
436
+ rcsDesc,
404
437
  ...(suggestions.length > 0 && {
405
438
  buttonText: suggestions[0]?.text,
406
439
  }),
@@ -421,11 +454,12 @@ export function SlideBoxContent(props) {
421
454
  selectedOfferDetails,
422
455
  getFormData,
423
456
  eventContextTags,
457
+ waitEventContextTags,
424
458
  };
425
459
 
426
460
  return (
427
461
  <CreativesWrapper>
428
- {!isFullMode && slidBoxContent === 'templates' && (
462
+ {slidBoxContent === 'templates' && (!isFullMode || useLocalTemplates) && (
429
463
  <TemplatesV2
430
464
  isFullMode={isFullMode}
431
465
  onSelectTemplate={onSelectTemplate}
@@ -455,8 +489,10 @@ export function SlideBoxContent(props) {
455
489
  enableNewChannels={enableNewChannels}
456
490
  hideTestAndPreviewBtn={hideTestAndPreviewBtn}
457
491
  eventContextTags={eventContextTags}
492
+ waitEventContextTags={waitEventContextTags}
458
493
  loyaltyMetaData={loyaltyMetaData}
459
494
  isLoyaltyModule={isLoyaltyModule}
495
+ localTemplatesConfig={localTemplatesConfig}
460
496
  />
461
497
  )}
462
498
  {isPreview && (
@@ -558,11 +594,13 @@ export function SlideBoxContent(props) {
558
594
  onCreateComplete={onCreateComplete}
559
595
  smsRegister={smsRegister}
560
596
  eventContextTags={eventContextTags}
597
+ waitEventContextTags={waitEventContextTags}
561
598
  getLiquidTags={getLiquidTags}
562
599
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
563
600
  handleTestAndPreview={handleTestAndPreview}
564
601
  handleCloseTestAndPreview={handleCloseTestAndPreview}
565
602
  isTestAndPreviewMode={isTestAndPreviewMode}
603
+ onValidationFail={onValidationFail}
566
604
  />
567
605
  )}
568
606
  {isEditFTP && (
@@ -600,6 +638,7 @@ export function SlideBoxContent(props) {
600
638
  }}
601
639
  hostName={hostName}
602
640
  eventContextTags={eventContextTags}
641
+ waitEventContextTags={waitEventContextTags}
603
642
  showLiquidErrorInFooter={showLiquidErrorInFooter}
604
643
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
605
644
  handleTestAndPreview={handleTestAndPreview}
@@ -624,11 +663,13 @@ export function SlideBoxContent(props) {
624
663
  route={{ name: 'sms' }}
625
664
  isCreateSms={isCreateSms}
626
665
  isComponent
666
+ templateData={templateData}
627
667
  isGetFormData={isGetFormData}
628
668
  getFormSubscriptionData={getFormData}
629
669
  getLiquidTags={getLiquidTags}
630
670
  getDefaultTags={type}
631
671
  isFullMode={isFullMode}
672
+ onValidationFail={onValidationFail}
632
673
  forwardedTags={forwardedTags}
633
674
  selectedOfferDetails={selectedOfferDetails}
634
675
  onPreviewContentClicked={onPreviewContentClicked}
@@ -637,6 +678,9 @@ export function SlideBoxContent(props) {
637
678
  smsRegister={smsRegister}
638
679
  onShowTemplates={onShowTemplates}
639
680
  eventContextTags={eventContextTags}
681
+ restrictPersonalization={restrictPersonalization}
682
+ isAnonymousType={isAnonymousType}
683
+ waitEventContextTags={waitEventContextTags}
640
684
  />
641
685
  )}
642
686
 
@@ -670,6 +714,7 @@ export function SlideBoxContent(props) {
670
714
  moduleType={moduleType}
671
715
  showLiquidErrorInFooter={showLiquidErrorInFooter}
672
716
  eventContextTags={eventContextTags}
717
+ waitEventContextTags={waitEventContextTags}
673
718
  isLoyaltyModule={isLoyaltyModule}
674
719
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
675
720
  handleTestAndPreview={handleTestAndPreview}
@@ -677,13 +722,16 @@ export function SlideBoxContent(props) {
677
722
  isTestAndPreviewMode={isTestAndPreviewMode}
678
723
  location={location}
679
724
  onHtmlEditorValidationStateChange={onHtmlEditorValidationStateChange}
725
+ restrictPersonalization={restrictPersonalization}
726
+ isAnonymousType={isAnonymousType}
680
727
  />
681
728
  )}
682
729
  {(isEditEmailWithId || isEmailEditWithContent) && (
683
730
  (() => {
684
731
  const supportCKEditor = commonUtil.hasSupportCKEditor();
685
- // When supportCKEditor is true: Always use Email component (legacy flow)
686
- if (supportCKEditor || templateData?.is_drag_drop) {
732
+ // When supportCKEditor is true: Use Email component (legacy flow with CKEditor).
733
+ // When supportCKEditor is false: Always use EmailWrapper (BEE or HTML editor, never CKEditor).
734
+ if (supportCKEditor) {
687
735
  return (
688
736
  <Email
689
737
  key="cretives-container-email-edit"
@@ -711,6 +759,7 @@ export function SlideBoxContent(props) {
711
759
  moduleType={moduleType}
712
760
  showLiquidErrorInFooter={showLiquidErrorInFooter}
713
761
  eventContextTags={eventContextTags}
762
+ waitEventContextTags={waitEventContextTags}
714
763
  isLoyaltyModule={isLoyaltyModule}
715
764
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
716
765
  handleTestAndPreview={handleTestAndPreview}
@@ -750,6 +799,7 @@ export function SlideBoxContent(props) {
750
799
  moduleType={moduleType}
751
800
  showLiquidErrorInFooter={showLiquidErrorInFooter}
752
801
  eventContextTags={eventContextTags}
802
+ waitEventContextTags={waitEventContextTags}
753
803
  isLoyaltyModule={isLoyaltyModule}
754
804
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
755
805
  handleTestAndPreview={handleTestAndPreview}
@@ -772,6 +822,7 @@ export function SlideBoxContent(props) {
772
822
  <MobliPushEdit
773
823
  getFormLibraryData={getFormData}
774
824
  setIsLoadingContent={setIsLoadingContent}
825
+ getLiquidTags={getLiquidTags}
775
826
  location={{
776
827
  pathname: `/mobilepush/edit/`,
777
828
  query,
@@ -792,10 +843,14 @@ export function SlideBoxContent(props) {
792
843
  hideTestAndPreviewBtn={hideTestAndPreviewBtn}
793
844
  creativesMode={creativesMode}
794
845
  eventContextTags={eventContextTags}
846
+ waitEventContextTags={waitEventContextTags}
795
847
  showLiquidErrorInFooter={showLiquidErrorInFooter}
796
848
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
797
849
  handleTestAndPreview={handleTestAndPreview}
798
850
  handleCloseTestAndPreview={handleCloseTestAndPreview}
851
+ restrictPersonalization={restrictPersonalization}
852
+ isAnonymousType={isAnonymousType}
853
+ onPersonalizationTokensChange={onPersonalizationTokensChange}
799
854
  />
800
855
  ) : (
801
856
  <MobilePushNew
@@ -821,8 +876,12 @@ export function SlideBoxContent(props) {
821
876
  hideTestAndPreviewBtn={hideTestAndPreviewBtn}
822
877
  creativesMode={creativesMode}
823
878
  eventContextTags={eventContextTags}
879
+ waitEventContextTags={waitEventContextTags}
824
880
  showLiquidErrorInFooter={showLiquidErrorInFooter}
825
881
  handleClose={handleClose}
882
+ restrictPersonalization={restrictPersonalization}
883
+ isAnonymousType={isAnonymousType}
884
+ onPersonalizationTokensChange={onPersonalizationTokensChange}
826
885
  />
827
886
  )
828
887
  )}
@@ -838,6 +897,7 @@ export function SlideBoxContent(props) {
838
897
  mobilePushCreateMode={mobilePushCreateMode}
839
898
  isGetFormData={isGetFormData}
840
899
  getFormData={getFormData}
900
+ getLiquidTags={getLiquidTags}
841
901
  templateData={templateData}
842
902
  type={type}
843
903
  step={templateStep}
@@ -856,14 +916,18 @@ export function SlideBoxContent(props) {
856
916
  hideTestAndPreviewBtn={hideTestAndPreviewBtn}
857
917
  onTestContentClicked={onTestContentClicked}
858
918
  eventContextTags={eventContextTags}
919
+ waitEventContextTags={waitEventContextTags}
859
920
  showLiquidErrorInFooter={showLiquidErrorInFooter}
860
921
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
861
922
  handleTestAndPreview={handleTestAndPreview}
862
923
  handleCloseTestAndPreview={handleCloseTestAndPreview}
924
+ restrictPersonalization={restrictPersonalization}
925
+ isAnonymousType={isAnonymousType}
926
+ onPersonalizationTokensChange={onPersonalizationTokensChange}
863
927
  />
864
928
  ) : (
865
929
  <MobilePushNew
866
- key="creatives-mobilepush-wrapper"
930
+ key="creatives-mobilepush-create-new"
867
931
  date={new Date().getMilliseconds()}
868
932
  setIsLoadingContent={setIsLoadingContent}
869
933
  onMobilepushModeChange={onMobilepushModeChange}
@@ -891,9 +955,12 @@ export function SlideBoxContent(props) {
891
955
  hideTestAndPreviewBtn={hideTestAndPreviewBtn}
892
956
  onTestContentClicked={onTestContentClicked}
893
957
  eventContextTags={eventContextTags}
958
+ waitEventContextTags={waitEventContextTags}
894
959
  showLiquidErrorInFooter={showLiquidErrorInFooter}
895
960
  onCreateComplete={onCreateComplete}
896
961
  creativesMode={creativesMode}
962
+ restrictPersonalization={restrictPersonalization}
963
+ isAnonymousType={isAnonymousType}
897
964
  />
898
965
  )
899
966
  )}
@@ -914,6 +981,7 @@ export function SlideBoxContent(props) {
914
981
  onSelectTemplate={onSelectTemplate}
915
982
  orgUnitId={orgUnitId}
916
983
  eventContextTags={eventContextTags}
984
+ waitEventContextTags={waitEventContextTags}
917
985
  showLiquidErrorInFooter={showLiquidErrorInFooter}
918
986
  />
919
987
  )
@@ -935,6 +1003,7 @@ export function SlideBoxContent(props) {
935
1003
  fbAdManager={fbAdManager}
936
1004
  onSelectTemplate={onSelectTemplate}
937
1005
  eventContextTags={eventContextTags}
1006
+ waitEventContextTags={waitEventContextTags}
938
1007
  showLiquidErrorInFooter={showLiquidErrorInFooter}
939
1008
  />
940
1009
  )
@@ -958,6 +1027,7 @@ export function SlideBoxContent(props) {
958
1027
  handleClose={handleClose}
959
1028
  selectedOfferDetails={selectedOfferDetails}
960
1029
  eventContextTags={eventContextTags}
1030
+ waitEventContextTags={waitEventContextTags}
961
1031
  showLiquidErrorInFooter={showLiquidErrorInFooter}
962
1032
  />
963
1033
  )
@@ -978,6 +1048,7 @@ export function SlideBoxContent(props) {
978
1048
  handleClose={handleClose}
979
1049
  selectedOfferDetails={selectedOfferDetails}
980
1050
  eventContextTags={eventContextTags}
1051
+ waitEventContextTags={waitEventContextTags}
981
1052
  showLiquidErrorInFooter={showLiquidErrorInFooter}
982
1053
  />
983
1054
  )
@@ -994,6 +1065,7 @@ export function SlideBoxContent(props) {
994
1065
  templateData={templateData}
995
1066
  selectedOfferDetails={selectedOfferDetails}
996
1067
  eventContextTags={eventContextTags}
1068
+ waitEventContextTags={waitEventContextTags}
997
1069
  showLiquidErrorInFooter={showLiquidErrorInFooter}
998
1070
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
999
1071
  handleTestAndPreview={handleTestAndPreview}
@@ -1018,6 +1090,7 @@ export function SlideBoxContent(props) {
1018
1090
  handleTestAndPreview={handleTestAndPreview}
1019
1091
  handleCloseTestAndPreview={handleCloseTestAndPreview}
1020
1092
  eventContextTags={eventContextTags}
1093
+ waitEventContextTags={waitEventContextTags}
1021
1094
  showLiquidErrorInFooter={showLiquidErrorInFooter}
1022
1095
  createNew/> }
1023
1096
 
@@ -1025,6 +1098,7 @@ export function SlideBoxContent(props) {
1025
1098
  isFullMode={isFullMode}
1026
1099
  onCreateComplete={onCreateComplete}
1027
1100
  eventContextTags={eventContextTags}
1101
+ waitEventContextTags={waitEventContextTags}
1028
1102
  handleClose={handleClose}
1029
1103
  showLiquidErrorInFooter={showLiquidErrorInFooter}
1030
1104
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
@@ -1042,6 +1116,7 @@ export function SlideBoxContent(props) {
1042
1116
  forwardedTags={forwardedTags}
1043
1117
  selectedOfferDetails={selectedOfferDetails}
1044
1118
  eventContextTags={eventContextTags}
1119
+ waitEventContextTags={waitEventContextTags}
1045
1120
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
1046
1121
  handleTestAndPreview={handleTestAndPreview}
1047
1122
  handleCloseTestAndPreview={handleCloseTestAndPreview}
@@ -1059,8 +1134,39 @@ export function SlideBoxContent(props) {
1059
1134
  )}
1060
1135
 
1061
1136
  {isCreateInApp && (
1062
- <InAppWrapper
1063
- key="creatives-inapp-wrapper"
1137
+ (isFullMode && !commonUtil.hasNewEditorFlowInAppEnabled()) ||
1138
+ (!isFullMode && isLoyaltyModule) ||
1139
+ (!isFullMode && !isLoyaltyModule && !commonUtil.hasNewEditorFlowInAppEnabled()) ? (
1140
+ <InApp
1141
+ key="creatives-inapp-create"
1142
+ location={{ pathname: '/inapp/create', query, search: '' }}
1143
+ setIsLoadingContent={setIsLoadingContent}
1144
+ isGetFormData={isGetFormData}
1145
+ getFormData={getFormData}
1146
+ getDefaultTags={type}
1147
+ isFullMode={isFullMode}
1148
+ templateData={templateData}
1149
+ cap={cap}
1150
+ showTemplateName={showTemplateName}
1151
+ showLiquidErrorInFooter={showLiquidErrorInFooter}
1152
+ onValidationFail={onValidationFail}
1153
+ forwardedTags={forwardedTags}
1154
+ selectedOfferDetails={selectedOfferDetails}
1155
+ onPreviewContentClicked={onPreviewContentClicked}
1156
+ onTestContentClicked={onTestContentClicked}
1157
+ eventContextTags={eventContextTags}
1158
+ waitEventContextTags={waitEventContextTags}
1159
+ onCreateComplete={onCreateComplete}
1160
+ handleClose={handleClose}
1161
+ moduleType={moduleType}
1162
+ showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
1163
+ handleTestAndPreview={handleTestAndPreview}
1164
+ handleCloseTestAndPreview={handleCloseTestAndPreview}
1165
+ isTestAndPreviewMode={isTestAndPreviewMode}
1166
+ />
1167
+ ) : (
1168
+ <InAppWrapper
1169
+ key="creatives-inapp-wrapper"
1064
1170
  date={new Date().getMilliseconds()}
1065
1171
  setIsLoadingContent={setIsLoadingContent}
1066
1172
  onInAppEditorTypeChange={onInAppEditorTypeChange}
@@ -1085,6 +1191,7 @@ export function SlideBoxContent(props) {
1085
1191
  moduleType={moduleType}
1086
1192
  showLiquidErrorInFooter={showLiquidErrorInFooter}
1087
1193
  eventContextTags={eventContextTags}
1194
+ waitEventContextTags={waitEventContextTags}
1088
1195
  onCreateComplete={onCreateComplete}
1089
1196
  handleClose={handleClose}
1090
1197
  getDefaultTags={type}
@@ -1095,10 +1202,12 @@ export function SlideBoxContent(props) {
1095
1202
  handleCloseTestAndPreview={handleCloseTestAndPreview}
1096
1203
  isTestAndPreviewMode={isTestAndPreviewMode}
1097
1204
  />
1205
+ )
1098
1206
  )}
1099
-
1207
+
1100
1208
  {isEditInApp && (<InApp
1101
1209
  isFullMode={isFullMode}
1210
+ isLoyaltyModule={isLoyaltyModule}
1102
1211
  templateData={templateData}
1103
1212
  getFormData={getFormData}
1104
1213
  getDefaultTags={type}
@@ -1106,6 +1215,7 @@ export function SlideBoxContent(props) {
1106
1215
  onCreateComplete={onCreateComplete}
1107
1216
  selectedOfferDetails={selectedOfferDetails}
1108
1217
  eventContextTags={eventContextTags}
1218
+ waitEventContextTags={waitEventContextTags}
1109
1219
  params={{
1110
1220
  id: templateData._id,
1111
1221
  }}
@@ -1142,10 +1252,14 @@ export function SlideBoxContent(props) {
1142
1252
  supportedTags={supportedTags}
1143
1253
  selectedOfferDetails={selectedOfferDetails}
1144
1254
  eventContextTags={eventContextTags}
1255
+ restrictPersonalization={restrictPersonalization}
1256
+ isAnonymousType={isAnonymousType}
1257
+ waitEventContextTags={waitEventContextTags}
1145
1258
  />
1146
1259
  )}
1147
1260
  {isCreateRcs && (<Rcs
1148
1261
  {...rcsCommonProps}
1262
+ templateData={templateData}
1149
1263
  showLiquidErrorInFooter={showLiquidErrorInFooter}
1150
1264
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
1151
1265
  handleTestAndPreview={handleTestAndPreview}
@@ -1235,6 +1349,8 @@ SlideBoxContent.propTypes = {
1235
1349
  showTestAndPreviewSlidebox: PropTypes.bool,
1236
1350
  handleTestAndPreview: PropTypes.func,
1237
1351
  handleCloseTestAndPreview: PropTypes.func,
1238
- isTestAndPreviewMode: PropTypes.bool
1352
+ isTestAndPreviewMode: PropTypes.bool,
1353
+ waitEventContextTags: PropTypes.object,
1354
+ eventContextTags: PropTypes.array,
1239
1355
  };
1240
1356
  export default SlideBoxContent;
@@ -6,15 +6,16 @@ import CapError from '@capillarytech/cap-ui-library/CapError';
6
6
  import PropTypes from 'prop-types';
7
7
  import messages from './messages';
8
8
  import ErrorInfoNote from '../../v2Components/ErrorInfoNote';
9
- import { PREVIEW } from './constants';
9
+ import { PREVIEW, EMAIL, SMS, EDIT_TEMPLATE, MOBILE_PUSH } from './constants';
10
10
  import { EMAIL_CREATE_MODES } from '../EmailWrapper/constants';
11
11
  import { hasSupportCKEditor } from '../../utils/common';
12
+ import { getMessageForDevice, getTitleForDevice } from '../../utils/commonUtils';
12
13
 
13
14
  function getFullModeSaveBtn(slidBoxContent, isCreatingTemplate) {
14
15
  if (isCreatingTemplate) {
15
16
  return <FormattedMessage {...messages.creativesTemplatesDone} />;
16
17
  }
17
- return slidBoxContent === "editTemplate"
18
+ return slidBoxContent === EDIT_TEMPLATE
18
19
  ? <FormattedMessage {...messages.creativesTemplatesUpdate} />
19
20
  : <FormattedMessage {...messages.creativesTemplatesSaveFullMode} />;
20
21
  }
@@ -43,13 +44,23 @@ function SlideBoxFooter(props) {
43
44
  currentChannel,
44
45
  emailCreateMode,
45
46
  selectedEmailCreateMode,
47
+ restrictPersonalization = false,
48
+ isAnonymousType = false,
49
+ templateData = {},
50
+ hasPersonalizationTokenError: hasPersonalizationTokenErrorProp = false,
51
+ /** When set (e.g. SMS library create), overrides `creativesTemplatesSave` (“Done”) for the primary button */
52
+ primarySaveButtonMessage,
46
53
  } = props;
47
-
48
54
  // Calculate if buttons should be disabled
49
55
  // Only apply validation state checks for EMAIL channel in HTML Editor mode (not BEE/DragDrop)
50
56
  // For other channels, BEE editor, or when htmlEditorValidationState is not provided, don't disable based on validation
51
- const isEmailChannel = currentChannel?.toUpperCase() === 'EMAIL';
52
- const isEditMode = slidBoxContent === 'editTemplate';
57
+ const isEmailChannel = currentChannel?.toUpperCase() === EMAIL;
58
+ const isSmsChannel = currentChannel?.toUpperCase() === SMS;
59
+ // Use templateData.type in library/edit so footer shows when editing a mobile push template (currentChannel may not be set to template channel)
60
+ const isMobilePushChannel =
61
+ currentChannel?.toUpperCase() === MOBILE_PUSH ||
62
+ (templateData?.type && templateData.type.toUpperCase() === MOBILE_PUSH);
63
+ const isEditMode = slidBoxContent === EDIT_TEMPLATE;
53
64
 
54
65
  // Use selectedEmailCreateMode for accurate mode detection in create mode (emailCreateMode is mapped for backwards compatibility)
55
66
  // In edit mode: htmlEditorValidationState is initialized as {} but only updated by HTML Editor
@@ -125,8 +136,36 @@ function SlideBoxFooter(props) {
125
136
  const isBEEEditorModeInCreate = !isHTMLEditorMode && !isEditMode;
126
137
  const isBEEEditorMode = isBEEEditorModeInEdit || isBEEEditorModeInCreate;
127
138
  const hasBEEEditorErrors = isEmailChannel && isBEEEditorMode && (hasStandardErrors || hasLiquidErrors) && (!htmlEditorValidationState || !htmlEditorHasErrors);
139
+ const hasSmsValidationErrors = isSmsChannel && (hasStandardErrors || hasLiquidErrors);
140
+ // Mobile Push OLD: footer only for extractTags/Aira liquid errors, not standard tag errors
141
+ const hasMobilePushValidationErrors = isMobilePushChannel && hasLiquidErrors;
142
+
143
+ const shouldShowErrorInfoNote = hasBEEEditorErrors || hasSmsValidationErrors || hasMobilePushValidationErrors || isSupportCKEditor;
144
+
145
+ // Check for personalization tokens in title/message when anonymous user tries to save
146
+ const hasPersonalizationTokens = () => {
147
+ if (!isAnonymousType || !templateData) return false;
148
+
149
+ const androidTitle = getTitleForDevice(templateData, 'ANDROID') || '';
150
+ const iosTitle = getTitleForDevice(templateData, 'IOS') || '';
151
+ const androidMessageBody = getMessageForDevice(templateData, 'ANDROID') || '';
152
+ const iosMessageBody = getMessageForDevice(templateData, 'IOS') || '';
153
+ // Check for personalization tags {{ }} in title or message body
154
+ const contentToCheck = `${androidTitle} ${iosTitle} ${androidMessageBody} ${iosMessageBody}`;
155
+ // Check for liquid tags {{ }}
156
+ if (contentToCheck.includes('{{') && contentToCheck.includes('}}')) {
157
+ return true;
158
+ }
159
+ // Check for event context tags [
160
+ if (contentToCheck.includes('[') && contentToCheck.includes(']')) {
161
+ return true;
162
+ }
163
+ return false;
164
+ };
165
+
166
+ // Use prop from parent (FormBuilder flow) when available; else fall back to templateData check
167
+ const hasPersonalizationTokenError = hasPersonalizationTokenErrorProp === true || (restrictPersonalization && hasPersonalizationTokens());
128
168
 
129
- const shouldShowErrorInfoNote = hasBEEEditorErrors || isSupportCKEditor;
130
169
  return (
131
170
  <div className="template-footer-width">
132
171
  {shouldShowErrorInfoNote && (
@@ -147,9 +186,11 @@ function SlideBoxFooter(props) {
147
186
  <CapRow>
148
187
  <CapButton
149
188
  onClick={onSave}
150
- disabled={isTemplateNameEmpty || fetchingCmsData || shouldDisableButtons}
189
+ disabled={isTemplateNameEmpty || fetchingCmsData || shouldDisableButtons || hasPersonalizationTokenError}
151
190
  >
152
- {isFullMode ? (
191
+ {primarySaveButtonMessage ? (
192
+ <FormattedMessage {...primarySaveButtonMessage} />
193
+ ) : isFullMode ? (
153
194
  getFullModeSaveBtn(slidBoxContent, isCreatingTemplate)
154
195
  ) : (
155
196
  <FormattedMessage {...messages.creativesTemplatesSave} />
@@ -159,7 +200,7 @@ function SlideBoxFooter(props) {
159
200
  <CapButton
160
201
  type="secondary"
161
202
  onClick={onTestAndPreview}
162
- disabled={shouldDisableButtons}
203
+ disabled={shouldDisableButtons || hasPersonalizationTokenError}
163
204
  style={{ marginLeft: '8px' }}
164
205
  >
165
206
  <FormattedMessage {...messages.testAndPreview} />
@@ -220,6 +261,15 @@ SlideBoxFooter.propTypes = {
220
261
  currentChannel: PropTypes.string,
221
262
  emailCreateMode: PropTypes.string,
222
263
  selectedEmailCreateMode: PropTypes.string,
264
+ restrictPersonalization: PropTypes.bool,
265
+ isAnonymousType: PropTypes.bool,
266
+ templateData: PropTypes.object,
267
+ formData: PropTypes.array,
268
+ hasPersonalizationTokenError: PropTypes.bool,
269
+ primarySaveButtonMessage: PropTypes.shape({
270
+ id: PropTypes.string,
271
+ defaultMessage: PropTypes.string,
272
+ }),
223
273
  };
224
274
 
225
275
  SlideBoxFooter.defaultProps = {
@@ -245,5 +295,8 @@ SlideBoxFooter.defaultProps = {
245
295
  currentChannel: '',
246
296
  emailCreateMode: '',
247
297
  selectedEmailCreateMode: '',
298
+ formData: [],
299
+ hasPersonalizationTokenError: false,
300
+ primarySaveButtonMessage: undefined,
248
301
  };
249
302
  export default SlideBoxFooter;
@@ -16,6 +16,7 @@ import { isTraiDLTEnable } from '../../utils/common';
16
16
  import { formatString } from '../../utils/Formatter';
17
17
  import {
18
18
  CAP_SPACE_12,
19
+ CAP_SPACE_16,
19
20
  } from '@capillarytech/cap-ui-library/styled/variables';
20
21
  import { WHATSAPP_HELP_DOC_LINK, JOURNEY } from './constants';
21
22
 
@@ -24,7 +25,7 @@ const StyledLabel = styled(CapLabelInline)`
24
25
  margin-right: ${CAP_SPACE_12};
25
26
  `;
26
27
  const PrefixWrapper = styled.div`
27
- margin-right: 16px;
28
+ margin-right: ${CAP_SPACE_16};
28
29
  `;
29
30
  const renderData = (type, value, channel) => (
30
31
  <StyledLabel className={channel?.toLowerCase() === ZALO ? 'zalo-template-name-spacing' : ''} type={type}>
@@ -33,7 +34,25 @@ const renderData = (type, value, channel) => (
33
34
  );
34
35
 
35
36
  export function SlideBoxHeader(props) {
36
- const { slidBoxContent, templateData, onShowTemplates, creativesMode, isFullMode, showPrefix, shouldShowTemplateName, channel, templateNameRenderProp, weChatTemplateType, onWeChatMaptemplateStepChange, weChatMaptemplateStep, templateStep, smsRegister, handleClose, moduleType } = props;
37
+ const {
38
+ slidBoxContent,
39
+ templateData,
40
+ onShowTemplates,
41
+ creativesMode,
42
+ isFullMode,
43
+ showPrefix,
44
+ shouldShowTemplateName,
45
+ channel,
46
+ templateNameRenderProp,
47
+ weChatTemplateType,
48
+ onWeChatMaptemplateStepChange,
49
+ weChatMaptemplateStep,
50
+ templateStep,
51
+ smsRegister,
52
+ handleClose,
53
+ moduleType,
54
+ useLocalTemplates = false,
55
+ } = props;
37
56
  const showTemplateNameHeader = isFullMode && shouldShowTemplateName;
38
57
  const mapTemplateCreate = !showTemplateNameHeader && slidBoxContent === 'createTemplate' && weChatTemplateType === MAP_TEMPLATE && templateStep !== 'modeSelection';
39
58
  const isTraiDlt = isTraiDLTEnable(isFullMode, smsRegister);
@@ -81,6 +100,9 @@ export function SlideBoxHeader(props) {
81
100
  window.open(WHATSAPP_HELP_DOC_LINK, '_blank');
82
101
  };
83
102
 
103
+ const showCreativesTemplatesBackButton =
104
+ !isFullMode && (moduleType === JOURNEY || useLocalTemplates);
105
+
84
106
  return (
85
107
  <div key="creatives-container-slidebox-header-content">
86
108
  {slidBoxContent === 'templates' && !showTemplateNameHeader && (
@@ -89,7 +111,7 @@ export function SlideBoxHeader(props) {
89
111
  description={![NO_COMMUNICATION, FTP].includes(channel) &&
90
112
  <FormattedMessage {...messages.creativeTemplatesDesc} />
91
113
  }
92
- prefix={!isFullMode && moduleType === JOURNEY &&
114
+ prefix={showCreativesTemplatesBackButton &&
93
115
  <PrefixWrapper>
94
116
  <CapIcons.backIcon onClick={handleClose} />
95
117
  </PrefixWrapper>
@@ -135,7 +157,7 @@ export function SlideBoxHeader(props) {
135
157
  }
136
158
  </>
137
159
  }
138
- prefix={creativesMode !== 'edit' && !isFullMode && showPrefix &&
160
+ prefix={!isFullMode && showPrefix &&
139
161
  <PrefixWrapper>
140
162
  <CapIcons.backIcon onClick={onShowTemplates} />
141
163
  </PrefixWrapper>
@@ -191,5 +213,8 @@ SlideBoxHeader.propTypes = {
191
213
  shouldShowTemplateName: PropTypes.bool,
192
214
  templateNameRenderProp: PropTypes.func,
193
215
  smsRegister: PropTypes.any,
216
+ handleClose: PropTypes.func,
217
+ moduleType: PropTypes.string,
218
+ useLocalTemplates: PropTypes.bool,
194
219
  };
195
220
  export default SlideBoxHeader;
@@ -11,6 +11,7 @@ export const EBILL = "EBILL";
11
11
  export const LINE = "LINE";
12
12
  export const CALL_TASK = "CALL_TASK";
13
13
  export const MOBILE_PUSH = "MOBILEPUSH";
14
+ export const MPUSH = "MPUSH";
14
15
  export const WECHAT = "WECHAT";
15
16
  export const FACEBOOK = "FACEBOOK";
16
17
  export const FTP = "FTP";
@@ -52,3 +53,26 @@ export const GENERIC = "GENERIC";
52
53
  export const LIQUID_ERROR_MSG = "LIQUID_ERROR_MSG";
53
54
  export const STANDARD_ERROR_MSG = "STANDARD_ERROR_MSG";
54
55
  export const COMMON_CHANNELS = ['sms', 'email', 'wechat', 'mobilepush', 'webpush', 'line', 'viber', 'facebook', 'call_task', 'ftp', 'assets'];
56
+
57
+ /** Normalized channel forms (e.g. from camelCase) that do not match pane keys; maps to canonical pane key for hide/disable. */
58
+ export const NORMALIZED_CHANNEL_ALIASES = {
59
+ we_chat: WECHAT.toLowerCase(),
60
+ m_push: MOBILE_PUSH.toLowerCase(),
61
+ // paneKey `inApp` → `in_app`; TemplatesV2 pane uses key INAPP → `inapp` — both must match for channelsToHide
62
+ in_app: INAPP.toLowerCase(),
63
+ };
64
+ export const MIXED = "MIXED";
65
+ export const VISITOR = "VISITOR";
66
+ export const ALLOWED_CHANNELS_FOR_ANONYMOUS = ['mobilepush', 'webpush'];
67
+ export const ALL_CHANNELS_NEW = [
68
+ 'sms', 'email', 'whatsapp', 'facebook', 'line', 'viber', 'rcs', 'zalo', 'inapp', 'call_task', 'ftp',
69
+ ];
70
+
71
+ export const LOCAL_TEMPLATE_CONFIG_KEYS = ['useLocalTemplates', 'localTemplates', 'localTemplatesLoading', 'localTemplatesFilterContent', 'localTemplatesUseSkeleton', 'localTemplatesOnPageChange'];
72
+
73
+ /** Keys passed from parents into `Templates` when using local SMS template list (extends `LOCAL_TEMPLATE_CONFIG_KEYS`). */
74
+ export const LOCAL_TEMPLATE_CONFIG_KEYS_FOR_PICK = [
75
+ ...LOCAL_TEMPLATE_CONFIG_KEYS,
76
+ 'localTemplatesLoadingTip',
77
+ 'localTemplatesFooterContent',
78
+ ];