@capillarytech/creatives-library 6.3.7 → 6.4.1

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 (43) hide show
  1. package/app.js +63 -10
  2. package/components/CapTagList/index.js +5 -5
  3. package/components/EmailPreview/index.js +3 -3
  4. package/components/FormBuilder/index.js +2 -2
  5. package/components/PreviewSideBar/index.js +8 -8
  6. package/components/Sidebar/index.js +7 -7
  7. package/components/TemplatePreview/index.js +7 -7
  8. package/containers/Ebill/index.js +2 -2
  9. package/containers/Email/index.js +25 -18
  10. package/containers/Line/Create/index.js +2 -2
  11. package/containers/Line/Edit/index.js +7 -7
  12. package/containers/MobilePush/Create/index.js +5 -5
  13. package/containers/MobilePush/Edit/index.js +5 -5
  14. package/containers/Sms/Create/index.js +1 -1
  15. package/containers/Sms/Edit/index.js +1 -1
  16. package/containers/Templates/index.js +8 -8
  17. package/containers/WeChat/MapTemplates/index.js +1 -1
  18. package/containers/WeChat/RichmediaTemplates/Create/index.js +5 -3
  19. package/package.json +6 -3
  20. package/utils/Formatter.js +1 -1
  21. package/v2Components/CapTagList/index.js +7 -7
  22. package/v2Components/EmailPreview/index.js +1 -1
  23. package/v2Components/FormBuilder/index.js +4 -4
  24. package/v2Components/NavigationBar/index.js +3 -3
  25. package/v2Components/PreviewSideBar/index.js +8 -8
  26. package/v2Components/TemplatePreview/index.js +3 -3
  27. package/v2Containers/CreativesContainer/SlideBoxContent.js +5 -5
  28. package/v2Containers/CreativesContainer/SlideBoxHeader.js +1 -1
  29. package/v2Containers/CreativesContainer/index.js +5 -5
  30. package/v2Containers/Ebill/index.js +2 -2
  31. package/v2Containers/Email/index.js +19 -14
  32. package/v2Containers/Email/sagas.js +1 -1
  33. package/v2Containers/EmailWrapper/index.js +1 -1
  34. package/v2Containers/Line/Create/index.js +1 -1
  35. package/v2Containers/Line/Edit/index.js +5 -5
  36. package/v2Containers/MobilePush/Create/index.js +5 -5
  37. package/v2Containers/MobilePush/Edit/index.js +8 -8
  38. package/v2Containers/Sms/Create/index.js +1 -1
  39. package/v2Containers/Sms/Edit/index.js +1 -1
  40. package/v2Containers/Templates/index.js +27 -25
  41. package/v2Containers/WeChat/MapTemplates/index.js +1 -1
  42. package/v2Containers/WeChat/RichmediaTemplates/Create/index.js +4 -2
  43. package/v2Containers/WeChat/Wrapper/index.js +2 -2
@@ -316,7 +316,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
316
316
  return;
317
317
  }
318
318
  this.props.router.push({
319
- pathname: `/${nextProps.route.name.toLowerCase()}/create`,
319
+ pathname: `/${(nextProps.route.name || '').toLowerCase()}/create`,
320
320
  query: type === 'embedded' ? {type: 'embedded', module, isLanguageSupport, isEdmSupport} : {module},
321
321
  });
322
322
  }
@@ -498,12 +498,12 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
498
498
  this.setState({loading: true});
499
499
  }
500
500
 
501
- handleMenuAction = (item, key) => {
501
+ handleMenuAction = (item = {}, key) => {
502
502
  console.log('Menu Clicked ', item.key, key);
503
- if (item.key.toLowerCase() === 'uploadfile') {
503
+ if ((item.key || '').toLowerCase() === 'uploadfile') {
504
504
  document.getElementById('filename').click();
505
505
  console.log('Upload File');
506
- } else if (item.key.toLowerCase() === 'useeditor') {
506
+ } else if ((item.key || '').toLowerCase() === 'useeditor') {
507
507
  console.log('Use Editor');
508
508
  this.toggleEdmEmailTemplateSelection();
509
509
  }
@@ -827,7 +827,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
827
827
  this.getAllTemplates({params, resetPage: true});
828
828
  });
829
829
  }
830
- handleType = (data) => {
830
+ handleType = (data = {}) => {
831
831
  this.setState({mode: data}, () => {
832
832
  const params = {
833
833
  name: this.state.searchText,
@@ -1076,14 +1076,14 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1076
1076
  </div>,
1077
1077
  });
1078
1078
  }*/
1079
- data.map( (template) => {
1079
+ data.map( (template = {}) => {
1080
1080
  // console.log("Templates ", template._id, " Data ", template);
1081
1081
  const temp = {};
1082
1082
  // console.log('template ', template);
1083
1083
  const updateDateTime = (moment().format('DD-MM-YYYY') === moment(template.updatedAt).format('DD-MM-YYYY')) ? moment(template.updatedAt).format('hh:mma') : moment(template.updatedAt).format('DD MMM YYYY');
1084
1084
  let content = '';
1085
1085
  temp.id = template._id;
1086
- if (this.state.channel === 'wechat' && template.type.toLowerCase() === 'wechat') {
1086
+ if (this.state.channel === 'wechat' && (template.type || '').toLowerCase() === 'wechat') {
1087
1087
  let path = '';
1088
1088
  if (template && template.versions && template.versions.base && !_.isEmpty(template.versions.base)) {
1089
1089
  if (template.definition && template.definition.msgcontent && template.definition.msgcontent === "RICH_MEDIA_WECHAT") {
@@ -1131,7 +1131,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1131
1131
  {template._id === this.state.hoveredItem ? <CapButton onClick={(e) => this.handleEditClick(e, template._id)} className="edit-button" type="secondary">{type === 'embedded' ? this.props.intl.formatMessage(messages.selectButton) : this.props.intl.formatMessage(messages.editButton)}</CapButton> : ''}
1132
1132
  {template._id === this.state.hoveredItem ? <CapButton onClick={() => this.handlePreviewClick(template)} className="preview-button" type="cancel">{this.props.intl.formatMessage(messages.previewButton)}</CapButton> : ''}
1133
1133
  </div>);
1134
- } else if (this.state.channel.toLowerCase() === 'line' && template.type.toLowerCase() === 'line') {
1134
+ } else if (this.state.channel.toLowerCase() === 'line' && template.type && template.type.toLowerCase() === 'line') {
1135
1135
  //content = template.versions.base.messages[0].Text;
1136
1136
  content = {
1137
1137
  bodyText: template.versions.base.content.messages[0].text ? template.versions.base.content.messages[0].text : '',
@@ -985,7 +985,7 @@ export class MapTemplates extends React.Component { // eslint-disable-line react
985
985
  const query = {
986
986
  layout: 'WECHAT',
987
987
  type: 'TAG',
988
- context: data.toLowerCase() === 'all' ? 'default' : data.toLowerCase(),
988
+ context: (data || '').toLowerCase() === 'all' ? 'default' : (data || '').toLowerCase(),
989
989
  embedded: this.props.location.query.type === 'embedded' ? this.props.location.query.type : 'full',
990
990
  };
991
991
  this.props.globalActions.fetchSchemaForEntity(query);
@@ -796,9 +796,9 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
796
796
  const templateData = _.cloneDeep(this.state.templateData);
797
797
  const titleSet = new Set();
798
798
  let isRepeated = false;
799
- _.forEach(templateData, (content) => {
799
+ _.forEach(templateData, (content = '') => {
800
800
  const setSizeBefore = titleSet.size;
801
- titleSet.add(content.formData['title-value'].toLowerCase());
801
+ titleSet.add((content.formData['title-value'] || '').toLowerCase());
802
802
  const setSizeAfter = titleSet.size;
803
803
  if (setSizeAfter === setSizeBefore) {
804
804
  isRepeated = true;
@@ -896,7 +896,9 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
896
896
  return true;
897
897
  }
898
898
  updateContentData = () => {
899
- this.state.editorInstanse.insertHtml(`<img src='${this.props.ContentImageData.metaInfo.wechatUrl}' alt='Capillary Image'>`);
899
+ if (this.state.editorInstanse) {
900
+ this.state.editorInstanse.insertHtml(`<img src='${this.props.ContentImageData.metaInfo.wechatUrl}' alt='Capillary Image'>`);
901
+ }
900
902
  this.props.actions.clearContentImageStore();
901
903
  this.setState({loading: false});
902
904
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "6.3.7",
4
+ "version": "6.4.1",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -13,7 +13,9 @@
13
13
  "license": "LicenseRef-LICENSE",
14
14
  "dependencies": {
15
15
  "@babel/polyfill": "7.4.3",
16
- "@capillarytech/cap-ui-utils": "1.2.4",
16
+ "@bugsnag/js": "^7.2.1",
17
+ "@bugsnag/plugin-react": "^7.2.1",
18
+ "@capillarytech/cap-ui-utils": "1.2.6",
17
19
  "babel-cli": "^6.26.0",
18
20
  "chalk": "1.1.3",
19
21
  "jquery": "^3.3.1",
@@ -28,6 +30,7 @@
28
30
  "redux-immutable": "3.0.8",
29
31
  "reselect": "2.5.4",
30
32
  "styled-components": "^3.2.1",
31
- "whatwg-fetch": "2.0.1"
33
+ "whatwg-fetch": "2.0.1",
34
+ "webpack-bugsnag-plugins": "^1.4.3"
32
35
  }
33
36
  }
@@ -8,7 +8,7 @@ export function formatUnderscoreToSpaces(str) {
8
8
  return str.split('_').join(' ');
9
9
  }
10
10
 
11
- export function capitalizeString(str) {
11
+ export function capitalizeString(str = '') {
12
12
  const newStr = [];
13
13
  const words = str.toLowerCase().split(' ');
14
14
  _.forEach(words, (value) => {
@@ -49,16 +49,16 @@ class CapTagList extends React.Component { // eslint-disable-line react/prefer-s
49
49
  this.handleOnExpand(info.node.props.eventKey);
50
50
  };
51
51
 
52
- getSearchedExpandedKeys(tags, value) {
52
+ getSearchedExpandedKeys(tags, value = '') {
53
53
  let list = [];
54
- _.forEach(tags, (val, key) => {
54
+ _.forEach(tags, (val = {}, key) => {
55
55
  if (_.has(val, 'subtags')) {
56
- if (val.name.toLowerCase().indexOf(value.toLowerCase()) !== -1) {
56
+ if ((val.name || '').toLowerCase().indexOf(value.toLowerCase()) !== -1) {
57
57
  list.push(key);
58
58
  }
59
59
  const temp = this.getSearchedExpandedKeys(val.subtags, value);
60
60
  list = list.concat(temp);
61
- } else if (val.name.toLowerCase().indexOf(value.toLowerCase()) !== -1) {
61
+ } else if ((val.name || '').toLowerCase().indexOf(value.toLowerCase()) !== -1) {
62
62
  list.push(key);
63
63
  }
64
64
  });
@@ -131,9 +131,9 @@ class CapTagList extends React.Component { // eslint-disable-line react/prefer-s
131
131
  this.setState({showModal: true, visible: false});
132
132
  };
133
133
 
134
- renderTags(tags, searchString) {
134
+ renderTags(tags, searchString = '') {
135
135
  const list = [];
136
- _.forEach(tags, (val, key) => {
136
+ _.forEach(tags, (val = '', key) => {
137
137
  let supportedTagsString = '';
138
138
  _.forEach(val.supportedTags, (supportedTag) => {
139
139
  supportedTagsString += `${supportedTag} ,`;
@@ -147,7 +147,7 @@ class CapTagList extends React.Component { // eslint-disable-line react/prefer-s
147
147
  {temp}
148
148
  </CapTreeNode>
149
149
  ));
150
- } else if (searchString === '' || !searchString || val.name.toLowerCase().indexOf(searchString.toLowerCase()) !== -1) {
150
+ } else if (searchString === '' || !searchString || ((val.name || '').toLowerCase().indexOf(searchString.toLowerCase()) !== -1)) {
151
151
  const tempNode = (<CapTreeNode title={val.desc || val.name} tag={val} isLeaf key={val.couponSeriesId ? `${key}(${val.couponSeriesId})` : `${key}`}></CapTreeNode>);
152
152
  list.push(tempNode);
153
153
  }
@@ -43,7 +43,7 @@ const StyledCapIcon = styled(CapIcon)`
43
43
  class EmailPreview extends React.Component { // eslint-disable-line react/prefer-stateless-function
44
44
  render() {
45
45
  const { device, content, versions = {} } = this.props;
46
- const emailSubject = get(versions, 'base.subject');
46
+ const emailSubject = get(versions, 'base.subject', '');
47
47
  let messageContainerName = '';
48
48
  let subjectClassName = 'email-subject-desktop';
49
49
  if (device === 'tablet') {
@@ -2099,7 +2099,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2099
2099
  const isEdmSupport = (this.props.location.query.isEdmSupport !== "false") || false;
2100
2100
  const module = this.props.location.query.module ? this.props.location.query.module : 'default';
2101
2101
  this.props.router.push({
2102
- pathname: `/${this.props.schema.channel.toLowerCase()}/`,
2102
+ pathname: `/${(this.props.schema.channel || '').toLowerCase()}/`,
2103
2103
  query: type === 'embedded' ? {type: 'embedded', module, isLanguageSupport, isEdmSupport} : {module, isLanguageSupport, isEdmSupport},
2104
2104
  });
2105
2105
  } else if (id === "email-language-delete-modal") {
@@ -2156,7 +2156,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2156
2156
  const fileParams = {
2157
2157
  width: this.width || img.width,
2158
2158
  height: this.height || img.height,
2159
- error: file.size / (1e+6) > 3,
2159
+ error: file && (file.size / (1e+6) > 3),
2160
2160
  };
2161
2161
  this.callChildEvent({file, type: 'image', fileParams}, val, val.submitAction);
2162
2162
  };
@@ -2204,7 +2204,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2204
2204
  //
2205
2205
  const temp = {};
2206
2206
  temp.id = template._id;
2207
- if (this.props.schema.channel.toLowerCase() === 'email') {
2207
+ if ((this.props.schema.channel || '').toLowerCase() === 'email') {
2208
2208
  //
2209
2209
  const imgSrc = template && template.versions && template.versions.base ? template.versions.base.preview_http_url : '';
2210
2210
  // const ifPreviewGenerated = template && template.versions && template.versions.base ? template.versions.base.isPreviewGenerated : 0;
@@ -3149,7 +3149,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
3149
3149
  }
3150
3150
  break;
3151
3151
  case "ckeditor": {
3152
- if (this.props.schema && this.props.schema.channel && this.props.schema.channel.toLowerCase() === 'wechat' ) {
3152
+ if (this.props.schema && (this.props.schema.channel || '').toLowerCase() === 'wechat' ) {
3153
3153
  const content = !_.isEmpty(this.state.formData) && this.state.formData['content-value'] ? this.state.formData['content-value'] : '';
3154
3154
  columns.push(
3155
3155
  <CKEditor
@@ -89,11 +89,11 @@ class NavigationBar extends React.Component {
89
89
  const { currentOrgDetails } = this.props.userData;
90
90
  const productsList = [];
91
91
  if (!isEmpty(currentOrgDetails)) {
92
- forEach(currentOrgDetails.module_details, (module) => {
93
- if (module.name.toLowerCase() !== PRODUCT_MASTERS) {
92
+ forEach(currentOrgDetails.module_details, (module = {}) => {
93
+ if ((module.name || '').toLowerCase() !== PRODUCT_MASTERS) {
94
94
  const productName = module.code;
95
95
  const intlProductName = messages[productName];
96
- const moduleName = intlProductName ? formatMessage(intlProductName) : module.name.toLowerCase();
96
+ const moduleName = intlProductName ? formatMessage(intlProductName) : (module.name || '').toLowerCase();
97
97
  productsList.push({
98
98
  value: moduleName,
99
99
  url: module.url,
@@ -49,10 +49,10 @@ class PreviewSideBar extends React.Component { // eslint-disable-line react/pref
49
49
  render() {
50
50
  console.log('preview sidebar', this.props);
51
51
  let content = '';
52
- if (this.props.channel.toLowerCase() === 'wechat') {
52
+ if ((this.props.channel || '').toLowerCase() === 'wechat') {
53
53
  console.log('Template Infog ', this.props.templateData);
54
54
  content = this.props.templateData.content;
55
- } else if (this.props.channel.toLowerCase() === "mobilepush" && !_.isEmpty(this.props.templateData)) {
55
+ } else if ((this.props.channel || '').toLowerCase() === "mobilepush" && !_.isEmpty(this.props.templateData)) {
56
56
  const data = this.state.device === "android" ? this.props.templateData.versions.base.ANDROID : this.props.templateData.versions.base.IOS;
57
57
  content = {
58
58
  header: data.title,
@@ -68,7 +68,7 @@ class PreviewSideBar extends React.Component { // eslint-disable-line react/pref
68
68
  content.actions = [{label: data.expandableDetails.ctas[0].actionLabel}, {label: data.expandableDetails.ctas[0].actionLabel2}];
69
69
  }
70
70
  }
71
- } else if (this.props.channel.toLowerCase() === "line") {
71
+ } else if ((this.props.channel || '').toLowerCase() === "line") {
72
72
  const isMsgReady = (this.props.templateData && this.props.templateData.versions && this.props.templateData.versions.base);
73
73
  if (isMsgReady) {
74
74
  content = {
@@ -85,7 +85,7 @@ class PreviewSideBar extends React.Component { // eslint-disable-line react/pref
85
85
  }
86
86
  }
87
87
  let path = '';
88
- if (this.props.channel.toLowerCase() === 'wechat') {
88
+ if ((this.props.channel || '').toLowerCase() === 'wechat') {
89
89
  path = this.props.templateData && this.props.templateData.definition && this.props.templateData.definition.msgcontent === "RICH_MEDIA_WECHAT" ? `/wechat/richmedia/edit/${this.props.templateData._id}` : `/wechat/edit/${this.props.templateData._id}`;
90
90
  }
91
91
  console.log('final content is', content);
@@ -101,7 +101,7 @@ class PreviewSideBar extends React.Component { // eslint-disable-line react/pref
101
101
  <CapButton type={this.state.device === "iphone" ? "primary" : "secondary"} value={"iphone"}>IOS</CapButton>
102
102
  </ButtonGroup>}
103
103
  </div>
104
- {this.props.channel.toLowerCase() === "mobilepush" ?
104
+ {(this.props.channel || '').toLowerCase() === "mobilepush" ?
105
105
  <TemplatePreview
106
106
  device={this.state.device === "android" ? "android" : "iphone"}
107
107
  channel={this.props.channel}
@@ -114,15 +114,15 @@ class PreviewSideBar extends React.Component { // eslint-disable-line react/pref
114
114
  content={content || ''}
115
115
  channel={this.props.channel}
116
116
  location={this.props.location}
117
- charCounterEnabled={this.props.channel.toLowerCase() === 'sms'}
118
- unicodeEnabled={this.props.channel.toLowerCase() === 'sms'}
117
+ charCounterEnabled={(this.props.channel || '').toLowerCase() === 'sms'}
118
+ unicodeEnabled={(this.props.channel || '').toLowerCase() === 'sms'}
119
119
  templateData={this.props.templateData}
120
120
  >
121
121
  </TemplatePreview>
122
122
  }
123
123
  <hr className="seperator-line" />
124
124
  <div className="preview-action-container" style={{margin: '16px'}}>
125
- {this.props.channel.toLowerCase() === 'sms' && !this.props.embedded && <CapButton onClick={() => this.goToDuplicate()}className="preview-buttons" style={{marginRight: '8px'}} type="secondary"><FormattedMessage {...messages.duplicate} /></CapButton>}
125
+ {(this.props.channel || '').toLowerCase() === 'sms' && !this.props.embedded && <CapButton onClick={() => this.goToDuplicate()}className="preview-buttons" style={{marginRight: '8px'}} type="secondary"><FormattedMessage {...messages.duplicate} /></CapButton>}
126
126
  <CapButton onClick={(e) => this.goToEdit(e, path)} className="preview-buttons" type="primary">{this.props.location.query.type === 'embedded' ? <FormattedMessage {...messages.select} /> : <FormattedMessage {...messages.edit} />}</CapButton>
127
127
  </div>
128
128
  </div>
@@ -137,7 +137,7 @@ class TemplatePreview extends React.Component { // eslint-disable-line react/pre
137
137
  }
138
138
  const type = this.props.location && this.props.location.query.type ? this.props.location.query.type : '';
139
139
  let iosActions = [];
140
- if (channel.toLowerCase() === "mobilepush") {
140
+ if ((channel || '').toLowerCase() === "mobilepush") {
141
141
  iosActions = _.map(content.actions, (action) => {
142
142
  if (action.label) {
143
143
  return (<div className="actions" key={`action-${action.label}`}>
@@ -212,7 +212,7 @@ class TemplatePreview extends React.Component { // eslint-disable-line react/pre
212
212
  </div>
213
213
  {!this.props.showCount && <div>
214
214
  <CapColumn className="character-count-col" span={22}>
215
- {channel && channel.toLowerCase() === 'sms' && <CapHeading type="h3">
215
+ {(channel || '').toLowerCase() === 'sms' && <CapHeading type="h3">
216
216
  <FormattedMessage {...messages.charactersTotal} values={{smsCount: smsDetails.parts, charCount: smsDetails.chars_used}}/>
217
217
  {smsDetails.unicode &&
218
218
  <FormattedMessage {...messages.smsFormatType}/>
@@ -227,7 +227,7 @@ class TemplatePreview extends React.Component { // eslint-disable-line react/pre
227
227
  }
228
228
  {channel && channel.toLowerCase() === 'wechat' ?
229
229
  ( <div className="shell-v2 align-center" id="sms-preview">
230
- <CapImage className="preview-image" src={channel.toLowerCase() === 'wechat' ? wechatBodyNew : smsMobileAndroid} alt="Preview is being generated"/>
230
+ <CapImage className="preview-image" src={(channel || '').toLowerCase() === 'wechat' ? wechatBodyNew : smsMobileAndroid} alt="Preview is being generated"/>
231
231
  <div className="msgContainer wechat">
232
232
  <div className="message-pop align-left" style={{ background: `${this.props.channel.toLowerCase() === 'wechat' ? '#ffffff' : '#3F51B5'}`, color: `${this.props.channel.toLowerCase() === 'wechat' ? '#333333' : '#ffffff'}`}}>{content}
233
233
  </div>
@@ -82,7 +82,7 @@ function SlideBoxContent(props) {
82
82
  isGetFormData,
83
83
  getFormData,
84
84
  onCreateComplete,
85
- messageDetails,
85
+ messageDetails = {},
86
86
  onCreateNew,
87
87
  currentChannel,
88
88
  onChannelChange,
@@ -116,14 +116,14 @@ function SlideBoxContent(props) {
116
116
  saveMessage,
117
117
  selectedAccount,
118
118
  } = props;
119
- const type = messageDetails.type.toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
119
+ const type = (messageDetails.type || '').toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
120
120
  const query = { type: !isFullMode && 'embedded', module: isFullMode ? 'default' : 'library', isEditFromCampaigns: (templateData || {}).isEditFromCampaigns};
121
121
  const creativesLocationProps = {
122
122
  pathname: `/sms/edit`,
123
123
  query,
124
124
  search: '',
125
125
  };
126
- let channel = currentChannel;//for create mode
126
+ let channel = currentChannel || '';//for create mode
127
127
  const {
128
128
  isCreate: isCreateLine = false,
129
129
  isEdit: isEditLine = false,
@@ -193,7 +193,7 @@ function SlideBoxContent(props) {
193
193
  handlePeviewTemplate={onPreviewTemplate}
194
194
  location={location}
195
195
  createNew={onCreateNew}
196
- channel={channel.toLowerCase()}
196
+ channel={(channel || '').toLowerCase()}
197
197
  onChannelChange={onChannelChange}
198
198
  onCallTaskSubmit={onCallTaskSubmit}
199
199
  cap={cap}
@@ -208,7 +208,7 @@ function SlideBoxContent(props) {
208
208
  <TemplatePreview
209
209
  content={getChannelPreviewContent(templateData)}
210
210
  unicodeEnabled={get(templateData, `versions.base['unicode-validity']`)}
211
- channel={templateData.type.toLowerCase()}
211
+ channel={(templateData.type || '').toLowerCase()}
212
212
  charCounterEnabled={channel === constants.SMS}
213
213
  templateData={templateData}
214
214
  showCount
@@ -9,7 +9,7 @@ import { MAP_TEMPLATE } from '../WeChat/Wrapper/constants';
9
9
  const PrefixWrapper = styled.div`
10
10
  margin-right: 16px;
11
11
  `;
12
- function getChannelLabel(channel) {
12
+ function getChannelLabel(channel = '') {
13
13
  const labels = {
14
14
  sms: 'SMS',
15
15
  email: 'Email',
@@ -174,16 +174,16 @@ class Creatives extends React.Component {
174
174
  }
175
175
  case constants.CALL_TASK: {
176
176
  creativesTemplateData = {
177
- subject: templateData.subject,
178
- messageBody: templateData.messageBody,
179
- description: templateData.description,
177
+ subject: templateData && templateData.subject,
178
+ messageBody: templateData && templateData.messageBody,
179
+ description: templateData && templateData.description,
180
180
  edit: true,
181
181
  type: channel,
182
182
  };
183
183
  break;
184
184
  }
185
185
  case constants.MOBILE_PUSH: {
186
- const mode = get(templateData, 'androidContent.type') || get(templateData, 'iosContent.type');
186
+ const mode = get(templateData, 'androidContent.type') || get(templateData, 'iosContent.type') || '';
187
187
  creativesTemplateData = {
188
188
  type: channel,
189
189
  name: templateData.messageSubject,
@@ -262,7 +262,7 @@ class Creatives extends React.Component {
262
262
  case constants.EMAIL:
263
263
  if (template.value.base) {
264
264
  const emailBase = template.value.base;
265
- templateData = {...templateData, ...emailBase, emailBody: emailBase.html_content, emailSubject: emailBase.subject};
265
+ templateData = {...templateData, ...emailBase, emailBody: emailBase.html_content, emailSubject: (emailBase && emailBase.subject) ? emailBase.subject : ''};
266
266
  delete templateData.html_content;
267
267
  delete templateData.subject;
268
268
  }
@@ -663,7 +663,7 @@ export class Ebill extends React.Component { // eslint-disable-line react/prefer
663
663
  const msgString = JSON.stringify(msg);
664
664
  const win = document.getElementById(`edmeditor${this.state.currentTab > 1 ? this.state.currentTab : ''}`).contentWindow;
665
665
  win.postMessage(msgString, '*');
666
- } else {
666
+ } else if (this.state.editorInstanse) {
667
667
  this.state.editorInstanse.insertHtml(`{{${data}}}`);
668
668
  }
669
669
  };
@@ -825,7 +825,7 @@ export class Ebill extends React.Component { // eslint-disable-line react/prefer
825
825
  const query = {
826
826
  layout: 'EBILL',
827
827
  type: 'TAG',
828
- context: data.toLowerCase() === 'all' ? 'default' : data.toLowerCase(),
828
+ context: (data || '').toLowerCase() === 'all' ? 'default' : (data || '').toLowerCase(),
829
829
  embedded: this.props.location.query.type === 'embedded' ? this.props.location.query.type : 'full',
830
830
  };
831
831
  this.props.globalActions.fetchSchemaForEntity(query);
@@ -481,7 +481,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
481
481
  }), "*");
482
482
  }
483
483
  this.edmEvent = undefined;
484
- } else {
484
+ } else if (this.state.editorInstanse) {
485
485
  this.state.editorInstanse.insertHtml(`<img src='${nextProps.Email.uploadedAssetData.metaInfo.secure_file_path}' alt='Capillary Image'>`);
486
486
  //this.resetCkEditorInstance(this.state.currentTab, this.state.formData, true, nextProps.Email.uploadedAssetData, true);
487
487
  }
@@ -606,10 +606,10 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
606
606
  const langIndex = formData[this.state.currentTab - 1].selectedLanguages.indexOf(langId);
607
607
  const win = document.getElementById(`edmeditor${(langIndex + 1) > 1 ? (langIndex + 1) : ''}`).contentWindow;
608
608
  win.postMessage(msgString, '*');
609
- } else if (data === "unsubscribe") {
609
+ } else if (data === "unsubscribe" && this.state.editorInstanse) {
610
610
  const anchor = `<a href='{{${data}}}'>${data}</a>`;
611
611
  this.state.editorInstanse.insertHtml(`${anchor}`);
612
- } else {
612
+ } else if (this.state.editorInstanse) {
613
613
  this.state.editorInstanse.insertHtml(`{{${data}}}`);
614
614
  }
615
615
  //this.resetCkEditorInstance(currentTab, formData, true, data);
@@ -1079,10 +1079,12 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1079
1079
 
1080
1080
  instance1 = instance;
1081
1081
  this.setState({editorInstanse: instance1}, () => {
1082
- if (onInsert && !isImage) {
1083
- this.state.editorInstanse.insertHtml(`{{${value}}}`);
1084
- } else if (onInsert) {
1085
- this.state.editorInstanse.insertHtml(`<img src='${value.metaInfo.secure_file_path}' alt='Capillary Image'>`);
1082
+ if (this.state.editorInstanse) {
1083
+ if (onInsert && !isImage) {
1084
+ this.state.editorInstanse.insertHtml(`{{${value}}}`);
1085
+ } else if (onInsert) {
1086
+ this.state.editorInstanse.insertHtml(`<img src='${value.metaInfo.secure_file_path}' alt='Capillary Image'>`);
1087
+ }
1086
1088
  }
1087
1089
  });
1088
1090
  }
@@ -1147,7 +1149,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1147
1149
  e.preventDefault();
1148
1150
  const _URL = window.URL || window.webkitURL;
1149
1151
  const file = files[0];
1150
- const fileSize = (file.size / ( 1024 * 1024 ));
1152
+ const fileSize = file && (file.size / ( 1024 * 1024 ));
1151
1153
  if (fileSize > 5) {
1152
1154
  const message = this.props.intl.formatMessage(messages.uploadSizeError);
1153
1155
  CapNotification.error({key: 'uploadImageIssue', message});
@@ -1514,7 +1516,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1514
1516
  }), "*");
1515
1517
  }
1516
1518
  this.edmEvent = undefined;
1517
- } else {
1519
+ } else if (this.state.editorInstanse) {
1518
1520
  this.state.editorInstanse.insertHtml(`<img src='${data.metaInfo.secure_file_path}' alt='Capillary Image'>`);
1519
1521
  //this.resetCkEditorInstance(this.state.currentTab, this.state.formData, true, data, true);
1520
1522
  }
@@ -1862,7 +1864,9 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1862
1864
  }
1863
1865
 
1864
1866
  selectAsset = (asset) => {
1865
- this.state.editorInstanse.insertHtml(`<img src='${asset}' alt='Capillary Image'>`);
1867
+ if (this.state.editorInstanse) {
1868
+ this.state.editorInstanse.insertHtml(`<img src='${asset}' alt='Capillary Image'>`);
1869
+ }
1866
1870
  }
1867
1871
 
1868
1872
  prepareImageData() {
@@ -1898,9 +1902,10 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1898
1902
  <div className="more-icon-wrapper">
1899
1903
  <Popover
1900
1904
  placement="leftTop"
1901
- content={<div style={{ cursor: 'pointer'}}><p onClick={() => this.deleteAsset(asset)}>
1902
- <FormattedMessage {...messages.delete} />
1903
- </p></div>} trigger="click">
1905
+ content={<div style={{ cursor: 'pointer'}}>
1906
+ <p>
1907
+ <FormattedMessage {...messages.delete} />
1908
+ </p></div>} trigger="click">
1904
1909
  <i className="material-icons creative-icons">more_vert</i>
1905
1910
  </Popover>
1906
1911
  </div>
@@ -1998,7 +2003,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1998
2003
  const query = {
1999
2004
  layout: 'EMAIL',
2000
2005
  type: 'TAG',
2001
- context: data.toLowerCase() === 'all' ? 'default' : data.toLowerCase(),
2006
+ context: (data || '').toLowerCase() === 'all' ? 'default' : (data || '').toLowerCase(),
2002
2007
  embedded: 'full',
2003
2008
  };
2004
2009
  this.props.globalActions.fetchSchemaForEntity(query);
@@ -7,7 +7,7 @@ export function* createTemplate(template) {
7
7
  let errorMsg;
8
8
  try {
9
9
  const result = yield call(Api.createEmailTemplate, template);
10
- if (result.message || result.status.code === 500) {
10
+ if (!result.success || result.status.code === 500) {
11
11
  errorMsg = result.message;
12
12
  yield put({ type: types.CREATE_TEMPLATE_FAILURE, errorMsg });
13
13
  } else {
@@ -118,7 +118,7 @@ export class EmailWrapper extends React.Component { // eslint-disable-line react
118
118
  label: 'uploadZip',
119
119
  });
120
120
  }
121
- handleFileUpload = (file) => {
121
+ handleFileUpload = (file = {}) => {
122
122
  const { templatesActions, intl, showNextStep, isUploading } = this.props;
123
123
  if (!isUploading) {
124
124
  const fileExtension = file.name.split('.').pop();
@@ -881,7 +881,7 @@ export class Line extends Component {
881
881
  layout: 'LINE',
882
882
  type: 'TAG',
883
883
  context:
884
- data.toLowerCase() === 'all' ? 'default' : data.toLowerCase(),
884
+ (data || '').toLowerCase() === 'all' ? 'default' : (data || '').toLowerCase(),
885
885
  embedded:
886
886
  this.props.location.query.type === 'embedded'
887
887
  ? this.props.location.query.type
@@ -431,8 +431,8 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
431
431
  if (secondaryCta1) {
432
432
  const cta = {
433
433
  actionText: android['secondary-cta-0-label'],
434
- type: android['cta-deeplink-secondary-cta-0'].toLowerCase() === "deeplink" ? "DEEP_LINK" : "EXTERNAL_URL",
435
- actionLink: android['cta-deeplink-secondary-cta-0'].toLowerCase() === "deeplink" ? android['cta-deeplink-secondary-cta-0-select'] : android['cta-deeplink-secondary-cta-0-text'],
434
+ type: (android['cta-deeplink-secondary-cta-0'] || '').toLowerCase() === "deeplink" ? "DEEP_LINK" : "EXTERNAL_URL",
435
+ actionLink: (android['cta-deeplink-secondary-cta-0'] || '').toLowerCase() === "deeplink" ? android['cta-deeplink-secondary-cta-0-select'] : android['cta-deeplink-secondary-cta-0-text'],
436
436
  seccdeepLinkName: this.getLinkName(android['cta-deeplink-secondary-cta-0-select']),
437
437
  };
438
438
  if (this.props.location.query.type === 'embedded') {
@@ -456,8 +456,8 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
456
456
  if (secondaryCta2) {
457
457
  obj.versions.base.ANDROID.expandableDetails.ctas.push({
458
458
  actionText: android['secondary-cta-1-label'],
459
- type: android['cta-deeplink-secondary-cta-1'].toLowerCase() === "deeplink" ? "DEEP_LINK" : "EXTERNAL_URL",
460
- actionLink: android['cta-deeplink-secondary-cta-1'].toLowerCase() === "deeplink" ? android['cta-deeplink-secondary-cta-1-select'] : android['cta-deeplink-secondary-cta-1-text'],
459
+ type: (android['cta-deeplink-secondary-cta-1'] || '').toLowerCase() === "deeplink" ? "DEEP_LINK" : "EXTERNAL_URL",
460
+ actionLink: (android['cta-deeplink-secondary-cta-1'] || '').toLowerCase() === "deeplink" ? android['cta-deeplink-secondary-cta-1-select'] : android['cta-deeplink-secondary-cta-1-text'],
461
461
  seccdeepLinkName: this.getLinkName(android['cta-deeplink-secondary-cta-1-select']),
462
462
  });
463
463
  if (obj.versions.base.ANDROID.expandableDetails.ctas[obj.versions.base.ANDROID.expandableDetails.ctas.length - 1].type === "DEEP_LINK") {
@@ -947,7 +947,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
947
947
  const query = {
948
948
  layout: 'line',
949
949
  type: 'TAG',
950
- context: data.toLowerCase() === 'all' ? 'default' : data.toLowerCase(),
950
+ context: (data || '').toLowerCase() === 'all' ? 'default' : (data || '').toLowerCase(),
951
951
  embedded: this.props.location.query.type === 'embedded' ? this.props.location.query.type : 'full',
952
952
  };
953
953
  this.props.globalActions.fetchSchemaForEntity(query);
@@ -467,8 +467,8 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
467
467
  if (secondaryCta1) {
468
468
  const cta = {
469
469
  actionText: android['secondary-cta-0-label'],
470
- type: android['cta-deeplink-secondary-cta-0'].toLowerCase() === "deeplink" ? "DEEP_LINK" : "EXTERNAL_URL",
471
- actionLink: android['cta-deeplink-secondary-cta-0'].toLowerCase() === "deeplink" ? android['cta-deeplink-secondary-cta-0-select'] : android['cta-deeplink-secondary-cta-0-text'],
470
+ type: (android['cta-deeplink-secondary-cta-0'] || '').toLowerCase() === "deeplink" ? "DEEP_LINK" : "EXTERNAL_URL",
471
+ actionLink: (android['cta-deeplink-secondary-cta-0'] || '').toLowerCase() === "deeplink" ? android['cta-deeplink-secondary-cta-0-select'] : android['cta-deeplink-secondary-cta-0-text'],
472
472
  seccdeepLinkName: this.getLinkName(android['cta-deeplink-secondary-cta-0-select']),
473
473
  };
474
474
  if (this.props.location.query.type === 'embedded') {
@@ -492,8 +492,8 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
492
492
  if (secondaryCta2) {
493
493
  const cta = {
494
494
  actionText: android['secondary-cta-1-label'],
495
- type: android['cta-deeplink-secondary-cta-1'].toLowerCase() === "deeplink" ? "DEEP_LINK" : "EXTERNAL_URL",
496
- actionLink: android['cta-deeplink-secondary-cta-1'].toLowerCase() === "deeplink" ? android['cta-deeplink-secondary-cta-1-select'] : android['cta-deeplink-secondary-cta-1-text'],
495
+ type: (android['cta-deeplink-secondary-cta-1'] || '').toLowerCase() === "deeplink" ? "DEEP_LINK" : "EXTERNAL_URL",
496
+ actionLink: (android['cta-deeplink-secondary-cta-1'] || '').toLowerCase() === "deeplink" ? android['cta-deeplink-secondary-cta-1-select'] : android['cta-deeplink-secondary-cta-1-text'],
497
497
  seccdeepLinkName: this.getLinkName(android['cta-deeplink-secondary-cta-1-select']),
498
498
  };
499
499
  if (this.props.location.query.type === 'embedded') {
@@ -1662,7 +1662,7 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
1662
1662
  const query = {
1663
1663
  layout: 'mobilepush',
1664
1664
  type: 'TAG',
1665
- context: data.toLowerCase() === 'all' ? 'default' : data.toLowerCase(),
1665
+ context: (data || '').toLowerCase() === 'all' ? 'default' : (data || '').toLowerCase(),
1666
1666
  embedded: this.props.location.query.type === 'embedded' ? this.props.location.query.type : 'full',
1667
1667
  };
1668
1668
  this.props.globalActions.fetchSchemaForEntity(query);