@capillarytech/creatives-library 7.8.1 → 7.9.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 (63) hide show
  1. package/app.js +5 -1
  2. package/components/FormBuilder/index.js +2 -2
  3. package/containers/Email/index.js +8 -3
  4. package/containers/MobilePush/Create/index.js +2 -2
  5. package/containers/MobilePush/Edit/index.js +2 -2
  6. package/containers/WeChat/MapTemplates/index.js +15 -3
  7. package/package.json +1 -1
  8. package/services/api.js +20 -5
  9. package/translations/en.json +113 -2
  10. package/translations/zh.json +112 -1
  11. package/utils/gtmTrackers/gtmEvents/creativeDetails.js +6 -2
  12. package/utils/gtmTrackers/index.js +8 -4
  13. package/v2Components/CapImageUpload/index.js +14 -8
  14. package/v2Components/FormBuilder/index.js +10 -1
  15. package/v2Components/NavigationBar/index.js +63 -29
  16. package/v2Components/NavigationBar/messages.js +5 -0
  17. package/v2Components/TemplatePreview/assets/images/mobile.svg +24 -0
  18. package/v2Containers/App/constants.js +23 -3
  19. package/v2Containers/Cap/actions.js +2 -2
  20. package/v2Containers/Cap/constants.js +3 -2
  21. package/v2Containers/Cap/index.js +31 -18
  22. package/v2Containers/Cap/messages.js +8 -0
  23. package/v2Containers/Cap/sagas.js +18 -6
  24. package/v2Containers/CapFacebookPreview/constants.js +4 -0
  25. package/v2Containers/CapFacebookPreview/index.js +92 -67
  26. package/v2Containers/CapFacebookPreview/reducer.js +19 -10
  27. package/v2Containers/CreativesContainer/SlideBoxContent.js +2 -0
  28. package/v2Containers/CreativesContainer/index.js +80 -2
  29. package/v2Containers/Facebook/Advertisement/index.js +2 -2
  30. package/v2Containers/Facebook/Advertisement/index.scss +1 -1
  31. package/v2Containers/Facebook/index.js +15 -4
  32. package/v2Containers/Line/Container/Drawer/index.js +1 -1
  33. package/v2Containers/Line/Create/_lineCreate.scss +64 -0
  34. package/v2Containers/Line/Create/actions.js +94 -0
  35. package/v2Containers/Line/Create/constants.js +43 -0
  36. package/v2Containers/Line/Create/index.js +1132 -0
  37. package/v2Containers/Line/Create/initialSchema.js +378 -0
  38. package/v2Containers/Line/Create/messages.js +229 -0
  39. package/v2Containers/Line/Create/reducer.js +99 -0
  40. package/v2Containers/Line/Create/sagas.js +113 -0
  41. package/v2Containers/Line/Create/selectors.js +30 -0
  42. package/v2Containers/Line/CreateWrapper/constants.js +2 -0
  43. package/v2Containers/Line/CreateWrapper/index.js +117 -0
  44. package/v2Containers/Line/CreateWrapper/messages.js +55 -0
  45. package/v2Containers/Line/Edit/_lineEdit.scss +23 -0
  46. package/v2Containers/Line/Edit/actions.js +79 -0
  47. package/v2Containers/Line/Edit/constants.js +27 -0
  48. package/v2Containers/Line/Edit/index.js +1051 -0
  49. package/v2Containers/Line/Edit/messages.js +173 -0
  50. package/v2Containers/Line/Edit/reducer.js +83 -0
  51. package/v2Containers/Line/Edit/sagas.js +81 -0
  52. package/v2Containers/Line/Edit/selectors.js +29 -0
  53. package/v2Containers/Line/Edit/tests/actions.test.js +18 -0
  54. package/v2Containers/Line/Edit/tests/index.test.js +10 -0
  55. package/v2Containers/Line/Edit/tests/reducer.test.js +9 -0
  56. package/v2Containers/Line/Edit/tests/sagas.test.js +15 -0
  57. package/v2Containers/Line/Edit/tests/selectors.test.js +10 -0
  58. package/v2Containers/MobilePush/Edit/index.js +2 -2
  59. package/v2Containers/MobilepushWrapper/index.js +1 -1
  60. package/v2Containers/Templates/_templates.scss +4 -2
  61. package/v2Containers/Templates/index.js +5 -2
  62. package/v2Containers/TemplatesV2/index.js +11 -3
  63. package/v2Containers/WeChat/MapTemplates/index.js +12 -2
@@ -10,6 +10,7 @@ import { connect } from 'react-redux';
10
10
  import { createStructuredSelector } from 'reselect';
11
11
  import { bindActionCreators } from 'redux';
12
12
  import styled from 'styled-components';
13
+ import { GA } from '@capillarytech/cap-ui-utils';
13
14
 
14
15
  import * as actions from './actions';
15
16
  import { selectEmailLayout, uploadSelector, templateUserList, makeSelectTemplates } from '../Templates/selectors';
@@ -18,6 +19,7 @@ import SlideBoxHeader from './SlideBoxHeader';
18
19
  import SlideBoxFooter from './SlideBoxFooter';
19
20
  import * as constants from './constants';
20
21
  import * as commonUtil from '../../utils/common';
22
+ import { gtmPush } from '../../utils/gtmTrackers';
21
23
  import './index.scss';
22
24
  import * as templateActions from '../Templates/actions';
23
25
  import * as globalActions from '../Cap/actions';
@@ -25,11 +27,13 @@ import {isLoading as isLoadingSelector} from './selectors';
25
27
  import messages from './messages';
26
28
  import { MAP_TEMPLATE } from '../WeChat/Wrapper/constants';
27
29
  import { makeSelectFetchingCmsData } from '../Email/selectors';
30
+ import { IMAGE, IMAGE_MAP, IMAGE_CAROUSEL, VIDEO, TEMPLATE, STICKER } from '../Line/Container/constants';
28
31
  import {IMAGE, VIDEO } from '../Facebook/Advertisement/constant';
29
32
  import { CREATIVE } from '../Facebook/constants';
30
33
 
31
34
 
32
35
  const classPrefix = 'add-creatives-section';
36
+ const CREATIVES_CONTAINER = 'creativesContainer';
33
37
 
34
38
  const SlideBoxWrapper = styled.div`
35
39
  .cap-slide-box-v2-container{
@@ -68,6 +72,10 @@ class Creatives extends React.Component {
68
72
  this.props.globalActions.clearMetaEntities();
69
73
  }
70
74
 
75
+ componentDidMount() {
76
+ GA.timeTracker.startTimer(CREATIVES_CONTAINER);
77
+ }
78
+
71
79
  onEnterTemplateName = () => {
72
80
  this.setState({templateNameExists: true});
73
81
  };
@@ -91,7 +99,7 @@ class Creatives extends React.Component {
91
99
  this.setState({ slidBoxContent: 'preview', templateData });
92
100
  };
93
101
  onEditTemplate = () => {
94
- this.setState({ slidBoxContent: 'editTemplate', showSlideBox: true });
102
+ this.setState({ slidBoxContent: 'editTemplate', showSlideBox: true, templateNameExists: true });
95
103
  };
96
104
  onCreateNew = (fbAdManager) => {
97
105
  const data = { slidBoxContent: 'createTemplate', showSlideBox: true };
@@ -345,7 +353,7 @@ class Creatives extends React.Component {
345
353
  }
346
354
 
347
355
  getCreativesData = (channel, template, templateRecords) => { //from creatives to consumers
348
- let templateData = {channel };
356
+ let templateData = { channel };
349
357
  switch (channel) {
350
358
  case constants.SMS:
351
359
  if (template.value.base) {
@@ -502,6 +510,75 @@ class Creatives extends React.Component {
502
510
  return creativesMode;
503
511
  }
504
512
 
513
+ logGTMEvent(channel, creativesData) {
514
+ const LIBRARY = 'library';
515
+ const timeTaken = GA.timeTracker.stopTimer(CREATIVES_CONTAINER, {
516
+ category: 'Campaigns',
517
+ action: 'Creatives',
518
+ label: 'Indirect',
519
+ });
520
+ const {
521
+ androidContent: {
522
+ title: androidTitle,
523
+ message: androidMessage,
524
+ type: androidType,
525
+ } = {},
526
+ iosContent: {
527
+ title: iosTitle,
528
+ message: iosMessage,
529
+ type: iosType,
530
+ } = {},
531
+ messageBody = '',
532
+ emailBody = '',
533
+ } = creativesData;
534
+ let gtmDetails = {
535
+ channel,
536
+ timeTaken,
537
+ mode: LIBRARY,
538
+ content: messageBody,
539
+ };
540
+ switch (channel) {
541
+ case constants.SMS:
542
+ case constants.WECHAT:
543
+ case constants.VIBER:
544
+ break;
545
+ case constants.EMAIL:
546
+ gtmDetails = {
547
+ ...gtmDetails,
548
+ content: emailBody,
549
+ };
550
+ break;
551
+ case constants.MOBILE_PUSH:
552
+ gtmDetails = {
553
+ ...gtmDetails,
554
+
555
+ content: `${androidTitle} ${androidMessage} ${iosTitle} ${iosMessage}`,
556
+ imageAdded: androidType === 'IMAGE' || iosType === 'IMAGE',
557
+ };
558
+ break;
559
+ case constants.LINE:
560
+ gtmDetails = Object.assign({
561
+ ...gtmDetails,
562
+ }, this.getLineMessageTypes(messageBody));
563
+ break;
564
+ default:
565
+ return false;
566
+ }
567
+ gtmPush('creativeDetails', gtmDetails);
568
+ }
569
+
570
+ getLineMessageTypes(messageBody) {
571
+ const {
572
+ messages: lineMessages = [],
573
+ } = JSON.parse(messageBody);
574
+ const typeOfMessages = lineMessages.map((message) => message.type);
575
+ return {
576
+ imageAdded: typeOfMessages.some((type) => [IMAGE, IMAGE_MAP, IMAGE_CAROUSEL, TEMPLATE].includes(type)),
577
+ videoAdded: typeOfMessages.includes(VIDEO),
578
+ stickerAdded: typeOfMessages.includes(STICKER),
579
+ };
580
+ }
581
+
505
582
  getFormData = (template) => {
506
583
  if (template.validity) {
507
584
  this.setState(
@@ -512,6 +589,7 @@ class Creatives extends React.Component {
512
589
  const templateData = this.state.templateData ? this.state.templateData : template; //select existing or create new content
513
590
  const channel = templateData.type;
514
591
  const creativesData = this.getCreativesData(channel, template, templateData );// convers data to consumer understandable format
592
+ this.logGTMEvent(channel, creativesData);
515
593
  this.props.getCreativesData(creativesData);// send data to consumer
516
594
  },
517
595
  );
@@ -474,9 +474,9 @@ export const Advertisement = (props) => {
474
474
  if (webSiteLink === "" || errorMsg.websiteLinkErrorMsg ) {
475
475
  flag = true;
476
476
  }
477
- if (Object.keys(imageData).length === 0 && subType === IMAGE) {
477
+ if (!imageData?.imageSrc && subType === IMAGE) {
478
478
  flag = true;
479
- } else if (Object.keys(videoData).length === 0 && subType === VIDEO) {
479
+ } else if (!videoData?.videoSrc && subType === VIDEO) {
480
480
  flag = true;
481
481
  }
482
482
  subTypes.push(subType);
@@ -21,7 +21,7 @@ $classPrefix: add-facebook-ad-section;
21
21
  display: inline-block;
22
22
  }
23
23
  .cap-input-edit-name{
24
- width: 500px;
24
+ width: 319px;
25
25
  }
26
26
  .cap-link-edit-name{
27
27
  display: inline-block;
@@ -269,7 +269,11 @@ const Facebook = (props) => {
269
269
  ]);
270
270
  const query = {type: 'embedded', module: 'library'};
271
271
  const location = {pathname: `/FACEBOOK`, search: '', query};
272
- return (showTemplateList ? (
272
+
273
+ // fbAdManager ==cretaives only the case for default startegy and user selected "capillary ad manager"
274
+ // below condition (fbAdManager !==CREATIVE) is for edit fb ad manager from campaign
275
+ //-> select capillary ad manager-> select template
276
+ return ((showTemplateList && fbAdManager !==CREATIVE) ? (
273
277
  <Templates
274
278
  key={"FACEBOOK"}
275
279
  location={location}
@@ -280,11 +284,18 @@ const Facebook = (props) => {
280
284
  onSelectTemplate={onSelectTemplate}
281
285
  renderNewCardGrid={renderNewCardGrid}
282
286
  handlePeviewTemplate={handlePeviewTemplate}
283
- fbAdManager={CREATIVE}
287
+ fbAdManager={CREATIVE} // it means we are selecting capillary ad manager from campaign
284
288
  />
285
289
  ) :
286
- (!isFullMode && (fbAdManager !== CREATIVE && messageStrategy === "DEFAULT" || (templateData?.edit && templateData?.fbContentType !==CREATIVE)) ) ?
287
- (<div className={className}>
290
+ (!isFullMode && ((fbAdManager !== CREATIVE && messageStrategy === "DEFAULT")
291
+ || (templateData?.edit && templateData?.fbContentType !==CREATIVE && fbAdManager !== CREATIVE )) ) ?
292
+
293
+ // not fullmode +
294
+ // default strtaegy and not selected "capillary ad manager" from campaign message +
295
+ //edit template && not coming from campaign message where user selected "capillary ad manager" (means edit "fb ad manager" from campaign) &&
296
+ // & also we are not selecting capillary ad manager from campaign
297
+
298
+ (<div className={className}>
288
299
 
289
300
  <div className="is-scrollable-section" >
290
301
  <div className="account-details-wrapper">
@@ -59,7 +59,7 @@ export const LineDrawer = ({
59
59
  queryParams.page = page;
60
60
  queryParams.perPage = 25;
61
61
 
62
- if (params.name !== "") {
62
+ if (params?.name) {
63
63
  queryParams.name = params.name;
64
64
  queryParams.page = 1;
65
65
  }
@@ -0,0 +1,64 @@
1
+ @import '~@capillarytech/cap-ui-library/styles/_variables.scss';
2
+
3
+ .line-row{
4
+ margin-bottom: 16px;
5
+ }
6
+ .slidebox-content-container {
7
+ overflow-x: hidden;
8
+ }
9
+ .line-image {
10
+ position: relative;
11
+ }
12
+ .image-container {
13
+ display: flex;
14
+ & > div {
15
+ min-width: 516px;
16
+ }
17
+ border-radius: 5px;
18
+ .image-placeholder{
19
+ line-height: 150px;
20
+ }
21
+ img {
22
+ object-fit: cover;
23
+ max-width: 100%;
24
+ max-height: 100%;
25
+ height: auto !important;
26
+ width: auto !important;
27
+ }
28
+ }
29
+
30
+ .pagination-container.gallery-upload {
31
+ height: calc(100vh - 60px);
32
+
33
+ .cap-custom-card-list-col {
34
+ max-width: 156px;
35
+ max-height: 156px;
36
+ display: inline-block;
37
+ margin-left: $CAP_SPACE_04;
38
+ margin-right: $CAP_SPACE_04;
39
+ }
40
+
41
+ .ant-card-body {
42
+ padding-top: 0;
43
+
44
+ .ant-card-meta-description img {
45
+ height: 80px;
46
+ width: auto;
47
+ }
48
+ }
49
+ }
50
+
51
+ .gallery-image {
52
+ height: 156px;
53
+ width: 156px;
54
+ border-radius: 4px;
55
+ margin: 3px;
56
+ }
57
+
58
+ .sms-text {
59
+ img {
60
+ display: block;
61
+ max-width: 100%;
62
+ object-fit: cover;
63
+ }
64
+ }
@@ -0,0 +1,94 @@
1
+ /*
2
+ *
3
+ * Create actions
4
+ *
5
+ */
6
+
7
+ import * as types from './constants';
8
+
9
+ export function createTemplate(template, callback) {
10
+ console.log('action trigereed createtemplate');
11
+ return {
12
+ type: types.CREATE_TEMPLATE_REQUEST,
13
+ template,
14
+ callback,
15
+ };
16
+ }
17
+
18
+ export function clearCreateResponse() {
19
+ console.log('clearCreateResponse');
20
+ return {
21
+ type: types.CLEAR_CREATE_RESPONSE_REQUEST,
22
+ };
23
+ }
24
+
25
+ export function defaultAction() {
26
+ return {
27
+ type: types.DEFAULT_ACTION,
28
+ };
29
+ }
30
+
31
+ export function uploadAsset(file, assetType, fileParams) {
32
+ return {
33
+ type: types.UPLOAD_ASSET_REQUEST,
34
+ file,
35
+ assetType,
36
+ fileParams,
37
+ };
38
+ }
39
+
40
+ export function clearAsset() {
41
+ return {
42
+ type: types.CLEAR_ASSET,
43
+ };
44
+ }
45
+
46
+
47
+ // FOR EDIT
48
+
49
+
50
+ export function editTemplate(template, callback) {
51
+ console.log('action trigereed editTemplate line @@@');
52
+ return {
53
+ type: types.EDIT_TEMPLATE_REQUEST,
54
+ template,
55
+ callback,
56
+ };
57
+ }
58
+
59
+ export function getTemplateDetails(id) {
60
+ console.log('getting template line @@@', id);
61
+ return {
62
+ type: types.GET_TEMPLATE_DETAILS_REQUEST,
63
+ id,
64
+ channel: 'LINE',
65
+ };
66
+ }
67
+
68
+ export function clearEditResponse() {
69
+ console.log('clearEditResponse');
70
+ return {
71
+ type: types.CLEAR_EDIT_RESPONSE_REQUEST,
72
+ };
73
+ }
74
+
75
+ export function clearData() {
76
+ return {
77
+ type: types.CLEAR_DATA,
78
+ };
79
+ }
80
+
81
+ export function getLineTemplatesList(channel, queryParams) {
82
+ return {
83
+ type: types.GET_LINE_TEMPLATES_LIST_REQUEST,
84
+ channel,
85
+ queryParams,
86
+ };
87
+ }
88
+
89
+ export function setSelectedTemplate(templateData) {
90
+ return {
91
+ type: types.SET_SELECTED_TEMPLATE,
92
+ data: templateData,
93
+ };
94
+ }
@@ -0,0 +1,43 @@
1
+ /*
2
+ *
3
+ * Create constants
4
+ *
5
+ */
6
+
7
+ export const DEFAULT_ACTION = 'app/Create/DEFAULT_ACTION';
8
+
9
+
10
+ export const CREATE_TEMPLATE_REQUEST = 'app/v2Containers/Line/Create/CREATE_TEMPLATE_REQUEST';
11
+ export const CREATE_TEMPLATE_SUCCESS = 'app/v2Containers/Line/Create/CREATE_TEMPLATE_SUCCESS';
12
+ export const CREATE_TEMPLATE_FAILURE = 'app/v2Containers/Line/Create/CREATE_TEMPLATE_FAILURE';
13
+ export const UPLOAD_ASSET_REQUEST = 'app/v2Containers/Line/Create/UPLOAD_ASSET_REQUEST';
14
+ export const UPLOAD_ASSET_SUCCESS = 'app/v2Containers/Line/Create/UPLOAD_ASSET_SUCCESS';
15
+ export const UPLOAD_ASSET_FAILURE = 'app/v2Containers/Line/Create/UPLOAD_ASSET_FAILURE';
16
+ export const CLEAR_ASSET = 'app/v2Containers/Line/Create/CLEAR_ASSET';
17
+
18
+ export const CLEAR_CREATE_RESPONSE_REQUEST = 'app/v2Containers/Line/Create/CLEAR_CREATE_RESPONSE_REQUEST';
19
+ export const CLEAR_CREATE_RESPONSE_SUCCESS = 'app/v2Containers/Line/Create/CLEAR_CREATE_RESPONSE_SUCCESS';
20
+ export const CLEAR_CREATE_RESPONSE_FAILURE = 'app/v2Containers/Line/Create/CLEAR_CREATE_RESPONSE_FAILURE';
21
+
22
+ export const LINE_IMG_HEIGHT = 400;
23
+ export const LINE_IMG_WIDTH = 300;
24
+ export const LINE_IMG_SIZE = 30000000;
25
+
26
+
27
+ // edit
28
+
29
+ export const GET_TEMPLATE_DETAILS_REQUEST = 'app/v2Containers/line/Edit/GET_TEMPLATE_DETAILS_REQUEST';
30
+ export const GET_TEMPLATE_DETAILS_SUCCESS = 'app/v2Containers/line/Edit/GET_TEMPLATE_DETAILS_SUCCESS';
31
+ export const GET_TEMPLATE_DETAILS_FAILURE = 'app/v2Containers/line/Edit/GET_TEMPLATE_DETAILS_FAILURE';
32
+
33
+ export const EDIT_TEMPLATE_REQUEST = 'app/v2Containers/line/Edit/EDIT_TEMPLATE_REQUEST';
34
+ export const EDIT_TEMPLATE_SUCCESS = 'app/v2Containers/line/Edit/EDIT_TEMPLATE_SUCCESS';
35
+ export const EDIT_TEMPLATE_FAILURE = 'app/v2Containers/line/Edit/EDIT_TEMPLATE_FAILURE';
36
+
37
+ export const CLEAR_EDIT_RESPONSE_REQUEST = 'app/v2Containers/line/Edit/CLEAR_EDIT_RESPONSE_REQUEST';
38
+ export const CLEAR_DATA = 'app/v2Containers/Line/Edit/CLEAR_DATA';
39
+ export const SET_SELECTED_TEMPLATE = 'app/v2Containers/Line/Edit/SET_SELECTED_TEMPLATE';
40
+
41
+ export const GET_LINE_TEMPLATES_LIST_REQUEST = 'app/v2Containers/Line/GET_LINE_TEMPLATES_LIST_REQUEST';
42
+ export const GET_LINE_TEMPLATES_LIST_SUCCESS = 'app/v2Containers/Line/GET_LINE_TEMPLATES_LIST_SUCCESS';
43
+ export const GET_LINE_TEMPLATES_LIST_FAILURE = 'app/v2Containers/Line/GET_LINE_TEMPLATES_LIST_FAILURE';