@capillarytech/creatives-library 3.2.3 → 3.3.0

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 (63) hide show
  1. package/components/FormBuilder/index.js +1 -1
  2. package/components/Header/index.js +4 -3
  3. package/components/Header/messages.js +4 -0
  4. package/config/app.js +1 -1
  5. package/containers/Assets/Gallery/index.js +1 -1
  6. package/containers/Cap/index.js +3 -5
  7. package/containers/Email/index.js +2 -2
  8. package/containers/Email/messages.js +8 -0
  9. package/containers/LanguageProvider/index.js +2 -1
  10. package/containers/Templates/index.js +2 -2
  11. package/containers/Templates/messages.js +24 -4
  12. package/containers/WeChat/RichmediaTemplates/Create/messages.js +24 -0
  13. package/i18n.js +16 -9
  14. package/package.json +1 -1
  15. package/translations/en.json +108 -60
  16. package/translations/zh.json +108 -60
  17. package/utils/smsCharCountV2.js +1 -1
  18. package/v2Components/CapTagList/index.js +2 -2
  19. package/v2Components/FormBuilder/index.js +5 -2
  20. package/v2Components/NavigationBar/index.js +9 -10
  21. package/v2Components/NewCallTask/index.js +3 -1
  22. package/v2Components/TopBar/index.js +3 -0
  23. package/v2Components/TopBar/messages.js +8 -0
  24. package/v2Containers/Assets/Gallery/index.js +1 -1
  25. package/v2Containers/Assets/Gallery/messages.js +4 -0
  26. package/v2Containers/CallTask/index.js +3 -1
  27. package/v2Containers/Cap/index.js +3 -2
  28. package/v2Containers/CreativesContainer/SlideBoxContent.js +11 -1
  29. package/v2Containers/CreativesContainer/index.js +4 -1
  30. package/v2Containers/Email/index.js +5 -2
  31. package/v2Containers/Email/messages.js +8 -0
  32. package/v2Containers/EmailWrapper/index.js +3 -0
  33. package/v2Containers/LanguageProvider/constants.js +0 -1
  34. package/v2Containers/LanguageProvider/index.js +2 -0
  35. package/v2Containers/LanguageProvider/reducer.js +1 -7
  36. package/v2Containers/MobilePush/Create/index.js +2 -1
  37. package/v2Containers/MobilePush/Create/messages.js +4 -0
  38. package/v2Containers/MobilePush/Edit/index.js +2 -1
  39. package/v2Containers/MobilePush/Edit/messages.js +4 -0
  40. package/v2Containers/Sms/Create/index.js +3 -1
  41. package/v2Containers/Sms/Create/messages.js +16 -0
  42. package/v2Containers/Sms/Edit/index.js +3 -1
  43. package/v2Containers/Sms/Edit/messages.js +16 -0
  44. package/v2Containers/TagList/index.js +43 -0
  45. package/v2Containers/Templates/_templates.scss +9 -1
  46. package/v2Containers/Templates/index.js +65 -52
  47. package/v2Containers/TemplatesV2/index.js +1 -0
  48. package/v2Containers/WeChat/MapTemplates/index.js +0 -1
  49. package/v2Containers/WeChat/RichmediaTemplates/Create/_createRichmedia.scss +10 -0
  50. package/v2Containers/WeChat/RichmediaTemplates/Create/actions.js +9 -0
  51. package/v2Containers/WeChat/RichmediaTemplates/Create/constants.js +3 -0
  52. package/v2Containers/WeChat/RichmediaTemplates/Create/index.js +146 -4
  53. package/v2Containers/WeChat/RichmediaTemplates/Create/messages.js +86 -57
  54. package/v2Containers/WeChat/RichmediaTemplates/Create/reducer.js +24 -1
  55. package/v2Containers/WeChat/RichmediaTemplates/Create/sagas.js +45 -0
  56. package/v2Containers/WeChat/RichmediaTemplates/Edit/constants.js +4 -0
  57. package/v2Containers/WeChat/RichmediaTemplates/Edit/index.js +8 -1
  58. package/v2Containers/WeChat/Wrapper/_wrapper.scss +9 -1
  59. package/v2Containers/WeChat/Wrapper/messages.js +5 -5
  60. package/containers/Cap/messsages.js +0 -63
  61. package/v2Components/Header/index.js +0 -46
  62. package/v2Components/Header/tests/index.test.js +0 -10
  63. package/v2Containers/TemplatesV2/_templatesV2.scss +0 -5
@@ -60,6 +60,7 @@ function SlideBoxContent(props) {
60
60
  onValidationFail,
61
61
  channelsToHide,
62
62
  forwardedTags,
63
+ selectedOfferDetails,
63
64
  channelsToDisable,
64
65
  weChatTemplateType,
65
66
  onWechatTemplateChange,
@@ -176,6 +177,7 @@ function SlideBoxContent(props) {
176
177
  getDefaultTags={type}
177
178
  templateData={templateData}
178
179
  forwardedTags={forwardedTags}
180
+ selectedOfferDetails={selectedOfferDetails}
179
181
  />
180
182
  )}
181
183
  {
@@ -185,6 +187,7 @@ function SlideBoxContent(props) {
185
187
  templateData={templateData}
186
188
  onCallTaskSubmit={onCallTaskSubmit}
187
189
  forwardedTags={forwardedTags}
190
+ selectedOfferDetails={selectedOfferDetails}
188
191
  />
189
192
  }
190
193
  {
@@ -193,6 +196,7 @@ function SlideBoxContent(props) {
193
196
  mode={'create'}
194
197
  onCallTaskSubmit={onCallTaskSubmit}
195
198
  forwardedTags={forwardedTags}
199
+ selectedOfferDetails={selectedOfferDetails}
196
200
  />
197
201
  }
198
202
  {isCreateSms && (
@@ -206,6 +210,7 @@ function SlideBoxContent(props) {
206
210
  getDefaultTags={type}
207
211
  isFullMode={isFullMode}
208
212
  forwardedTags={forwardedTags}
213
+ selectedOfferDetails={selectedOfferDetails}
209
214
  />
210
215
  )}
211
216
  {isEmailCreate && (
@@ -227,6 +232,7 @@ function SlideBoxContent(props) {
227
232
  showTemplateName={showTemplateName}
228
233
  onValidationFail={onValidationFail}
229
234
  forwardedTags={forwardedTags}
235
+ selectedOfferDetails={selectedOfferDetails}
230
236
  />
231
237
  )}
232
238
  {(isEditEmailWithId || isEmailEditWithContent) && (
@@ -249,6 +255,7 @@ function SlideBoxContent(props) {
249
255
  showTemplateName={showTemplateName}
250
256
  onValidationFail={onValidationFail}
251
257
  forwardedTags={forwardedTags}
258
+ selectedOfferDetails={selectedOfferDetails}
252
259
  />
253
260
  )}
254
261
  {isEditMPush &&
@@ -268,6 +275,7 @@ function SlideBoxContent(props) {
268
275
  getDefaultTags={type}
269
276
  onValidationFail={onValidationFail}
270
277
  forwardedTags={forwardedTags}
278
+ selectedOfferDetails={selectedOfferDetails}
271
279
  />
272
280
  }
273
281
  {isCreateMPush &&
@@ -291,7 +299,8 @@ function SlideBoxContent(props) {
291
299
  showTemplateName={showTemplateName}
292
300
  query={query}
293
301
  forwardedTags={forwardedTags}
294
- onValidationFail={onValidationFail}/>
302
+ onValidationFail={onValidationFail}
303
+ selectedOfferDetails={selectedOfferDetails}/>
295
304
  }
296
305
  </CreativesWrapper>
297
306
  );
@@ -325,6 +334,7 @@ SlideBoxContent.propTypes = {
325
334
  onValidationFail: PropTypes.func,
326
335
  channelsToHide: PropTypes.array,
327
336
  forwardedTags: PropTypes.object,
337
+ selectedOfferDetails: PropTypes.array,
328
338
  channelsToDisable: PropTypes.array,
329
339
  weChatTemplateType: PropTypes.string,
330
340
  onWechatTemplateChange: PropTypes.func,
@@ -465,8 +465,9 @@ class Creatives extends React.Component {
465
465
  }
466
466
  render() {
467
467
  const {slidBoxContent, isGetFormData, showSlideBox, templateData, currentChannel, emailCreateMode, templateStep, isLoadingContent, mobilePushCreateMode, isDiscardMessage, weChatTemplateType, weChatMaptemplateStep} = this.state;
468
- const {isFullMode, creativesMode, cap, isUploading, channelsToHide, selectedWeChatAccount, forwardedTags, channelsToDisable} = this.props;
468
+ const {isFullMode, creativesMode, cap, isUploading, channelsToHide, selectedWeChatAccount, forwardedTags, channelsToDisable, selectedOfferDetails} = this.props;
469
469
  const mapTemplateCreate = slidBoxContent === 'createTemplate' && weChatTemplateType === MAP_TEMPLATE && templateStep !== 'modeSelection';
470
+ /* TODO: Instead of passing down same props separately to each component down, write common function to these props and pass it accordingly */
470
471
  return (
471
472
  <SlideBoxWrapper className={classnames(`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`)}>
472
473
  <CapSlideBox
@@ -522,6 +523,7 @@ class Creatives extends React.Component {
522
523
  onValidationFail={this.onValidationFail}
523
524
  channelsToHide={channelsToHide}
524
525
  forwardedTags={forwardedTags}
526
+ selectedOfferDetails={selectedOfferDetails}
525
527
  channelsToDisable={channelsToDisable}
526
528
  weChatTemplateType={weChatTemplateType}
527
529
  onWechatTemplateChange={this.onWechatTemplateChange}
@@ -574,6 +576,7 @@ Creatives.propTypes = {
574
576
  EmailLayout: PropTypes.string,
575
577
  channelsToHide: PropTypes.array,
576
578
  forwardedTags: PropTypes.object,
579
+ selectedOfferDetails: PropTypes.array,
577
580
  channelsToDisable: PropTypes.array,
578
581
  selectedWeChatAccount: PropTypes.object,
579
582
  };
@@ -2559,9 +2559,10 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2559
2559
  // const actionComponents = '';
2560
2560
  const schema = this.state.schema;
2561
2561
  const isLoading = this.isEmailLoading();
2562
- const previewHeader = (<h3>Email Preview</h3>);
2563
- const imagePreviewHeader = (<h3>Image Selection</h3>);
2562
+ const previewHeader = (<h3>{this.props.intl.formatMessage(messages.h3emailPreview)}</h3>);
2563
+ const imagePreviewHeader = (<h3>{this.props.intl.formatMessage(messages.h3imageSelection)}</h3>);
2564
2564
  const imagePreviewContent = this.getImagePreviewContent();
2565
+ const { selectedOfferDetails } = this.props;
2565
2566
  if (!this.props.currentOrgDetails || !this.props.currentOrgDetails.basic_details) {
2566
2567
  return (<div>Loading...</div>);
2567
2568
  }
@@ -2617,6 +2618,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2617
2618
  getValidationData={this.saveValidationData}
2618
2619
  saveForm={this.state.saveForm}
2619
2620
  stopValidation={this.stopValidation}
2621
+ selectedOfferDetails={selectedOfferDetails}
2620
2622
  /> : ''}
2621
2623
  </Col>
2622
2624
  </Row>
@@ -2669,6 +2671,7 @@ Email.propTypes = {
2669
2671
  defaultData: PropTypes.object,
2670
2672
  showTemplateName: PropTypes.func,
2671
2673
  onValidationFail: PropTypes.func,
2674
+ selectedOfferDetails: PropTypes.array,
2672
2675
  };
2673
2676
 
2674
2677
  const mapStateToProps = (state, props) => createStructuredSelector({
@@ -278,4 +278,12 @@ export default defineMessages({
278
278
  id: 'creatives.containersV2.Email.alertMessage',
279
279
  defaultMessage: 'Alert',
280
280
  },
281
+ "h3emailPreview": {
282
+ id: 'creatives.containersV2.Email.h3emailPreview',
283
+ defaultMessage: 'Email preview',
284
+ },
285
+ "h3imageSelection": {
286
+ id: 'creatives.containersV2.Email.h3imageSelection',
287
+ defaultMessage: 'Image selection',
288
+ },
281
289
  });
@@ -173,6 +173,7 @@ export class EmailWrapper extends React.Component { // eslint-disable-line react
173
173
  setIsLoadingContent,
174
174
  onValidationFail,
175
175
  forwardedTags,
176
+ selectedOfferDetails,
176
177
  } = this.props;
177
178
  const {
178
179
  templateName,
@@ -232,6 +233,7 @@ export class EmailWrapper extends React.Component { // eslint-disable-line react
232
233
  showTemplateName={showTemplateName}
233
234
  onValidationFail={onValidationFail}
234
235
  forwardedTags={forwardedTags}
236
+ selectedOfferDetails={selectedOfferDetails}
235
237
  />}
236
238
  {CmsTemplates && !isShowEmailCreate && <CmsTemplatesComponent cmsTemplates={CmsTemplates} handleEdmDefaultTemplateSelection={this.useEditor} />}
237
239
  </div>
@@ -263,6 +265,7 @@ EmailWrapper.propTypes = {
263
265
  showTemplateName: PropTypes.func,
264
266
  onValidationFail: PropTypes.func,
265
267
  forwardedTags: PropTypes.object,
268
+ selectedOfferDetails: PropTypes.array,
266
269
  };
267
270
 
268
271
  const mapStateToProps = createStructuredSelector({
@@ -4,7 +4,6 @@
4
4
  *
5
5
  */
6
6
 
7
- export const CHANGE_LOCALE = 'app/LanguageToggle/CHANGE_LOCALE';
8
7
  export const DEFAULT_LOCALE = 'en';
9
8
 
10
9
  export const GET_LOCIZ_MESSAGE_REQUEST =
@@ -15,6 +15,7 @@ import zhCN from 'antd/es/locale-provider/zh_CN';
15
15
  import { connect } from 'react-redux';
16
16
  import { createStructuredSelector } from 'reselect';
17
17
  import { IntlProvider } from 'react-intl';
18
+ import moment from 'moment';
18
19
  import { bindActionCreators } from 'redux';
19
20
  import * as actions from './actions';
20
21
  import { makeSelectLocale } from './selectors';
@@ -24,6 +25,7 @@ export class LanguageProvider extends React.PureComponent { // eslint-disable-li
24
25
  componentDidMount() {
25
26
  const user = localStorage.getItem('user');
26
27
  let locale = localStorage.getItem('jlocale') || 'en';
28
+ moment.locale(locale);
27
29
  if (user) {
28
30
  locale = JSON.parse(user).lang;
29
31
  }
@@ -7,21 +7,15 @@
7
7
  import { fromJS } from 'immutable';
8
8
 
9
9
  import * as types from './constants';
10
- import {
11
- DEFAULT_LOCALE,
12
- } from '../Cap/constants'; // eslint-disable-line
13
10
 
14
11
  const initialState = fromJS({
15
- locale: DEFAULT_LOCALE,
12
+ locale: types.DEFAULT_LOCALE,
16
13
  messages: {},
17
14
  localeLoading: false,
18
15
  });
19
16
 
20
17
  function languageProviderReducer(state = initialState, action) {
21
18
  switch (action.type) {
22
- case types.CHANGE_LOCALE:
23
- return state
24
- .set('locale', action.locale);
25
19
  case types.GET_LOCIZ_MESSAGE_REQUEST:
26
20
  return state.set('localeLoading', true);
27
21
  case types.GET_LOCIZ_MESSAGE_SUCCESS:
@@ -978,7 +978,7 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
978
978
  size={"label"}/>
979
979
  </CapColumn>
980
980
  <CapColumn span={6}>
981
- <CapLink title="change" onClick={() => this.addSecondoryCtaIos(true, this.state.formData, {id: "add-sec-cta-ios"})}/>
981
+ <CapLink title={this.props.intl.formatMessage(messages.change)} onClick={() => this.addSecondoryCtaIos(true, this.state.formData, {id: "add-sec-cta-ios"})}/>
982
982
  </CapColumn>
983
983
  </CapRow>,
984
984
  primitive: true,
@@ -1705,6 +1705,7 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
1705
1705
  setModalContent={this.setModalContent}
1706
1706
  startValidation={this.state.startValidation}
1707
1707
  stopValidation={this.stopValidation}
1708
+ selectedOfferDetails={this.props.selectedOfferDetails}
1708
1709
  />
1709
1710
  </CapColumn>
1710
1711
  {this.props.iosCtasData && this.state.showIosCtaTable &&
@@ -290,4 +290,8 @@ export default defineMessages({
290
290
  id: 'creatives.containersV2.MobilePush.Create.here',
291
291
  defaultMessage: 'here .',
292
292
  },
293
+ "change": {
294
+ id: 'creatives.containersV2.MobilePush.Create.change',
295
+ defaultMessage: 'change',
296
+ },
293
297
  });
@@ -967,7 +967,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
967
967
  size={"label"}/>
968
968
  </CapColumn>
969
969
  <CapColumn span={6}>
970
- <CapLink title="change" onClick={() => this.addSecondoryCtaIos(true, this.state.formData, {id: "add-sec-cta-ios"})}/>
970
+ <CapLink title={this.props.intl.formatMessage(messages.change)} onClick={() => this.addSecondoryCtaIos(true, this.state.formData, {id: "add-sec-cta-ios"})}/>
971
971
  </CapColumn>
972
972
  </CapRow>,
973
973
  primitive: true,
@@ -1792,6 +1792,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
1792
1792
  setModalContent={this.setModalContent}
1793
1793
  startValidation={this.state.startValidation}
1794
1794
  stopValidation={this.stopValidation}
1795
+ selectedOfferDetails={this.props.selectedOfferDetails}
1795
1796
  />}
1796
1797
  </CapColumn>
1797
1798
  {this.props.iosCtasData && this.state.showIosCtaTable &&
@@ -282,4 +282,8 @@ export default defineMessages({
282
282
  id: 'creatives.containersV2.MobilePush.Edit.pleaseInput',
283
283
  defaultMessage: "Please input",
284
284
  },
285
+ "change": {
286
+ id: 'creatives.containersV2.MobilePush.Edit.change',
287
+ defaultMessage: "change",
288
+ },
285
289
  });
@@ -176,7 +176,7 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
176
176
  const unicodeEnabled = _.get(this.state, `formData[0]['unicode-validity']`);
177
177
  const smsDetails = updateCharCount(content || "", unicodeEnabled || false);
178
178
  if (this.smsCount.current) {
179
- this.smsCount.current.innerText = `${smsDetails.parts}SMS (${smsDetails.chars_used} characters)`;
179
+ this.smsCount.current.innerText = `${smsDetails.parts}${this.props.intl.formatMessage(messages.sms)} (${smsDetails.chars_used} ${this.props.intl.formatMessage(messages.characters)})`;
180
180
  }
181
181
  }
182
182
 
@@ -970,6 +970,7 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
970
970
  router={this.props.router}
971
971
  startValidation={this.state.startValidation}
972
972
  stopValidation={this.stopValidation}
973
+ selectedOfferDetails={this.props.selectedOfferDetails}
973
974
  />
974
975
  </CapColumn>
975
976
  </CapRow>
@@ -995,6 +996,7 @@ Create.propTypes = {
995
996
  isFullMode: PropTypes.bool,
996
997
  getFormSubscriptionData: PropTypes.func,
997
998
  isLoadingMetaEntities: PropTypes.bool,
999
+ selectedOfferDetails: PropTypes.array,
998
1000
  };
999
1001
 
1000
1002
  const mapStateToProps = createStructuredSelector({
@@ -110,4 +110,20 @@ export default defineMessages({
110
110
  id: 'creatives.containersV2.Create.templateNotValid',
111
111
  defaultMessage: 'Template data is not valid',
112
112
  },
113
+ "Creative name": {
114
+ id: 'creatives.containersV2.Create.creativeName',
115
+ defaultMessage: 'Creative name',
116
+ },
117
+ "Add label": {
118
+ id: 'creatives.containersV2.Create.addLabel',
119
+ defaultMessage: 'Add label',
120
+ },
121
+ "sms": {
122
+ id: 'creatives.containersV2.Create.sms',
123
+ defaultMessage: 'SMS',
124
+ },
125
+ "characters" : {
126
+ id: 'creatives.containersV2.Create.characters',
127
+ defaultMessage: 'characters',
128
+ },
113
129
  });
@@ -194,7 +194,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
194
194
  const unicodeEnabled = _.get(this.state, `formData[0]['unicode-validity']`);
195
195
  const smsDetails = updateCharCount(content || "", unicodeEnabled || false);
196
196
  if (this.smsCount.current) {
197
- this.smsCount.current.innerText = `${smsDetails.parts}SMS (${smsDetails.chars_used} characters)`;
197
+ this.smsCount.current.innerText = `${smsDetails.parts}${this.props.intl.formatMessage(messages.sms)} (${smsDetails.chars_used} ${this.props.intl.formatMessage(messages.characters)})`;
198
198
  }
199
199
  }
200
200
 
@@ -966,6 +966,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
966
966
  router={this.props.router}
967
967
  startValidation={this.state.startValidation}
968
968
  stopValidation={this.stopValidation}
969
+ selectedOfferDetails={this.props.selectedOfferDetails}
969
970
  />
970
971
  </CapColumn>
971
972
  </CapRow>
@@ -994,6 +995,7 @@ Edit.propTypes = {
994
995
  setIsLoadingContent: PropTypes.func,
995
996
  // route: PropTypes.object,
996
997
  injectedTags: PropTypes.object,
998
+ selectedOfferDetails: PropTypes.array,
997
999
  };
998
1000
 
999
1001
  const mapStateToProps = createStructuredSelector({
@@ -102,4 +102,20 @@ export default defineMessages({
102
102
  id: 'creatives.containersV2.Edit.templateMarkedSuccessfully',
103
103
  defaultMessage: "Template Marked as Final Successfully",
104
104
  },
105
+ "Creative name": {
106
+ id: 'creatives.containersV2.Edit.creativeName',
107
+ defaultMessage: 'Creative name',
108
+ },
109
+ "Add label": {
110
+ id: 'creatives.containersV2.Edit.addLabel',
111
+ defaultMessage: 'Add label',
112
+ },
113
+ "sms": {
114
+ id: 'creatives.containersV2.Edit.sms',
115
+ defaultMessage: 'SMS',
116
+ },
117
+ "characters" : {
118
+ id: 'creatives.containersV2.Edit.characters',
119
+ defaultMessage: 'characters',
120
+ },
105
121
  });
@@ -31,6 +31,7 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
31
31
  this.populateTags = this.populateTags.bind(this);
32
32
  this.populateTagForChildren = this.populateTagForChildren.bind(this);
33
33
  this.transformInjectedTags = this.transformInjectedTags.bind(this);
34
+ this.transformCouponTags = this.transformCouponTags.bind(this);
34
35
  }
35
36
 
36
37
  componentDidMount() {
@@ -138,6 +139,44 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
138
139
  return tagsObject[tagValue];
139
140
  }
140
141
 
142
+ transformCouponTags(offerDetails, allTags) {
143
+ const couponTags = {};
144
+ const couponTagsKeys = Object.keys(_.get(allTags, 'coupon.subtags', []));
145
+ const withCouponId = (obj, id) => {
146
+ const tempObj = {};
147
+ if (obj.subtags) {
148
+ tempObj.subtags = _.mapValues(obj.subtags, (tag) => ({
149
+ ...withCouponId(tag, id),
150
+ }));
151
+ }
152
+ return {
153
+ ...obj,
154
+ ...tempObj,
155
+ couponSeriesId: id,
156
+ };
157
+ };
158
+ offerDetails.forEach((offer) => {
159
+ const { id, couponName } = offer;
160
+ const couponSubTags = {};
161
+ couponTagsKeys.forEach((couponTagKey) => {
162
+ const couponSubTagsObj = withCouponId(allTags.coupon.subtags[couponTagKey], id);
163
+ couponSubTags[couponTagKey] = couponSubTagsObj;
164
+ });
165
+ const key = couponName || id;
166
+ couponTags[key] = {
167
+ 'tag-header': true,
168
+ 'name': couponName || id,
169
+ 'desc': couponName || id,
170
+ 'couponSeriesId': id,
171
+ 'subtags': couponSubTags,
172
+ 'resolved': true,
173
+ 'couponTags': true,
174
+ };
175
+ });
176
+ // eslint-disable-next-line no-param-reassign
177
+ allTags.coupon.subtags = couponTags;
178
+ }
179
+
141
180
  transformInjectedTags(tags) {
142
181
  _.forEach(tags, (tag) => {
143
182
  const temp = tag;
@@ -189,6 +228,9 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
189
228
  tags = this.populateTags(this.props.tags);
190
229
  console.log('populating tags', tags);
191
230
  }
231
+ if (this.props.selectedOfferDetails && !_.isEmpty(this.props.selectedOfferDetails) && (tags && tags.coupon)) {
232
+ this.transformCouponTags(this.props.selectedOfferDetails, tags);
233
+ }
192
234
  tags = _.merge( {}, tags, injectedTags);
193
235
  console.log('merged tags', tags);
194
236
  return (
@@ -220,6 +262,7 @@ TagList.propTypes = {
220
262
  moduleFilterEnabled: PropTypes.bool,
221
263
  className: PropTypes.string,
222
264
  userLocale: PropTypes.string,
265
+ selectedOfferDetails: PropTypes.array,
223
266
  };
224
267
 
225
268
  const mapStateToProps = createStructuredSelector({
@@ -1,4 +1,6 @@
1
- .ant-tabs-content{
1
+ @import '~@capillarytech/cap-ui-library/styles/_variables.scss';
2
+
3
+ .ant-tabs-content{
2
4
  margin-top: 16px;
3
5
  .ant-tabs-tabpane-active{
4
6
  padding: unset;
@@ -16,6 +18,12 @@
16
18
  }
17
19
  }
18
20
 
21
+ .ant-radio-group.#{cap-radioCard-v2} {
22
+ .ant-radio-button-wrapper {
23
+ border: 1px solid $CAP_G07;
24
+ }
25
+ }
26
+
19
27
  .card-title {
20
28
  line-height: 24px;
21
29
  font-size: 14px;
@@ -54,6 +54,7 @@ import { MOBILE_PUSH, WECHAT, SMS, EMAIL, EBILL, LINE } from '../CreativesContai
54
54
  import emailIllustration from '../Assets/images/emailIllustration.svg';
55
55
  import smsIllustration from '../Assets/images/smsIllustration.svg';
56
56
  import pushIllustration from '../Assets/images/pushIllustration.svg';
57
+ import { CAP_SPACE_16 } from '@capillarytech/cap-ui-library/styled/variables';
57
58
 
58
59
 
59
60
  const {CapCustomCardList} = CapCustomCard;
@@ -67,6 +68,7 @@ const InlineDiv = styled.div`
67
68
  }
68
69
  `;
69
70
  const ACCOUNT_SELECTION_MODE = "accountSelectionMode";
71
+ const ACCOUNT_CHANGE_MODE = 'accountChangeMode';
70
72
  const TEMPLATES_MODE = "templatesMode";
71
73
  const WECHAT_FILTERS = {
72
74
  ALL: 'all',
@@ -1525,6 +1527,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1525
1527
 
1526
1528
  renderAccountSelection = () => {
1527
1529
  const accountOptions = [];
1530
+ const { selectedAccount } = this.state;
1528
1531
  let { channel = '' } = this.state;
1529
1532
  channel = channel.toUpperCase();
1530
1533
  const { Templates: templates = {}, location = {} } = this.props;
@@ -1570,7 +1573,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1570
1573
  }
1571
1574
  return (<CapSpin spinning={fetchingWeCrmAccounts}>
1572
1575
  {isEmpty(weCrmAccounts) && !fetchingWeCrmAccounts ? <FormattedMessage {...messages.noAccountsPresentWeChat} /> :
1573
- <div style={{overflowX: "auto"}}>
1576
+ <div style={{ overflowX: "auto", paddingBottom: CAP_SPACE_16 }}>
1574
1577
  <CapHeader
1575
1578
  title={isMobilePushChannel ? this.props.intl.formatMessage(messages.mobilepushAccount) : this.props.intl.formatMessage(messages.wechatAccount)}
1576
1579
  description={this.props.intl.formatMessage(messages.chooseAccount)}
@@ -1584,7 +1587,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1584
1587
  cardHeight="48px"
1585
1588
  cardWidth="276px"
1586
1589
  size="small"
1587
- />
1590
+ defaultValue={selectedAccount}
1591
+ selected={selectedAccount}
1592
+ />
1588
1593
  </div>
1589
1594
  }
1590
1595
  </CapSpin>);
@@ -1594,18 +1599,23 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1594
1599
  this.setState({activeMode: ACCOUNT_SELECTION_MODE});
1595
1600
  }
1596
1601
 
1602
+ setAccountChangeMode = () => {
1603
+ this.setState({activeMode: ACCOUNT_CHANGE_MODE});
1604
+ }
1605
+
1597
1606
  setTemplatesMode = () => {
1598
1607
  this.setState({activeMode: TEMPLATES_MODE});
1599
1608
  }
1600
1609
 
1601
1610
  showAccountName = () => {
1602
- const { selectedAccount, channel } = this.state;
1611
+ const { activeMode, selectedAccount, channel } = this.state;
1603
1612
  const { Templates: templates = {}} = this.props;
1604
1613
  const { weCrmAccounts = []} = templates;
1605
1614
  const isMobilePushChannel = channel === MOBILE_PUSH;
1606
- return (<CapHeader
1615
+ return (activeMode !== ACCOUNT_CHANGE_MODE &&
1616
+ <CapHeader
1607
1617
  title={<CapHeading type="h4">{isMobilePushChannel ? this.props.intl.formatMessage(messages.mobilepushAccount) : this.props.intl.formatMessage(messages.wechatAccount)}</CapHeading>}
1608
- description={<><CapHeading type="h3">{selectedAccount} {weCrmAccounts.length > 1 && <CapLink onClick={this.setAccountSelectionMode} style={{display: 'inline-block', position: 'relative', top: '3px'}} fontWeight="regular" fontSize="14px" title="change"/>} </CapHeading></>}
1618
+ description={<><CapHeading type="h3">{selectedAccount} {weCrmAccounts.length > 1 && <CapLink onClick={this.setAccountChangeMode} style={{display: 'inline-block', position: 'relative', top: '3px'}} fontWeight="regular" fontSize="14px" title="change"/>} </CapHeading></>}
1609
1619
  size="regular"
1610
1620
  />);
1611
1621
  }
@@ -1691,63 +1701,66 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1691
1701
  const {route} = this.props;
1692
1702
  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);
1693
1703
  return (
1694
- <div className={`creatives-templates-list ${this.props.isFullMode ? 'full-mode' : 'library-mode'}`}>
1695
- <input type="file" id="filename" style={{ display: 'none'}} accept=".zip, .html, .htm" onChange={(event) => this.handleFileUpload(event, {files: event.target.files})} />
1704
+ <>
1705
+ {activeMode === ACCOUNT_CHANGE_MODE && this.renderAccountSelection()}
1706
+ <div className={`creatives-templates-list ${this.props.isFullMode ? 'full-mode' : 'library-mode'}`}>
1707
+ <input type="file" id="filename" style={{ display: 'none'}} accept=".zip, .html, .htm" onChange={(event) => this.handleFileUpload(event, {files: event.target.files})} />
1696
1708
 
1697
1709
 
1698
- <CapRow>
1699
- <Pagination onPageChange={templates.length ? this.onPaginationChange : () => {}} paginationSelector="pagination-container">
1700
- {this.getTemplateDataForGrid({isLoading, loadingTip, channel: this.state.channel, templates: this.props.TemplatesList, filterContent, handlers: {handlePreviewClick: this.handlePreviewClick, handleEditClick: this.handleEditClick}})}
1701
- </Pagination>
1702
- {(((this.state.selectedAccount !== '' && !isEmpty(this.props.Templates.selectedWeChatAccount) && this.state.channel.toLowerCase() === 'wechat') || this.state.channel.toLowerCase() !== 'wechat') && isEmpty(this.props.TemplatesList)) && !this.props.Templates.getAllTemplatesInProgress && !isEmpty(this.state.searchText) &&
1710
+ <CapRow>
1711
+ <Pagination onPageChange={templates.length ? this.onPaginationChange : () => {}} paginationSelector="pagination-container">
1712
+ {this.getTemplateDataForGrid({isLoading, loadingTip, channel: this.state.channel, templates: this.props.TemplatesList, filterContent, handlers: {handlePreviewClick: this.handlePreviewClick, handleEditClick: this.handleEditClick}})}
1713
+ </Pagination>
1714
+ {(((this.state.selectedAccount !== '' && !isEmpty(this.props.Templates.selectedWeChatAccount) && this.state.channel.toLowerCase() === 'wechat') || this.state.channel.toLowerCase() !== 'wechat') && isEmpty(this.props.TemplatesList)) && !this.props.Templates.getAllTemplatesInProgress && !isEmpty(this.state.searchText) &&
1703
1715
  <div style={{ height: '65vh', textAlign: 'center', lineHeight: '65vh'}}>
1704
1716
  <CapHeading type="h6">{this.props.intl.formatMessage(messages.noTemplatesFound)}</CapHeading>
1705
1717
  </div>}
1706
- </CapRow>
1707
-
1708
-
1709
- <CapRow>
1710
- {!isEmpty(creativesParams.mode) && isFullMode && //creatives container for fullmode
1711
- <CreativesContainer
1712
- key={creativesParams.mode}
1713
- messageDetails={{type: "default"}}
1714
- creativesMode={creativesParams.mode}
1715
- messages={messages}
1716
- isFullMode={isFullMode}
1717
- templateData={creativesParams}
1718
- getCreativesData={() => { this.onCreateComplete(true); }}
1719
- channel={route.name.toUpperCase()}
1720
- handleCloseCreatives={this.onCreateComplete}
1721
- selectedWeChatAccount={get(this.props, 'Templates.selectedWeChatAccount', {})}
1718
+ </CapRow>
1719
+
1720
+
1721
+ <CapRow>
1722
+ {!isEmpty(creativesParams.mode) && isFullMode && //creatives container for fullmode
1723
+ <CreativesContainer
1724
+ key={creativesParams.mode}
1725
+ messageDetails={{type: "default"}}
1726
+ creativesMode={creativesParams.mode}
1727
+ messages={messages}
1728
+ isFullMode={isFullMode}
1729
+ templateData={creativesParams}
1730
+ getCreativesData={() => { this.onCreateComplete(true); }}
1731
+ channel={route.name.toUpperCase()}
1732
+ handleCloseCreatives={this.onCreateComplete}
1733
+ selectedWeChatAccount={get(this.props, 'Templates.selectedWeChatAccount', {})}
1722
1734
  />
1723
1735
  }
1724
- </CapRow>
1725
- <CapRow>
1726
-
1727
- {(this.state.channel.toLowerCase() === 'ebill' || this.state.channel.toLowerCase() === 'email') && htmlPreviewContent && <EmailPreview
1728
- header={previewHeader}
1729
- content={htmlPreviewContent}
1730
- show={this.state.showHtmlPreview}
1731
- device={this.state.device}
1732
- handleClose={this.toggleEmailPreview}
1733
- changePreviewDevice={this.changePreviewDevice}
1734
- versions={get(this.state, 'previewTemplate.versions', {})}
1735
- lastModified={this.state.previewTemplate ? this.state.previewTemplate.updatedAt : ''}
1736
- updatedByName={commonUtil.getUserNameById(parseInt(this.state.previewTemplate.updatedBy, 10), commonUtil.getMergedUserList(this.props.Templates.userList))}
1736
+ </CapRow>
1737
+ <CapRow>
1738
+
1739
+ {(this.state.channel.toLowerCase() === 'ebill' || this.state.channel.toLowerCase() === 'email') && htmlPreviewContent && <EmailPreview
1740
+ header={previewHeader}
1741
+ content={htmlPreviewContent}
1742
+ show={this.state.showHtmlPreview}
1743
+ device={this.state.device}
1744
+ handleClose={this.toggleEmailPreview}
1745
+ changePreviewDevice={this.changePreviewDevice}
1746
+ versions={get(this.state, 'previewTemplate.versions', {})}
1747
+ lastModified={this.state.previewTemplate ? this.state.previewTemplate.updatedAt : ''}
1748
+ updatedByName={commonUtil.getUserNameById(parseInt(this.state.previewTemplate.updatedBy, 10), commonUtil.getMergedUserList(this.props.Templates.userList))}
1737
1749
  />}
1738
- <CapSlideBox
1739
- header={(<h3>{this.props.intl.formatMessage(messages.layoutSelection)}</h3>)}
1740
- width={60}
1741
- content={cmsTemplateSelectionContent}
1742
- show={this.state.showEdmEmailTemplates}
1743
- handleClose={this.toggleEdmEmailTemplateSelection}
1744
- loadingText={"Loading EDM Templates"}
1745
- isLoading={this.props.Templates.getCmsTemplatesInProgress}
1750
+ <CapSlideBox
1751
+ header={(<h3>{this.props.intl.formatMessage(messages.layoutSelection)}</h3>)}
1752
+ width={60}
1753
+ content={cmsTemplateSelectionContent}
1754
+ show={this.state.showEdmEmailTemplates}
1755
+ handleClose={this.toggleEdmEmailTemplateSelection}
1756
+ loadingText={"Loading EDM Templates"}
1757
+ isLoading={this.props.Templates.getCmsTemplatesInProgress}
1746
1758
  />
1747
- {this.renderDeleteConfirmationModal()}
1748
- </CapRow>
1759
+ {this.renderDeleteConfirmationModal()}
1760
+ </CapRow>
1749
1761
 
1750
- </div>
1762
+ </div>
1763
+ </>
1751
1764
  );
1752
1765
  }
1753
1766