@capillarytech/creatives-library 8.0.166 → 8.0.168-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (321) hide show
  1. package/components/BreadCrumbs/index.js +65 -0
  2. package/components/BreadCrumbs/messages.js +13 -0
  3. package/components/CapTagList/index.js +235 -0
  4. package/components/CapTagList/messages.js +45 -0
  5. package/components/Card/_customCard.scss +40 -0
  6. package/components/Card/index.js +78 -0
  7. package/components/Card/tests/__snapshots__/index.test.js.snap +22 -0
  8. package/components/Card/tests/index.test.js +20 -0
  9. package/components/CardGrid/index.js +71 -0
  10. package/components/Ckeditor/index.js +238 -0
  11. package/components/Ckeditor/messages.js +13 -0
  12. package/components/Ckeditor/style.scss +3 -0
  13. package/components/Component/index.js +29 -0
  14. package/components/CustomPopOver/index.js +81 -0
  15. package/components/CustomPopOver/messages.js +17 -0
  16. package/components/DateFilter/index.js +349 -0
  17. package/components/DateFilter/messages.js +57 -0
  18. package/components/DateRange/index.js +114 -0
  19. package/components/DateRange/messages.js +25 -0
  20. package/components/Edmeditor/index.js +65 -0
  21. package/components/Edmeditor/messages.js +13 -0
  22. package/components/EmailPreview/_emailPreview.scss +119 -0
  23. package/components/EmailPreview/assets/images/iPad.svg +10 -0
  24. package/components/EmailPreview/assets/images/mobile.png +0 -0
  25. package/components/EmailPreview/index.js +107 -0
  26. package/components/EmailPreview/messages.js +33 -0
  27. package/components/Footer/index.js +27 -0
  28. package/components/Footer/messages.js +13 -0
  29. package/components/FormBuilder/_formBuilder.scss +83 -0
  30. package/components/FormBuilder/index.js +3279 -0
  31. package/components/FormBuilder/messages.js +61 -0
  32. package/components/Header/index.js +44 -0
  33. package/components/Header/messages.js +29 -0
  34. package/components/ImagePreview/_imagePreview.scss +63 -0
  35. package/components/ImagePreview/index.js +52 -0
  36. package/components/ImagePreview/messages.js +17 -0
  37. package/components/PageHeader/_pageHeader.scss +22 -0
  38. package/components/PageHeader/index.js +37 -0
  39. package/components/PageHeader/messages.js +13 -0
  40. package/components/Pagination/_pagination.scss +5 -0
  41. package/components/Pagination/index.js +49 -0
  42. package/components/PreviewSideBar/_previewsidebar.scss +28 -0
  43. package/components/PreviewSideBar/index.js +152 -0
  44. package/components/PreviewSideBar/messages.js +41 -0
  45. package/components/Sidebar/_sidebar.scss +115 -0
  46. package/components/Sidebar/index.js +214 -0
  47. package/components/Sidebar/messages.js +21 -0
  48. package/components/SlideBox/_slideBox.scss +63 -0
  49. package/components/SlideBox/index.js +47 -0
  50. package/components/SlideBox/tests/index.test.js +103 -0
  51. package/components/SmsEditor/index.js +55 -0
  52. package/components/SmsTest/index.js +117 -0
  53. package/components/SmsTest/messages.js +21 -0
  54. package/components/TemplatePreview/WechatRichmediaTemplatePreview/_wechatRichmediaTemplatePrev.scss +42 -0
  55. package/components/TemplatePreview/WechatRichmediaTemplatePreview/index.js +141 -0
  56. package/components/TemplatePreview/WechatRichmediaTemplatePreview/messages.js +21 -0
  57. package/components/TemplatePreview/_templatePreview.scss +642 -0
  58. package/components/TemplatePreview/assets/images/WECHAT_5x.png +0 -0
  59. package/components/TemplatePreview/assets/images/androidPushMessage.svg +45 -0
  60. package/components/TemplatePreview/assets/images/home-screen-android.svg +21 -0
  61. package/components/TemplatePreview/assets/images/home-screen-ios.svg +16 -0
  62. package/components/TemplatePreview/assets/images/iPhonePushMessage.svg +135 -0
  63. package/components/TemplatePreview/assets/images/mobile.svg +24 -0
  64. package/components/TemplatePreview/assets/images/sms-body.png +0 -0
  65. package/components/TemplatePreview/assets/images/sms-icon.png +0 -0
  66. package/components/TemplatePreview/assets/images/sms_mobile.png +0 -0
  67. package/components/TemplatePreview/assets/images/sms_mobile_android.svg +22 -0
  68. package/components/TemplatePreview/assets/images/sms_mobile_ios.svg +16 -0
  69. package/components/TemplatePreview/assets/images/user-icon.svg +19 -0
  70. package/components/TemplatePreview/assets/images/wechat-mobile.svg +78 -0
  71. package/components/TemplatePreview/assets/images/wechat_mobile_android.svg +20 -0
  72. package/components/TemplatePreview/index.js +617 -0
  73. package/components/TemplatePreview/messages.js +78 -0
  74. package/components/Toastr/index.js +60 -0
  75. package/components/Toastr/messages.js +13 -0
  76. package/components/ToastrMessage/index.js +113 -0
  77. package/components/ToastrMessage/messages.js +17 -0
  78. package/components/TopBar/_topbar.scss +46 -0
  79. package/components/TopBar/assets/images/capillary_logo.png +0 -0
  80. package/components/TopBar/assets/images/old_capillary_logo.png +0 -0
  81. package/components/TopBar/index.js +113 -0
  82. package/components/TopBar/messages.js +29 -0
  83. package/containers/App/actions.js +7 -0
  84. package/containers/App/constants.js +114 -0
  85. package/containers/App/index.js +52 -0
  86. package/containers/App/reducer.js +19 -0
  87. package/containers/App/sagas.js +31 -0
  88. package/containers/App/selectors.js +25 -0
  89. package/containers/App/test/saga.test.js +11 -0
  90. package/containers/Assets/Gallery/_gallery.scss +126 -0
  91. package/containers/Assets/Gallery/actions.js +37 -0
  92. package/containers/Assets/Gallery/constants.js +23 -0
  93. package/containers/Assets/Gallery/index.js +473 -0
  94. package/containers/Assets/Gallery/messages.js +93 -0
  95. package/containers/Assets/Gallery/reducer.js +81 -0
  96. package/containers/Assets/Gallery/sagas.js +80 -0
  97. package/containers/Assets/Gallery/selectors.js +25 -0
  98. package/containers/Assets/Gallery/tests/__snapshots__/reducer.test.js.snap +9 -0
  99. package/containers/Assets/Gallery/tests/actions.test.js +25 -0
  100. package/containers/Assets/Gallery/tests/reducer.test.js +96 -0
  101. package/containers/Assets/Gallery/tests/saga.test.js +157 -0
  102. package/containers/Cap/actions.js +66 -0
  103. package/containers/Cap/constants.js +25 -0
  104. package/containers/Cap/index.js +402 -0
  105. package/containers/Cap/messages.js +75 -0
  106. package/containers/Cap/reducer.js +113 -0
  107. package/containers/Cap/sagas.js +159 -0
  108. package/containers/Cap/selectors.js +75 -0
  109. package/containers/Cap/tests/__snapshots__/index.test.js.snap +2270 -0
  110. package/containers/Cap/tests/index.test.js +22 -0
  111. package/containers/Cap/tests/saga.test.js +284 -0
  112. package/containers/Dashboard/actions.js +15 -0
  113. package/containers/Dashboard/constants.js +7 -0
  114. package/containers/Dashboard/index.js +76 -0
  115. package/containers/Dashboard/messages.js +13 -0
  116. package/containers/Dashboard/reducer.js +21 -0
  117. package/containers/Dashboard/sagas.js +17 -0
  118. package/containers/Dashboard/selectors.js +25 -0
  119. package/containers/Dashboard/test/saga.test.js +9 -0
  120. package/containers/Ebill/_ebill.scss +5 -0
  121. package/containers/Ebill/actions.js +43 -0
  122. package/containers/Ebill/constants.js +20 -0
  123. package/containers/Ebill/index.js +1278 -0
  124. package/containers/Ebill/messages.js +77 -0
  125. package/containers/Ebill/reducer.js +72 -0
  126. package/containers/Ebill/sagas.js +74 -0
  127. package/containers/Ebill/selectors.js +25 -0
  128. package/containers/Ebill/test/saga.test.js +11 -0
  129. package/containers/Email/_email.scss +141 -0
  130. package/containers/Email/actions.js +81 -0
  131. package/containers/Email/constants.js +36 -0
  132. package/containers/Email/index.js +3325 -0
  133. package/containers/Email/messages.js +289 -0
  134. package/containers/Email/reducer.js +142 -0
  135. package/containers/Email/sagas.js +135 -0
  136. package/containers/Email/selectors.js +31 -0
  137. package/containers/Email/test/saga.test.js +671 -0
  138. package/containers/LanguageProvider/actions.js +17 -0
  139. package/containers/LanguageProvider/constants.js +8 -0
  140. package/containers/LanguageProvider/index.js +80 -0
  141. package/containers/LanguageProvider/reducer.js +30 -0
  142. package/containers/LanguageProvider/selectors.js +20 -0
  143. package/containers/LanguageProvider/tests/actions.test.js +19 -0
  144. package/containers/LanguageProvider/tests/index.test.js +78 -0
  145. package/containers/LanguageProvider/tests/reducer.test.js +20 -0
  146. package/containers/LanguageProvider/tests/selectors.test.js +15 -0
  147. package/containers/Line/Create/_lineCreate.scss +54 -0
  148. package/containers/Line/Create/actions.js +90 -0
  149. package/containers/Line/Create/constants.js +39 -0
  150. package/containers/Line/Create/index.js +836 -0
  151. package/containers/Line/Create/messages.js +189 -0
  152. package/containers/Line/Create/reducer.js +99 -0
  153. package/containers/Line/Create/sagas.js +121 -0
  154. package/containers/Line/Create/selectors.js +36 -0
  155. package/containers/Line/Create/tests/saga.test.js +202 -0
  156. package/containers/Line/Edit/_lineEdit.scss +35 -0
  157. package/containers/Line/Edit/actions.js +79 -0
  158. package/containers/Line/Edit/constants.js +27 -0
  159. package/containers/Line/Edit/index.js +1050 -0
  160. package/containers/Line/Edit/messages.js +177 -0
  161. package/containers/Line/Edit/reducer.js +83 -0
  162. package/containers/Line/Edit/sagas.js +80 -0
  163. package/containers/Line/Edit/selectors.js +29 -0
  164. package/containers/Line/Edit/test/saga.test.js +160 -0
  165. package/containers/Login/assets/images/capillary_logo.png +0 -0
  166. package/containers/Login/components/LoginForm/index.js +62 -0
  167. package/containers/Login/components/LoginForm/messages.js +33 -0
  168. package/containers/Login/index.js +130 -0
  169. package/containers/Login/messages.js +25 -0
  170. package/containers/Login/selectors.js +25 -0
  171. package/containers/MobilePush/Create/_mobilePushCreate.scss +39 -0
  172. package/containers/MobilePush/Create/actions.js +46 -0
  173. package/containers/MobilePush/Create/constants.js +23 -0
  174. package/containers/MobilePush/Create/index.js +2303 -0
  175. package/containers/MobilePush/Create/messages.js +269 -0
  176. package/containers/MobilePush/Create/reducer.js +70 -0
  177. package/containers/MobilePush/Create/sagas.js +74 -0
  178. package/containers/MobilePush/Create/selectors.js +28 -0
  179. package/containers/MobilePush/Create/test/saga.test.js +19 -0
  180. package/containers/MobilePush/Edit/_mobilePushCreate.scss +39 -0
  181. package/containers/MobilePush/Edit/actions.js +91 -0
  182. package/containers/MobilePush/Edit/constants.js +35 -0
  183. package/containers/MobilePush/Edit/index.js +2601 -0
  184. package/containers/MobilePush/Edit/messages.js +266 -0
  185. package/containers/MobilePush/Edit/reducer.js +112 -0
  186. package/containers/MobilePush/Edit/sagas.js +126 -0
  187. package/containers/MobilePush/Edit/selectors.js +29 -0
  188. package/containers/MobilePush/Edit/tests/saga.test.js +255 -0
  189. package/containers/NotFoundPage/index.js +25 -0
  190. package/containers/NotFoundPage/messages.js +13 -0
  191. package/containers/NotFoundPage/tests/index.test.js +17 -0
  192. package/containers/Sms/Create/_smsCreate.scss +42 -0
  193. package/containers/Sms/Create/actions.js +27 -0
  194. package/containers/Sms/Create/constants.js +16 -0
  195. package/containers/Sms/Create/index.js +1488 -0
  196. package/containers/Sms/Create/messages.js +109 -0
  197. package/containers/Sms/Create/reducer.js +41 -0
  198. package/containers/Sms/Create/sagas.js +40 -0
  199. package/containers/Sms/Create/selectors.js +28 -0
  200. package/containers/Sms/Create/test/saga.test.js +11 -0
  201. package/containers/Sms/Edit/actions.js +40 -0
  202. package/containers/Sms/Edit/constants.js +17 -0
  203. package/containers/Sms/Edit/index.js +1472 -0
  204. package/containers/Sms/Edit/messages.js +105 -0
  205. package/containers/Sms/Edit/reducer.js +50 -0
  206. package/containers/Sms/Edit/sagas.js +60 -0
  207. package/containers/Sms/Edit/selectors.js +32 -0
  208. package/containers/Sms/Edit/test/saga.test.js +13 -0
  209. package/containers/TagList/_tagList.scss +8 -0
  210. package/containers/TagList/actions.js +15 -0
  211. package/containers/TagList/constants.js +32 -0
  212. package/containers/TagList/index.js +236 -0
  213. package/containers/TagList/messages.js +13 -0
  214. package/containers/TagList/reducer.js +23 -0
  215. package/containers/TagList/sagas.js +11 -0
  216. package/containers/TagList/selectors.js +25 -0
  217. package/containers/Templates/_templates.scss +333 -0
  218. package/containers/Templates/actions.js +103 -0
  219. package/containers/Templates/constants.js +60 -0
  220. package/containers/Templates/index.js +1756 -0
  221. package/containers/Templates/messages.js +337 -0
  222. package/containers/Templates/reducer.js +142 -0
  223. package/containers/Templates/sagas.js +163 -0
  224. package/containers/Templates/selectors.js +28 -0
  225. package/containers/Templates/test/saga.test.js +241 -0
  226. package/containers/WeChat/MapTemplates/_mapTemplates.scss +8 -0
  227. package/containers/WeChat/MapTemplates/actions.js +52 -0
  228. package/containers/WeChat/MapTemplates/constants.js +28 -0
  229. package/containers/WeChat/MapTemplates/index.js +1610 -0
  230. package/containers/WeChat/MapTemplates/messages.js +157 -0
  231. package/containers/WeChat/MapTemplates/reducer.js +74 -0
  232. package/containers/WeChat/MapTemplates/sagas.js +84 -0
  233. package/containers/WeChat/MapTemplates/selectors.js +25 -0
  234. package/containers/WeChat/MapTemplates/test/saga.test.js +155 -0
  235. package/containers/WeChat/RichmediaTemplates/Create/_createRichmedia.scss +57 -0
  236. package/containers/WeChat/RichmediaTemplates/Create/actions.js +36 -0
  237. package/containers/WeChat/RichmediaTemplates/Create/constants.js +15 -0
  238. package/containers/WeChat/RichmediaTemplates/Create/index.js +1071 -0
  239. package/containers/WeChat/RichmediaTemplates/Create/messages.js +165 -0
  240. package/containers/WeChat/RichmediaTemplates/Create/reducer.js +60 -0
  241. package/containers/WeChat/RichmediaTemplates/Create/richmediaschema.js +497 -0
  242. package/containers/WeChat/RichmediaTemplates/Create/sagas.js +51 -0
  243. package/containers/WeChat/RichmediaTemplates/Create/selectors.js +37 -0
  244. package/containers/WeChat/RichmediaTemplates/Create/test/saga.test.js +13 -0
  245. package/containers/WeChat/RichmediaTemplates/Edit/actions.js +20 -0
  246. package/containers/WeChat/RichmediaTemplates/Edit/constants.js +10 -0
  247. package/containers/WeChat/RichmediaTemplates/Edit/index.js +136 -0
  248. package/containers/WeChat/RichmediaTemplates/Edit/messages.js +13 -0
  249. package/containers/WeChat/RichmediaTemplates/Edit/reducer.js +28 -0
  250. package/containers/WeChat/RichmediaTemplates/Edit/sagas.js +36 -0
  251. package/containers/WeChat/RichmediaTemplates/Edit/selectors.js +30 -0
  252. package/containers/WeChat/RichmediaTemplates/Edit/test/saga.test.js +12 -0
  253. package/containers/WeChat/RichmediaTemplates/View/actions.js +15 -0
  254. package/containers/WeChat/RichmediaTemplates/View/constants.js +7 -0
  255. package/containers/WeChat/RichmediaTemplates/View/index.js +47 -0
  256. package/containers/WeChat/RichmediaTemplates/View/messages.js +21 -0
  257. package/containers/WeChat/RichmediaTemplates/View/reducer.js +23 -0
  258. package/containers/WeChat/RichmediaTemplates/View/sagas.js +11 -0
  259. package/containers/WeChat/RichmediaTemplates/View/selectors.js +25 -0
  260. package/index.js +2 -4
  261. package/package.json +1 -1
  262. package/routes.js +202 -136
  263. package/services/getSchema.js +1 -1
  264. package/services/localStorageApi.js +0 -1
  265. package/tests/i18n.test.js +1 -1
  266. package/utils/asyncInjectors.js +78 -0
  267. package/utils/authWrapper.js +1 -1
  268. package/utils/callNativeEvent.js +16 -0
  269. package/utils/checkStore.js +21 -0
  270. package/utils/common.js +2 -2
  271. package/utils/customAuthWrapper.js +62 -0
  272. package/utils/customConnectedAuthWrapper.js +26 -0
  273. package/utils/tagValidations.js +1 -1
  274. package/utils/test-utils.js +6 -2
  275. package/utils/tests/authWrapper.test.js +1 -1
  276. package/utils/tests/checkStore.test.js +1 -1
  277. package/utils/tests/customAuth.test.js +1 -1
  278. package/utils/transformerUtils.js +1 -1
  279. package/v2Components/CapActionButton/index.js +52 -12
  280. package/v2Components/CapActionButton/messages.js +4 -0
  281. package/v2Components/CapActionButton/tests/index.test.js +135 -0
  282. package/v2Components/CapDeviceContent/index.js +5 -0
  283. package/v2Components/CapInAppCTA/index.js +29 -14
  284. package/v2Components/CapInAppCTA/index.scss +0 -2
  285. package/v2Components/CapInAppCTA/messages.js +4 -0
  286. package/v2Components/CapMpushCTA/index.js +54 -38
  287. package/v2Components/CapMpushCTA/index.scss +2 -2
  288. package/v2Components/CapMpushCTA/messages.js +4 -0
  289. package/v2Components/CapTagList/index.js +14 -9
  290. package/v2Components/CapTagListWithInput/index.js +169 -0
  291. package/v2Components/CapTagListWithInput/messages.js +10 -0
  292. package/v2Components/Carousel/style.scss +1 -1
  293. package/v2Components/EmailMobilePreview/index.js +2 -2
  294. package/v2Components/FormBuilder/index.js +9 -3
  295. package/v2Components/NavigationBar/tests/saga.test.js +31 -36
  296. package/v2Components/TemplatePreview/index.js +1 -2
  297. package/v2Components/TestAndPreviewSlidebox/PreviewSection.js +1 -1
  298. package/v2Components/TestAndPreviewSlidebox/index.js +24 -4
  299. package/v2Containers/Cap/tests/saga.test.js +1 -1
  300. package/v2Containers/Email/index.js +43 -2
  301. package/v2Containers/Email/initialSchema.js +24 -18
  302. package/v2Containers/FTP/index.js +1 -1
  303. package/v2Containers/Line/Container/Text/index.js +1 -1
  304. package/v2Containers/MobilePush/Create/index.js +23 -3
  305. package/v2Containers/MobilePush/commonMethods.js +24 -3
  306. package/v2Containers/MobilePushNew/components/CtaButtons.js +20 -0
  307. package/v2Containers/MobilePushNew/components/MediaUploaders.js +31 -3
  308. package/v2Containers/MobilePushNew/components/PlatformContentFields.js +34 -3
  309. package/v2Containers/MobilePushNew/components/tests/MediaUploaders.test.js +153 -5
  310. package/v2Containers/MobilePushNew/index.js +9 -0
  311. package/v2Containers/MobilePushNew/index.scss +2 -1
  312. package/v2Containers/Rcs/index.js +77 -71
  313. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +15270 -492
  314. package/v2Containers/Sms/Create/index.js +1 -1
  315. package/v2Containers/Sms/Edit/index.js +1 -1
  316. package/v2Containers/TagList/index.js +1 -1
  317. package/v2Containers/TagList/utils.js +1 -1
  318. package/v2Containers/Templates/index.js +1 -1
  319. package/v2Containers/Templates/sagas.js +1 -1
  320. package/v2Containers/Viber/index.js +102 -76
  321. package/constants/unified.js +0 -189
@@ -0,0 +1,169 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { injectIntl, intlShape } from 'react-intl';
4
+ import CapRow from '@capillarytech/cap-ui-library/CapRow';
5
+ import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
6
+ import CapInput from '@capillarytech/cap-ui-library/CapInput';
7
+ import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
8
+ import TagList from '../../v2Containers/TagList';
9
+ import messages from './messages';
10
+
11
+ /**
12
+ * CapTagListWithInput - A reusable component that combines TagList and CapInput
13
+ * for external links/URLs that can be used across all channels
14
+ */
15
+ export const CapTagListWithInput = (props) => {
16
+ const {
17
+ intl,
18
+ // TagList props
19
+ tags = [],
20
+ injectedTags = {},
21
+ location = {},
22
+ selectedOfferDetails = [],
23
+ onTagSelect,
24
+ onContextChange,
25
+ moduleFilterEnabled = true,
26
+ className = '',
27
+ userLocale = 'en',
28
+ eventContextTags = [],
29
+ // CapInput props
30
+ inputId,
31
+ inputValue = '',
32
+ inputOnChange,
33
+ inputPlaceholder,
34
+ inputErrorMessage = '',
35
+ inputSize = 'default',
36
+ inputMaxLength,
37
+ inputRequired = false,
38
+ inputDisabled = false,
39
+ // Layout props
40
+ headingText,
41
+ headingType = 'h4',
42
+ headingStyle = {},
43
+ containerStyle = {},
44
+ tagListStyle = {},
45
+ inputStyle = {},
46
+ // Custom props
47
+ showHeading = true,
48
+ showTagList = true,
49
+ showInput = true,
50
+ inputProps = {},
51
+ } = props;
52
+
53
+ const { formatMessage } = intl;
54
+
55
+ return (
56
+ <CapColumn style={containerStyle}>
57
+ <CapRow style={{display: 'flex', flexDirection: 'row'}}>
58
+ {showHeading && headingText && (
59
+ <CapHeading type={headingType} style={headingStyle}>
60
+ {headingText}
61
+ </CapHeading>
62
+ )}
63
+
64
+ {showTagList && (
65
+ <TagList
66
+ key={`${inputId}_tags`}
67
+ className={className}
68
+ moduleFilterEnabled={moduleFilterEnabled}
69
+ label={formatMessage(messages.addLabels)}
70
+ onTagSelect={onTagSelect}
71
+ onContextChange={onContextChange}
72
+ location={location}
73
+ tags={tags}
74
+ injectedTags={injectedTags}
75
+ userLocale={userLocale}
76
+ selectedOfferDetails={selectedOfferDetails}
77
+ eventContextTags={eventContextTags}
78
+ style={tagListStyle}
79
+ />
80
+ )}
81
+ </CapRow>
82
+ {showInput && (
83
+ <CapInput
84
+ id={inputId}
85
+ onChange={inputOnChange}
86
+ placeholder={inputPlaceholder}
87
+ value={inputValue}
88
+ size={inputSize}
89
+ maxLength={inputMaxLength}
90
+ errorMessage={inputErrorMessage}
91
+ isRequired={inputRequired}
92
+ disabled={inputDisabled}
93
+ style={inputStyle}
94
+ {...inputProps}
95
+ />
96
+ )}
97
+ </CapColumn>
98
+ );
99
+ };
100
+
101
+ CapTagListWithInput.propTypes = {
102
+ intl: intlShape.isRequired,
103
+ // TagList props
104
+ tags: PropTypes.array,
105
+ injectedTags: PropTypes.object,
106
+ location: PropTypes.object,
107
+ selectedOfferDetails: PropTypes.array,
108
+ onTagSelect: PropTypes.func.isRequired,
109
+ onContextChange: PropTypes.func.isRequired,
110
+ moduleFilterEnabled: PropTypes.bool,
111
+ className: PropTypes.string,
112
+ userLocale: PropTypes.string,
113
+ eventContextTags: PropTypes.array,
114
+
115
+ // CapInput props
116
+ inputId: PropTypes.string.isRequired,
117
+ inputValue: PropTypes.string,
118
+ inputOnChange: PropTypes.func.isRequired,
119
+ inputPlaceholder: PropTypes.string,
120
+ inputErrorMessage: PropTypes.string,
121
+ inputSize: PropTypes.oneOf(['small', 'default', 'large']),
122
+ inputMaxLength: PropTypes.number,
123
+ inputRequired: PropTypes.bool,
124
+ inputDisabled: PropTypes.bool,
125
+ inputProps: PropTypes.object,
126
+
127
+ // Layout props
128
+ headingText: PropTypes.string,
129
+ headingType: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']),
130
+ headingStyle: PropTypes.object,
131
+ containerStyle: PropTypes.object,
132
+ tagListStyle: PropTypes.object,
133
+ inputStyle: PropTypes.object,
134
+
135
+ // Custom props
136
+ showHeading: PropTypes.bool,
137
+ showTagList: PropTypes.bool,
138
+ showInput: PropTypes.bool,
139
+ };
140
+
141
+ CapTagListWithInput.defaultProps = {
142
+ tags: [],
143
+ injectedTags: {},
144
+ location: {},
145
+ selectedOfferDetails: [],
146
+ moduleFilterEnabled: true,
147
+ className: '',
148
+ userLocale: 'en',
149
+ eventContextTags: [],
150
+ inputValue: '',
151
+ inputSize: 'default',
152
+ inputRequired: false,
153
+ inputDisabled: false,
154
+ inputPlaceholder: '',
155
+ inputErrorMessage: '',
156
+ inputMaxLength: undefined,
157
+ headingText: '',
158
+ headingType: 'h4',
159
+ headingStyle: {},
160
+ containerStyle: {},
161
+ tagListStyle: {},
162
+ inputStyle: {},
163
+ showHeading: true,
164
+ showTagList: true,
165
+ showInput: true,
166
+ inputProps: {},
167
+ };
168
+
169
+ export default injectIntl(CapTagListWithInput);
@@ -0,0 +1,10 @@
1
+ import { defineMessages } from 'react-intl';
2
+
3
+ const prefix = 'creatives.componentsV2.CapTagListWithInput';
4
+
5
+ export default defineMessages({
6
+ addLabels: {
7
+ id: `${prefix}.addLabels`,
8
+ defaultMessage: 'Add labels',
9
+ },
10
+ });
@@ -26,7 +26,7 @@
26
26
  text-align: center;
27
27
  width: 120px !important;
28
28
  border-radius: 12px;
29
- background-color: $CAP_G09;
29
+ background-color: $CAP_G09,
30
30
  }
31
31
 
32
32
  .ant-carousel .slick-slide {
@@ -19,8 +19,8 @@ import messages from '../EmailPreviewV2/messages';
19
19
  import './index.scss';
20
20
  import mobileBody from '../../assets/DeviceForEmail.png';
21
21
  import { iframePreviewAdjustWidth, removeLinksFromHtmlContent } from './../../utils/common';
22
- import {selectTemplateContent} from '../../v2Containers/Templates/selectors';
23
- import * as templateActions from '../../v2Containers/Templates/actions';
22
+ import {selectTemplateContent} from '../../containers/Templates/selectors';
23
+ import * as templateActions from '../../containers/Templates/actions';
24
24
 
25
25
  const deviceAspectRatio = {
26
26
  mobile: {
@@ -54,9 +54,9 @@ import { SMS, MOBILE_PUSH, LINE, ENABLE_AI_SUGGESTIONS,AI_CONTENT_BOT_DISABLED,
54
54
  import globalMessages from '../../v2Containers/Cap/messages';
55
55
  import { convert } from 'html-to-text';
56
56
  import { OUTBOUND } from './constants';
57
- import { GET_TRANSLATION_MAPPED } from '../../constants/unified';
57
+ import { GET_TRANSLATION_MAPPED } from '../../containers/TagList/constants';
58
58
  import moment from 'moment';
59
- import { CUSTOMER_BARCODE_TAG , COPY_OF, ENTRY_TRIGGER_TAG_REGEX} from '../../constants/unified';
59
+ import { CUSTOMER_BARCODE_TAG , COPY_OF, ENTRY_TRIGGER_TAG_REGEX} from '../../containers/App/constants';
60
60
  import { REQUEST } from '../../v2Containers/Cap/constants'
61
61
  import { hasLiquidSupportFeature, isEmailUnsubscribeTagMandatory } from '../../utils/common';
62
62
  import { isUrl } from '../../v2Containers/Line/Container/Wrapper/utils';
@@ -3343,7 +3343,13 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
3343
3343
  const currentLang = (!_.isEmpty(this.state.formData) && !_.isEmpty(this.state.formData[`${this.state.currentTab - 1}`]) && !_.isEmpty(this.state.formData[`${this.state.currentTab - 1}`].selectedLanguages) && this.state.formData[`${this.state.currentTab - 1}`].selectedLanguages[langIndex]) ? this.state.formData[`${this.state.currentTab - 1}`].selectedLanguages[langIndex] : this.props.baseLanguage;
3344
3344
  const isBEEAppEnable = this.checkBeeEditorAllowedForLibrary();
3345
3345
 
3346
- if (!(_.get(this.state, `formData[${this.state.currentTab - 1}][${currentLang}].is_drag_drop`, false)) || isBEEAppEnable === false || channel !== 'EMAIL') {
3346
+ // Always render Subject TagList (title-tagList) even when Bee editor is active for EMAIL channel
3347
+ if (
3348
+ val.id === 'title-tagList' ||
3349
+ !(_.get(this.state, `formData[${this.state.currentTab - 1}][${currentLang}].is_drag_drop`, false)) ||
3350
+ isBEEAppEnable === false ||
3351
+ channel !== 'EMAIL'
3352
+ ) {
3347
3353
  columns.push(
3348
3354
  <CapColumn key={`input-${val.id}`} offset={val.offset} span={val.width ? val.width : ''} style={val.style ? val.style : {marginBottom: '16px'}}>
3349
3355
  <TagList
@@ -1,61 +1,56 @@
1
1
  import { expectSaga } from "redux-saga-test-plan";
2
2
  import * as matchers from "redux-saga-test-plan/matchers";
3
3
  import CapCollapsibleLeftNavigationSagas from '@capillarytech/cap-ui-library/CapCollapsibleLeftNavigation/saga';
4
-
4
+ import * as CapAskAira from '@capillarytech/cap-ui-library/CapAskAira';
5
5
  import rootSagas from "../saga";
6
6
 
7
- // Mock the analyticsBotSaga module
8
- jest.mock('@capillarytech/cap-ui-library/CapAskAira', () => ({
9
- analyticsBotSaga: [
10
- {
11
- * call() { yield true; },
12
- },
13
- {
14
- * call() { yield true; },
15
- },
16
- ],
17
- }));
18
-
19
7
  describe("analyticsBotSagaFn", () => {
20
8
  const { saga: analyticsBotSagaFn } = rootSagas.find(
21
9
  (s) => s.key === "analyticsBotSaga"
22
10
  );
23
11
 
24
- test.concurrent("should handle when analyticsBotSaga is valid array", () => {
25
- // Mock module with valid array
26
- jest.mock('@capillarytech/cap-ui-library/CapAskAira', () => ({
27
- analyticsBotSaga: [
28
- {
29
- * call() { yield true; },
30
- },
31
- {
32
- * call() { yield true; },
33
- },
34
- ],
35
- }));
12
+ beforeEach(() => {
13
+ // Reset all mocks before each test
14
+ jest.resetModules();
15
+ jest.clearAllMocks();
16
+ });
17
+
18
+ test("should handle when analyticsBotSaga is valid array", () => {
19
+ // Setup valid array case
20
+ const mockSagas = [
21
+ { call: jest.fn() },
22
+ { call: jest.fn() },
23
+ ];
24
+ Object.defineProperty(CapAskAira, 'analyticsBotSaga', {
25
+ value: mockSagas,
26
+ configurable: true,
27
+ });
36
28
 
37
29
  return expectSaga(analyticsBotSagaFn)
38
30
  .provide([
39
- [matchers.call.fn(() => {}), undefined],
31
+ [matchers.call.fn(mockSagas[0].call), undefined],
32
+ [matchers.call.fn(mockSagas[1].call), undefined],
40
33
  ])
41
34
  .run();
42
35
  });
43
36
 
44
- test.concurrent("should handle when analyticsBotSaga is undefined", () => {
45
- // Mock module with undefined analyticsBotSaga
46
- jest.mock('@capillarytech/cap-ui-library/CapAskAira', () => ({
47
- analyticsBotSaga: undefined,
48
- }));
37
+ test("should handle when analyticsBotSaga is undefined", () => {
38
+ // Setup undefined case
39
+ Object.defineProperty(CapAskAira, 'analyticsBotSaga', {
40
+ value: undefined,
41
+ configurable: true,
42
+ });
49
43
 
50
44
  return expectSaga(analyticsBotSagaFn)
51
45
  .run();
52
46
  });
53
47
 
54
- test.concurrent("should handle when analyticsBotSaga is not an array", () => {
55
- // Mock module with non-array analyticsBotSaga
56
- jest.mock('@capillarytech/cap-ui-library/CapAskAira', () => ({
57
- analyticsBotSaga: {},
58
- }));
48
+ test("should handle when analyticsBotSaga is not an array", () => {
49
+ // Setup non-array case
50
+ Object.defineProperty(CapAskAira, 'analyticsBotSaga', {
51
+ value: {},
52
+ configurable: true,
53
+ });
59
54
 
60
55
  return expectSaga(analyticsBotSagaFn)
61
56
  .run();
@@ -32,11 +32,10 @@ import {
32
32
  RCS,
33
33
  ZALO,
34
34
  INAPP,
35
- VIBER,
36
- FACEBOOK,
37
35
  MOBILE_PUSH
38
36
  } from '../../v2Containers/CreativesContainer/constants';
39
37
  import Carousel from '../Carousel';
38
+ import { VIBER, FACEBOOK } from '../../v2Containers/App/constants';
40
39
  import whatsappMobileAndroid from './assets/images/whatsapp_mobile_android.svg';
41
40
  import inAppMobileAndroidModal from './assets/images/inapp_mobile_android_modal.svg';
42
41
  import inAppMobileAndroidTop from './assets/images/inapp_mobile_android_top.svg';
@@ -20,7 +20,7 @@ const PreviewSection = ({
20
20
  device={previewDevice}
21
21
  onDeviceChange={setPreviewDevice}
22
22
  customer={selectedCustomer}
23
- subject={formData['template-subject']}
23
+ subject={previewDataHtml?.resolvedTitle || formData['template-subject']}
24
24
  >
25
25
  {isUpdatingPreview && (
26
26
  <CapRow className="loading-container">
@@ -108,6 +108,21 @@ const TestAndPreviewSlidebox = (props) => {
108
108
  requiredTags.some((tag) => !customValues[tag.fullPath])
109
109
  ), [requiredTags, customValues]);
110
110
 
111
+ // Function to resolve tags in text with custom values
112
+ const resolveTagsInText = (text, tagValues) => {
113
+ if (!text) return text;
114
+ let resolvedText = text;
115
+
116
+ // Replace each tag with its custom value
117
+ Object.keys(tagValues).forEach((tagPath) => {
118
+ const tagName = tagPath.split('.').pop(); // Get the actual tag name from the path
119
+ const tagRegex = new RegExp(`{{${tagName}}}`, 'g');
120
+ resolvedText = resolvedText.replace(tagRegex, tagValues[tagPath] || `{{${tagName}}}`);
121
+ });
122
+
123
+ return resolvedText;
124
+ };
125
+
111
126
  // Get the current content based on editor type
112
127
  const getCurrentContent = useMemo(() => {
113
128
  const currentTabData = formData[currentTab - 1];
@@ -380,9 +395,10 @@ const TestAndPreviewSlidebox = (props) => {
380
395
  setCustomValues(updatedValues);
381
396
 
382
397
  // Update preview with prefilled values
398
+ const resolvedSubject = resolveTagsInText(formData['template-subject'], updatedValues);
383
399
  const payload = {
384
400
  channel: EMAIL,
385
- messageTitle: formData['template-subject'],
401
+ messageTitle: resolvedSubject,
386
402
  messageBody: getCurrentContent,
387
403
  resolvedTags: updatedValues,
388
404
  userId: selectedCustomer?.customerId,
@@ -501,9 +517,10 @@ const TestAndPreviewSlidebox = (props) => {
501
517
  setCustomValues(emptyValues);
502
518
 
503
519
  // Update preview with empty values
520
+ const resolvedSubject = resolveTagsInText(formData['template-subject'], emptyValues);
504
521
  const payload = {
505
522
  channel: EMAIL,
506
- messageTitle: formData['template-subject'],
523
+ messageTitle: resolvedSubject,
507
524
  messageBody: getCurrentContent,
508
525
  resolvedTags: emptyValues,
509
526
  userId: selectedCustomer?.customerId,
@@ -517,9 +534,12 @@ const TestAndPreviewSlidebox = (props) => {
517
534
  // Include unsubscribe tag if content contains it
518
535
  const resolvedTags = { ...customValues };
519
536
 
537
+ // Resolve subject tags with custom values
538
+ const resolvedSubject = resolveTagsInText(formData['template-subject'], customValues);
539
+
520
540
  const payload = {
521
541
  channel: EMAIL,
522
- messageTitle: formData['template-subject'],
542
+ messageTitle: resolvedSubject,
523
543
  messageBody: getCurrentContent,
524
544
  resolvedTags,
525
545
  userId: selectedCustomer?.customerId,
@@ -585,7 +605,7 @@ const TestAndPreviewSlidebox = (props) => {
585
605
  emailMessageContent: {
586
606
  channel: EMAIL,
587
607
  messageBody: previewData?.resolvedBody || getCurrentContent,
588
- messageSubject: previewData?.resolvedTitle || formData['template-subject'],
608
+ messageSubject: previewData?.resolvedTitle || resolveTagsInText(formData['template-subject'], customValues),
589
609
  },
590
610
  }, messageMetaConfigId, (response) => {
591
611
  const payload = {
@@ -36,7 +36,7 @@ import {
36
36
  CREATE_CENTRAL_COMMS_META_ID_REQUEST,
37
37
  } from '../constants';
38
38
  import { callback, error, error2, videoConfigData } from '../../mockdata';
39
- import { LOGOUT_FAILURE, LOGOUT_SUCCESS } from '../../../constants/unified';
39
+ import { LOGOUT_FAILURE, LOGOUT_REQUEST, LOGOUT_SUCCESS } from '../../../containers/Cap/constants';
40
40
 
41
41
 
42
42
 
@@ -37,9 +37,9 @@ import { FONT_COLOR_05 } from '@capillarytech/cap-ui-library/styled/variables';
37
37
  import { gtmPush } from '../../utils/gtmTrackers';
38
38
  const {CapCustomCardList} = CapCustomCard;
39
39
  import {storeS3FileSizeDetails, CREATIVES_S3_ASSET_FILESIZES} from '../../utils/cdnTransformation';
40
- import { CUSTOMER_BARCODE_TAG } from '../../constants/unified';
41
40
 
42
41
  import { containsBase64Images } from '../../utils/content';
42
+ import { CUSTOMER_BARCODE_TAG } from '../../containers/App/constants';
43
43
  import injectReducer from '../../utils/injectReducer';
44
44
  import v2EmailReducer from './reducer';
45
45
  import { v2EmailSagas } from './sagas';
@@ -100,6 +100,10 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
100
100
  "template-name": {
101
101
  onChange: this.onTemplateNameChange,
102
102
  },
103
+ // allow tag insertion into Subject input field via a dedicated TagList
104
+ "title-tagList": {
105
+ onTagSelect: this.onTagSelect,
106
+ },
103
107
  "template-version": {
104
108
  onSelect: this.handleVersionSelect,
105
109
  addVersion: this.addVersion,
@@ -646,7 +650,44 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
646
650
 
647
651
  }
648
652
 
649
- onTagSelect = (data) => {
653
+ onTagSelect = (data, currentTab, sourceVal) => {
654
+ // If tag is selected from Subject's TagList, insert into subject input
655
+ if (sourceVal && sourceVal.id === 'title-tagList') {
656
+ const tagToInsert = `{{${data}}}`;
657
+ const formData = _.cloneDeep(this.state.formData);
658
+ const fieldId = 'template-subject';
659
+ const input = document.getElementById(fieldId) || document.querySelector(`#${fieldId} input`);
660
+ let subjectValue = formData[fieldId] || '';
661
+ try {
662
+ if (input && (typeof input.selectionStart === 'number')) {
663
+ const startPos = input.selectionStart;
664
+ const endPos = input.selectionEnd;
665
+ subjectValue = `${subjectValue.substring(0, startPos)}${tagToInsert}${subjectValue.substring(endPos)}`;
666
+ formData[fieldId] = subjectValue;
667
+ this.setState({ formData }, () => {
668
+ try {
669
+ input.focus();
670
+ const newPos = startPos + tagToInsert.length;
671
+ input.selectionStart = newPos;
672
+ input.selectionEnd = newPos;
673
+ } catch (e) {}
674
+ });
675
+ } else {
676
+ subjectValue = `${subjectValue}${tagToInsert}`;
677
+ formData[fieldId] = subjectValue;
678
+ this.setState({ formData });
679
+ if (input) {
680
+ try { input.value = subjectValue; } catch (e) {}
681
+ }
682
+ }
683
+ } catch (e) {
684
+ // fallback safe append
685
+ formData[fieldId] = `${subjectValue}${tagToInsert}`;
686
+ this.setState({ formData });
687
+ }
688
+ return;
689
+ }
690
+
650
691
  const isDragDrop = this.state.formData[`${this.state.currentTab - 1}`][this.state.formData[`${this.state.currentTab - 1}`].activeTab].is_drag_drop;
651
692
  const formData = _.cloneDeep(this.state.formData);
652
693
  const isBEESupport = (this.props.location.query.isBEESupport !== "false") || false;
@@ -33,24 +33,30 @@ export const response = {
33
33
  onlyDisplay: false,
34
34
  errorMessage: "Email Subject cannot be empty.",
35
35
  },
36
- // {
37
- // offset: 20,
38
- // id: "title-tagList",
39
- // label: "Tags",
40
- // target: "message-title2",
41
- // type: "tag-list",
42
- // metaType: "List",
43
- // datatype: "select",
44
- // required: true,
45
- // fluid: true,
46
- // onlyDisplay: true,
47
- // styling: "semantic",
48
- // order: 1,
49
- // customComponent: true,
50
- // supportedEvents: [
51
- // "onTagSelect",
52
- // ],
53
- // },
36
+ {
37
+ // Add label control for subject input
38
+ id: "title-tagList",
39
+ label: "Add label",
40
+ type: "tag-list",
41
+ metaType: "List",
42
+ datatype: "select",
43
+ required: true,
44
+ fluid: true,
45
+ onlyDisplay: true,
46
+ style: {
47
+ float: "none",
48
+ marginTop: "2%",
49
+ marginRight: "20%",
50
+ },
51
+ styling: "semantic",
52
+ order: 2,
53
+ customComponent: true,
54
+ // Helps handler identify the destination input
55
+ target: "template-subject",
56
+ supportedEvents: [
57
+ "onTagSelect",
58
+ ],
59
+ },
54
60
  ],
55
61
  },
56
62
  ],
@@ -29,7 +29,7 @@ import { makeSelectLoyaltyPromotionDisplay, setInjectedTags } from '../Cap/selec
29
29
  import withCreatives from '../../hoc/withCreatives';
30
30
  import messages from './messages';
31
31
  import './_FTP.scss';
32
- import * as globalActions from '../Cap/actions';
32
+ import * as globalActions from '../../containers/Cap/actions';
33
33
  import { TagList } from '../TagList';
34
34
  import { NO_COMMUNICATION, CREATE, EDIT, PREVIEW } from '../App/constants';
35
35
  import { getTreeStructuredTags } from '../../utils/common';
@@ -17,7 +17,7 @@ import withStyles from '../../../../hoc/withStyles';
17
17
  import globalMessages from '../../../Cap/messages';
18
18
  import { validateTags } from '../../../../utils/tagValidations';
19
19
  import moment from 'moment';
20
- import { GET_TRANSLATION_MAPPED } from '../../../../constants/unified';
20
+ import { GET_TRANSLATION_MAPPED } from '../../../../containers/TagList/constants';
21
21
 
22
22
  const { TextArea } = CapInput;
23
23
  const {CapCustomCardList} = CapCustomCard;
@@ -291,7 +291,28 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
291
291
  rowClassName: 'mobile-push-row',
292
292
  id: 'cta-external-link',
293
293
  cols: [
294
-
294
+ {
295
+ // Add label control for external link input
296
+ id: "title-tagList",
297
+ label: "Add label",
298
+ type: "tag-list",
299
+ metaType: "List",
300
+ datatype: "select",
301
+ required: true,
302
+ fluid: true,
303
+ onlyDisplay: true,
304
+ style: {
305
+ marginRight: "10%",
306
+ },
307
+ styling: "semantic",
308
+ order: 2,
309
+ customComponent: true,
310
+ // Helps handler identify the destination input
311
+ target: inputId,
312
+ supportedEvents: [
313
+ "onTagSelect",
314
+ ],
315
+ },
295
316
  {
296
317
  id: inputId,
297
318
  placeholder: this.props.intl.formatMessage(messages.externalLink),
@@ -304,8 +325,7 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
304
325
  width: 18,
305
326
  offset: 1,
306
327
  style: {
307
- width: '100%',
308
-
328
+ width: '95%',
309
329
  },
310
330
  styling: "semantic",
311
331
  order: 1,
@@ -202,11 +202,32 @@ function getLinkTypeFields({inputFieldsArgs, fieldIndex, deepLinkOptions, formDa
202
202
  identifier: inputId,
203
203
 
204
204
  cols: [
205
-
205
+ {
206
+ // Add label control for external link input
207
+ id: "title-tagList",
208
+ label: "Add label",
209
+ type: "tag-list",
210
+ metaType: "List",
211
+ datatype: "select",
212
+ required: true,
213
+ fluid: true,
214
+ onlyDisplay: true,
215
+ style: {
216
+ marginRight: "10%",
217
+ },
218
+ styling: "semantic",
219
+ order: 2,
220
+ customComponent: true,
221
+ // Helps handler identify the destination input
222
+ target: inputId,
223
+ supportedEvents: [
224
+ "onTagSelect",
225
+ ],
226
+ },
206
227
  {
207
228
  id: inputId,
208
229
  placeholder: "External Link",
209
- type: "input", //Resembles component to be used
230
+ type: "input", //Resembles component to be used
210
231
  metaType: "text",
211
232
  datatype: "string",
212
233
  errorMessage: <FormattedMessage {...messages.invalidExternalLink}/>,
@@ -215,7 +236,7 @@ function getLinkTypeFields({inputFieldsArgs, fieldIndex, deepLinkOptions, formDa
215
236
  width: 18,
216
237
  offset: 1,
217
238
  style: {
218
- width: '100%',
239
+ width: '95%',
219
240
  },
220
241
  styling: "semantic",
221
242
  order: 1,