@capillarytech/creatives-library 2.0.14 → 2.0.16

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.
@@ -28,6 +28,8 @@ function SlideBoxContent(props) {
28
28
  onCreateNew,
29
29
  toggleShowSlideBox,
30
30
  showSlideBox,
31
+ currentChannel,
32
+ onChannelChange,
31
33
  } = props;
32
34
  const type = messageDetails.type.toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
33
35
  const query = { type: 'embedded', module: 'library' };
@@ -42,8 +44,9 @@ function SlideBoxContent(props) {
42
44
  let isEmailEditWithContent = false;
43
45
  let isPreview = false;
44
46
  let isEmailPreview = false;
45
- if (templateData) {
46
- const channel = templateData.type;
47
+ let channel = currentChannel;//for create mode
48
+ if (templateData && channel) {
49
+ channel = templateData.type;// for edit mode with template data
47
50
  isEditSms = slidBoxContent === 'editTemplate' && channel === constants.SMS;
48
51
  isCreateSms = slidBoxContent === 'createTemplate' && channel === constants.SMS;
49
52
  isEditEmailWithId = slidBoxContent === 'editTemplate' && channel === constants.EMAIL && templateData._id;
@@ -61,6 +64,8 @@ function SlideBoxContent(props) {
61
64
  handlePeviewTemplate={onPreviewTemplate}
62
65
  location={location}
63
66
  createNew={onCreateNew}
67
+ channel={channel}
68
+ onChannelChange={onChannelChange}
64
69
  />
65
70
  )}
66
71
  {isPreview && (
@@ -147,5 +152,7 @@ SlideBoxContent.propTypes = {
147
152
  onCreateNew: PropTypes.func,
148
153
  toggleShowSlideBox: PropTypes.func,
149
154
  showSlideBox: PropTypes.bool,
155
+ onChannelChange: PropTypes.func,
156
+ currentChannel: PropTypes.string,
150
157
  };
151
158
  export default SlideBoxContent;
@@ -19,8 +19,9 @@ class Creatives extends React.Component {
19
19
  super(props);
20
20
  this.state = {
21
21
  showSlideBox: true,
22
- slidBoxContent: this.getSlideBocContent({mode: props.creativesMode, templateData: props.templateData}),
22
+ slidBoxContent: this.getSlideBocContent({mode: props.creativesMode, templateData: props.templateData, isFullMode: props.isFullMode}),
23
23
  templateData: this.getTemplateData(props.templateData),
24
+ currentChannel: this.props.channel || 'sms',
24
25
  };
25
26
  }
26
27
  componentWillUnmount() {
@@ -44,27 +45,13 @@ class Creatives extends React.Component {
44
45
  onShowTemplates = () => {
45
46
  this.setState({ slidBoxContent: 'templates', showSlideBox: true });
46
47
  };
47
- getSlideBocContent({mode, templateData}) {
48
- let creativesMode = 'templates';
49
- if (mode === 'create' && isEmpty(templateData)) {
50
- creativesMode = 'templates';
51
- } else if (mode === 'edit') {
52
- creativesMode = 'editTemplate';
53
- }
54
- return creativesMode;
48
+ onChannelChange = (channel) => {
49
+ this.setState({currentChannel: channel});
55
50
  }
56
- getCreativesData = (channel, template) => { //from creatives to consumers
57
- const templateData = {channel };
58
- if (channel === constants.SMS && template.value.base) {
59
- templateData.messageBody = template.value.base['sms-editor'];
60
- } else if (channel === constants.EMAIL && template.value.base) {
61
- templateData.emailBody = template.value.base.html_content;
62
- templateData.emailSubject = template.value.base.subject;
63
- }
64
- return templateData;
65
- };
51
+
66
52
  getTemplateData = (templateData) => { //from consumers to creatives
67
- if (templateData) {
53
+ const {isFullMode} = this.props;
54
+ if (!isFullMode && templateData) { // for component mode
68
55
  const {channel} = templateData;
69
56
  let creativesTeplateData = {type: channel };
70
57
  if (channel === constants.SMS) {
@@ -99,6 +86,27 @@ class Creatives extends React.Component {
99
86
  return null;
100
87
  }
101
88
 
89
+ getCreativesData = (channel, template) => { //from creatives to consumers
90
+ const templateData = {channel };
91
+ if (channel === constants.SMS && template.value.base) {
92
+ templateData.messageBody = template.value.base['sms-editor'];
93
+ } else if (channel === constants.EMAIL && template.value.base) {
94
+ templateData.emailBody = template.value.base.html_content;
95
+ templateData.emailSubject = template.value.base.subject;
96
+ }
97
+ return templateData;
98
+ };
99
+ getSlideBocContent({mode, templateData, isFullMode}) {
100
+ let creativesMode = isFullMode ? 'createTemplate' : 'templates';// for library mode templates page is initial mode and for full mode createTemplates
101
+ if (mode === 'create' && isFullMode) {
102
+ creativesMode = 'createTemplate';
103
+ } else if (mode === 'create' && isEmpty(templateData)) {
104
+ creativesMode = 'templates';
105
+ } else if (mode === 'edit') {
106
+ creativesMode = 'editTemplate';
107
+ }
108
+ return creativesMode;
109
+ }
102
110
  getFormData = (template) => {
103
111
  if (template.validity) {
104
112
  this.setState(
@@ -123,7 +131,8 @@ class Creatives extends React.Component {
123
131
  this.setState({ isGetFormData: true });
124
132
  };
125
133
  render() {
126
- const {slidBoxContent, isGetFormData, showSlideBox, templateData} = this.state;
134
+ const {slidBoxContent, isGetFormData, showSlideBox, templateData, currentChannel} = this.state;
135
+ const {isFullMode} = this.props;
127
136
  return (
128
137
  <div className={classnames(`${classPrefix}`)}>
129
138
  <CapSlideBox
@@ -148,6 +157,9 @@ class Creatives extends React.Component {
148
157
  isGetFormData={isGetFormData}
149
158
  toggleShowSlideBox={this.toggleShowSlideBox}
150
159
  showSlideBox={showSlideBox}
160
+ isFullMode={isFullMode}
161
+ currentChannel={currentChannel}
162
+ onChannelChange={this.onChannelChange}
151
163
  />
152
164
  }
153
165
  footer={
@@ -175,5 +187,7 @@ Creatives.propTypes = {
175
187
  location: PropTypes.object,
176
188
  handleCloseCreatives: PropTypes.func,
177
189
  templateData: PropTypes.object,
190
+ isFullMode: PropTypes.bool,
191
+ channel: PropTypes.string,
178
192
  };
179
193
  export default injectIntl(Creatives);
@@ -1,4 +1,4 @@
1
- @import '@capillarytech/cap-ui-library/styles/_variables.scss';
1
+ @import '~@capillarytech/cap-ui-library/styles/_variables.scss';
2
2
 
3
3
  $classPrefix: add-creatives-section;
4
4
 
@@ -44,6 +44,7 @@ import * as commonUtil from '../../utils/common';
44
44
  import SlideBox from '../../components/SlideBox';
45
45
  import Pagination from '../../components/Pagination';
46
46
  import EmailPreview from '../../components/EmailPreview';
47
+ import CreativesContainer from '../CreativesContainer';
47
48
  const MenuItem = Menu.Item;
48
49
  const Option = Select.Option;
49
50
  const BreadcrumbItem = Breadcrumb.Item;
@@ -307,10 +308,10 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
307
308
  this.props.createNew();
308
309
  return;
309
310
  }
310
- this.props.router.push({
311
+ this.setState({routeParams: {
311
312
  pathname: `/${nextProps.route.name.toLowerCase()}/create`,
312
313
  query: type === 'embedded' ? {type: 'embedded', module, isLanguageSupport, isEdmSupport} : {module},
313
- });
314
+ }});
314
315
  }
315
316
 
316
317
  if (!nextProps.Templates.sendingFile && !_.isEqual(this.props.Templates.sendingFile, nextProps.Templates.sendingFile) && nextProps.Templates.errorSendingFile) {
@@ -369,26 +370,8 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
369
370
  this.getAllTemplates({params, resetPage: true});
370
371
  });
371
372
  }
373
+ onPaginationChange = () => { this.getAllTemplates({getNextPage: true}); }
372
374
 
373
- setLocale = () => {
374
- const user = localStorage.getItem('user');
375
- let locale = 'en';
376
- if (user) {
377
- locale = JSON.parse(user).lang;
378
- }
379
- locale = this.getMappedLocale(locale);
380
- //locale = 'zh';
381
- console.log('Setting final locale as', locale);
382
- moment.locale(locale);
383
- };
384
-
385
- getMappedLocale = (locale) => {
386
- const map = {
387
- 'en': 'en',
388
- 'zh-cn': 'zh',
389
- };
390
- return map[locale];
391
- };
392
375
 
393
376
  getAllTemplates = ({params, getNextPage, resetPage}, resetTemplates) => {
394
377
  let queryParams = params;
@@ -435,7 +418,24 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
435
418
  });
436
419
  }
437
420
  };
438
-
421
+ getMappedLocale = (locale) => {
422
+ const map = {
423
+ 'en': 'en',
424
+ 'zh-cn': 'zh',
425
+ };
426
+ return map[locale];
427
+ };
428
+ setLocale = () => {
429
+ const user = localStorage.getItem('user');
430
+ let locale = 'en';
431
+ if (user) {
432
+ locale = JSON.parse(user).lang;
433
+ }
434
+ locale = this.getMappedLocale(locale);
435
+ //locale = 'zh';
436
+ console.log('Setting final locale as', locale);
437
+ moment.locale(locale);
438
+ };
439
439
  getCurrentWindow(e) {
440
440
  console.log('in sms templates', e);
441
441
  const response = {
@@ -445,39 +445,49 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
445
445
  };
446
446
  parent.postMessage(JSON.stringify(response), '*');
447
447
  }
448
-
448
+ getCreativesMode = () => {
449
+ const routeParams = this.state.routeParams;
450
+ let creativesMode = '';
451
+ if (routeParams) {
452
+ if (routeParams.pathname.indexOf('create') > -1) {
453
+ creativesMode = 'create';
454
+ }
455
+ }
456
+ return creativesMode;
457
+ }
449
458
  skipTemplateSelection = (e) => {
450
459
  console.log("vvv", e);
451
460
  const type = this.props.location.query.type;
452
461
  const module = (type === 'embedded') ? this.props.location.query.module : 'default';
462
+ let routeParams = {};
453
463
  if (this.state.channel.toLowerCase() === 'email') {
454
464
  const isLanguageSupport = this.props.location.query.isLanguageSupport || false;
455
- this.props.router.push({
465
+ routeParams = {
456
466
  pathname: `/email/view`,
457
467
  query: type === 'embedded' ? {type: 'embedded', module, isLanguageSupport} : {},
458
- });
468
+ };
459
469
  } else if (this.state.channel.toLowerCase() === 'sms') {
460
- this.props.router.push({
470
+ routeParams = {
461
471
  pathname: `/sms/view`,
462
472
  query: type === 'embedded' ? {type: 'embedded', module} : {},
463
- });
473
+ };
464
474
  } else if (this.state.channel.toLowerCase() === 'mobilepush') {
465
- this.props.router.push({
475
+ routeParams = {
466
476
  pathname: `/mobilepush/edit/${e.template_id}`,
467
477
  query: type === 'embedded' ? {type: 'embedded', module, account_id: e.account_id} : {},
468
- });
478
+ };
469
479
  } else if (this.state.channel.toLowerCase() === 'wechat') {
470
- this.props.router.push({
480
+ routeParams = {
471
481
  pathname: `/wechat/edit/${e.template_id}`,
472
482
  query: type === 'embedded' ? {type: 'embedded', module, source_account_id: e.source_account_id} : {},
473
- });
483
+ };
474
484
  } else if (this.state.channel.toLowerCase() === 'line') {
475
- this.props.router.push({
485
+ routeParams = {
476
486
  pathname: `/line/view/${e.msg_type}/`,
477
487
  query: type === 'embedded' ? {type: 'embedded', module, account_id: e.account_id } : {},
478
- });
488
+ };
479
489
  }
480
- this.setState({loading: true});
490
+ this.setState({loading: true, routeParams});
481
491
  }
482
492
 
483
493
  handleMenuAction = (item, key) => {
@@ -494,6 +504,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
494
504
  handleBlankTemplateAction = (item, channel) => {
495
505
  const type = this.props.location.query.type;
496
506
  const module = this.props.location.query.module ? this.props.location.query.module : 'default';
507
+ let routeParams = {};
497
508
  if (item === "uploadFile") {
498
509
  document.getElementById('filename').click();
499
510
  } else if (item === "editor") {
@@ -501,16 +512,17 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
501
512
  } else if (this.isEnabledInLibraryModule("callCreateFromProps")) {
502
513
  this.props.createNew(item);
503
514
  } else if (item === 'textTemplate') {
504
- this.props.router.push({
515
+ routeParams = {
505
516
  pathname: `/${channel === 'line' ? 'line' : 'mobilepush'}/create/text`,
506
517
  query: type === 'embedded' ? {type: 'embedded', module} : {module},
507
- });
518
+ };
508
519
  } else if (item === 'imageTemplate') {
509
- this.props.router.push({
520
+ routeParams = {
510
521
  pathname: `/${channel === 'line' ? 'line' : 'mobilepush'}/create/image`,
511
522
  query: type === 'embedded' ? {type: 'embedded', module} : {module},
512
- });
523
+ };
513
524
  }
525
+ this.setState({routeParams});
514
526
  }
515
527
 
516
528
  handleFileUpload = (e, {files}) => {
@@ -539,10 +551,10 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
539
551
  this.props.createNew();
540
552
  return;
541
553
  }
542
- this.props.router.push({
554
+ this.setState({routeParams: {
543
555
  pathname: `/${this.props.route.name.toLowerCase()}/create`,
544
556
  query: type === 'embedded' ? {type: 'embedded', module, isLanguageSupport, isEdmSupport} : {module},
545
- });
557
+ }});
546
558
  };
547
559
  reader.readAsText(files[0]);
548
560
  } else {
@@ -555,10 +567,10 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
555
567
  // const index = _.findIndex(this.props.Templates.weCRMtemplates, {template_id: key});
556
568
  // console.log('Wechat menu clicked ', item, key, index);
557
569
  const type = this.props.location.query.type;
558
- this.props.router.push({
570
+ this.setState({routeParams: {
559
571
  pathname: `/wechat/create`,
560
572
  query: type === 'embedded' ? {type: 'embedded'} : {},
561
- });
573
+ }});
562
574
  }
563
575
 
564
576
  prepareWeChatPreviewData(content, templateTags, tagData) {
@@ -722,19 +734,21 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
722
734
  const module = this.props.location.query.module ? this.props.location.query.module : 'default';
723
735
  const channel = this.state.channel.toLowerCase();
724
736
  //const keyType = ev.key && ev.key.toLowerCase() !== undefined ? ev.state.toLowerCase() : '';
737
+ let routeParams = {};
725
738
  if (this.isEnabledInLibraryModule("callCreateFromProps")) {
726
739
  this.props.createNew();
727
740
  } else if (ev.key && (ev.key.toLowerCase() === "text" || ev.key.toLowerCase() === "image")) {
728
- this.props.router.push({
741
+ routeParams = {
729
742
  pathname: `/${channel === 'line' ? 'line' : 'mobilepush'}/create/${ev.key.toLowerCase()}`,
730
743
  query: type === 'embedded' ? {type: 'embedded', module} : {module},
731
- });
744
+ };
732
745
  } else {
733
- this.props.router.push({
734
- pathname: `/${this.state.channel.toLowerCase()}/create`,
746
+ routeParams = {
747
+ pathname: `/templates/${this.state.channel.toLowerCase()}/create`,
735
748
  query: type === 'embedded' ? {type: 'embedded', module} : {module},
736
- });
749
+ };
737
750
  }
751
+ this.setState({routeParams});
738
752
  }
739
753
 
740
754
  searchTemplate(data) {
@@ -862,10 +876,10 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
862
876
  this.props.createNew();
863
877
  return;
864
878
  }
865
- this.props.router.push({
879
+ this.setState({routeParams: {
866
880
  pathname: `/${this.state.channel.toLowerCase()}/create`,
867
881
  query: getQuery,
868
- });
882
+ }});
869
883
  }
870
884
  };
871
885
 
@@ -907,10 +921,10 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
907
921
  if (this.state.channel.toLowerCase() === 'ebill') {
908
922
  pathName = `/ebill/edit/${id}`;
909
923
  }
910
- this.props.router.push({
924
+ this.setState({routeParams: {
911
925
  pathname: pathName,
912
926
  query: getQuery,
913
- });
927
+ }});
914
928
  }
915
929
  }
916
930
 
@@ -1227,30 +1241,30 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1227
1241
  pageHeaderText = this.props.intl.formatMessage(messages.lineHeader);
1228
1242
  }
1229
1243
  }
1230
- const options = [
1231
- {
1232
- value: "Most Recent",
1233
- label: this.props.intl.formatMessage(messages.mostRecentOption),
1234
- },
1235
- {
1236
- value: "Alphabetically",
1237
- label: this.props.intl.formatMessage(messages.alphabeticallyOption),
1238
- },
1239
- ];
1240
- const typeOptions = [
1241
- {
1242
- value: "All",
1243
- label: "All",
1244
- },
1245
- {
1246
- label: "Text",
1247
- value: 'Text',
1248
- },
1249
- {
1250
- label: "Image",
1251
- value: "Image",
1252
- },
1253
- ];
1244
+ // const options = [
1245
+ // {
1246
+ // value: "Most Recent",
1247
+ // label: this.props.intl.formatMessage(messages.mostRecentOption),
1248
+ // },
1249
+ // {
1250
+ // value: "Alphabetically",
1251
+ // label: this.props.intl.formatMessage(messages.alphabeticallyOption),
1252
+ // },
1253
+ // ];
1254
+ // const typeOptions = [
1255
+ // {
1256
+ // value: "All",
1257
+ // label: "All",
1258
+ // },
1259
+ // {
1260
+ // label: "Text",
1261
+ // value: 'Text',
1262
+ // },
1263
+ // {
1264
+ // label: "Image",
1265
+ // value: "Image",
1266
+ // },
1267
+ // ];
1254
1268
  const filterContent = (
1255
1269
  <div className="action-container">
1256
1270
  <CapInput
@@ -1261,24 +1275,14 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1261
1275
  value={this.state.searchText}
1262
1276
  onChange={(e) => this.searchTemplate(e.target.value)}
1263
1277
  />
1264
- {this.props.isComponent ? <div style={{display: "flex", justifyContent: "space-between", alignItems: 'center'}}>
1265
- <CapButton type="secondary" onClick={() => this.props.isComponent ? this.handleBlankTemplateAction() : this.createTemplate()}>{ this.props.intl.formatMessage(messages.createNewActionButton) }</CapButton>
1278
+ <div style={{display: "flex", justifyContent: "space-between", alignItems: 'center'}}>
1279
+ <CapButton
1280
+ type={this.props.isFullMode ? "primary" : "secondary"}
1281
+ onClick={(ev) => this.props.isFullMode ? this.createTemplate(ev) : this.handleBlankTemplateAction()} >
1282
+ { this.props.intl.formatMessage(messages.createNewActionButton) }
1283
+ </CapButton>
1266
1284
  </div>
1267
- :
1268
- <div className="action-container">
1269
- <div style={{display: "flex", justifyContent: "space-between", alignItems: 'center'}}>
1270
- <div className="select-font">{this.props.intl.formatMessage(messages.sortBy)}</div>
1271
- <CapSelect key={"select-account"} style={{width: '120px', marginLeft: '16px', minWidth: 'initial'}} defaultValue="Most Recent" onChange={this.handleSortBy} options={options}>
1272
- </CapSelect>
1273
- </div>
1274
- { (this.state.channel.toLowerCase() === 'mobilepush' || this.state.channel.toLowerCase() === 'line') &&
1275
- <div style={{display: "flex", justifyContent: "space-between", alignItems: 'center', marginLeft: '16px'}}>
1276
- <div className="select-font">Type</div>
1277
- <CapSelect key={"select-type"} style={{width: '120px', marginLeft: '16px', minWidth: 'initial'}} defaultValue="All" onChange={this.handleType} options={typeOptions}>
1278
- </CapSelect>
1279
- </div>
1280
- }
1281
- </div>}
1285
+
1282
1286
  </div>
1283
1287
  );
1284
1288
  const accountOptions = [];
@@ -1322,7 +1326,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1322
1326
  const pageHeader = (
1323
1327
  <div>
1324
1328
  {(this.props.location.query.type !== 'embedded') && `${pageHeaderText}`}
1325
- {!this.props.isComponent && templateText}
1329
+ {this.props.isFullMode && templateText}
1326
1330
  {(this.isEnabledInLibraryModule("showAccountSelection") || (((this.state.channel.toUpperCase() === 'WECHAT' || this.state.channel.toUpperCase() === "MOBILEPUSH") && (this.props.location.query.type !== 'embedded') && !_.isEmpty(this.props.Templates.weCrmAccounts)))) &&
1327
1331
  <CapSelect className="selectAccount" onSelect={this.onAccountSelect} value={this.props.Templates.selectedWeChatAccount ? this.props.Templates.selectedWeChatAccount.name : undefined} placeholder={this.props.intl.formatMessage(messages.selectAccount)}>
1328
1332
  {accountOptions}
@@ -1461,6 +1465,8 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1461
1465
  const templateList = this.populateTemplatesList(this.props.TemplatesList, true);
1462
1466
 
1463
1467
  const isSearch = this.props.Templates.isSearch;
1468
+ const creativesMode = this.getCreativesMode();
1469
+ const {isFullMode, route} = this.props;
1464
1470
  return (
1465
1471
  <div>
1466
1472
  <Spin
@@ -1470,7 +1476,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1470
1476
  <input type="file" id="filename" style={{ display: 'none'}} accept=".zip, .html, .htm" onChange={(event) => this.handleFileUpload(event, {files: event.target.files})} />
1471
1477
  <Row>
1472
1478
  <Col>
1473
- {(!this.props.isComponent || this.props.location.query.type !== "embedded") &&
1479
+ {(this.props.isFullMode || this.props.location.query.type !== "embedded") &&
1474
1480
  <Breadcrumb>
1475
1481
  <BreadcrumbItem>{this.props.intl.formatMessage(messages.campaigns)}</BreadcrumbItem>
1476
1482
  <BreadcrumbItem>{this.props.intl.formatMessage(messages.creatives)}</BreadcrumbItem>
@@ -1481,7 +1487,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1481
1487
  </Row>
1482
1488
  <Row className="template-header-container">
1483
1489
  <div className="template-header">{(this.props.location.query.type === 'embedded' && moduleName === 'dvs') ? pageHeaderDvs : pageHeader}</div>
1484
- {!this.props.isComponent && actionButton}
1485
1490
  </Row>
1486
1491
  <Row>
1487
1492
  <Helmet
@@ -1491,9 +1496,12 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1491
1496
  ]}
1492
1497
  />
1493
1498
  {this.props.renderNewCardGrid && templateList && templateList.length > 0 &&
1494
- this.props.renderNewCardGrid({templates: this.props.TemplatesList, filterContent, handlers: {handlePreviewClick: this.handlePreviewClick, handleEditClick: this.handleEditClick}})
1499
+ <Pagination onPageChange={this.onPaginationChange} paginationSelector="pagination-container">
1500
+ {this.props.renderNewCardGrid({templates: this.props.TemplatesList, filterContent, handlers: {handlePreviewClick: this.handlePreviewClick, handleEditClick: this.handleEditClick}})}
1501
+ </Pagination>
1495
1502
  }
1496
- {!this.props.renderNewCardGrid && ((templateList && templateList.length > 0) || isSearch) && <Pagination onPageChange={() => { console.log('getting all templates pagination'); this.getAllTemplates({getNextPage: true}); }} paginationSelector="pagination-container">
1503
+ {!this.props.renderNewCardGrid && ((templateList && templateList.length > 0) || isSearch) &&
1504
+ <Pagination onPageChange={this.onPaginationChange} paginationSelector="pagination-container">
1497
1505
  <CardGrid
1498
1506
  className={this.state.channel.toLowerCase() === "mobilepush" ? "mobilepush-templates" : ""}
1499
1507
  listItem={templateList}
@@ -1512,6 +1520,14 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1512
1520
  </div>}
1513
1521
  </Row>
1514
1522
  <Row>
1523
+ {!_.isEmpty(creativesMode) && isFullMode &&
1524
+ <CreativesContainer
1525
+ messageDetails={{type: "default"}}
1526
+ creativesMode={creativesMode}
1527
+ messages={messages}
1528
+ isFullMode={isFullMode}
1529
+ channel={route.name.toUpperCase()}/>
1530
+ }
1515
1531
  <PreviewSideBar
1516
1532
  showPreview={this.state.previewOpen}
1517
1533
  templateData={this.state.previewTemplate}
@@ -1569,7 +1585,7 @@ Templates.propTypes = {
1569
1585
  createNew: PropTypes.func,
1570
1586
  onSelectTemplate: PropTypes.func,
1571
1587
  lineActions: PropTypes.object,
1572
- isComponent: PropTypes.bool,
1588
+ isFullMode: PropTypes.bool,
1573
1589
  renderNewCardGrid: PropTypes.func,
1574
1590
  };
1575
1591
 
@@ -4,234 +4,258 @@
4
4
  * This contains all the text for the Templates component.
5
5
  */
6
6
  import { defineMessages } from 'react-intl';
7
-
7
+ const scope = `app.containers.Templates`;
8
8
  export default defineMessages({
9
9
  "header": {
10
- id: 'app.containers.Templates.header',
11
- defaultMessage: 'This is Templates container !',
10
+ id: `${scope}.header`,
11
+ defaultMessage: `This is Templates container !`,
12
12
  },
13
13
  "uploadedAt": {
14
- id: 'app.containers.Templates.uploadedAt',
15
- defaultMessage: 'Modified',
14
+ id: `${scope}.uploadedAt`,
15
+ defaultMessage: `Modified`,
16
16
  },
17
17
  "uploadedBy": {
18
- id: 'app.containers.Templates.uploadedBy',
19
- defaultMessage: 'Uploaded By',
18
+ id: `${scope}.uploadedBy`,
19
+ defaultMessage: `Uploaded By`,
20
20
  },
21
21
  "mapTemplate": {
22
- id: 'app.containers.Templates.mapTemplate',
23
- defaultMessage: 'Map Template',
22
+ id: `${scope}.mapTemplate`,
23
+ defaultMessage: `Map Template`,
24
24
  },
25
25
  "somethingWentWrong": {
26
- id: 'app.containers.Templates.somethingWentWrong',
27
- defaultMessage: 'Something Went Wrong!!',
26
+ id: `${scope}.somethingWentWrong`,
27
+ defaultMessage: `Something Went Wrong!!`,
28
28
  },
29
29
  "wechatHeader": {
30
- id: 'app.containers.Templates.wechatHeader',
31
- defaultMessage: 'WECHAT',
30
+ id: `${scope}.wechatHeader`,
31
+ defaultMessage: `WECHAT`,
32
32
  },
33
33
  "smsHeader": {
34
- id: 'app.containers.Templates.smsHeader',
35
- defaultMessage: 'SMS',
34
+ id: `${scope}.smsHeader`,
35
+ defaultMessage: `SMS`,
36
36
  },
37
37
  "emailHeader": {
38
- id: 'app.containers.Templates.emailHeader',
39
- defaultMessage: 'Email',
38
+ id: `${scope}.emailHeader`,
39
+ defaultMessage: `Email`,
40
40
  },
41
41
  "mobilepushHeader": {
42
- id: 'app.containers.Templates.mobilepushHeader',
43
- defaultMessage: 'Mobile Push',
42
+ id: `${scope}.mobilepushHeader`,
43
+ defaultMessage: `Mobile Push`,
44
44
  },
45
45
  "ebillHeader": {
46
- id: 'app.containers.Templates.ebillHeader',
47
- defaultMessage: 'Ebill',
46
+ id: `${scope}.ebillHeader`,
47
+ defaultMessage: `Ebill`,
48
48
  },
49
49
  "lineHeader": {
50
- id: 'app.containers.Templates.lineHeader',
51
- defaultMessage: 'Line',
50
+ id: `${scope}.lineHeader`,
51
+ defaultMessage: `Line`,
52
52
  },
53
53
  "selectWechatHeader": {
54
- id: 'app.containers.Templates.selectWechatHeader',
55
- defaultMessage: 'Select WECHAT Template',
54
+ id: `${scope}.selectWechatHeader`,
55
+ defaultMessage: `Select WECHAT Template`,
56
56
  },
57
57
  "selectSmsHeader": {
58
- id: 'app.containers.Templates.selectSmsHeader',
59
- defaultMessage: 'Select SMS Template',
58
+ id: `${scope}.selectSmsHeader`,
59
+ defaultMessage: `Select SMS Template`,
60
60
  },
61
61
  "selectAccount": {
62
- id: 'app.containers.Templates.selectAccount',
62
+ id: `${scope}.selectAccount`,
63
63
  defaultMessage: "Select Account",
64
64
  },
65
65
  "gettingAllTemplates": {
66
- id: 'app.containers.Templates.gettingAllTemplates',
66
+ id: `${scope}.gettingAllTemplates`,
67
67
  defaultMessage: "Getting all templates...",
68
68
  },
69
69
  "smsChannelTemplatesHeader": {
70
- id: 'app.containers.Templates.smsChannelTemplatesHeader',
70
+ id: `${scope}.smsChannelTemplatesHeader`,
71
71
  defaultMessage: "SMS Templates",
72
72
  },
73
73
  "wechatChannelTemplatesHeader": {
74
- id: 'app.containers.Templates.wechatChannelTemplatesHeader',
74
+ id: `${scope}.wechatChannelTemplatesHeader`,
75
75
  defaultMessage: "WECHAT Templates",
76
76
  },
77
77
  "blankTemplate": {
78
- id: 'app.containers.Templates.blankTemplate',
78
+ id: `${scope}.blankTemplate`,
79
79
  defaultMessage: "Blank Template",
80
80
  },
81
81
  "selectButton": {
82
- id: 'app.containers.Templates.selectButton',
82
+ id: `${scope}.selectButton`,
83
83
  defaultMessage: "Select",
84
84
  },
85
85
  "previewButton": {
86
- id: 'app.containers.Templates.previewButton',
86
+ id: `${scope}.previewButton`,
87
87
  defaultMessage: "Preview",
88
88
  },
89
89
  "editButton": {
90
- id: 'app.containers.Templates.editButton',
90
+ id: `${scope}.editButton`,
91
91
  defaultMessage: "Edit",
92
92
  },
93
93
  "duplicateButton": {
94
- id: 'app.containers.Templates.duplicateButton',
94
+ id: `${scope}.duplicateButton`,
95
95
  defaultMessage: "Duplicate",
96
96
  },
97
97
  "deleteButton": {
98
- id: 'app.containers.Templates.deleteButton',
98
+ id: `${scope}.deleteButton`,
99
99
  defaultMessage: "Delete",
100
100
  },
101
101
  "mostRecentOption": {
102
- id: 'app.containers.Templates.mostRecentOption',
102
+ id: `${scope}.mostRecentOption`,
103
103
  defaultMessage: "Most Recent",
104
104
  },
105
105
  "alphabeticallyOption": {
106
- id: 'app.containers.Templates.alphabeticallyOption',
106
+ id: `${scope}.alphabeticallyOption`,
107
107
  defaultMessage: "Alphabetically",
108
108
  },
109
109
  "searchText": {
110
- id: 'app.containers.Templates.searchText',
110
+ id: `${scope}.searchText`,
111
111
  defaultMessage: "Search",
112
112
  },
113
113
  "noAccountMessage": {
114
- id: 'app.containers.Templates.noAccountMessage',
114
+ id: `${scope}.noAccountMessage`,
115
115
  defaultMessage: "Please select an account to proceed",
116
116
  },
117
117
  "noTemplatesMessage": {
118
- id: 'app.containers.Templates.noTemplatesMessage',
118
+ id: `${scope}.noTemplatesMessage`,
119
119
  defaultMessage: "No Templates Available",
120
120
  },
121
121
  "createSmsActionButton": {
122
- id: 'app.containers.Templates.createSmsActionButton',
122
+ id: `${scope}.createSmsActionButton`,
123
123
  defaultMessage: "Create SMS",
124
124
  },
125
125
  "createEmailActionButton": {
126
- id: 'app.containers.Templates.createEmailActionButton',
126
+ id: `${scope}.createEmailActionButton`,
127
127
  defaultMessage: "Create Email",
128
128
  },
129
129
  "sortBy": {
130
- id: 'app.containers.Templates.sortBy',
130
+ id: `${scope}.sortBy`,
131
131
  defaultMessage: "Sort by",
132
132
  },
133
133
  "unMapButton": {
134
- id: 'app.containers.Templates.unMapButton',
134
+ id: `${scope}.unMapButton`,
135
135
  defaultMessage: "Unmap",
136
136
  },
137
137
  "templateDuplicateSuccess": {
138
- id: 'app.containers.Templates.templateDuplicateSuccess',
138
+ id: `${scope}.templateDuplicateSuccess`,
139
139
  defaultMessage: "Template Duplicated Successfully",
140
140
  },
141
141
  "templateDeleteSuccess": {
142
- id: 'app.containers.Templates.templateDeleteSuccess',
142
+ id: `${scope}.templateDeleteSuccess`,
143
143
  defaultMessage: "SMS Template Deleted Successfully",
144
144
  },
145
145
  "uploadFile": {
146
- id: 'app.containers.Templates.uploadFile',
146
+ id: `${scope}.uploadFile`,
147
147
  defaultMessage: "Upload File",
148
148
  },
149
149
  "useEditor": {
150
- id: 'app.containers.Templates.useEditor',
150
+ id: `${scope}.useEditor`,
151
151
  defaultMessage: "Use Editor",
152
152
  },
153
153
  "newTemplate": {
154
- id: 'app.containers.Templates.newTemplate',
154
+ id: `${scope}.newTemplate`,
155
155
  defaultMessage: "New Template",
156
156
  },
157
157
  "uploadingFile": {
158
- id: 'app.containers.Templates.uploadingFile',
158
+ id: `${scope}.uploadingFile`,
159
159
  defaultMessage: "Uploading File",
160
160
  },
161
161
  "zipUploadFailed": {
162
- id: 'app.containers.Templates.zipUploadFailed',
163
- defaultMessage: 'Failed to Upload zip file',
162
+ id: `${scope}.zipUploadFailed`,
163
+ defaultMessage: `Failed to Upload zip file`,
164
164
  },
165
165
  "campaigns": {
166
- id: 'app.containers.Templates.campaigns',
167
- defaultMessage: 'Campaigns',
166
+ id: `${scope}.campaigns`,
167
+ defaultMessage: `Campaigns`,
168
168
  },
169
169
  "creatives": {
170
- id: 'app.containers.Templates.creatives',
171
- defaultMessage: 'Creatives',
170
+ id: `${scope}.creatives`,
171
+ defaultMessage: `Creatives`,
172
172
  },
173
173
  "ebillPreview": {
174
- id: 'app.containers.Templates.ebillPreview',
175
- defaultMessage: 'Ebill Preview',
174
+ id: `${scope}.ebillPreview`,
175
+ defaultMessage: `Ebill Preview`,
176
176
  },
177
177
  "emailPreview": {
178
- id: 'app.containers.Templates.emailPreview',
179
- defaultMessage: 'Email Preview',
178
+ id: `${scope}.emailPreview`,
179
+ defaultMessage: `Email Preview`,
180
180
  },
181
181
  "Template deleted successfully": {
182
- id: 'app.containers.Templates.deletedSuccssfully',
183
- defaultMessage: 'Template deleted successfully',
182
+ id: `${scope}.deletedSuccssfully`,
183
+ defaultMessage: `Template deleted successfully`,
184
184
  },
185
185
  "Template deletion failed": {
186
- id: 'app.containers.Templates.deletionFailed',
187
- defaultMessage: 'Template deletion failed',
186
+ id: `${scope}.deletionFailed`,
187
+ defaultMessage: `Template deletion failed`,
188
188
  },
189
189
  "preview": {
190
- id: 'app.containers.Templates.preview',
191
- defaultMessage: 'Preview',
190
+ id: `${scope}.preview`,
191
+ defaultMessage: `Preview`,
192
192
  },
193
193
  "invalidUploadFileError": {
194
- id: 'app.containers.Templates.invalidUploadFileError',
195
- defaultMessage: 'File cannot be uploaded. Please select another file with valid file format.',
194
+ id: `${scope}.invalidUploadFileError`,
195
+ defaultMessage: `File cannot be uploaded. Please select another file with valid file format.`,
196
196
  },
197
197
  "templateDeleteConfirm": {
198
- id: 'app.containers.Templates.templateDeleteConfirm',
199
- defaultMessage: 'Are you sure you want to delete this Template?',
198
+ id: `${scope}.templateDeleteConfirm`,
199
+ defaultMessage: `Are you sure you want to delete this Template?`,
200
200
  },
201
201
  "cancelText": {
202
- id: 'app.containers.Templates.cancelText',
203
- defaultMessage: 'Cancel',
202
+ id: `${scope}.cancelText`,
203
+ defaultMessage: `Cancel`,
204
204
  },
205
205
  "yesText": {
206
- id: 'app.containers.Templates.yesText',
207
- defaultMessage: 'Yes',
206
+ id: `${scope}.yesText`,
207
+ defaultMessage: `Yes`,
208
208
  },
209
209
  "templateSelection": {
210
- id: 'app.containers.Templates.templateSelection',
211
- defaultMessage: 'Template Selection',
210
+ id: `${scope}.templateSelection`,
211
+ defaultMessage: `Template Selection`,
212
212
  },
213
213
  "layoutSelection": {
214
- id: 'app.containers.Templates.layoutSelection',
215
- defaultMessage: 'Select Layout',
214
+ id: `${scope}.layoutSelection`,
215
+ defaultMessage: `Select Layout`,
216
216
  },
217
217
  "textTemplate": {
218
- id: 'app.containers.Templates.textTemplate',
219
- defaultMessage: 'Text',
218
+ id: `${scope}.textTemplate`,
219
+ defaultMessage: `Text`,
220
220
  },
221
221
  "imageTemplate": {
222
- id: 'app.containers.Templates.imageTemplate',
223
- defaultMessage: 'Image',
222
+ id: `${scope}.imageTemplate`,
223
+ defaultMessage: `Image`,
224
224
  },
225
225
  "selectDefaultButton": {
226
- id: 'app.containers.Templates.selectDefaultButton',
227
- defaultMessage: 'Select',
226
+ id: `${scope}.selectDefaultButton`,
227
+ defaultMessage: `Select`,
228
228
  },
229
229
  "previewGenerateText": {
230
- id: 'app.containers.Templates.previewGenerateText',
231
- defaultMessage: 'Preview is being generated...',
230
+ id: `${scope}.previewGenerateText`,
231
+ defaultMessage: `Preview is being generated...`,
232
232
  },
233
233
  "createNewActionButton": {
234
- id: 'app.containers.Templates.createNewActionButton',
235
- defaultMessage: 'Create new',
234
+ id: `${scope}.createNewActionButton`,
235
+ defaultMessage: `Create new`,
236
+ },
237
+ "creativeTemplates": {
238
+ id: `${scope}.creativeTemplates`,
239
+ defaultMessage: `Creative templates`,
240
+ },
241
+ "editMessageContent": {
242
+ id: `${scope}.editMessageContent`,
243
+ defaultMessage: `Edit message Content`,
244
+ },
245
+ "createMessageContent": {
246
+ id: `${scope}.editMessageContent`,
247
+ defaultMessage: `New message`,
248
+ },
249
+ "creativeTemplatesDesc": {
250
+ id: `${scope}.creativeTemplatesDesc`,
251
+ defaultMessage: `(Select only one creative)`,
252
+ },
253
+ "creativesTemplatesSave": {
254
+ id: `${scope}.creativesTemplatesSave`,
255
+ defaultMessage: `Done`,
256
+ },
257
+ "creativesTemplatesEdit": {
258
+ id: `${scope}.creativesTemplatesSave`,
259
+ defaultMessage: `Edit`,
236
260
  },
237
261
  });
@@ -23,17 +23,25 @@ const {CapCustomCardList} = CapCustomCard;
23
23
  export class TemplatesV2 extends React.Component { // eslint-disable-line react/prefer-stateless-function
24
24
  constructor(props) {
25
25
  super(props);
26
+ const defaultChannel = this.props.channel || 'sms';
27
+ const deafaultPanes = [
28
+ {content: <div></div>, tab: 'Sms', key: 'sms'},
29
+ {content: <div></div>, tab: 'Email', key: 'email'},
30
+ // {content: this.getTemplatesComponent('wechat'), tab: 'Wechat', key: 'wechat'},
31
+ // {content: this.getTemplatesComponent('mobilepush'), tab: 'Mpush', key: 'mobilepush'},
32
+ ];
33
+ const panes = this.setChannelContent(defaultChannel, deafaultPanes);
26
34
  this.state = {
27
- selectedChannel: this.props.channel || 'sms',
28
- panes: [
29
- {content: this.getTemplatesComponent('sms'), tab: 'Sms', key: 'sms'},
30
- {content: this.getTemplatesComponent('email'), tab: 'Email', key: 'email'},
31
- {content: this.getTemplatesComponent('wechat'), tab: 'Wechat', key: 'wechat'},
32
- {content: this.getTemplatesComponent('mobilepush'), tab: 'Mpush', key: 'mobilepush'},
33
- ],
35
+ selectedChannel: defaultChannel,
36
+ panes,
34
37
  };
35
38
  }
36
-
39
+ componentWillReceiveProps(nextProps) {
40
+ if (this.props.channel !== nextProps.channel) {
41
+ const panes = this.setChannelContent(nextProps.channel, this.state.panes);
42
+ this.setState({selectedChannel: nextProps.channel, panes });
43
+ }
44
+ }
37
45
  getTemplateDataForGrid = ({templates, handlers, filterContent}) => {
38
46
  const cardDataList = templates.map((template) => (
39
47
  {
@@ -44,7 +52,9 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
44
52
  }));
45
53
  return (<div>
46
54
  {filterContent}
47
- <CapCustomCardList cardList={cardDataList} type="SMS" />
55
+ <div className="pagination-container">
56
+ <CapCustomCardList cardList={cardDataList} type="SMS" />
57
+ </div>
48
58
  </div>);
49
59
  }
50
60
  getTemplatesComponent(channel) {
@@ -58,32 +68,43 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
58
68
  location={{pathname: `/${channel}`, search: '', query}}
59
69
  route={{name: channel}}
60
70
  router={this.props.router}
61
- isComponent={!this.props.isFullMode}
71
+ isFullMode={this.props.isFullMode}
62
72
  createNew={this.props.createNew}
63
73
  onSelectTemplate={(id) => this.props.onSelectTemplate(this.selectTemplate(id))}
64
74
  renderNewCardGrid={this.getTemplateDataForGrid}
65
75
  />);
66
76
  }
67
- selectTemplate = (id) => find(this.props.TemplatesList, {_id: id})
68
77
 
69
- channelChange = (selectedChannel) => {
70
- const panes = this.state.panes.map((p) => {
78
+ setChannelContent = (selectedChannel, argsPanes) => {
79
+ const panes = argsPanes.map((p) => {
71
80
  const pane = p;
72
81
  if (pane.key === selectedChannel) {
73
82
  pane.content = this.getTemplatesComponent(pane.tab.toLowerCase());
74
83
  return pane;
75
84
  }
76
- return pane;
85
+ return {...pane, content: <div></div>};
77
86
  });
78
- this.setState({panes, selectedChannel});
87
+ return panes;
79
88
  }
89
+ channelChange = (selectedChannel) => {
90
+ const panes = this.setChannelContent(selectedChannel, this.state.panes);
91
+ this.setState({panes, selectedChannel}, () => { this.props.onChannelChange(selectedChannel); });
92
+ }
93
+ selectTemplate = (id) => find(this.props.TemplatesList, {_id: id})
94
+
80
95
  isLoading() {
81
96
  return this.props.Templates.loadingTemplates;
82
97
  }
83
98
  render() {
84
99
  return (
85
100
  <div>
86
- <CapTab panes={this.state.panes} onChange={this.channelChange} activeKey={this.state.selectedChannel} defaultActiveKey={this.state.selectedChannel}/>
101
+ <CapTab
102
+ panes={this.state.panes}
103
+ onChange={this.channelChange}
104
+ activeKey={this.state.selectedChannel}
105
+ defaultActiveKey={this.state.selectedChannel}/>
106
+
107
+
87
108
  </div>
88
109
 
89
110
  );
@@ -100,6 +121,7 @@ TemplatesV2.propTypes = {
100
121
  TemplatesList: PropTypes.arrayOf(PropTypes.object),
101
122
  handlePeviewTemplate: PropTypes.func,
102
123
  intl: intlShape,
124
+ onChannelChange: PropTypes.func,
103
125
  };
104
126
 
105
127
  TemplatesV2.defaultProps = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "2.0.14",
4
+ "version": "2.0.16",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -61,7 +61,7 @@
61
61
  "sanitize.css": "4.1.0",
62
62
  "semantic-ui-react": "0.68.3",
63
63
  "source-map-loader": "^0.2.4",
64
- "styled-components": "1.1.2",
64
+ "styled-components": "2",
65
65
  "warning": "3.0.0",
66
66
  "whatwg-fetch": "2.0.1"
67
67
  }