@capillarytech/creatives-library 2.0.56 → 2.0.57

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.
@@ -556,7 +556,8 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
556
556
  _.forEach(this.state.formData, (tab, index) => {
557
557
  let isCurrentTabValid = true;
558
558
  let skipValidation = false;
559
- if (type.toLowerCase() === 'embedded' && ((isOnlyAndroid && parseInt(index) === 1) || (isOnlyIos && parseInt(index) === 0))) {
559
+ if (type.toLowerCase() === 'embedded' && ((isOnlyAndroid && parseInt(index) === 1) || (isOnlyIos && parseInt(index) === 0)) && isOnlyAndroid !== isOnlyIos) {
560
+ // skip validation of the tab which is not open in embedded mode
560
561
  skipValidation = true;
561
562
  }
562
563
  if (!isNaN(index) && tab && !skipValidation) {
@@ -2161,7 +2162,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2161
2162
  case "input":
2162
2163
  if (styling === 'semantic') {
2163
2164
  ifError = this.state.checkValidation && (isVersionEnable ? this.state.errorData[`${this.state.currentTab - 1}`][val.id] : this.state.errorData[val.id]);
2164
-
2165
+ const value = isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id];
2165
2166
  columns.push(
2166
2167
  <CapColumn key={val.id} span={val.width}>
2167
2168
  <CapInput
@@ -2173,7 +2174,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2173
2174
  placeholder={val.placeholder}
2174
2175
  onChange={(e) => this.updateFormData(e.target.value, val)}
2175
2176
  defaultValue={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2176
- value={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2177
+ value={value || ""}
2177
2178
  disabled={val.disabled}
2178
2179
  />
2179
2180
  </CapColumn>
@@ -2193,6 +2194,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2193
2194
  break;
2194
2195
  case "textarea":
2195
2196
  ifError = this.state.checkValidation && (isVersionEnable ? this.state.errorData[`${this.state.currentTab - 1}`][val.id] : this.state.errorData[val.id]);
2197
+ const value = isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id];
2196
2198
  if (styling === 'semantic') {
2197
2199
  columns.push(
2198
2200
  <CapColumn key="input" span={val.width}>
@@ -2204,7 +2206,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2204
2206
  onChange={(e) => this.updateFormData(e.target.value, val)}
2205
2207
  style={val.style ? val.style : {}}
2206
2208
  defaultValue={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2207
- value={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2209
+ value={value || ""}
2208
2210
  rows={20}
2209
2211
  disabled={val.disabled}
2210
2212
  cols={20}
@@ -2518,7 +2520,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2518
2520
  switch (type) {
2519
2521
  case "input":
2520
2522
  ifError = this.state.checkValidation && (isVersionEnable ? this.state.errorData[`${this.state.currentTab - 1}`][val.id] : this.state.errorData[val.id]);
2521
-
2523
+ const value = isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id];
2522
2524
  if (styling === 'semantic') {
2523
2525
  columns.push(
2524
2526
  <CapColumn key={val.id} span={val.width}>
@@ -2530,7 +2532,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2530
2532
  style={val.style ? val.style : {}}
2531
2533
  placeholder={val.placeholder}
2532
2534
  onChange={(e) => this.updateFormData(e.target.value, val)}
2533
- value={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2535
+ value={value || ""}
2534
2536
  defaultValue={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2535
2537
  disabled={val.disabled}
2536
2538
  />
@@ -2551,6 +2553,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2551
2553
  break;
2552
2554
  case "textarea":
2553
2555
  ifError = this.state.checkValidation && (isVersionEnable ? this.state.errorData[`${this.state.currentTab - 1}`][val.id] : this.state.errorData[val.id]);
2556
+ const textValue = isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id];
2554
2557
  if (styling === 'semantic') {
2555
2558
  columns.push(
2556
2559
  <CapColumn key="input" span={val.width} offset={val.offset}>
@@ -2564,7 +2567,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2564
2567
  onChange={(e) => this.updateFormData(e.target.value, val)}
2565
2568
  style={val.style ? val.style : {}}
2566
2569
  defaultValue={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2567
- value={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2570
+ value={textValue || ""}
2568
2571
  rows={10}
2569
2572
  cols={2}
2570
2573
  />
@@ -7,8 +7,10 @@ import SmsCreate from '../Sms/Create';
7
7
  import SmsEdit from '../Sms/Edit';
8
8
  import Email from '../Email';
9
9
  import EmailWrapper from '../EmailWrapper';
10
+ import MobilepusWrapper from '../MobilepushWrapper';
10
11
  import EmailPreviewV2 from '../../components/EmailPreviewV2';
11
12
  import CallTask from '../CallTask';
13
+ import MobliPushEdit from '../MobilePush/Edit';
12
14
  import * as constants from './constants';
13
15
  const CreativesWrapper = styled.div`
14
16
  .ant-popover,
@@ -32,8 +34,10 @@ function SlideBoxContent(props) {
32
34
  onChannelChange,
33
35
  onEmailModeChange,
34
36
  emailCreateMode,
37
+ onMobilepushModeChange,
38
+ mobilePushCreateMode,
35
39
  templateStep,
36
- onEmailNextStep,
40
+ onCreateNextStep,
37
41
  cap,
38
42
  onResetStep,
39
43
  isFullMode,
@@ -49,6 +53,7 @@ function SlideBoxContent(props) {
49
53
  };
50
54
  let channel = currentChannel;//for create mode
51
55
  const isCreateSms = slidBoxContent === 'createTemplate' && channel === constants.SMS;
56
+ const isCreateMPush = slidBoxContent === 'createTemplate' && channel === constants.MOBILE_PUSH;
52
57
  const isCreateCallTask = slidBoxContent === 'createTemplate' && channel === 'CALLTASK';
53
58
  let isEditSms = false;
54
59
  let isEditEmailWithId = false;
@@ -56,11 +61,13 @@ function SlideBoxContent(props) {
56
61
  let isPreview = false;
57
62
  let isEmailPreview = false;
58
63
  let isEditCallTask = false;
64
+ let isEditMPush = false;
59
65
  const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL;
60
66
  if (templateData && channel) {
61
67
  channel = templateData.type;// for edit mode with template data
62
68
  isEditSms = slidBoxContent === 'editTemplate' && channel === constants.SMS;
63
69
  isEditCallTask = slidBoxContent === 'editTemplate' && channel === constants.CALL_TASK;
70
+ isEditMPush = slidBoxContent === 'editTemplate' && channel === constants.MOBILE_PUSH;
64
71
  isEditEmailWithId = slidBoxContent === 'editTemplate' && channel === constants.EMAIL && templateData._id;
65
72
  isEmailEditWithContent = slidBoxContent === 'editTemplate' && channel === constants.EMAIL && !templateData._id;
66
73
  isPreview = slidBoxContent === 'preview' && channel !== constants.EMAIL;
@@ -148,7 +155,7 @@ function SlideBoxContent(props) {
148
155
  templateData={templateData}
149
156
  type={type}
150
157
  step={templateStep}
151
- showNextStep={onEmailNextStep}
158
+ showNextStep={onCreateNextStep}
152
159
  isFullMode={isFullMode}
153
160
  cap={cap}
154
161
  onResetStep={onResetStep}
@@ -172,6 +179,38 @@ function SlideBoxContent(props) {
172
179
  cap={cap}
173
180
  />
174
181
  )}
182
+ {isEditMPush &&
183
+ <MobliPushEdit
184
+ getFormLibraryData={getFormData}
185
+ setIsLoadingContent={setIsLoadingContent}
186
+ location={{
187
+ pathname: `/mobilepush/edit/`,
188
+ query,
189
+ }}
190
+ isFullMode={false}
191
+ isGetFormData={isGetFormData}
192
+ route={{ name: 'mobilepush' }}
193
+ templateData={templateData}
194
+ />
195
+ }
196
+ {isCreateMPush &&
197
+ <MobilepusWrapper
198
+ key="creatives-mobilepush-wrapper"
199
+ date={new Date().getMilliseconds()}
200
+ setIsLoadingContent={setIsLoadingContent}
201
+ onMobilepushModeChange={onMobilepushModeChange}
202
+ mobilePushCreateMode={mobilePushCreateMode}
203
+ isGetFormData={isGetFormData}
204
+ getFormData={getFormData}
205
+ templateData={templateData}
206
+ type={type}
207
+ step={templateStep}
208
+ showNextStep={onCreateNextStep}
209
+ isFullMode={isFullMode}
210
+ cap={cap}
211
+ onResetStep={onResetStep}
212
+ query={query}/>
213
+ }
175
214
  </CreativesWrapper>
176
215
  );
177
216
  }
@@ -190,11 +229,13 @@ SlideBoxContent.propTypes = {
190
229
  onEmailModeChange: PropTypes.func,
191
230
  emailCreateMode: PropTypes.string,
192
231
  templateStep: PropTypes.string,
193
- onEmailNextStep: PropTypes.func,
232
+ onCreateNextStep: PropTypes.func,
194
233
  cap: PropTypes.object,
195
234
  onResetStep: PropTypes.func,
196
235
  onCallTaskSubmit: PropTypes.func,
197
236
  isFullMode: PropTypes.bool,
198
237
  setIsLoadingContent: PropTypes.func,
238
+ onMobilepushModeChange: PropTypes.func,
239
+ mobilePushCreateMode: PropTypes.string,
199
240
  };
200
241
  export default SlideBoxContent;
@@ -3,7 +3,7 @@ import { FormattedMessage } from 'react-intl';
3
3
  import { CapButton } from '@capillarytech/cap-ui-library';
4
4
  import PropTypes from 'prop-types';
5
5
  function SlideBoxFooter(props) {
6
- const { slidBoxContent, onSave, messages, onEditTemplate, onEmailNextStep} = props;
6
+ const { slidBoxContent, onSave, messages, onEditTemplate, onCreateNextStep} = props;
7
7
  return (
8
8
  <div>
9
9
  <div>
@@ -13,7 +13,7 @@ function SlideBoxFooter(props) {
13
13
  </CapButton>
14
14
  )}
15
15
  {props.shouldShowContinueFooter() &&
16
- <CapButton onClick={onEmailNextStep}>
16
+ <CapButton onClick={onCreateNextStep}>
17
17
  <FormattedMessage {...messages.continue} />
18
18
  </CapButton>
19
19
  }
@@ -31,7 +31,7 @@ SlideBoxFooter.propTypes = {
31
31
  onSave: PropTypes.func,
32
32
  messages: PropTypes.object,
33
33
  onEditTemplate: PropTypes.func,
34
- onEmailNextStep: PropTypes.func,
34
+ onCreateNextStep: PropTypes.func,
35
35
  shouldShowContinueFooter: PropTypes.func,
36
36
  shouldShowDoneFooter: PropTypes.func,
37
37
  };
@@ -8,5 +8,6 @@ export const DEFAULT_ACTION = 'app/CreativesContainer/DEFAULT_ACTION';
8
8
  export const EMAIL = "EMAIL";
9
9
  export const SMS = "SMS";
10
10
  export const CALL_TASK = "CALL_TASK";
11
+ export const MOBILE_PUSH = "MOBILEPUSH";
11
12
  export const SHOW_CONTANER_LOADER = "app/CreativesContainer/SHOW_CONTANER_LOADER";
12
13
  export const HIDE_CONTAINER_LOADER = "app/CreativesContainer/HIDE_CONTAINER_LOADER";
@@ -5,7 +5,7 @@ import {
5
5
  } from '@capillarytech/cap-ui-library';
6
6
  import { injectIntl } from 'react-intl';
7
7
  import classnames from 'classnames';
8
- import {isEmpty} from 'lodash';
8
+ import {isEmpty, get} from 'lodash';
9
9
  import { connect } from 'react-redux';
10
10
  import { createStructuredSelector } from 'reselect';
11
11
  import { bindActionCreators } from 'redux';
@@ -71,11 +71,11 @@ class Creatives extends React.Component {
71
71
  onChannelChange = (channel) => {
72
72
  this.setState({currentChannel: channel});
73
73
  }
74
- onEmailNextStep = () => {
74
+ onCreateNextStep = () => {
75
75
  this.setState((prevState) => {
76
76
  let templateStep = prevState.templateStep + 1;
77
77
  const {emailCreateMode, currentChannel} = prevState;
78
- if (currentChannel.toUpperCase() === constants.EMAIL && emailCreateMode === "upload") {
78
+ if ((currentChannel.toUpperCase() === constants.EMAIL && emailCreateMode === "upload") || currentChannel.toUpperCase() === constants.MOBILE_PUSH) {
79
79
  templateStep = prevState.templateStep + 2;
80
80
  }
81
81
 
@@ -88,7 +88,9 @@ class Creatives extends React.Component {
88
88
  onEmailModeChange = (mode) => {
89
89
  this.setState({ emailCreateMode: mode});
90
90
  }
91
-
91
+ onMobilepushModeChange = (mode) => {
92
+ this.setState({ mobilePushCreateMode: mode});
93
+ }
92
94
 
93
95
  onCallTaskSubmit = (data) => {
94
96
  this.props.getCreativesData({
@@ -136,6 +138,19 @@ class Creatives extends React.Component {
136
138
  edit: true,
137
139
  type: channel,
138
140
  };
141
+ } else if (channel === constants.MOBILE_PUSH) {
142
+ const mode = get(templateData, 'androidContent.type') || get(templateData, 'iosContent.type');
143
+ creativesTeplateData = {
144
+ type: channel,
145
+ name: templateData.messageSubject,
146
+ versions: {
147
+ base: {
148
+ ANDROID: templateData.androidContent,
149
+ IOS: templateData.iosContent,
150
+ },
151
+ },
152
+ definition: {accountId: templateData.accountId, mode: mode.toLowerCase()},
153
+ };
139
154
  }
140
155
  return creativesTeplateData;
141
156
  }
@@ -149,6 +164,28 @@ class Creatives extends React.Component {
149
164
  } else if (channel === constants.EMAIL && template.value.base) {
150
165
  templateData.emailBody = template.value.base.html_content;
151
166
  templateData.emailSubject = template.value.base.subject;
167
+ } else if (channel === constants.MOBILE_PUSH && get(template, "value.versions.base")) {
168
+ const mobilpushTemplate = template.value;
169
+ templateData.accountId = get(mobilpushTemplate, 'definition.accountId');
170
+ const androidContent = get(mobilpushTemplate, 'versions.base.ANDROID');
171
+ if (!isEmpty(androidContent)) {
172
+ delete androidContent.cuid;
173
+ delete androidContent.luid;
174
+ delete androidContent.communicationId;
175
+ templateData.androidContent = androidContent;
176
+ templateData.androidContent.type = get(mobilpushTemplate, 'definition.mode').toUpperCase();
177
+ templateData.androidContent.deviceType = 'ANDROID';
178
+ }
179
+ const iosContent = get(mobilpushTemplate, 'versions.base.IOS');
180
+ if (!isEmpty(iosContent)) {
181
+ delete iosContent.cuid;
182
+ delete iosContent.luid;
183
+ delete iosContent.communicationId;
184
+ templateData.iosContent = iosContent;
185
+ templateData.iosContent.type = get(mobilpushTemplate, 'definition.mode').toUpperCase();
186
+ templateData.iosContent.deviceType = 'IOS';
187
+ }
188
+ templateData.messageSubject = mobilpushTemplate.name;
152
189
  }
153
190
  return templateData;
154
191
  };
@@ -207,15 +244,19 @@ class Creatives extends React.Component {
207
244
  };
208
245
  shouldShowFooter = () => {
209
246
  const {isFullMode } = this.props;
210
- const {slidBoxContent, currentChannel, emailCreateMode, templateStep} = this.state;
247
+ const {slidBoxContent, currentChannel, emailCreateMode, templateStep, mobilePushCreateMode} = this.state;
211
248
  const channel = currentChannel.toUpperCase();
212
249
  const currentStep = this.creativesTemplateSteps[templateStep];
213
250
  let showFooter = false;
251
+ const isMobilepush = channel === constants.MOBILE_PUSH;
214
252
  if (!isFullMode ) {
215
253
  const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
216
254
  const isCreate = (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate') && !isEmailCreate;
217
255
  const isCallTask = channel === 'CALLTASK';
218
256
  showFooter = (isCreate || (isEmailCreate && emailCreateMode) || slidBoxContent === 'preview') && !isCallTask;
257
+ if (isMobilepush) {
258
+ showFooter = currentStep === "modeSelection" || (currentStep === 'createTemplateContent' && !isEmpty(mobilePushCreateMode));
259
+ }
219
260
  } else if (channel === constants.EMAIL && isFullMode) {
220
261
  const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
221
262
  showFooter = isEmailCreate && emailCreateMode;
@@ -235,23 +276,36 @@ class Creatives extends React.Component {
235
276
  shouldShowDoneFooter = () => {
236
277
  const {slidBoxContent, templateStep, currentChannel} = this.state;
237
278
  const currentStep = this.creativesTemplateSteps[templateStep];
238
- const isEmailCreate = slidBoxContent === 'createTemplate' && currentChannel.toUpperCase() === constants.EMAIL && currentStep !== 'createTemplateContent';
239
- const isCreate = (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate') && !isEmailCreate;
240
- return isCreate;
279
+ let showDone = false;
280
+ const channel = currentChannel.toUpperCase();
281
+ if (channel === constants.EMAIL || channel === constants.SMS) {
282
+ const isEmailCreate = slidBoxContent === 'createTemplate' && currentChannel.toUpperCase() === constants.EMAIL && currentStep !== 'createTemplateContent';
283
+ showDone = (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate') && !isEmailCreate;
284
+ } else if (channel === constants.MOBILE_PUSH) {
285
+ showDone = currentStep === "createTemplateContent" || slidBoxContent === "editTemplate";
286
+ }
287
+
288
+ return showDone;
241
289
  }
242
290
  shouldShowContinueFooter = () => { // only for email for now, has to be modified according to channel
243
- const {slidBoxContent, templateStep, currentChannel, emailCreateMode} = this.state;
291
+ const {slidBoxContent, templateStep, currentChannel, emailCreateMode, mobilePushCreateMode} = this.state;
244
292
  let isShowContinueFooter = false;
245
- if ((emailCreateMode === "upload" && !isEmpty(this.props.EmailLayout)) || emailCreateMode === "editor") {
246
- const currentStep = this.creativesTemplateSteps[templateStep];
247
- let isEmailCreate = slidBoxContent === 'createTemplate';
248
- isEmailCreate = currentChannel.toUpperCase() === constants.EMAIL && ((emailCreateMode === "upload" && currentStep !== 'createTemplateContent') || ( emailCreateMode === "editor" && currentStep !== 'createTemplateContent' && currentStep !== "templateSelection"));
249
- isShowContinueFooter = isEmailCreate && emailCreateMode;
293
+ const currentStep = this.creativesTemplateSteps[templateStep];
294
+ const channel = currentChannel.toUpperCase();
295
+ if (channel === constants.EMAIL || channel === constants.SMS) {
296
+ if ((emailCreateMode === "upload" && !isEmpty(this.props.EmailLayout)) || emailCreateMode === "editor") {
297
+ let isEmailCreate = slidBoxContent === 'createTemplate';
298
+ isEmailCreate = currentChannel.toUpperCase() === constants.EMAIL && ((emailCreateMode === "upload" && currentStep !== 'createTemplateContent') || ( emailCreateMode === "editor" && currentStep !== 'createTemplateContent' && currentStep !== "templateSelection"));
299
+ isShowContinueFooter = isEmailCreate && emailCreateMode;
300
+ }
301
+ } else if (currentChannel.toUpperCase() === constants.MOBILE_PUSH) {
302
+ isShowContinueFooter = !isEmpty(mobilePushCreateMode) && currentStep === "modeSelection";
250
303
  }
304
+
251
305
  return isShowContinueFooter;
252
306
  }
253
307
  render() {
254
- const {slidBoxContent, isGetFormData, showSlideBox, templateData, currentChannel, emailCreateMode, templateStep, isLoadingContent} = this.state;
308
+ const {slidBoxContent, isGetFormData, showSlideBox, templateData, currentChannel, emailCreateMode, templateStep, isLoadingContent, mobilePushCreateMode} = this.state;
255
309
  const {isFullMode, creativesMode, cap, isUploading} = this.props;
256
310
  return (
257
311
  <div className={classnames(`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'}`)}>
@@ -286,10 +340,12 @@ class Creatives extends React.Component {
286
340
  onEmailModeChange={this.onEmailModeChange}//used when create is clicked in email
287
341
  emailCreateMode={emailCreateMode}// upload zip || use editor are values
288
342
  templateStep={this.creativesTemplateSteps[templateStep]}
289
- onEmailNextStep={this.onEmailNextStep}
343
+ onCreateNextStep={this.onCreateNextStep}
290
344
  onResetStep={this.resetStep}
291
345
  cap={cap}
292
346
  setIsLoadingContent={this.setIsLoadingContent}
347
+ onMobilepushModeChange={this.onMobilepushModeChange}
348
+ mobilePushCreateMode={mobilePushCreateMode}
293
349
  />
294
350
  }
295
351
  footer={this.shouldShowFooter() &&
@@ -298,7 +354,7 @@ class Creatives extends React.Component {
298
354
  onSave={this.saveMessage}
299
355
  onEditTemplate={this.onEditTemplate}
300
356
  slidBoxContent={slidBoxContent}
301
- onEmailNextStep={this.onEmailNextStep}
357
+ onCreateNextStep={this.onCreateNextStep}
302
358
  currentChannel={currentChannel.toUpperCase()}
303
359
  templateStep={this.creativesTemplateSteps[templateStep]}
304
360
  emailCreateMode={emailCreateMode}
@@ -2620,7 +2620,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2620
2620
  />}
2621
2621
  <ImagePreview
2622
2622
  header={imagePreviewHeader}
2623
- content={imagePreviewContent}
2623
+ content={imagePreviewContent}
2624
2624
  show={this.state.showImageSelectionBox}
2625
2625
  handleClose={this.handleImagePreviewClose}
2626
2626
  isLoading={this.props.Email.fetchingAllAssets}
@@ -2673,3 +2673,4 @@ function mapDispatchToProps(dispatch) {
2673
2673
  }
2674
2674
 
2675
2675
  export default UserIsAuthenticated(connect(mapStateToProps, mapDispatchToProps)(injectIntl(Email)));
2676
+
@@ -504,10 +504,12 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
504
504
  };
505
505
  getFormData = (e) => {
506
506
  console.log('posting final result', this.state.formData);
507
+ const templateData = this.getTransformedData(this.state.formData);
507
508
  const response = {
508
509
  action: "getFormData",
509
- value: this.getTransformedData(this.state.formData),
510
+ value: templateData,
510
511
  validity: this.state.isFormValid,
512
+ type: templateData.type,
511
513
  };
512
514
  this.setState({checkValidation: true});
513
515
  if (e) {
@@ -2216,7 +2218,7 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
2216
2218
  injectedTags={this.state.injectedTags ? this.state.injectedTags : {}}
2217
2219
  onFormValidityChange={this.setFormValidity}
2218
2220
  usingTabContainer
2219
- checkValidation={false}
2221
+ checkValidation={this.state.checkValidation}
2220
2222
  iosCtasData={this.state.iosCtasData}
2221
2223
  tabKey={this.state.tabKey}
2222
2224
  tabCount={2}
@@ -13,7 +13,7 @@ import { connect } from 'react-redux';
13
13
  import { Row, Col, Spin, Breadcrumb, notification } from 'antd';
14
14
  import { createStructuredSelector } from 'reselect';
15
15
  import { injectIntl, intlShape } from 'react-intl';
16
- import _ from 'lodash';
16
+ import _, {get} from 'lodash';
17
17
  import {makeSelectEdit, makeSelectEditResponse, makeSelectTemplateDetailsResponse} from "../../MobilePush/Edit/selectors";
18
18
  import {makeSelectMetaEntities} from "../../Cap/selectors";
19
19
  import {getMessageObject} from "../../../utils/messageUtils";
@@ -186,9 +186,10 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
186
186
  if (!_.isEmpty(this.state.schema)) {
187
187
  this.injectEvents(this.state.schema);
188
188
  }
189
- if (this.props.location.query && typeof this.props.location.query.module === 'undefined') { // when this containers is imported from creatives library
190
- if (this.props.params.id) {
191
- this.props.actions.getTemplateDetails(this.props.params.id);
189
+ if (this.props.location.query && (typeof this.props.location.query.module === 'undefined' || this.props.isFullMode === false)) { // when this containers is imported from creatives library
190
+ const templateId = get(this, "props.params.id");
191
+ if (templateId) {
192
+ this.props.actions.getTemplateDetails(templateId);
192
193
  } else {
193
194
  this.props.actions.setTemplateDetails(this.props.templateData);
194
195
  }
@@ -213,11 +214,12 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
213
214
  }
214
215
  if (nextProps.metaEntities && nextProps.metaEntities.layouts && nextProps.metaEntities.layouts.length > 0 && _.isEmpty(this.state.fullSchema)) {
215
216
  this.setState({fullSchema: nextProps.metaEntities.layouts[0].definition, schema: (nextProps.location.query.module === 'loyalty') ? nextProps.metaEntities.layouts[0].definition.textSchema : {}}, () => {
216
- if (nextProps.location.query.module !== 'loyalty' && this.props.params.id !== 'temp') {
217
- this.props.actions.getTemplateDetails(this.props.params.id);
217
+ const templateId = get(this, "props.params.id");
218
+ if (nextProps.location.query.module !== 'loyalty' && templateId && templateId !== 'temp') {
219
+ this.props.actions.getTemplateDetails(templateId);
218
220
  }
219
221
  const type = this.props.location.query.type;
220
- if (type === 'embedded' && this.props.params.id === 'temp' && _.isEmpty(this.state.formData)) { // when his.props.params.id is temp that means mobile push template content will be passed from post message from parent with startTemplateCreation action
222
+ if (type === 'embedded' && templateId === 'temp' && _.isEmpty(this.state.formData)) { // when his.props.params.id is temp that means mobile push template content will be passed from post message from parent with startTemplateCreation action
221
223
  const response = {
222
224
  action: 'startTemplateCreation',
223
225
  };
@@ -595,7 +597,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
595
597
  licenseCode: selectedWeChatAccount.sourceAccountIdentifier,
596
598
  };
597
599
  if (this.props.location.query && this.props.location.query.module !== 'dvs') {
598
- obj.definition.mode = this.props.Edit.templateDetails.mode;
600
+ obj.definition.mode = this.props.Edit.templateDetails.mode || get(this, 'props.Edit.templateDetails.definition.mode');
599
601
  }
600
602
  const android = {};
601
603
  Object.keys(formData[0]).forEach((data) => {
@@ -2549,6 +2551,7 @@ Edit.propTypes = {
2549
2551
  supportedTags: PropTypes.array,
2550
2552
  getDefaultTags: PropTypes.string,
2551
2553
  templateData: PropTypes.object,
2554
+ isFullMode: PropTypes.bool,
2552
2555
  };
2553
2556
 
2554
2557
  const mapStateToProps = createStructuredSelector({
@@ -3,7 +3,8 @@ import { createSelector } from 'reselect';
3
3
  /**
4
4
  * Direct selector to the create state domain
5
5
  */
6
- const selectMobilePushEditDomain = () => (state) => state.get('edit');
6
+ const selectMobilePushEditDomain = () => (state, props) => props.isFullMode === false ? state.get('mobileEdit') : state.get('edit'); // reducer injected as mobileEdit in library mode.
7
+
7
8
 
8
9
  /**
9
10
  * Other specific selectors
@@ -0,0 +1,92 @@
1
+ /*
2
+ *
3
+ * MobilepushWrapper
4
+ *
5
+ */
6
+ import PropTypes from 'prop-types';
7
+ import React from 'react';
8
+ import { connect } from 'react-redux';
9
+ import { FormattedMessage } from 'react-intl';
10
+ import {CapRadioCard, CapHeader} from '@capillarytech/cap-ui-library';
11
+ import {isEmpty} from 'lodash';
12
+ import MobilepushCreate from '../MobilePush/Create';
13
+ import messages from './messages';
14
+
15
+ export class MobilepushWrapper extends React.Component { // eslint-disable-line react/prefer-stateless-function
16
+ constructor(props) {
17
+ super(props);
18
+ this.modes = [
19
+ {
20
+ title: <FormattedMessage {...messages.text}/>,
21
+ content: <FormattedMessage {...messages.text}/>,
22
+ value: 'text',
23
+ // onClick: () => {
24
+ // this.emailUploader.current.click();
25
+ // },
26
+ },
27
+ {
28
+ title: <FormattedMessage {...messages.image}/>,
29
+ content: <FormattedMessage {...messages.image}/>,
30
+ value: 'image',
31
+ },
32
+ ];
33
+ }
34
+ onChange = (e) => {
35
+ this.props.onMobilepushModeChange( e.target.value );
36
+ };
37
+ render() {
38
+ const {mobilePushCreateMode, step, getFormData, setIsLoadingContent, isGetFormData, query} = this.props;
39
+ const isShowMobilepushCreate = !isEmpty(mobilePushCreateMode);
40
+ return (
41
+ <div>
42
+ {step === "modeSelection" ?
43
+ <div>
44
+ <CapHeader size="small" title={<FormattedMessage {...messages.createMode}/>}/>
45
+ <CapRadioCard
46
+ panes={this.modes}
47
+ onChange={this.onChange}
48
+ selected={mobilePushCreateMode}
49
+ />
50
+ </div>
51
+ :
52
+ <div>
53
+ {isShowMobilepushCreate && <MobilepushCreate
54
+ getFormLibraryData={getFormData}
55
+ setIsLoadingContent={setIsLoadingContent}
56
+ location={{
57
+ pathname: `/mobilepush/create/${mobilePushCreateMode}`,
58
+ query,
59
+ }}
60
+ params={{mode: mobilePushCreateMode}}
61
+ isFullMode={false}
62
+ isGetFormData={isGetFormData}
63
+ route={{ name: 'mobilepush' }}
64
+ />
65
+
66
+
67
+ }
68
+ </div>
69
+ }
70
+ </div>
71
+ );
72
+ }
73
+ }
74
+
75
+ MobilepushWrapper.propTypes = {
76
+ onMobilepushModeChange: PropTypes.func,
77
+ mobilePushCreateMode: PropTypes.string,
78
+ step: PropTypes.string,
79
+ getFormData: PropTypes.string,
80
+ setIsLoadingContent: PropTypes.func,
81
+ isGetFormData: PropTypes.bool,
82
+ query: PropTypes.object,
83
+ };
84
+
85
+
86
+ function mapDispatchToProps(dispatch) {
87
+ return {
88
+ dispatch,
89
+ };
90
+ }
91
+
92
+ export default connect(null, mapDispatchToProps)(MobilepushWrapper);
@@ -0,0 +1,25 @@
1
+ /*
2
+ * MobilepushWrapper Messages
3
+ *
4
+ * This contains all the text for the MobilepushWrapper component.
5
+ */
6
+ import { defineMessages } from 'react-intl';
7
+
8
+ export default defineMessages({
9
+ header: {
10
+ id: 'app.containers.MobilepushWrapper.header',
11
+ defaultMessage: 'This is MobilepushWrapper container !',
12
+ },
13
+ image: {
14
+ id: 'app.containers.MobilepushWrapper.image',
15
+ defaultMessage: 'Image content',
16
+ },
17
+ text: {
18
+ id: 'app.containers.MobilepushWrapper.text',
19
+ defaultMessage: 'Text content',
20
+ },
21
+ createMode: {
22
+ id: 'app.containers.MobilepushWrapper.createMode',
23
+ defaultMessage: 'Which type of content you want to create?',
24
+ },
25
+ });
@@ -0,0 +1,10 @@
1
+ // import React from 'react';
2
+ // import { shallow } from 'enzyme';
3
+
4
+ // import { MobilepushWrapper } from '../index';
5
+
6
+ describe('<MobilepushWrapper />', () => {
7
+ it('Expect to have unit tests specified', () => {
8
+ expect(true).toEqual(false);
9
+ });
10
+ });
@@ -8,13 +8,13 @@ import PropTypes from 'prop-types';
8
8
 
9
9
  import React from 'react';
10
10
  import { connect } from 'react-redux';
11
- import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
11
+ import {injectIntl, intlShape } from 'react-intl';
12
12
  import { createStructuredSelector } from 'reselect';
13
13
  import moment from "moment";
14
14
  import _ from 'lodash';
15
15
  import { bindActionCreators } from 'redux';
16
- import { Row, Select, Dropdown, Menu, Modal} from 'antd';
17
- import {CapButton, CapInput, CapIcon, CapSelect, CapPopover, CapSpin, CapCustomCard} from '@capillarytech/cap-ui-library';
16
+ import { Row, Dropdown, Menu, Modal} from 'antd';
17
+ import {CapButton, CapInput, CapIcon, CapSelect, CapPopover, CapSpin, CapCustomCard, CapRow, CapColumn} from '@capillarytech/cap-ui-library';
18
18
  import { makeSelectTemplates, makeSelectTemplatesResponse } from './selectors';
19
19
  import { makeSelectCreate as makeSelectCreateSms} from '../Sms/Create/selectors';
20
20
  import { makeSelectCreate as makeSelectCreateMobilePush } from '../MobilePush/Create/selectors';
@@ -44,7 +44,6 @@ import Pagination from '../../components/Pagination';
44
44
  import EmailPreview from '../../components/EmailPreview';
45
45
  import CreativesContainer from '../CreativesContainer';
46
46
  const MenuItem = Menu.Item;
47
- const Option = Select.Option;
48
47
  const {CapCustomCardList} = CapCustomCard;
49
48
 
50
49
  export class Templates extends React.Component { // eslint-disable-line react/prefer-stateless-function
@@ -1318,16 +1317,27 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1318
1317
  if (this.props.location.query.type === 'embedded' && (!this.props.location.query.module || (this.props.location.query.module && this.props.location.query.module !== 'library'))) {
1319
1318
  if (this.props.location.query.source_account_id && account.sourceAccountIdentifier === this.props.location.query.source_account_id) {
1320
1319
  accountOptions.push(
1321
- <Option key={this.state.channel.toUpperCase() === "MOBILEPUSH" ? account.id : account.uuid} value={account.name}>{account.name}</Option>
1320
+ { key: this.state.channel.toUpperCase() === "MOBILEPUSH" ? account.id : account.uuid,
1321
+ label: account.name,
1322
+ value: account.name,
1323
+ }
1322
1324
  );
1323
1325
  } else if (this.props.location.query.module && (this.state.channel.toUpperCase() === "WECHAT" || this.state.channel.toUpperCase() === "MOBILEPUSH")) {
1324
1326
  accountOptions.push(
1325
- <Option key={this.state.channel.toUpperCase() === "MOBILEPUSH" ? account.id : account.uuid} value={account.name}>{account.name}</Option>
1327
+ {
1328
+ key: this.state.channel.toUpperCase() === "MOBILEPUSH" ? account.id : account.uuid,
1329
+ value: account.name,
1330
+ label: account.name,
1331
+ }
1326
1332
  );
1327
1333
  }
1328
1334
  } else {
1329
1335
  accountOptions.push(
1330
- <Option key={this.state.channel.toUpperCase() === "MOBILEPUSH" ? account.id : account.uuid} value={account.name}>{account.name}</Option>
1336
+ {
1337
+ key: this.state.channel.toUpperCase() === "MOBILEPUSH" ? account.id : account.uuid,
1338
+ value: account.name,
1339
+ label: account.name,
1340
+ }
1331
1341
  );
1332
1342
  }
1333
1343
  }
@@ -1336,17 +1346,26 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1336
1346
  const pageHeader = (
1337
1347
  <div>
1338
1348
  {(this.isEnabledInLibraryModule("showAccountSelection") || (((this.state.channel.toUpperCase() === 'WECHAT' || this.state.channel.toUpperCase() === "MOBILEPUSH") && (this.props.location.query.type !== 'embedded') && !_.isEmpty(this.props.Templates.weCrmAccounts)))) &&
1339
- <CapSelect className="selectAccount" onSelect={this.onAccountSelect} value={this.props.Templates.selectedWeChatAccount ? this.props.Templates.selectedWeChatAccount.name : undefined} placeholder={this.props.intl.formatMessage(messages.selectAccount)}>
1340
- {accountOptions}
1341
- </CapSelect>}
1349
+ <CapSelect
1350
+ className="selectAccount"
1351
+ onSelect={this.onAccountSelect}
1352
+ value={this.props.Templates.selectedWeChatAccount ? this.props.Templates.selectedWeChatAccount.name : undefined}
1353
+ placeholder={this.props.intl.formatMessage(messages.selectAccount)}
1354
+ options={accountOptions}
1355
+ />
1356
+ }
1342
1357
  </div>
1343
1358
  );
1344
1359
  const pageHeaderDvs = (
1345
1360
  <div>
1346
1361
  {((this.state.channel.toUpperCase() === 'WECHAT' || this.state.channel.toUpperCase() === "MOBILEPUSH") && (this.props.location.query.type === 'embedded') && !_.isEmpty(this.props.Templates.weCrmAccounts)) &&
1347
- <CapSelect className="selectAccount" onSelect={this.onAccountSelect} value={this.props.Templates.selectedWeChatAccount ? this.props.Templates.selectedWeChatAccount.name : undefined} placeholder={this.props.intl.formatMessage(messages.selectAccount)}>
1348
- {accountOptions}
1349
- </CapSelect>}
1362
+ <CapSelect
1363
+ className="selectAccount"
1364
+ onSelect={this.onAccountSelect}
1365
+ value={this.props.Templates.selectedWeChatAccount ? this.props.Templates.selectedWeChatAccount.name : undefined} placeholder={this.props.intl.formatMessage(messages.selectAccount)}
1366
+ options={accountOptions}
1367
+ />
1368
+ }
1350
1369
  </div>
1351
1370
  );
1352
1371
  let actionButton = '';
@@ -1481,9 +1500,11 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1481
1500
  onChange={(e) => this.searchTemplate(e.target.value)}
1482
1501
  />
1483
1502
  <div style={{display: "flex", justifyContent: "space-between", alignItems: 'center'}}>
1503
+ {(this.props.location.query.type === 'embedded' ) ? pageHeaderDvs : pageHeader}
1484
1504
  <CapButton
1485
1505
  type={this.props.isFullMode ? "primary" : "secondary"}
1486
1506
  disabled={isLoading}
1507
+ style={{marginLeft: '8px'}}
1487
1508
  onClick={(ev) => this.props.isFullMode ? this.createTemplate(ev) : this.handleBlankTemplateAction()} >
1488
1509
  { this.props.intl.formatMessage(messages.createNewActionButton) }
1489
1510
  </CapButton>
@@ -1506,10 +1527,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1506
1527
  const loadingTip = (this.props.Templates.sendingFile && (this.state.channel.toLowerCase() === 'email' || this.state.channel.toLowerCase() === 'ebill')) ? this.props.intl.formatMessage(messages.uploadingFile) : this.props.intl.formatMessage(messages.gettingAllTemplates);
1507
1528
  return (
1508
1529
  <div>
1509
- <Row className="template-header-container">
1510
- <div className="template-header">{(this.props.location.query.type === 'embedded' ) ? pageHeaderDvs : pageHeader}</div>
1511
- </Row>
1512
-
1513
1530
  <input type="file" id="filename" style={{ display: 'none'}} accept=".zip, .html, .htm" onChange={(event) => this.handleFileUpload(event, {files: event.target.files})} />
1514
1531
 
1515
1532
 
@@ -1612,6 +1629,7 @@ Templates.propTypes = {
1612
1629
  isFullMode: PropTypes.bool,
1613
1630
  renderNewCardGrid: PropTypes.func,
1614
1631
  handlePeviewTemplate: PropTypes.func,
1632
+ router: PropTypes.object,
1615
1633
  };
1616
1634
 
1617
1635
  const mapStateToProps = createStructuredSelector({
@@ -55,7 +55,7 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
55
55
  {content: <div></div>, tab: 'Email', key: 'email'},
56
56
  // {content: <div></div>, tab: 'Call Task', key: 'calltask'},
57
57
  // {content: this.getTemplatesComponent('wechat'), tab: 'Wechat', key: 'wechat'},
58
- // {content: <div></div>, tab: 'Mpush', key: 'mobilepush'},
58
+ {content: <div></div>, tab: 'Mpush', key: 'mobilepush'},
59
59
  ];
60
60
  const panes = this.setChannelContent(defaultChannel, deafaultPanes);
61
61
  this.state = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "2.0.56",
4
+ "version": "2.0.57",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",