@capillarytech/creatives-library 7.17.91 → 7.17.92

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 (50) hide show
  1. package/index.js +6 -0
  2. package/package.json +1 -1
  3. package/routes.js +5 -0
  4. package/services/api.js +5 -0
  5. package/v2Components/CapDeviceContent/index.js +338 -0
  6. package/v2Components/CapDeviceContent/index.scss +115 -0
  7. package/v2Components/CapDeviceContent/messages.js +107 -0
  8. package/v2Components/CapDeviceContent/tests/index.test.js +75 -0
  9. package/v2Components/CapImageUpload/index.js +10 -3
  10. package/v2Components/CapImageUpload/messages.js +4 -0
  11. package/v2Components/CapInAppCTA/constants.js +25 -0
  12. package/v2Components/CapInAppCTA/index.js +281 -0
  13. package/v2Components/CapInAppCTA/index.scss +93 -0
  14. package/v2Components/CapInAppCTA/messages.js +85 -0
  15. package/v2Components/MobilePushPreviewV2/index.js +81 -23
  16. package/v2Components/TemplatePreview/_templatePreview.scss +448 -0
  17. package/v2Components/TemplatePreview/assets/images/inapp_mobile_android_bottom.svg +11 -0
  18. package/v2Components/TemplatePreview/assets/images/inapp_mobile_android_full.svg +11 -0
  19. package/v2Components/TemplatePreview/assets/images/inapp_mobile_android_modal.svg +11 -0
  20. package/v2Components/TemplatePreview/assets/images/inapp_mobile_android_top.svg +11 -0
  21. package/v2Components/TemplatePreview/assets/images/inapp_mobile_ios_bottom.svg +6 -0
  22. package/v2Components/TemplatePreview/assets/images/inapp_mobile_ios_full.svg +18 -0
  23. package/v2Components/TemplatePreview/assets/images/inapp_mobile_ios_modal.svg +7 -0
  24. package/v2Components/TemplatePreview/assets/images/inapp_mobile_ios_top.svg +13 -0
  25. package/v2Components/TemplatePreview/index.js +660 -375
  26. package/v2Components/TemplatePreview/messages.js +4 -0
  27. package/v2Containers/App/constants.js +1 -0
  28. package/v2Containers/CreativesContainer/SlideBoxContent.js +43 -0
  29. package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -1
  30. package/v2Containers/CreativesContainer/constants.js +1 -0
  31. package/v2Containers/CreativesContainer/index.js +94 -27
  32. package/v2Containers/CreativesContainer/messages.js +4 -0
  33. package/v2Containers/InApp/actions.js +64 -0
  34. package/v2Containers/InApp/constants.js +95 -0
  35. package/v2Containers/InApp/index.js +745 -0
  36. package/v2Containers/InApp/index.scss +47 -0
  37. package/v2Containers/InApp/messages.js +86 -0
  38. package/v2Containers/InApp/reducer.js +109 -0
  39. package/v2Containers/InApp/sagas.js +143 -0
  40. package/v2Containers/InApp/selectors.js +12 -0
  41. package/v2Containers/InApp/tests/action.test.js +53 -0
  42. package/v2Containers/InApp/tests/index.test.js +152 -0
  43. package/v2Containers/InApp/tests/mockData.js +897 -0
  44. package/v2Containers/InApp/tests/reducer.test.js +177 -0
  45. package/v2Containers/InApp/tests/sagas.test.js +391 -0
  46. package/v2Containers/Templates/_templates.scss +7 -0
  47. package/v2Containers/Templates/index.js +103 -23
  48. package/v2Containers/Templates/messages.js +20 -0
  49. package/v2Containers/TemplatesV2/index.js +8 -2
  50. package/v2Containers/TemplatesV2/messages.js +4 -0
@@ -86,4 +86,8 @@ export default defineMessages({
86
86
  id: 'creatives.componentsV2.TemplatePreview.previewUrlMetaImage',
87
87
  defaultMessage: 'Preview url meta image',
88
88
  },
89
+ addToCart: {
90
+ id: `creatives.componentsV2.TemplatePreview.addToCart`,
91
+ defaultMessage: 'Add to cart',
92
+ },
89
93
  });
@@ -54,6 +54,7 @@ export const LINE = 'line';
54
54
  export const EMAIL = 'email';
55
55
  export const ASSETS = 'assets';
56
56
  export const ZALO = 'zalo';
57
+ export const INAPP = 'inapp';
57
58
 
58
59
  export const JP_LOCALE_HIDE_FEATURE = 'JP_LOCALE_HIDE_FEATURE';
59
60
 
@@ -22,6 +22,7 @@ import LineContainer from '../Line/Container';
22
22
  import FTP from '../FTP';
23
23
  import Viber from '../Viber';
24
24
  import Whatsapp from '../Whatsapp';
25
+ import InApp from '../InApp';
25
26
  import Rcs from '../Rcs';
26
27
  import { getWhatsappContent } from '../Whatsapp/utils';
27
28
  import * as commonUtil from '../../utils/common';
@@ -182,6 +183,7 @@ export function SlideBoxContent(props) {
182
183
  const isCreateSms = isCreate && channel === constants.SMS;
183
184
  const isCreateFacebook = isCreate && channel === constants.FACEBOOK;
184
185
  const isCreateWhatsapp = isCreate && channel === constants.WHATSAPP;
186
+ const isCreateInApp = isCreate && channel === constants.INAPP;
185
187
  const isCreateRcs = isCreate && channel === constants.RCS;
186
188
  const isCreateMPush = isCreate && channel === constants.MOBILE_PUSH;
187
189
  const isCreateCallTask = isCreate && channel === constants.CALL_TASK;
@@ -191,11 +193,13 @@ export function SlideBoxContent(props) {
191
193
  let isPreview = false;
192
194
  let isEmailPreview = false;
193
195
  let isMpushPreview = false;
196
+ let isInappPreview = false;
194
197
  let isEditCallTask = false;
195
198
  let isEditMPush = false;
196
199
  let isEditFacebook = false;
197
200
  let isEditFTP = false;
198
201
  let isEditWhatsapp = false;
202
+ let isEditInApp = false;
199
203
  let isEditRcs = false;
200
204
  let isEditZalo = false;
201
205
  const isEmailCreate = isCreate && channel === constants.EMAIL;
@@ -212,8 +216,10 @@ export function SlideBoxContent(props) {
212
216
  isPreview = slidBoxContent === 'preview' && [constants.SMS, constants.LINE, constants.WHATSAPP, constants.FACEBOOK, constants.VIBER, constants.RCS].includes(channel);
213
217
  isEmailPreview = slidBoxContent === 'preview' && channel === constants.EMAIL;
214
218
  isMpushPreview = slidBoxContent === 'preview' && channel === constants.MOBILE_PUSH;
219
+ isInappPreview = slidBoxContent === 'preview' && channel === constants.INAPP;
215
220
  isEditFTP = isEdit && [constants.NO_COMMUNICATION, constants.FTP].includes(channel);
216
221
  isEditZalo = isEdit && channel?.toUpperCase() === constants.ZALO;
222
+ isEditInApp = isEdit && channel === constants.INAPP;
217
223
  }
218
224
  const isDltEnabled = commonUtil.isTraiDLTEnable(isFullMode, smsRegister);
219
225
  const hasJPLocaleHideFeatureEnabled = commonUtil?.hasJPLocaleHideFeatureEnabled();
@@ -438,6 +444,13 @@ export function SlideBoxContent(props) {
438
444
  />
439
445
  )
440
446
  }
447
+ {isInappPreview && (
448
+ <MobilePushPreview
449
+ templateData={templateData}
450
+ channel={channel}
451
+ forwardedTags={forwardedTags}
452
+ />
453
+ )}
441
454
  {isMpushPreview && (
442
455
  <MobilePushPreview
443
456
  templateData={templateData}
@@ -786,6 +799,36 @@ export function SlideBoxContent(props) {
786
799
  }}/>
787
800
  )}
788
801
 
802
+ {isCreateInApp && (<InApp
803
+ isFullMode={isFullMode}
804
+ onCreateComplete={onCreateComplete}
805
+ handleClose={handleClose}
806
+ location={{
807
+ pathname: `/inapp/create`,
808
+ query,
809
+ search: '',
810
+ }}
811
+ />
812
+ )}
813
+
814
+ {isEditInApp && (<InApp
815
+ isFullMode={isFullMode}
816
+ templateData={templateData}
817
+ getFormData={getFormData}
818
+ getDefaultTags={type}
819
+ forwardedTags={forwardedTags}
820
+ onCreateComplete={onCreateComplete}
821
+ selectedOfferDetails={selectedOfferDetails}
822
+ params={{
823
+ id: templateData._id,
824
+ }}
825
+ location={{
826
+ pathname: `/inapp/edit`,
827
+ query,
828
+ search: '',
829
+ }} />
830
+ )}
831
+
789
832
  {isCreateRcs && (<Rcs
790
833
  {...rcsCommonProps}
791
834
  location={{
@@ -11,7 +11,7 @@ import whatsppMsg from '../Whatsapp/messages';
11
11
  import { LANGUAGE_OPTIONS } from '../Whatsapp/constants';
12
12
  import globalMessages from '../Cap/messages';
13
13
  import { MAP_TEMPLATE } from '../WeChat/Wrapper/constants';
14
- import { NO_COMMUNICATION, FTP, WHATSAPP, RCS, ZALO } from '../App/constants';
14
+ import { NO_COMMUNICATION, FTP, WHATSAPP, RCS, ZALO, INAPP } from '../App/constants';
15
15
  import { isTraiDLTEnable } from '../../utils/common';
16
16
  import { formatString } from '../../utils/Formatter';
17
17
  import {
@@ -39,7 +39,9 @@ export function SlideBoxHeader(props) {
39
39
  const isTraiDlt = isTraiDLTEnable(isFullMode, smsRegister);
40
40
  const showCreateTraiSMSHeader = isTraiDlt && channel.toLowerCase() === "sms";
41
41
  const isWhatsappEdit = channel.toLowerCase() === WHATSAPP && slidBoxContent === 'editTemplate';
42
+ const isInAppEdit = channel.toLowerCase() === INAPP && slidBoxContent === 'editTemplate';
42
43
  const isWhatsappCreate = channel.toLowerCase() === WHATSAPP && slidBoxContent === 'createTemplate';
44
+ const isInAppCreate = channel.toLowerCase() === INAPP && slidBoxContent === 'createTemplate';
43
45
  const isZaloEdit = channel.toLowerCase() === ZALO && slidBoxContent === 'editTemplate';
44
46
  const zaloOverview = isZaloEdit && isFullMode;
45
47
  const whatsappOverview = isWhatsappEdit && isFullMode;
@@ -60,6 +62,7 @@ export function SlideBoxHeader(props) {
60
62
  sms: <FormattedMessage {...messages.smsHeader} />,
61
63
  email: <FormattedMessage {...messages.emailHeader} />,
62
64
  mobilepush: <FormattedMessage {...messages.pushNotificationHeader} />,
65
+ inapp: <FormattedMessage {...messages.inAppHeader} />,
63
66
  wechat: <FormattedMessage {...messages.wechat} />,
64
67
  line: <FormattedMessage {...messages.lineHeader} />,
65
68
  no_communication: <FormattedMessage {...messages.noCommunication} />,
@@ -19,6 +19,7 @@ export const VIBER = "VIBER";
19
19
  export const WHATSAPP = "WHATSAPP";
20
20
  export const RCS = "RCS";
21
21
  export const ZALO = "ZALO";
22
+ export const INAPP = "INAPP";
22
23
  export const PREVIEW = "preview";
23
24
  export const EDIT_TEMPLATE = "editTemplate";
24
25
 
@@ -40,6 +40,7 @@ import { LOYALTY } from '../App/constants';
40
40
  import { WHATSAPP_STATUSES, WHATSAPP_MEDIA_TYPES } from '../Whatsapp/constants';
41
41
 
42
42
  import { updateImagesInHtml } from '../../utils/cdnTransformation';
43
+ import { IOS } from '../InApp/constants';
43
44
 
44
45
  const classPrefix = 'add-creatives-section';
45
46
  const CREATIVES_CONTAINER = 'creativesContainer';
@@ -83,7 +84,7 @@ export class Creatives extends React.Component {
83
84
 
84
85
  componentDidMount() {
85
86
  GA.timeTracker.startTimer(CREATIVES_CONTAINER);
86
- if(!this.props?.isFullMode){
87
+ if (!this.props?.isFullMode) {
87
88
  this.props?.templateActions.getCdnTransformationConfig();
88
89
  }
89
90
  }
@@ -155,7 +156,7 @@ export class Creatives extends React.Component {
155
156
  this.setState((prevState) => {
156
157
  let templateStep = prevState.templateStep + 1;
157
158
  const {emailCreateMode, currentChannel} = prevState;
158
- if ((currentChannel.toUpperCase() === constants.EMAIL && emailCreateMode === "upload") || currentChannel.toUpperCase() === constants.MOBILE_PUSH || currentChannel.toUpperCase() === constants.WECHAT) {
159
+ if ((currentChannel.toUpperCase() === constants.EMAIL && emailCreateMode === "upload") || currentChannel.toUpperCase() === constants.MOBILE_PUSH || currentChannel.toUpperCase() === constants.WECHAT || constants.INAPP) {
159
160
  templateStep = prevState.templateStep + 2;
160
161
  }
161
162
  return {
@@ -168,6 +169,9 @@ export class Creatives extends React.Component {
168
169
  this.setState({ emailCreateMode: mode});
169
170
  }
170
171
 
172
+ onInAppModeChange = (mode) => {
173
+ this.setState({ inAppCreateMode: mode});
174
+ }
171
175
 
172
176
  onMobilepushModeChange = (mode) => {
173
177
  this.setState({ mobilePushCreateMode: mode});
@@ -191,6 +195,7 @@ export class Creatives extends React.Component {
191
195
  this.setState({ isGetFormData: false });
192
196
  };
193
197
  getTemplateData = (templateData) => { //from consumers to creatives
198
+ console.log('in getTemplateData', templateData, this.props);
194
199
  const { isFullMode, messageDetails = {}, smsRegister } = this.props;
195
200
  const { additionalProperties = {} } = messageDetails;
196
201
  if (!isFullMode && templateData) { // for component mode
@@ -266,21 +271,23 @@ export class Creatives extends React.Component {
266
271
  };
267
272
  break;
268
273
  }
269
- case constants.MOBILE_PUSH: {
270
- const mode = get(templateData, 'androidContent.type') || get(templateData, 'iosContent.type') || '';
271
- creativesTemplateData = {
272
- type: channel,
273
- name: templateData.messageSubject,
274
- versions: {
275
- base: {
276
- ANDROID: templateData.androidContent,
277
- IOS: templateData.iosContent,
274
+ case constants.MOBILE_PUSH:
275
+ case constants.INAPP:
276
+ {
277
+ const mode = get(templateData, 'androidContent.type') || get(templateData, 'iosContent.type') || '';
278
+ creativesTemplateData = {
279
+ type: channel,
280
+ name: templateData.messageSubject,
281
+ versions: {
282
+ base: {
283
+ ANDROID: templateData.androidContent,
284
+ IOS: templateData.iosContent,
285
+ },
278
286
  },
279
- },
280
- definition: {accountId: templateData.accountId, mode: mode.toLowerCase()},
281
- };
282
- break;
283
- }
287
+ definition: {accountId: templateData.accountId, mode: mode.toLowerCase()},
288
+ };
289
+ break;
290
+ }
284
291
  case constants.WECHAT: {
285
292
  const messageBody = JSON.parse(templateData.messageBody);
286
293
  creativesTemplateData = {
@@ -526,6 +533,7 @@ export class Creatives extends React.Component {
526
533
 
527
534
  getCreativesData = async (channel, template, templateRecords) => { //from creatives to consumers
528
535
  let templateData = { channel };
536
+ console.log('in getCreativesData', channel, template);
529
537
  switch (channel) {
530
538
  case constants.SMS:
531
539
  if (template?.value?.base) {
@@ -613,6 +621,50 @@ export class Creatives extends React.Component {
613
621
  templateData.messageSubject = mobilpushTemplate.name ? mobilpushTemplate.name : "messageSubject";
614
622
  }
615
623
  break;
624
+ case constants.INAPP:
625
+ if (get(template, "value.versions.base")) {
626
+ const inAppTemplate = template.value;
627
+ templateData.accountId = get(inAppTemplate, 'definition.accountId');
628
+ const type = (get(this.props, "messageDetails.type") || '').toLowerCase();
629
+ if (type === LOYALTY) {
630
+ templateData.licenseCode = get(inAppTemplate, 'definition.licenseCode');
631
+ templateData.templateId = get(inAppTemplate, '_id');
632
+ }
633
+ const androidContent = get(inAppTemplate, 'versions.base.ANDROID');
634
+ if (!isEmpty(androidContent)) {
635
+ if (type !== LOYALTY) {
636
+ delete androidContent.cuid;
637
+ delete androidContent.luid;
638
+ delete androidContent.communicationId;
639
+ }
640
+ const custom = {};
641
+ forEach(androidContent.custom, (customKeyValue) => {
642
+ custom[customKeyValue.key] = customKeyValue.value;
643
+ });
644
+ androidContent.custom = custom;
645
+ templateData.androidContent = androidContent;
646
+ templateData.androidContent.type = get(inAppTemplate, 'definition.mode', '').toUpperCase();
647
+ templateData.androidContent.deviceType = 'ANDROID';
648
+ }
649
+ const iosContent = get(inAppTemplate, 'versions.base.IOS');
650
+ if (!isEmpty(iosContent)) {
651
+ if (type !== LOYALTY) {
652
+ delete iosContent.cuid;
653
+ delete iosContent.luid;
654
+ delete iosContent.communicationId;
655
+ }
656
+ const custom = {};
657
+ forEach(iosContent.custom, (customKeyValue) => {
658
+ custom[customKeyValue.key] = customKeyValue.value;
659
+ });
660
+ iosContent.custom = custom;
661
+ templateData.iosContent = iosContent;
662
+ templateData.iosContent.type = get(inAppTemplate, 'definition.mode').toUpperCase();
663
+ templateData.iosContent.deviceType = IOS.toUpperCase();
664
+ }
665
+ templateData.messageSubject = inAppTemplate?.name ? inAppTemplate?.name : "messageSubject";
666
+ }
667
+ break;
616
668
  case constants.WECHAT:
617
669
  if (template.value) {
618
670
  const { accountId, previewContent, ...messageBody } = template.value;
@@ -709,10 +761,10 @@ export class Creatives extends React.Component {
709
761
  header,
710
762
  footer,
711
763
  headerVarMapped,
712
- headerTemplate
764
+ headerTemplate,
713
765
  };
714
766
  const {
715
- whatsappDocName = '', whatsappDocSize, whatsappDocPages, whatsappDocImg = ''
767
+ whatsappDocName = '', whatsappDocSize, whatsappDocPages, whatsappDocImg = '',
716
768
  } = whatsappDocParams;
717
769
  switch (mediaType) {
718
770
  case (WHATSAPP_MEDIA_TYPES.IMAGE):
@@ -842,6 +894,7 @@ export class Creatives extends React.Component {
842
894
  default:
843
895
  break;
844
896
  }
897
+ console.log('in getCreativesData templateData', templateData);
845
898
  return templateData;
846
899
  };
847
900
  getSlideBoxContent({mode, templateData, isFullMode}) {
@@ -904,6 +957,13 @@ export class Creatives extends React.Component {
904
957
  imageAdded: androidType === 'IMAGE' || iosType === 'IMAGE',
905
958
  };
906
959
  break;
960
+ case constants.INAPP:
961
+ gtmDetails = {
962
+ ...gtmDetails,
963
+ content: `${androidTitle} ${androidMessage} ${iosTitle} ${iosMessage}`,
964
+ imageAdded: androidType === IMAGE || iosType === IMAGE,
965
+ };
966
+ break;
907
967
  case constants.LINE:
908
968
  gtmDetails = Object.assign({
909
969
  ...gtmDetails,
@@ -937,10 +997,10 @@ export class Creatives extends React.Component {
937
997
  const templateData = this.state.templateData ? this.state.templateData : template; //select existing or create new content
938
998
  const channel = templateData.type;
939
999
  const creativesData = this.getCreativesData(channel, template, templateData );// convers data to consumer understandable format
940
- creativesData.then(data=>{
1000
+ creativesData.then((data) => {
941
1001
  this.logGTMEvent(channel, data);
942
1002
  this.props.getCreativesData(data);// send data to consumer
943
- })
1003
+ });
944
1004
  },
945
1005
  );
946
1006
  }
@@ -981,12 +1041,13 @@ export class Creatives extends React.Component {
981
1041
  }
982
1042
  shouldShowFooter = () => {
983
1043
  const {isFullMode } = this.props;
984
- const {slidBoxContent, currentChannel, emailCreateMode, templateNameExists, templateStep, mobilePushCreateMode, weChatTemplateType, templateData} = this.state;
1044
+ const {slidBoxContent, currentChannel, emailCreateMode, templateNameExists, templateStep, mobilePushCreateMode, inAppCreateMode, weChatTemplateType, templateData} = this.state;
985
1045
  const channel = currentChannel.toUpperCase();
986
1046
  const currentStep = this.creativesTemplateSteps[templateStep];
987
1047
  let showFooter = false;
988
1048
  showFooter = isFullMode && slidBoxContent === "preview";
989
1049
  const isMobilepush = channel === constants.MOBILE_PUSH;
1050
+ const isInApp = channel === constants.INAPP;
990
1051
  if (!isFullMode ) {
991
1052
  const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
992
1053
  const isCreate = (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate') && !isEmailCreate;
@@ -995,6 +1056,9 @@ export class Creatives extends React.Component {
995
1056
  if (isMobilepush) {
996
1057
  showFooter = currentStep === "modeSelection" || (currentStep === 'createTemplateContent' && !isEmpty(mobilePushCreateMode));
997
1058
  }
1059
+ if (isInApp) {
1060
+ showFooter = currentStep === "modeSelection" || (currentStep === 'createTemplateContent' && !isEmpty(inAppCreateMode));
1061
+ }
998
1062
  } else if (channel === constants.EMAIL && isFullMode) {
999
1063
  const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
1000
1064
  showFooter = isEmailCreate && emailCreateMode;
@@ -1049,7 +1113,7 @@ export class Creatives extends React.Component {
1049
1113
  if (channel === constants.EMAIL || channel === constants.SMS) {
1050
1114
  const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
1051
1115
  showDone = (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate') && !isEmailCreate;
1052
- } else if (channel === constants.MOBILE_PUSH || channel === constants.WECHAT) {
1116
+ } else if ([constants.WECHAT, constants.MOBILE_PUSH, constants.INAPP].includes(channel)) {
1053
1117
  showDone = currentStep === "createTemplateContent" || slidBoxContent === "editTemplate";
1054
1118
  }
1055
1119
 
@@ -1072,7 +1136,7 @@ export class Creatives extends React.Component {
1072
1136
  onChange={(ev) => {
1073
1137
  const value = ev.currentTarget.value;
1074
1138
  const isEmptyTemplateName = value.trim() ? false : true;
1075
- this.setState({isTemplateNameEmpty : isEmptyTemplateName});
1139
+ this.setState({isTemplateNameEmpty: isEmptyTemplateName});
1076
1140
  const newFormData = {...formData, 'template-name': value};
1077
1141
  onFormDataChange(newFormData);
1078
1142
  }}
@@ -1080,10 +1144,10 @@ export class Creatives extends React.Component {
1080
1144
  showTemplateName = ({formData, onFormDataChange}) => { //gets called from email/index after template data is fetched
1081
1145
  const {slidBoxContent, currentChannel, isEditName} = this.state;
1082
1146
  const channel = currentChannel.toUpperCase();
1083
- if ((channel === constants.EMAIL || channel === constants.MOBILE_PUSH) && (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate')) {
1147
+ if ([constants.EMAIL, constants.MOBILE_PUSH, constants.INAPP].includes(channel) && (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate')) {
1084
1148
  const name = get(formData, 'template-name');
1085
1149
  if (channel === constants.EMAIL && !name && slidBoxContent === 'createTemplate') {
1086
- this.setState({isTemplateNameEmpty:true});
1150
+ this.setState({isTemplateNameEmpty: true});
1087
1151
  }
1088
1152
  this.templateContainerDetails = {formData, onFormDataChange};
1089
1153
  if (name && !isEditName) {
@@ -1094,7 +1158,7 @@ export class Creatives extends React.Component {
1094
1158
  }
1095
1159
  }
1096
1160
  shouldShowContinueFooter = () => { // only for email for now, has to be modified according to channel
1097
- const {slidBoxContent, templateStep, currentChannel, emailCreateMode, mobilePushCreateMode, weChatTemplateType} = this.state;
1161
+ const {slidBoxContent, templateStep, currentChannel, emailCreateMode, mobilePushCreateMode, inAppCreateMode, weChatTemplateType} = this.state;
1098
1162
  let isShowContinueFooter = false;
1099
1163
  const currentStep = this.creativesTemplateSteps[templateStep];
1100
1164
  const channel = currentChannel.toUpperCase();
@@ -1108,6 +1172,8 @@ export class Creatives extends React.Component {
1108
1172
  isShowContinueFooter = !isEmpty(mobilePushCreateMode) && currentStep === "modeSelection";
1109
1173
  } else if (currentChannel.toUpperCase() === constants.WECHAT) {
1110
1174
  isShowContinueFooter = !isEmpty(weChatTemplateType) && currentStep === "modeSelection";
1175
+ } else if (currentChannel.toUpperCase() === constants.INAPP) {
1176
+ isShowContinueFooter = !isEmpty(inAppCreateMode) && currentChannel === "modeSelection";
1111
1177
  }
1112
1178
 
1113
1179
  return isShowContinueFooter;
@@ -1117,7 +1183,7 @@ export class Creatives extends React.Component {
1117
1183
  const {templateContainerDetails} = this;
1118
1184
  const {formData, onFormDataChange} = templateContainerDetails;
1119
1185
  const channel = currentChannel.toUpperCase();
1120
- if ((channel === constants.EMAIL || channel === constants.MOBILE_PUSH) && (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate')) {
1186
+ if ([constants.EMAIL, constants.MOBILE_PUSH, constants.INAPP].includes(channel) && (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate')) {
1121
1187
  const name = get(formData, 'template-name');
1122
1188
  return showTemplateNameComponentEdit ? this.templateNameComponentInput({formData, onFormDataChange, name}) : this.templateNameComponentHeader({formData, onFormDataChange, name});
1123
1189
  }
@@ -1150,6 +1216,7 @@ export class Creatives extends React.Component {
1150
1216
  smsRegister,
1151
1217
  enableNewChannels,
1152
1218
  } = this.props;
1219
+ console.log('this.props', this.props);
1153
1220
  const mapTemplateCreate = slidBoxContent === 'createTemplate' && weChatTemplateType === MAP_TEMPLATE && templateStep !== 'modeSelection';
1154
1221
  /* TODO: Instead of passing down same props separately to each component down, write common function to these props and pass it accordingly */
1155
1222
  return (
@@ -338,6 +338,10 @@ export default defineMessages({
338
338
  id: `${scope}.pushNotificationHeader`,
339
339
  defaultMessage: `Push notification`,
340
340
  },
341
+ "inAppHeader": {
342
+ id: `${scope}.inAppHeader`,
343
+ defaultMessage: `In App Message`,
344
+ },
341
345
  "wechat": {
342
346
  id: `${scope}.wechat`,
343
347
  defaultMessage: `Wechat`,
@@ -0,0 +1,64 @@
1
+ import { INAPP } from "../CreativesContainer/constants";
2
+ import {
3
+ INAPP_TEMPLATE_CREATE_REQUEST,
4
+ CLEAR_CREATE_RESPONSE_REQUEST,
5
+ GET_INAPP_TEMPLATE_DETAILS_REQUEST,
6
+ RESET_EDIT_TEMPLATE,
7
+ UPLOAD_INAPP_ASSET_REQUEST,
8
+ CLEAR_INAPP_ASSET,
9
+ INAPP_EDIT_TEMPLATE_REQUEST,
10
+ } from "./constants";
11
+
12
+ export function createInAppTemplate(payload, callback) {
13
+ return {
14
+ type: INAPP_TEMPLATE_CREATE_REQUEST,
15
+ payload,
16
+ callback,
17
+ };
18
+ }
19
+ export function clearCreateResponse() {
20
+ return {
21
+ type: CLEAR_CREATE_RESPONSE_REQUEST,
22
+ };
23
+ }
24
+ // FOR EDIT
25
+ export function getTemplateDetails(id, callback) {
26
+ return {
27
+ type: GET_INAPP_TEMPLATE_DETAILS_REQUEST,
28
+ id,
29
+ channel: INAPP,
30
+ callback,
31
+ };
32
+ }
33
+
34
+ export function editTemplate(template, callback) {
35
+ return {
36
+ type: INAPP_EDIT_TEMPLATE_REQUEST,
37
+ payload: template,
38
+ callback,
39
+ };
40
+ }
41
+
42
+ export function resetEditTemplate() {
43
+ return {
44
+ type: RESET_EDIT_TEMPLATE,
45
+ };
46
+ }
47
+
48
+ export const uploadInAppAsset = (
49
+ file,
50
+ assetType,
51
+ fileParams,
52
+ templateType,
53
+ ) => ({
54
+ type: UPLOAD_INAPP_ASSET_REQUEST,
55
+ file,
56
+ assetType,
57
+ fileParams,
58
+ templateType,
59
+ });
60
+
61
+ export const clearInAppAsset = (templateType) => ({
62
+ type: CLEAR_INAPP_ASSET,
63
+ templateType,
64
+ });
@@ -0,0 +1,95 @@
1
+ import React from "react";
2
+ import { FormattedMessage } from "react-intl";
3
+ import { WEBSITE } from "../../v2Components/CapInAppCTA/constants";
4
+ import messages from "./messages";
5
+
6
+ const prefix = "app/v2Containers/InApp";
7
+ export const INAPP_TEMPLATE_CREATE_REQUEST = `${prefix}/INAPP_TEMPLATE_CREATE_REQUEST`;
8
+ export const INAPP_TEMPLATE_CREATE_SUCCESS = `${prefix}/INAPP_TEMPLATE_CREATE_SUCCESS`;
9
+ export const INAPP_TEMPLATE_CREATE_FAILURE = `${prefix}/INAPP_TEMPLATE_CREATE_FAILURE`;
10
+ export const INAPP_EDIT_TEMPLATE_REQUEST = `${prefix}/INAPP_EDIT_TEMPLATE_REQUEST`;
11
+ export const INAPP_EDIT_TEMPLATE_SUCCESS = `${prefix}/INAPP_EDIT_TEMPLATE_SUCCESS`;
12
+ export const INAPP_EDIT_TEMPLATE_FAILURE = `${prefix}/INAPP_EDIT_TEMPLATE_FAILURE`;
13
+ export const CLEAR_CREATE_RESPONSE_REQUEST = `${prefix}/CLEAR_CREATE_RESPONSE_REQUEST`;
14
+ // FOR EDIT
15
+ export const GET_INAPP_TEMPLATE_DETAILS_REQUEST = `${prefix}/Edit/GET_INAPP_TEMPLATE_DETAILS_REQUEST`;
16
+ export const GET_INAPP_TEMPLATE_DETAILS_SUCCESS = `${prefix}/Edit/GET_INAPP_TEMPLATE_DETAILS_SUCCESS`;
17
+ export const GET_INAPP_TEMPLATE_DETAILS_FAILURE = `${prefix}/Edit/GET_INAPP_TEMPLATE_DETAILS_FAILURE`;
18
+ export const RESET_EDIT_TEMPLATE = `${prefix}/Edit/RESET_EDIT_TEMPLATE`;
19
+
20
+ export const UPLOAD_INAPP_ASSET_REQUEST = `${prefix}/UPLOAD_INAPP_ASSET_REQUEST`;
21
+ export const UPLOAD_INAPP_ASSET_SUCCESS = `${prefix}/UPLOAD_INAPP_ASSET_SUCCESS`;
22
+ export const UPLOAD_INAPP_ASSET_FAILURE = `${prefix}/UPLOAD_INAPP_ASSET_FAILURE`;
23
+ export const CLEAR_INAPP_ASSET = `${prefix}/CLEAR_INAPP_ASSET`;
24
+
25
+ export const INAPP_MEDIA_TYPES = {
26
+ TEXT: "TEXT",
27
+ IMAGE: "IMAGE",
28
+ };
29
+
30
+ export const NONE = "NONE";
31
+ export const CTA = "CTA";
32
+ export const MAPP_SDK = "MAPP_SDK";
33
+ export const INAPP_BUTTON_TYPES = {
34
+ NONE,
35
+ CTA,
36
+ };
37
+
38
+ export const DEEP_LINK = 'DEEP_LINK';
39
+
40
+ export const INITIAL_CTA_DATA = [
41
+ {
42
+ index: 0,
43
+ ctaType: WEBSITE,
44
+ text: "",
45
+ urlType: DEEP_LINK,
46
+ url: "",
47
+ isSaved: false,
48
+ label: "",
49
+ },
50
+ ];
51
+
52
+ export const URL_MAX_LENGTH = 2000;
53
+
54
+ export const ALLOWED_IMAGE_EXTENSIONS_REGEX = /\.(jpe?g|png)$/i;
55
+ export const INAPP_IMG_SIZE = 5000000; // 5MB
56
+
57
+ export const TEMPLATE_MESSAGE_MAX_LENGTH = 1024;
58
+
59
+ export const INAPP_MESSAGE_LAYOUT_TYPES = {
60
+ MODAL: "POPUP",
61
+ TOPBANNER: "HEADER",
62
+ BOTTOMBANNER: "FOOTER",
63
+ FULLSCREEN: "FULLSCREEN",
64
+ };
65
+
66
+ export const ANDROID = "ANDROID";
67
+ export const IOS = "iOS";
68
+ export const LAYOUT_RADIO_OPTIONS = [
69
+ {
70
+ value: INAPP_MESSAGE_LAYOUT_TYPES.MODAL,
71
+ label: <FormattedMessage {...messages.layoutModal} />,
72
+ },
73
+ {
74
+ value: INAPP_MESSAGE_LAYOUT_TYPES.TOPBANNER,
75
+ label: <FormattedMessage {...messages.layoutTopBanner} />,
76
+ },
77
+ {
78
+ value: INAPP_MESSAGE_LAYOUT_TYPES.BOTTOMBANNER,
79
+ label: <FormattedMessage {...messages.layoutBottomBanner} />,
80
+ },
81
+ {
82
+ value: INAPP_MESSAGE_LAYOUT_TYPES.FULLSCREEN,
83
+ label: <FormattedMessage {...messages.layoutFullScreen} />,
84
+ },
85
+ ];
86
+ export const MEDIA_RADIO_OPTIONS = [
87
+ {
88
+ value: INAPP_MEDIA_TYPES.TEXT,
89
+ label: <FormattedMessage {...messages.mediaText} />,
90
+ },
91
+ {
92
+ value: INAPP_MEDIA_TYPES.IMAGE,
93
+ label: <FormattedMessage {...messages.mediaImage} />,
94
+ },
95
+ ];