@capillarytech/creatives-library 7.7.0 → 7.7.3

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 (37) hide show
  1. package/app.js +5 -0
  2. package/index.html +2 -2
  3. package/index.js +3 -3
  4. package/package.json +4 -2
  5. package/services/api.js +2 -0
  6. package/utils/gtmTrackers/gtmEvents/creativeDetails.js +41 -0
  7. package/utils/gtmTrackers/index.js +17 -0
  8. package/v2Components/TemplatePreview/index.js +1 -0
  9. package/v2Containers/App/constants.js +11 -0
  10. package/v2Containers/Cap/index.js +23 -29
  11. package/v2Containers/CapFacebookPreview/index.js +9 -9
  12. package/v2Containers/CapFacebookPreview/index.scss +15 -0
  13. package/v2Containers/CreativesContainer/SlideBoxContent.js +16 -1
  14. package/v2Containers/CreativesContainer/index.js +122 -12
  15. package/v2Containers/Email/index.js +14 -3
  16. package/v2Containers/EmailWrapper/index.js +10 -3
  17. package/v2Containers/Facebook/Advertisement/index.js +72 -36
  18. package/v2Containers/Facebook/Advertisement/index.scss +1 -1
  19. package/v2Containers/Facebook/Facebook.style.js +1 -1
  20. package/v2Containers/Facebook/constants.js +4 -0
  21. package/v2Containers/Facebook/index.js +198 -122
  22. package/v2Containers/Facebook/messages.js +24 -4
  23. package/v2Containers/Line/Container/index.js +32 -4
  24. package/v2Containers/MobilePush/Create/index.js +25 -4
  25. package/v2Containers/MobilePush/Edit/index.js +27 -5
  26. package/v2Containers/MobilePush/Edit/sagas.js +1 -1
  27. package/v2Containers/MobilePush/commonMethods.js +19 -1
  28. package/v2Containers/Sms/Create/index.js +14 -2
  29. package/v2Containers/Sms/Edit/index.js +15 -2
  30. package/v2Containers/Templates/index.js +43 -27
  31. package/v2Containers/Templates/messages.js +1 -1
  32. package/v2Containers/Templates/reducer.js +4 -2
  33. package/v2Containers/TemplatesV2/index.js +23 -6
  34. package/v2Containers/TemplatesV2/messages.js +4 -0
  35. package/v2Containers/Viber/index.js +19 -3
  36. package/v2Containers/WeChat/MapTemplates/index.js +12 -3
  37. package/v2Containers/WeChat/RichmediaTemplates/Create/index.js +11 -2
@@ -27,6 +27,8 @@ import Email from '../Email';
27
27
  import CmsTemplatesComponent from '../../v2Components/CmsTemplatesComponent';
28
28
  import messages from './messages';
29
29
  import { CHANNEL_CREATE_TRACK_MAPPING } from '../App/constants';
30
+ import { gtmPush } from '../../utils/gtmTrackers';
31
+ import { EMAIL } from '../CreativesContainer/constants';
30
32
 
31
33
  const CapRadioCardWithLabel = ComponentWithLabelHOC(CapRadioCard);
32
34
  const { timeTracker } = GA;
@@ -116,13 +118,18 @@ export class EmailWrapper extends React.Component { // eslint-disable-line react
116
118
  };
117
119
  CapNotification.error(message);
118
120
  }
119
- stopTimerGA=() => {
121
+ stopTimerGA = () => {
120
122
  // stop timer
121
- timeTracker.stopTimer(CHANNEL_CREATE_TRACK_MAPPING.email, {
123
+ const timeTaken = timeTracker.stopTimer(CHANNEL_CREATE_TRACK_MAPPING.email, {
122
124
  category: 'Creatives',
123
125
  action: 'Create',
124
126
  label: 'uploadZip',
125
127
  });
128
+ gtmPush('creativeDetails', {
129
+ channel: EMAIL,
130
+ timeTaken,
131
+ mode: 'uploadZip'
132
+ });
126
133
  }
127
134
  handleFileUpload = (file = {}) => {
128
135
  const { templatesActions, intl, showNextStep, isUploading } = this.props;
@@ -133,8 +140,8 @@ export class EmailWrapper extends React.Component { // eslint-disable-line react
133
140
 
134
141
  if (supportedZipFormats.indexOf(fileExtension.toLowerCase()) !== -1) {
135
142
  templatesActions.handleZipUpload(file.originFileObj, () => { //handle upload success
143
+ this.stopTimerGA();
136
144
  this.setState({ modeContent: { file } }, showNextStep);
137
- stopTimerGA();
138
145
  }, this.handleZipUploadError);
139
146
  } else if (fileExtension === 'html' || fileExtension === 'htm') {
140
147
  const reader = new FileReader();
@@ -3,6 +3,8 @@ import React, { useState, useEffect, useCallback} from "react";
3
3
  import { injectIntl, FormattedMessage, intlShape } from 'react-intl';
4
4
  import { isUrl } from '../../Line/Container/Wrapper/utils';
5
5
  import get from 'lodash/get';
6
+ import isEmpty from 'lodash/isEmpty';
7
+
6
8
  import {
7
9
  CapInput,
8
10
  CapRadioCard,
@@ -82,10 +84,12 @@ export const Advertisement = (props) => {
82
84
  actions,
83
85
  fbADData = {},
84
86
  onCreateComplete,
85
- templateData,
87
+ templateData = {},
86
88
  params,
87
89
  getFormSubscriptionData,
88
90
  facebookTemplateData,
91
+ selectedMarketingObjective,
92
+ orgUnitId,
89
93
  } = props;
90
94
  const {
91
95
  formatMessage,
@@ -128,7 +132,7 @@ export const Advertisement = (props) => {
128
132
  orgUnitFacebookPageSettingsMap = {},
129
133
  employeeAccessToken: accessToken = "",
130
134
  accountId = "",
131
- } = selectedFacebookAccount;
135
+ } = selectedFacebookAccount || {};
132
136
  const { pageAccessToken, pageId: pId } = orgUnitFacebookPageSettingsMap[pageId] || {};
133
137
  videoData = {
134
138
  accessToken,
@@ -158,7 +162,7 @@ export const Advertisement = (props) => {
158
162
  }, [paramObj.id]);
159
163
 
160
164
  useEffect(() => {
161
- if ((params && params.id) || (templateData || {}).edit) {
165
+ if (params?.id || templateData?.edit) {
162
166
  const { FacebookAd = [], pageOrgUnitId: editPageId} = get(templateData, `versions.base.content`) || get(fbADData, `templateDetails.versions.base.content`) || {};
163
167
  const editMessageTitle = (templateData || {}).name || get(fbADData, 'templateDetails.name');
164
168
  const editFBContent = Object.values(FacebookAd);
@@ -217,6 +221,7 @@ export const Advertisement = (props) => {
217
221
  }
218
222
  }, [fbADData[`templateDetails`] || templateData]);
219
223
 
224
+
220
225
  const CustomToolTip = useCallback((msg) => <CapTooltipWithInfo
221
226
  infoIconProps={{svgProps: {width: 12, height: 12}, style: {marginLeft: 5}}}
222
227
  title={msg}
@@ -349,8 +354,7 @@ export const Advertisement = (props) => {
349
354
  }
350
355
  messageData.push(data);
351
356
  });
352
-
353
- return {
357
+ let finalResponse = {
354
358
  versions: {
355
359
  base: {
356
360
  content: {
@@ -362,12 +366,17 @@ export const Advertisement = (props) => {
362
366
  type: "FACEBOOK",
363
367
  name: messageTitle,
364
368
  };
369
+ if (!isFullMode) {
370
+ finalResponse = {...finalResponse, selectedMarketingObjective, accountId};
371
+ }
372
+ return finalResponse;
365
373
  }, [carouselData,
366
374
  pageId,
367
375
  messageTitle,
368
376
  primaryText,
369
377
  callToAction,
370
- displayLink]);
378
+ displayLink,
379
+ selectedMarketingObjective]);
371
380
 
372
381
  const onCreateFacebookAd = useCallback( () => {
373
382
  actions.createTemplate(
@@ -443,6 +452,7 @@ export const Advertisement = (props) => {
443
452
  updateMessageTitle(val);
444
453
  }, [messageTitle]);
445
454
 
455
+
446
456
  const isDisableDone = useCallback((isPreview) => {
447
457
  let flag = false;
448
458
  if (primaryText === "" ) {
@@ -492,8 +502,7 @@ export const Advertisement = (props) => {
492
502
  selectedAd,
493
503
  ]
494
504
  );
495
-
496
- const isDisableContinue = () => messageTitle.trim() === "" || selectedAd === "";
505
+ const isDisableContinue = () => isFullMode ? (messageTitle.trim() === "" || selectedAd === "") : ( selectedAd === "");
497
506
 
498
507
  const onClickContinue = useCallback(() => { updateStep('createFacebookAd'); }, [step]);
499
508
 
@@ -802,8 +811,8 @@ export const Advertisement = (props) => {
802
811
  setPageId(value);
803
812
  }, [pageId]);
804
813
 
805
- const selectedFacebookAccount = get(facebookTemplateData, 'selectedFacebookAccount', {});
806
- const {orgUnitFacebookPageSettingsMap = {}, employeeAccessToken: accessToken = "", accountId = "" } = selectedFacebookAccount;
814
+ const selectedFacebookAccount = templateData?.edit ? templateData?.selectedFacebookAccount : facebookTemplateData?.selectedFacebookAccount;
815
+ const {orgUnitFacebookPageSettingsMap = {}, employeeAccessToken: accessToken = "", accountId = "" } = selectedFacebookAccount || {};
807
816
 
808
817
  const getPageAccessOrgs = useCallback(() => {
809
818
  const {status, data } = fbADData.orgOuData || {};
@@ -813,14 +822,32 @@ export const Advertisement = (props) => {
813
822
  const orgName = (
814
823
  proxyOrgList.find(({ orgID }) => orgID === Number(orgId)) || {}
815
824
  ).orgName;
816
- if (status === 'SUCCESS') {
825
+ if (!status) {
826
+ // !status is the case of library
827
+ //if org id is the parent org
828
+ if (orgUnitFacebookPageSettingsMap[-1] && !pageId) {
829
+ setPageId(-1);
830
+ }
831
+ if (orgUnitFacebookPageSettingsMap[-1]) {
832
+ pageAccessOrgsOptions.push({label: orgName, value: -1});
833
+ }
834
+ // if we are coming from default startegy and calling templates from facebook/index.js
835
+ if (!pageId && orgUnitId && orgUnitFacebookPageSettingsMap[orgUnitId]) {
836
+ setPageId(orgUnitId);
837
+ }
838
+ } else if (status === 'SUCCESS') {
817
839
  Object.keys(data).forEach((obj) => {
818
840
  if ((orgUnitFacebookPageSettingsMap[data[obj]] || {}).pageAccessToken) {
819
- pageAccessOrgsOptions.push({label: data[obj] === -1 ? orgName : obj, value: data[obj]});
841
+ pageAccessOrgsOptions.push({label: obj, value: data[obj]});
820
842
  }
821
843
  });
822
- if (!pageId) {
844
+ if (orgUnitFacebookPageSettingsMap[-1]) {
845
+ pageAccessOrgsOptions.push({label: orgName, value: -1});
846
+ }
847
+ if (!pageId && !isEmpty(data)) {
823
848
  setPageId((pageAccessOrgsOptions[0] || {} ).value);
849
+ } else if (orgUnitFacebookPageSettingsMap[-1] && !pageId) {
850
+ setPageId(-1);
824
851
  }
825
852
  }
826
853
  return pageAccessOrgsOptions;
@@ -829,7 +856,7 @@ export const Advertisement = (props) => {
829
856
  const options = getPageAccessOrgs() || [];
830
857
  const { data = {} } = fbADData.orgOuData || {};
831
858
  const selectedPageName = Object.keys(data).find((key) => data[key] === pageId);
832
- return ( (step === 'modeSelection') ?
859
+ return ( (step === 'modeSelection' && (isEmpty(templateData) || templateData?.mode === "create")) ?
833
860
  ( <CapSpin spinning={adSpinLoader} className="add-facebook-ad-section">
834
861
  <div style={{ position: 'fixed', top: '25px', zIndex: 1}}>
835
862
  <CapHeader
@@ -838,25 +865,27 @@ export const Advertisement = (props) => {
838
865
  className={"cap-header-facebook-ad"}
839
866
  />
840
867
  </div>
841
- <CapInput
842
- id={`fbAd_input`}
843
- onChange={onTextTitleChange}
844
- className="text-template-title"
845
- defaultValue={messageTitle || ''}
846
- value={messageTitle || ''}
847
- style={{marginBottom: 27, width: '762px'}}
848
- size="default"
849
- label={formatMessage(messages.creativeName)}
850
- />
851
- {isFullMode && <CapSelect
852
- label={formatMessage(messages.facebookPage)}
853
- key={"select-facebook-page"}
854
- onChange={onChangeFacebookPage}
855
- options={options}
856
- defaultValue={(options[0] || {} ).value}
857
- value={pageId || (options[0] || {} ).value}
858
- style={{marginBottom: 27, width: '372px'}}
859
- ></CapSelect>}
868
+ {isFullMode && <>
869
+ <CapInput
870
+ id={`fbAd_input`}
871
+ onChange={onTextTitleChange}
872
+ className="text-template-title"
873
+ defaultValue={messageTitle || ''}
874
+ value={messageTitle || ''}
875
+ style={{marginBottom: 27, width: '762px'}}
876
+ size="default"
877
+ label={formatMessage(messages.creativeName)}
878
+ />
879
+ <CapSelect
880
+ label={formatMessage(messages.facebookPage)}
881
+ key={"select-facebook-page"}
882
+ onChange={onChangeFacebookPage}
883
+ options={options}
884
+ defaultValue={(options[0] || {} ).value}
885
+ value={pageId || (options[0] || {} ).value}
886
+ style={{marginBottom: 27, width: '372px'}}
887
+ ></CapSelect>
888
+ </>}
860
889
  <CapHeading
861
890
  type="h4"
862
891
  style={{marginBottom: 11}}
@@ -880,8 +909,15 @@ export const Advertisement = (props) => {
880
909
  </FbAdFooter>
881
910
  </CapSpin> ) : (
882
911
  <CapSpin spinning={spinLoader}>
912
+ {!isFullMode && isEmpty(templateData) && <div style={{ position: 'fixed', top: '25px', zIndex: 1}}>
913
+ <CapHeader
914
+ inline
915
+ title={formatMessage(messages.newFacebookCreatives)}
916
+ className={"cap-header-facebook-ad"}
917
+ />
918
+ </div>}
883
919
  <CapRow className="add-facebook-ad-section" >
884
- <div className="cap-header-facebook-ad">
920
+ {isFullMode && <div className="cap-header-facebook-ad">
885
921
  <CapHeading
886
922
  type="h2"
887
923
  className="truncate-text"
@@ -899,7 +935,7 @@ export const Advertisement = (props) => {
899
935
  title={<FormattedMessage {...messages.creativesTemplatesEditName}/>}
900
936
  onClick={onClickEditName}
901
937
  />}
902
- </div>
938
+ </div>}
903
939
  <CapColumn span={12}>
904
940
  {isFullMode && <><CapHeading
905
941
  type="h4"
@@ -974,8 +1010,8 @@ Advertisement.propTypes = {
974
1010
  facebookTemplateData: PropTypes.object,
975
1011
  templateData: PropTypes.object,
976
1012
  params: PropTypes.object,
1013
+ selectedMarketingObjective: PropTypes.any,
977
1014
 
978
1015
  };
979
1016
 
980
1017
  export default injectIntl(Advertisement);
981
-
@@ -30,7 +30,7 @@ $classPrefix: add-facebook-ad-section;
30
30
 
31
31
  .cap-header-facebook-ad{
32
32
  position: fixed;
33
- top: 27px;
33
+ top: 58px;
34
34
  z-index: 1000;
35
35
  .title-desc-container{
36
36
  padding-left: 10px;
@@ -50,7 +50,7 @@ export default css`
50
50
 
51
51
  .parameter-list-item {
52
52
  list-style: none;
53
- margin-bottom: ${CAP_SPACE_28};
53
+ margin-bottom: 60px;
54
54
 
55
55
  .parameter-index {
56
56
  float: left;
@@ -47,3 +47,7 @@ export const VALUE_REACH = 'VALUE_REACH';
47
47
  export const VALUE_VIDEO_VIEWS = 'VALUE_VIDEO_VIEWS';
48
48
  export const VALUE_LINK_CLICKS = 'VALUE_LINK_CLICKS';
49
49
  export const VALUE_POST_ENGAGEMENT = 'VALUE_POST_ENGAGEMENT';
50
+
51
+
52
+ export const AD_MANAGER = "AD_MANAGER";
53
+ export const CREATIVE = "CREATIVE";