@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.
- package/components/FormBuilder/index.js +1 -1
- package/components/Header/index.js +4 -3
- package/components/Header/messages.js +4 -0
- package/config/app.js +1 -1
- package/containers/Assets/Gallery/index.js +1 -1
- package/containers/Cap/index.js +3 -5
- package/containers/Email/index.js +2 -2
- package/containers/Email/messages.js +8 -0
- package/containers/LanguageProvider/index.js +2 -1
- package/containers/Templates/index.js +2 -2
- package/containers/Templates/messages.js +24 -4
- package/containers/WeChat/RichmediaTemplates/Create/messages.js +24 -0
- package/i18n.js +16 -9
- package/package.json +1 -1
- package/translations/en.json +108 -60
- package/translations/zh.json +108 -60
- package/utils/smsCharCountV2.js +1 -1
- package/v2Components/CapTagList/index.js +2 -2
- package/v2Components/FormBuilder/index.js +5 -2
- package/v2Components/NavigationBar/index.js +9 -10
- package/v2Components/NewCallTask/index.js +3 -1
- package/v2Components/TopBar/index.js +3 -0
- package/v2Components/TopBar/messages.js +8 -0
- package/v2Containers/Assets/Gallery/index.js +1 -1
- package/v2Containers/Assets/Gallery/messages.js +4 -0
- package/v2Containers/CallTask/index.js +3 -1
- package/v2Containers/Cap/index.js +3 -2
- package/v2Containers/CreativesContainer/SlideBoxContent.js +11 -1
- package/v2Containers/CreativesContainer/index.js +4 -1
- package/v2Containers/Email/index.js +5 -2
- package/v2Containers/Email/messages.js +8 -0
- package/v2Containers/EmailWrapper/index.js +3 -0
- package/v2Containers/LanguageProvider/constants.js +0 -1
- package/v2Containers/LanguageProvider/index.js +2 -0
- package/v2Containers/LanguageProvider/reducer.js +1 -7
- package/v2Containers/MobilePush/Create/index.js +2 -1
- package/v2Containers/MobilePush/Create/messages.js +4 -0
- package/v2Containers/MobilePush/Edit/index.js +2 -1
- package/v2Containers/MobilePush/Edit/messages.js +4 -0
- package/v2Containers/Sms/Create/index.js +3 -1
- package/v2Containers/Sms/Create/messages.js +16 -0
- package/v2Containers/Sms/Edit/index.js +3 -1
- package/v2Containers/Sms/Edit/messages.js +16 -0
- package/v2Containers/TagList/index.js +43 -0
- package/v2Containers/Templates/_templates.scss +9 -1
- package/v2Containers/Templates/index.js +65 -52
- package/v2Containers/TemplatesV2/index.js +1 -0
- package/v2Containers/WeChat/MapTemplates/index.js +0 -1
- package/v2Containers/WeChat/RichmediaTemplates/Create/_createRichmedia.scss +10 -0
- package/v2Containers/WeChat/RichmediaTemplates/Create/actions.js +9 -0
- package/v2Containers/WeChat/RichmediaTemplates/Create/constants.js +3 -0
- package/v2Containers/WeChat/RichmediaTemplates/Create/index.js +146 -4
- package/v2Containers/WeChat/RichmediaTemplates/Create/messages.js +86 -57
- package/v2Containers/WeChat/RichmediaTemplates/Create/reducer.js +24 -1
- package/v2Containers/WeChat/RichmediaTemplates/Create/sagas.js +45 -0
- package/v2Containers/WeChat/RichmediaTemplates/Edit/constants.js +4 -0
- package/v2Containers/WeChat/RichmediaTemplates/Edit/index.js +8 -1
- package/v2Containers/WeChat/Wrapper/_wrapper.scss +9 -1
- package/v2Containers/WeChat/Wrapper/messages.js +5 -5
- package/containers/Cap/messsages.js +0 -63
- package/v2Components/Header/index.js +0 -46
- package/v2Components/Header/tests/index.test.js +0 -10
- 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>
|
|
2563
|
-
const imagePreviewHeader = (<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({
|
|
@@ -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=
|
|
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 &&
|
|
@@ -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=
|
|
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 &&
|
|
@@ -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}
|
|
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}
|
|
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
|
-
|
|
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 (
|
|
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.
|
|
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
|
-
|
|
1695
|
-
|
|
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
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
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
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
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
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
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
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
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
|
-
|
|
1748
|
-
|
|
1759
|
+
{this.renderDeleteConfirmationModal()}
|
|
1760
|
+
</CapRow>
|
|
1749
1761
|
|
|
1750
|
-
|
|
1762
|
+
</div>
|
|
1763
|
+
</>
|
|
1751
1764
|
);
|
|
1752
1765
|
}
|
|
1753
1766
|
|