@capillarytech/creatives-library 3.10.0 → 3.11.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/assets/lineImageTemplate.png +0 -0
- package/components/TemplatePreview/WechatRichmediaTemplatePreview/index.js +7 -7
- package/components/TemplatePreview/_templatePreview.scss +287 -20
- package/components/TemplatePreview/assets/images/home-screen-android.svg +21 -0
- package/components/TemplatePreview/assets/images/home-screen-ios.svg +16 -0
- package/components/TemplatePreview/assets/images/sms_mobile_android.svg +22 -0
- package/components/TemplatePreview/assets/images/sms_mobile_ios.svg +16 -0
- package/components/TemplatePreview/assets/images/wechat_mobile_android.svg +20 -0
- package/components/TemplatePreview/index.js +203 -31
- package/components/TemplatePreview/messages.js +21 -0
- package/containers/Assets/Gallery/index.js +53 -59
- package/containers/Cap/index.js +1 -0
- package/index.js +6 -0
- package/package.json +1 -1
- package/routes.js +5 -0
- package/services/getSchema.js +4 -1
- package/translations/en.json +40 -4
- package/translations/zh.json +39 -3
- package/v2Components/FormBuilder/index.js +188 -37
- package/v2Components/FormBuilder/messages.js +16 -0
- package/v2Components/MobilePushPreviewV2/index.js +44 -36
- package/v2Components/MobilePushPreviewV2/messages.js +0 -8
- package/v2Components/TemplatePreview/WechatRichmediaTemplatePreview/_wechatRichmediaTemplatePrev.scss +64 -0
- package/v2Components/TemplatePreview/WechatRichmediaTemplatePreview/index.js +100 -18
- package/v2Components/TemplatePreview/WechatRichmediaTemplatePreview/messages.js +12 -0
- package/v2Components/TemplatePreview/_templatePreview.scss +24 -4
- package/v2Components/TemplatePreview/assets/images/home-screen-android.svg +21 -0
- package/v2Components/TemplatePreview/assets/images/home-screen-ios.svg +16 -0
- package/v2Components/TemplatePreview/assets/images/sms_mobile_android.svg +22 -0
- package/v2Components/TemplatePreview/assets/images/wechat-home-screen-android.svg +21 -0
- package/v2Components/TemplatePreview/assets/images/wechat_mobile_android.svg +20 -0
- package/v2Components/TemplatePreview/index.js +162 -23
- package/v2Components/TemplatePreview/messages.js +8 -0
- package/v2Containers/Assets/Gallery/index.js +54 -48
- package/v2Containers/CreativesContainer/SlideBoxContent.js +87 -4
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +1 -1
- package/v2Containers/CreativesContainer/index.js +58 -2
- package/v2Containers/CreativesContainer/messages.js +2 -2
- package/v2Containers/Email/_email.scss +7 -1
- package/v2Containers/Email/index.js +40 -14
- package/v2Containers/Email/messages.js +4 -0
- package/v2Containers/Email/reducer.js +1 -0
- package/v2Containers/EmailWrapper/index.js +7 -5
- package/v2Containers/Line/Create/_lineCreate.scss +40 -19
- package/v2Containers/Line/Create/actions.js +13 -9
- package/v2Containers/Line/Create/index.js +498 -237
- package/v2Containers/Line/Create/initialSchema.js +378 -0
- package/v2Containers/Line/Create/messages.js +42 -2
- package/v2Containers/Line/Create/sagas.js +10 -4
- package/v2Containers/Line/Create/selectors.js +3 -9
- package/v2Containers/Line/CreateWrapper/constants.js +2 -0
- package/v2Containers/Line/CreateWrapper/index.js +117 -0
- package/v2Containers/Line/CreateWrapper/messages.js +55 -0
- package/v2Containers/MobilePush/Create/index.js +5 -0
- package/v2Containers/MobilePush/Edit/index.js +5 -0
- package/v2Containers/MobilepushWrapper/index.js +4 -1
- package/v2Containers/Sms/Create/index.js +2 -1
- package/v2Containers/Sms/Edit/index.js +2 -0
- package/v2Containers/Templates/_templates.scss +24 -1
- package/v2Containers/Templates/actions.js +7 -0
- package/v2Containers/Templates/constants.js +2 -0
- package/v2Containers/Templates/index.js +118 -15
- package/v2Containers/Templates/messages.js +8 -0
- package/v2Containers/Templates/reducer.js +2 -0
- package/v2Containers/TemplatesV2/index.js +5 -4
- package/v2Containers/TemplatesV2/messages.js +4 -0
|
@@ -11,9 +11,10 @@ import PropTypes from 'prop-types';
|
|
|
11
11
|
import React from 'react';
|
|
12
12
|
import _ from 'lodash';
|
|
13
13
|
import { Tabs, Table, Modal} from 'antd';
|
|
14
|
-
import { CapButton, CapInput, CapPopover, CapCheckbox, CapRadio, CapSelect, CapTable, CapRow, CapColumn, CapNotification, CapUploader, CapHeading, CapIcon} from '@capillarytech/cap-ui-library';
|
|
14
|
+
import { CapDrawer, CapButton, CapInput, CapPopover, CapImage, CapCheckbox, CapRadio, CapSelect, CapTable, CapRow, CapColumn, CapNotification, CapUploader, CapHeading, CapIcon} from '@capillarytech/cap-ui-library';
|
|
15
15
|
import { injectIntl, intlShape, FormattedMessage } from 'react-intl';
|
|
16
16
|
import LabelHOC from '@capillarytech/cap-ui-library/assets/HOCs/ComponentWithLabelHOC';
|
|
17
|
+
import { CAP_SPACE_12, CAP_SPACE_08, FONT_COLOR_05, FONT_COLOR_04 } from '@capillarytech/cap-ui-library/styled/variables';
|
|
17
18
|
import TemplatePreview from '../TemplatePreview';
|
|
18
19
|
import TagList from '../../v2Containers/TagList';
|
|
19
20
|
import SlideBox from '../SlideBox';
|
|
@@ -24,7 +25,7 @@ import CustomPopOver from '../CustomPopOver';
|
|
|
24
25
|
import messages from './messages';
|
|
25
26
|
import './_formBuilder.scss';
|
|
26
27
|
import {updateCharCount, checkUnicode} from "../../utils/smsCharCountV2";
|
|
27
|
-
import {SMS} from '../../v2Containers/CreativesContainer/constants';
|
|
28
|
+
import { SMS, LINE } from '../../v2Containers/CreativesContainer/constants';
|
|
28
29
|
const TabPane = Tabs.TabPane;
|
|
29
30
|
const {Column} = Table;
|
|
30
31
|
const {TextArea} = CapInput;
|
|
@@ -55,6 +56,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
55
56
|
currentEventData: {},
|
|
56
57
|
popoverVisible: false,
|
|
57
58
|
customPopoverVisible: false,
|
|
59
|
+
isDrawerVisible: false,
|
|
58
60
|
};
|
|
59
61
|
this.renderForm = this.renderForm.bind(this);
|
|
60
62
|
this.updateFormData = this.updateFormData.bind(this);
|
|
@@ -207,7 +209,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
207
209
|
if (nextProps.isNewVersionFlow && !this.state.formData[this.state.currentTab - 1][this.state.formData[this.state.currentTab - 1].activeTab].tabKey) {
|
|
208
210
|
this.resetTabKeys(nextProps.formData, nextProps.tabCount, false, true);
|
|
209
211
|
}
|
|
210
|
-
if (type === 'embedded' || this.props.schema.channel.toUpperCase() === 'EMAIL') {
|
|
212
|
+
if (type === 'embedded' || ( this.props.schema.channel && this.props.schema.channel.toUpperCase() === 'EMAIL')) {
|
|
211
213
|
this.validateForm();
|
|
212
214
|
}
|
|
213
215
|
if ((this.props.schema && this.props.schema.channel && this.props.schema.channel.toUpperCase() === 'MOBILEPUSH')) {
|
|
@@ -253,6 +255,11 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
253
255
|
if (nextProps.modal && (!_.isEqual(nextProps.modal, this.props.modal) || _.isEmpty(this.state.modal))) {
|
|
254
256
|
this.setState({modal: nextProps.modal});
|
|
255
257
|
}
|
|
258
|
+
if (nextProps.isDrawerRequired !== this.props.isDrawerRequired) {
|
|
259
|
+
this.setState({
|
|
260
|
+
isDrawerVisible: nextProps.isDrawerRequired,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
256
263
|
}
|
|
257
264
|
|
|
258
265
|
onEdit() {
|
|
@@ -484,38 +491,74 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
484
491
|
}
|
|
485
492
|
|
|
486
493
|
//validation for LINE
|
|
487
|
-
if (
|
|
494
|
+
if (channel === LINE) {
|
|
488
495
|
|
|
489
|
-
if (this.state.formData['
|
|
490
|
-
const content = this.state.formData['0']['message-editor'];
|
|
496
|
+
if (this.state.formData['message-editor'] !== undefined ) {
|
|
497
|
+
const content = this.state.formData['0']['message-editor'] || '';
|
|
491
498
|
|
|
492
|
-
const tagValidationResponse = this.validateTags(content, tags, injectedTags);
|
|
499
|
+
const tagValidationResponse = this.validateTags((content), tags, injectedTags);
|
|
493
500
|
|
|
494
501
|
if (tagValidationResponse.valid) {
|
|
495
|
-
errorData
|
|
502
|
+
errorData = {
|
|
503
|
+
...errorData,
|
|
504
|
+
0: {
|
|
505
|
+
...errorData[0],
|
|
506
|
+
'message-editor': false,
|
|
507
|
+
}
|
|
508
|
+
};
|
|
496
509
|
} else {
|
|
497
|
-
|
|
498
|
-
|
|
510
|
+
errorData = {
|
|
511
|
+
...errorData,
|
|
512
|
+
0: {
|
|
513
|
+
...errorData[0],
|
|
514
|
+
'message-editor': true,
|
|
515
|
+
}
|
|
516
|
+
};
|
|
499
517
|
isValid = false;
|
|
500
518
|
}
|
|
501
519
|
if (content.trim() === '') {
|
|
502
|
-
|
|
503
|
-
|
|
520
|
+
errorData = {
|
|
521
|
+
...errorData,
|
|
522
|
+
0: {
|
|
523
|
+
...errorData[0],
|
|
524
|
+
'message-editor': true,
|
|
525
|
+
}
|
|
526
|
+
};
|
|
504
527
|
isValid = false;
|
|
505
528
|
}
|
|
506
529
|
}
|
|
507
530
|
|
|
508
|
-
if (
|
|
509
|
-
const
|
|
510
|
-
|
|
531
|
+
if (this.state.formData['image-upload-line'] !== undefined) {
|
|
532
|
+
const {
|
|
533
|
+
formData: {
|
|
534
|
+
0: {
|
|
535
|
+
image,
|
|
536
|
+
imagePreview,
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
} = this.state;
|
|
540
|
+
const imgContentLength = image ? image.length : 0;
|
|
541
|
+
const imgContentLengthPreview = imagePreview ? imagePreview.length : 0;
|
|
511
542
|
if ( (imgContentLength < 1) && (imgContentLengthPreview < 1) ) {
|
|
512
543
|
|
|
513
|
-
errorData
|
|
514
|
-
|
|
544
|
+
errorData = {
|
|
545
|
+
...errorData,
|
|
546
|
+
0: {
|
|
547
|
+
...errorData[0],
|
|
548
|
+
image: true,
|
|
549
|
+
imagePreview: true,
|
|
550
|
+
}
|
|
551
|
+
};
|
|
515
552
|
isValid = false;
|
|
516
553
|
}else{
|
|
517
|
-
errorData
|
|
518
|
-
|
|
554
|
+
errorData = {
|
|
555
|
+
...errorData,
|
|
556
|
+
0: {
|
|
557
|
+
...errorData[0],
|
|
558
|
+
image: false,
|
|
559
|
+
imagePreview: false,
|
|
560
|
+
}
|
|
561
|
+
};
|
|
519
562
|
}
|
|
520
563
|
}
|
|
521
564
|
if(type !== 'embedded' && (!this.state.formData['template-name'] || this.state.formData['template-name'] === '')) {
|
|
@@ -1149,7 +1192,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1149
1192
|
// this.formElements.push(col.id);
|
|
1150
1193
|
// }
|
|
1151
1194
|
if (!col.onlyDisplay && !ifError) {
|
|
1152
|
-
if (col.id.indexOf('tagList-') === -1) {
|
|
1195
|
+
if (col.id && col.id.indexOf('tagList-') === -1) {
|
|
1153
1196
|
this.formElements.push(col.id);
|
|
1154
1197
|
}
|
|
1155
1198
|
|
|
@@ -1349,7 +1392,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1349
1392
|
delete tempFormData[key];
|
|
1350
1393
|
} else if (typeof element === "object") {
|
|
1351
1394
|
_.forEach(element, (innerElement, innerKey) => {
|
|
1352
|
-
if (innerKey !== "tabKey" && innerKey !== "base" && innerKey !== 'name' && innerKey !== 'imagePreview' && this.formElements.indexOf(innerKey) === -1) {
|
|
1395
|
+
if (innerKey !== "tabKey" && innerKey !== "base" && innerKey !== 'name' && innerKey !== 'imagePreview' && innerKey !== 'image' && this.formElements.indexOf(innerKey) === -1) {
|
|
1353
1396
|
delete tempFormData[key][innerKey];
|
|
1354
1397
|
}
|
|
1355
1398
|
});
|
|
@@ -1921,7 +1964,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1921
1964
|
return;
|
|
1922
1965
|
} else if (event === 'markFinalVersion' || event === 'duplicateVersion' || event === 'deleteVersion' || event === 'renameVersion') {
|
|
1923
1966
|
this.setState({ popoverVisible: false });
|
|
1924
|
-
if ((event !== 'deleteVersion' && !this.props.isNewVersionFlow) || ((event === 'deleteVersion') && this.props.schema.channel.toUpperCase() === 'EMAIL')) {
|
|
1967
|
+
if ((event !== 'deleteVersion' && !this.props.isNewVersionFlow) || ((event === 'deleteVersion') && this.props.schema.channel && this.props.schema.channel.toUpperCase() === 'EMAIL')) {
|
|
1925
1968
|
val.injectedEvents[event].call(this.props.parent, data, this.state.currentTab);
|
|
1926
1969
|
} else {
|
|
1927
1970
|
this.setState({currentEvent: val.injectedEvents[event], currentEventData: data});
|
|
@@ -2100,8 +2143,8 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2100
2143
|
img.src = _URL.createObjectURL(file);
|
|
2101
2144
|
img.onload = () => {
|
|
2102
2145
|
const fileParams = {
|
|
2103
|
-
width: this.width,
|
|
2104
|
-
height: this.height,
|
|
2146
|
+
width: this.width || img.width,
|
|
2147
|
+
height: this.height || img.height,
|
|
2105
2148
|
error: file.size / (1e+6) > 3,
|
|
2106
2149
|
};
|
|
2107
2150
|
this.callChildEvent({file, type: 'image', fileParams}, val, val.submitAction);
|
|
@@ -2154,7 +2197,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2154
2197
|
//
|
|
2155
2198
|
const imgSrc = template && template.versions && template.versions.base ? template.versions.base.preview_http_url : '';
|
|
2156
2199
|
// const ifPreviewGenerated = template && template.versions && template.versions.base ? template.versions.base.isPreviewGenerated : 0;
|
|
2157
|
-
const content = <
|
|
2200
|
+
const content = <CapImage src={imgSrc || ''} alt="" />;
|
|
2158
2201
|
|
|
2159
2202
|
temp.content = (
|
|
2160
2203
|
<div
|
|
@@ -2339,8 +2382,10 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2339
2382
|
content={content}
|
|
2340
2383
|
charCounterEnabled={val.charCounterEnabled}
|
|
2341
2384
|
unicodeEnabled={unicodeEnabled}
|
|
2342
|
-
|
|
2343
|
-
|
|
2385
|
+
showTestAndPreviewIcon
|
|
2386
|
+
onPreviewContentClicked={this.props.onPreviewContentClicked}
|
|
2387
|
+
onTestContentClicked={this.props.onTestContentClicked}
|
|
2388
|
+
/>
|
|
2344
2389
|
</CapColumn>
|
|
2345
2390
|
);
|
|
2346
2391
|
break;
|
|
@@ -2532,6 +2577,81 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2532
2577
|
}
|
|
2533
2578
|
}
|
|
2534
2579
|
|
|
2580
|
+
onGalleryClick = (event) => {
|
|
2581
|
+
event.stopPropagation();
|
|
2582
|
+
this.props.setDrawerVisibility(true);
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
onReUpload = () => {
|
|
2586
|
+
const { formData } = this.state;
|
|
2587
|
+
this.props.onChange({
|
|
2588
|
+
...formData,
|
|
2589
|
+
0: {
|
|
2590
|
+
...formData[0],
|
|
2591
|
+
image: undefined,
|
|
2592
|
+
imagePreview: undefined,
|
|
2593
|
+
},
|
|
2594
|
+
base: {
|
|
2595
|
+
...formData.base,
|
|
2596
|
+
image: undefined,
|
|
2597
|
+
imagePreview: undefined,
|
|
2598
|
+
},
|
|
2599
|
+
reUpload: true,
|
|
2600
|
+
});
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2603
|
+
getUploadVariants = (isImage, val) => {
|
|
2604
|
+
if (this.props.schema && this.props.schema.channel === 'LINE') {
|
|
2605
|
+
if (!isImage) {
|
|
2606
|
+
return (
|
|
2607
|
+
<>
|
|
2608
|
+
<CapUploader.CapDragger
|
|
2609
|
+
customRequest={(data) => this.capUploaderCustomRequest(data, val)}
|
|
2610
|
+
{...val.componentProps}
|
|
2611
|
+
className="form-builder-dragger"
|
|
2612
|
+
>
|
|
2613
|
+
<CapHeading className="dragger-title" type="h7">
|
|
2614
|
+
<FormattedMessage {...messages.dragAndDrop} />
|
|
2615
|
+
</CapHeading>
|
|
2616
|
+
<CapHeading className="dragger-or" type="label6">
|
|
2617
|
+
<FormattedMessage {...messages.or} />
|
|
2618
|
+
</CapHeading>
|
|
2619
|
+
<CapButton className="dragger-button" type="secondary" style={{marginRight: CAP_SPACE_08}}>
|
|
2620
|
+
<FormattedMessage {...messages.uploadComputer} />
|
|
2621
|
+
</CapButton>
|
|
2622
|
+
<CapButton
|
|
2623
|
+
className="dragger-button"
|
|
2624
|
+
type="secondary"
|
|
2625
|
+
style={{marginLeft: CAP_SPACE_08}}
|
|
2626
|
+
onClick={this.onGalleryClick}
|
|
2627
|
+
>
|
|
2628
|
+
<FormattedMessage {...messages.uploadGallery} />
|
|
2629
|
+
</CapButton>
|
|
2630
|
+
</CapUploader.CapDragger>
|
|
2631
|
+
<CapHeading type="h6" style={{marginTop: CAP_SPACE_12 }}>
|
|
2632
|
+
<FormattedMessage {...messages.imageDimenstionDescription} />
|
|
2633
|
+
</CapHeading>
|
|
2634
|
+
</>
|
|
2635
|
+
);
|
|
2636
|
+
}
|
|
2637
|
+
return (
|
|
2638
|
+
<CapButton
|
|
2639
|
+
className="dragger-button"
|
|
2640
|
+
type="flat"
|
|
2641
|
+
style={{top: 0, position: 'absolute', right: 0, color: FONT_COLOR_05 }}
|
|
2642
|
+
onClick={this.onReUpload}
|
|
2643
|
+
>
|
|
2644
|
+
<FormattedMessage {...messages.imageReUpload} />
|
|
2645
|
+
</CapButton>
|
|
2646
|
+
);
|
|
2647
|
+
}
|
|
2648
|
+
return (
|
|
2649
|
+
<CapButton disabled={val.disabled ? val.disabled : false} type="flat" prefix={<CapIcon size="s" type="add-photo" />} onClick={(e) => this.openFileDialog(e, val.id)} style={{float: 'right', color: `${val.disabled ? FONT_COLOR_04 : FONT_COLOR_05}`}}>
|
|
2650
|
+
{val.label}
|
|
2651
|
+
</CapButton>
|
|
2652
|
+
);
|
|
2653
|
+
}
|
|
2654
|
+
|
|
2535
2655
|
renderMultiColSection(section, childIndex) {
|
|
2536
2656
|
const fields = [];
|
|
2537
2657
|
let contentSections = [];
|
|
@@ -2578,7 +2698,6 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2578
2698
|
);
|
|
2579
2699
|
return true;
|
|
2580
2700
|
}
|
|
2581
|
-
|
|
2582
2701
|
switch (type) {
|
|
2583
2702
|
case "input":
|
|
2584
2703
|
ifError = this.state.checkValidation && (isVersionEnable ? this.state.errorData[`${this.state.currentTab - 1}`][val.id] : this.state.errorData[val.id]);
|
|
@@ -2706,7 +2825,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2706
2825
|
<div>
|
|
2707
2826
|
<div className={`image-container ${ifError ? 'error' : ''}`}>
|
|
2708
2827
|
{self.state && !!self.state.formData[`${self.state.currentTab - 1}`].image ?
|
|
2709
|
-
<
|
|
2828
|
+
<CapImage src={self.state.formData[`${self.state.currentTab - 1}`].image} alt={val.alt} style={val.style}/>
|
|
2710
2829
|
:
|
|
2711
2830
|
<div style={{width: "100%", textAlign: "center"}}><span className="image-placeholder">{val.placeholder}</span></div>
|
|
2712
2831
|
}
|
|
@@ -2717,13 +2836,22 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2717
2836
|
);
|
|
2718
2837
|
break;
|
|
2719
2838
|
case 'upload':
|
|
2839
|
+
const {
|
|
2840
|
+
formData: {
|
|
2841
|
+
[`${self.state.currentTab - 1}`]: {
|
|
2842
|
+
image,
|
|
2843
|
+
} = {},
|
|
2844
|
+
} = {},
|
|
2845
|
+
} = self.state;
|
|
2846
|
+
const isImage = !!image;
|
|
2720
2847
|
ifError = (this.state.checkValidation || this.props.startValidation) && (isVersionEnable ? this.state.errorData[`${this.state.currentTab - 1}`][val.id] : this.state.errorData[val.id]);
|
|
2721
2848
|
const ImageComponent = (props) => (
|
|
2722
2849
|
<div key={`${val.id}-${this.state.currentTab}`}>
|
|
2723
2850
|
<div className={`image-container ${props.ifError ? 'error' : ''}`}>
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2851
|
+
|
|
2852
|
+
{isImage ?
|
|
2853
|
+
<CapImage src={self.state.formData[`${self.state.currentTab - 1}`].image} alt={props.alt} style={props.style}/>
|
|
2854
|
+
:
|
|
2727
2855
|
<div style={{width: "100%", textAlign: "center"}}><span className="image-placeholder">{props.placeholder}</span></div>
|
|
2728
2856
|
}
|
|
2729
2857
|
</div>
|
|
@@ -2736,9 +2864,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2736
2864
|
{val.showPreview && <WithLabel key={`${val.id}-with-label`} {...rest} errorMessage={ifError && errorMessage} ifError={ifError}/>}
|
|
2737
2865
|
<form encType="multipart/form-data" id={val.id}>
|
|
2738
2866
|
<input key={val.id} style={{ display: 'none'}} id="fileName" type="file" onChange={(e) => this.uploadImages(e, {files: e.target.files}, val)} accept={val.supportedExtensions ? val.supportedExtensions : "image/*"} />
|
|
2739
|
-
|
|
2740
|
-
{val.label}
|
|
2741
|
-
</CapButton>
|
|
2867
|
+
{this.getUploadVariants(isImage, val)}
|
|
2742
2868
|
</form>
|
|
2743
2869
|
</CapColumn>
|
|
2744
2870
|
);
|
|
@@ -2783,11 +2909,16 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2783
2909
|
);
|
|
2784
2910
|
break;
|
|
2785
2911
|
case "tag-list":
|
|
2912
|
+
let moduleFilterEnabled = this.props.location && this.props.location.query && this.props.location.query.type !== 'embedded';
|
|
2913
|
+
const channel = _.get(this.props, 'schema.channel', "");
|
|
2914
|
+
if (channel === 'EMAIL') {
|
|
2915
|
+
moduleFilterEnabled = this.props.isFullMode;
|
|
2916
|
+
}
|
|
2786
2917
|
columns.push(
|
|
2787
2918
|
<CapColumn key={`input-${val.id}`} offset={val.offset} span={val.width ? val.width : ''} style={val.style ? val.style : {marginBottom: '16px'}}>
|
|
2788
2919
|
<TagList
|
|
2789
2920
|
key={`input-${val.id}`}
|
|
2790
|
-
moduleFilterEnabled={
|
|
2921
|
+
moduleFilterEnabled={moduleFilterEnabled}
|
|
2791
2922
|
label={val.label ? val.label : ''}
|
|
2792
2923
|
onTagSelect={(data) => this.callChildEvent(data, val, 'onTagSelect')}
|
|
2793
2924
|
onContextChange={this.props.onContextChange}
|
|
@@ -2810,7 +2941,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2810
2941
|
type={val.buttonType}
|
|
2811
2942
|
icon={val.icon}
|
|
2812
2943
|
disabled={val.disabled ? val.disabled : false}
|
|
2813
|
-
onClick={(data) => this.callChildEvent(data, val, val.submitAction)}>
|
|
2944
|
+
onClick={(data) => val.id === 'save-button' ? this.saveForm() : this.callChildEvent(data, val, val.submitAction)}>
|
|
2814
2945
|
{val.value}
|
|
2815
2946
|
</CapButton>
|
|
2816
2947
|
</CapColumn>
|
|
@@ -2834,6 +2965,9 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2834
2965
|
content={content}
|
|
2835
2966
|
charCounterEnabled={val.charCounterEnabled}
|
|
2836
2967
|
unicodeEnabled={unicodeEnabled}
|
|
2968
|
+
showTestAndPreviewIcon
|
|
2969
|
+
onPreviewContentClicked={this.props.onPreviewContentClicked}
|
|
2970
|
+
onTestContentClicked={this.props.onTestContentClicked}
|
|
2837
2971
|
>
|
|
2838
2972
|
</TemplatePreview>
|
|
2839
2973
|
</CapColumn>
|
|
@@ -2883,6 +3017,10 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2883
3017
|
],
|
|
2884
3018
|
appName: val.content.appName,
|
|
2885
3019
|
}}
|
|
3020
|
+
showTestAndPreviewIcon
|
|
3021
|
+
onPreviewContentClicked={this.props.onPreviewContentClicked}
|
|
3022
|
+
onTestContentClicked={this.props.onTestContentClicked}
|
|
3023
|
+
templateDataRaw={this.props.templateData}
|
|
2886
3024
|
>
|
|
2887
3025
|
</TemplatePreview>
|
|
2888
3026
|
</CapColumn>
|
|
@@ -3296,6 +3434,16 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
3296
3434
|
loadingText={this.props.intl.formatMessage(messages.loadingEDMTemplates)}
|
|
3297
3435
|
isLoading={this.props.getCmsTemplatesInProgress}
|
|
3298
3436
|
/>
|
|
3437
|
+
{
|
|
3438
|
+
this.props.capDrawerContent && (
|
|
3439
|
+
<CapDrawer
|
|
3440
|
+
content={this.props.capDrawerContent}
|
|
3441
|
+
visible={this.state.isDrawerVisible}
|
|
3442
|
+
width={380}
|
|
3443
|
+
onClose={() => this.props.setDrawerVisibility(false)}
|
|
3444
|
+
/>
|
|
3445
|
+
)
|
|
3446
|
+
}
|
|
3299
3447
|
</CapRow>
|
|
3300
3448
|
);
|
|
3301
3449
|
}
|
|
@@ -3346,6 +3494,9 @@ FormBuilder.propTypes = {
|
|
|
3346
3494
|
handleDelete: PropTypes.func,
|
|
3347
3495
|
intl: intlShape.isRequired,
|
|
3348
3496
|
selectedOfferDetails: PropTypes.array,
|
|
3497
|
+
setDrawerVisibility: PropTypes.bool,
|
|
3498
|
+
capDrawerContent: PropTypes.array,
|
|
3499
|
+
isFullMode: PropTypes.bool,
|
|
3349
3500
|
};
|
|
3350
3501
|
|
|
3351
3502
|
export default injectIntl(FormBuilder);
|
|
@@ -58,4 +58,20 @@ export default defineMessages({
|
|
|
58
58
|
id: 'creatives.componentsV2.FormBuilder.loadingEDMTemplates',
|
|
59
59
|
defaultMessage: 'Loading EDM Templates',
|
|
60
60
|
},
|
|
61
|
+
uploadComputer: {
|
|
62
|
+
id: 'creatives.componentsV2.FormBuilder.uploadComputer',
|
|
63
|
+
defaultMessage: 'Your computer',
|
|
64
|
+
},
|
|
65
|
+
uploadGallery: {
|
|
66
|
+
id: 'creatives.componentsV2.FormBuilder.uploadGallery',
|
|
67
|
+
defaultMessage: 'Gallery',
|
|
68
|
+
},
|
|
69
|
+
imageDimenstionDescription: {
|
|
70
|
+
id: 'creatives.componentsV2.FormBuilder.imageDimenstionDescription',
|
|
71
|
+
defaultMessage: 'Dimensions: 300px x 400px Size: 30mb',
|
|
72
|
+
},
|
|
73
|
+
imageReUpload: {
|
|
74
|
+
id: 'creatives.componentsV2.FormBuilder.imageReUpload',
|
|
75
|
+
defaultMessage: 'Re upload',
|
|
76
|
+
},
|
|
61
77
|
});
|
|
@@ -7,16 +7,10 @@
|
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
|
|
9
9
|
import React from 'react';
|
|
10
|
-
import {
|
|
11
|
-
// import styled from 'styled-components';
|
|
12
|
-
|
|
13
|
-
import { FormattedMessage } from 'react-intl';
|
|
14
|
-
import { Button } from 'antd';
|
|
10
|
+
import { CapTab, CapIcon } from '@capillarytech/cap-ui-library';
|
|
15
11
|
import { get, map, isEmpty} from 'lodash';
|
|
16
12
|
import TemplatePreview from '../TemplatePreview';
|
|
17
13
|
import '../PreviewSideBar/_previewsidebar.scss';
|
|
18
|
-
import messages from './messages';
|
|
19
|
-
const ButtonGroup = Button.Group;
|
|
20
14
|
|
|
21
15
|
class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
|
22
16
|
constructor(props) {
|
|
@@ -24,8 +18,11 @@ class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react
|
|
|
24
18
|
this.goToEdit = this.goToEdit.bind(this);
|
|
25
19
|
this.goToDuplicate = this.goToDuplicate.bind(this);
|
|
26
20
|
this.changeDevice = this.changeDevice.bind(this);
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
this.getPreview = this.getPreview.bind(this);
|
|
22
|
+
this.setContent = this.setContent.bind(this);
|
|
23
|
+
this.goToDuplicate = this.goToDuplicate.bind(this);
|
|
24
|
+
const hasAndroid = get(props, 'templateData.versions.base.ANDROID') || get(props, 'templateData.androidContent.title');
|
|
25
|
+
const hasIos = get(props, 'templateData.versions.base.IOS') || get(props, 'templateData.iosContent.title');
|
|
29
26
|
let device = "android";
|
|
30
27
|
if (hasAndroid) {
|
|
31
28
|
device = 'android';
|
|
@@ -38,7 +35,7 @@ class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react
|
|
|
38
35
|
};
|
|
39
36
|
}
|
|
40
37
|
|
|
41
|
-
setContent
|
|
38
|
+
setContent(templateData, device) {
|
|
42
39
|
const androidContent = get(templateData, 'versions.base.ANDROID') || get(templateData, 'androidContent');
|
|
43
40
|
const iosContent = get(templateData, 'versions.base.IOS') || get(templateData, 'iosContent');
|
|
44
41
|
|
|
@@ -59,12 +56,21 @@ class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react
|
|
|
59
56
|
}
|
|
60
57
|
return content;
|
|
61
58
|
}
|
|
59
|
+
getPreview(device) {
|
|
60
|
+
return (
|
|
61
|
+
<TemplatePreview
|
|
62
|
+
device={device}
|
|
63
|
+
channel={this.props.channel}
|
|
64
|
+
content={this.state.content || ''}
|
|
65
|
+
templateData={this.props.templateData}
|
|
66
|
+
/>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
62
69
|
goToDuplicate() {
|
|
63
70
|
this.props.onDuplicateClick(this.props.templateData);
|
|
64
71
|
this.props.handleClose();
|
|
65
72
|
}
|
|
66
|
-
changeDevice(
|
|
67
|
-
const device = ev.target.value;
|
|
73
|
+
changeDevice(device) {
|
|
68
74
|
const content = this.setContent(this.props.templateData, device);
|
|
69
75
|
this.setState({device, content });
|
|
70
76
|
}
|
|
@@ -72,38 +78,40 @@ class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react
|
|
|
72
78
|
this.props.onEditClick(e, this.props.templateData._id, this.props.templateData.modeType, path);
|
|
73
79
|
}
|
|
74
80
|
render() {
|
|
75
|
-
const {templateData
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
const {device, content} = this.state;
|
|
81
|
+
const {templateData} = this.props;
|
|
82
|
+
const hasAndroid = get(templateData, 'versions.base.ANDROID') || get(templateData, 'androidContent.title');
|
|
83
|
+
const hasIos = get(templateData, 'versions.base.IOS') || get(templateData, 'iosContent.title');
|
|
84
|
+
const hasBothAndroidAndIos = hasAndroid && hasIos;
|
|
81
85
|
|
|
82
86
|
return (
|
|
83
|
-
|
|
84
87
|
<div>
|
|
85
88
|
<div className="devices">
|
|
86
|
-
{!isEmpty(templateData) &&
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
{!isEmpty(templateData) &&
|
|
90
|
+
( hasBothAndroidAndIos ? (
|
|
91
|
+
<CapTab
|
|
92
|
+
panes={[
|
|
93
|
+
{
|
|
94
|
+
content: this.getPreview('android'),
|
|
95
|
+
tab: <CapIcon type="android" size="m" />,
|
|
96
|
+
key: 'android',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
content: this.getPreview('iphone'),
|
|
100
|
+
tab: <CapIcon type="ios" size="m" />,
|
|
101
|
+
key: 'iphone',
|
|
102
|
+
},
|
|
103
|
+
]}
|
|
104
|
+
onChange={(activeKey) => this.changeDevice(activeKey)}
|
|
105
|
+
tabBarStyle={{margin: 'auto', width: '38%'}}
|
|
106
|
+
/>
|
|
107
|
+
) : (
|
|
108
|
+
(hasAndroid || hasIos) && this.getPreview(hasAndroid ? 'android' : 'ios')
|
|
109
|
+
))
|
|
110
|
+
}
|
|
91
111
|
</div>
|
|
92
|
-
<TemplatePreview
|
|
93
|
-
device={device === "android" ? "android" : "iphone"}
|
|
94
|
-
channel={channel}
|
|
95
|
-
content={content || ''}
|
|
96
|
-
templateData={templateData}
|
|
97
|
-
>
|
|
98
|
-
</TemplatePreview>
|
|
99
|
-
|
|
100
|
-
|
|
101
112
|
</div>
|
|
102
|
-
|
|
103
|
-
|
|
104
113
|
);
|
|
105
114
|
}
|
|
106
|
-
|
|
107
115
|
}
|
|
108
116
|
|
|
109
117
|
MobilePushPreviewV2.propTypes = {
|
|
@@ -10,12 +10,4 @@ export default defineMessages({
|
|
|
10
10
|
id: 'creatives.componentsv2.MobilePushPreviewV2.header',
|
|
11
11
|
defaultMessage: 'This is the MobilePushPreviewV2 component !',
|
|
12
12
|
},
|
|
13
|
-
android: {
|
|
14
|
-
id: 'creatives.componentsv2.MobilePushPreviewV2.android',
|
|
15
|
-
defaultMessage: 'Android',
|
|
16
|
-
},
|
|
17
|
-
ios: {
|
|
18
|
-
id: 'creatives.componentsv2.MobilePushPreviewV2.ios',
|
|
19
|
-
defaultMessage: 'IOS',
|
|
20
|
-
},
|
|
21
13
|
});
|
|
@@ -1,5 +1,69 @@
|
|
|
1
1
|
@import '~@capillarytech/cap-ui-library/styles/_variables.scss';
|
|
2
2
|
|
|
3
|
+
.shell-lock-screen-android .main-screen-preview .wechatMsgContainer{
|
|
4
|
+
position: absolute;
|
|
5
|
+
left: 53.5%;
|
|
6
|
+
top:28%;
|
|
7
|
+
background: white;
|
|
8
|
+
width: 19.5%;
|
|
9
|
+
text-align: left;
|
|
10
|
+
height: fit-content;
|
|
11
|
+
border-radius: 0.285rem;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.shell-lock-screen-android .lock-screen-preview{
|
|
15
|
+
.wechat-android-sender-id{
|
|
16
|
+
position: absolute;
|
|
17
|
+
top: 46%;
|
|
18
|
+
font-size: 10px;
|
|
19
|
+
left: 28%;
|
|
20
|
+
}
|
|
21
|
+
.wechat-android-title{
|
|
22
|
+
position: absolute;
|
|
23
|
+
top: 49%;
|
|
24
|
+
font-size: 10px;
|
|
25
|
+
left: 28%;
|
|
26
|
+
color: #5e6c84;
|
|
27
|
+
}
|
|
28
|
+
.wechat-android-action-buttons{
|
|
29
|
+
position: absolute;
|
|
30
|
+
left: 28%;
|
|
31
|
+
top: 53%;
|
|
32
|
+
font-size: 10px;
|
|
33
|
+
color: #3861ca;
|
|
34
|
+
font-weight: 500;
|
|
35
|
+
}
|
|
36
|
+
.wechat-ios-sender-id{
|
|
37
|
+
position: absolute;
|
|
38
|
+
top: 44%;
|
|
39
|
+
font-size: 10px;
|
|
40
|
+
left: 28.5%;
|
|
41
|
+
}
|
|
42
|
+
.wechat-ios-title{
|
|
43
|
+
position: absolute;
|
|
44
|
+
top: 47%;
|
|
45
|
+
font-size: 10px;
|
|
46
|
+
left: 28.5%;
|
|
47
|
+
color: #5e6c84;
|
|
48
|
+
}
|
|
49
|
+
.wechat-ios-action-reply{
|
|
50
|
+
position: absolute;
|
|
51
|
+
left: 35%;
|
|
52
|
+
top: 59%;
|
|
53
|
+
font-size: 12px;
|
|
54
|
+
color: #3861ca;
|
|
55
|
+
font-weight: 500;
|
|
56
|
+
}
|
|
57
|
+
.wechat-ios-action-cancel{
|
|
58
|
+
position: absolute;
|
|
59
|
+
left: 34.5%;
|
|
60
|
+
top: 66%;
|
|
61
|
+
font-size: 12px;
|
|
62
|
+
color: #3861ca;
|
|
63
|
+
font-weight: 500;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
3
67
|
.wechatMsgContainer{
|
|
4
68
|
position: absolute;
|
|
5
69
|
left: 30%;
|