@capillarytech/creatives-library 8.0.102-alpha.0 → 8.0.102
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/package.json +1 -1
- package/v2Containers/CreativesContainer/index.js +2 -8
- package/v2Containers/EmailWrapper/index.js +299 -40
- package/v2Containers/EmailWrapper/components/EmailWrapperView.js +0 -184
- package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +0 -289
- package/v2Containers/EmailWrapper/mockdata/mockdata.js +0 -127
- package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +0 -16
- package/v2Containers/EmailWrapper/tests/index.test.js +0 -101
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +0 -35
package/package.json
CHANGED
|
@@ -740,10 +740,7 @@ export class Creatives extends React.Component {
|
|
|
740
740
|
forEach(androidContent.custom, (customKeyValue) => {
|
|
741
741
|
custom[customKeyValue.key] = customKeyValue.value;
|
|
742
742
|
});
|
|
743
|
-
|
|
744
|
-
if (channel !== constants.MOBILE_PUSH) {
|
|
745
|
-
androidContent.custom = custom;
|
|
746
|
-
}
|
|
743
|
+
androidContent.custom = custom;
|
|
747
744
|
templateData.androidContent = androidContent;
|
|
748
745
|
templateData.androidContent.type = get(channelTemplate, 'definition.mode', '').toUpperCase();
|
|
749
746
|
templateData.androidContent.deviceType = 'ANDROID';
|
|
@@ -759,10 +756,7 @@ export class Creatives extends React.Component {
|
|
|
759
756
|
forEach(iosContent.custom, (customKeyValue) => {
|
|
760
757
|
custom[customKeyValue.key] = customKeyValue.value;
|
|
761
758
|
});
|
|
762
|
-
|
|
763
|
-
if (channel !== constants.MOBILE_PUSH) {
|
|
764
|
-
iosContent.custom = custom;
|
|
765
|
-
}
|
|
759
|
+
iosContent.custom = custom;
|
|
766
760
|
templateData.iosContent = iosContent;
|
|
767
761
|
templateData.iosContent.type = get(channelTemplate, 'definition.mode').toUpperCase();
|
|
768
762
|
templateData.iosContent.deviceType = IOS.toUpperCase();
|
|
@@ -6,9 +6,14 @@
|
|
|
6
6
|
import PropTypes from 'prop-types';
|
|
7
7
|
import React from 'react';
|
|
8
8
|
import { connect } from 'react-redux';
|
|
9
|
-
import { injectIntl, intlShape } from 'react-intl';
|
|
9
|
+
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
|
|
10
|
+
import { GA } from '@capillarytech/cap-ui-utils';
|
|
10
11
|
import { createStructuredSelector } from 'reselect';
|
|
11
12
|
import { bindActionCreators } from 'redux';
|
|
13
|
+
import _ from 'lodash';
|
|
14
|
+
import styled from 'styled-components';
|
|
15
|
+
import { CapRadioCard, CapNotification, CapInput, CapUploader, CapSpin, CapButton, CapError } from '@capillarytech/cap-ui-library';
|
|
16
|
+
import ComponentWithLabelHOC from '@capillarytech/cap-ui-library/assets/HOCs/ComponentWithLabelHOC';
|
|
12
17
|
import { UserIsAuthenticated } from '../../utils/authWrapper';
|
|
13
18
|
import {
|
|
14
19
|
selectEmailLayout,
|
|
@@ -18,48 +23,302 @@ import {
|
|
|
18
23
|
selectCmsTemplatesLoader,
|
|
19
24
|
} from '../Templates/selectors';
|
|
20
25
|
import * as templatesActionsCreators from '../Templates/actions';
|
|
26
|
+
import Email from '../Email';
|
|
27
|
+
import CmsTemplatesComponent from '../../v2Components/CmsTemplatesComponent';
|
|
28
|
+
import messages from './messages';
|
|
29
|
+
import { CHANNEL_CREATE_TRACK_MAPPING } from '../App/constants';
|
|
30
|
+
import { gtmPush } from '../../utils/gtmTrackers';
|
|
31
|
+
import { EMAIL } from '../CreativesContainer/constants';
|
|
21
32
|
import { selectCurrentOrgDetails } from "../../v2Containers/Cap/selectors";
|
|
22
|
-
import EmailWrapperView from './components/EmailWrapperView';
|
|
23
|
-
import useEmailWrapper from './hooks/useEmailWrapper';
|
|
24
33
|
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
const CapRadioCardWithLabel = ComponentWithLabelHOC(CapRadioCard);
|
|
35
|
+
const { timeTracker } = GA;
|
|
36
|
+
const CardContainer = styled.div`
|
|
37
|
+
margin-top: 16px;
|
|
38
|
+
.ant-radio-group{
|
|
39
|
+
.ant-radio-button-wrapper{
|
|
40
|
+
&:first-child{
|
|
41
|
+
margin-left: unset;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
`;
|
|
47
|
+
export class EmailWrapper extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
|
48
|
+
constructor(props) {
|
|
49
|
+
super(props);
|
|
50
|
+
this.emailUploader = React.createRef();
|
|
51
|
+
this.state = {
|
|
52
|
+
templateName: '',
|
|
53
|
+
routeParams: {
|
|
54
|
+
pathname: `/email/create`,
|
|
55
|
+
query: { module: 'library', type: 'embedded' },
|
|
56
|
+
},
|
|
57
|
+
modeContent: {
|
|
40
58
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
},
|
|
60
|
+
// selectedCreateMode: '',
|
|
61
|
+
isTemplateNameEmpty: true,
|
|
62
|
+
};
|
|
63
|
+
this.modes = [
|
|
64
|
+
{
|
|
65
|
+
title: <FormattedMessage {...messages.zipUpload} />,
|
|
66
|
+
content: <FormattedMessage {...messages.zipUploadDesc} />,
|
|
67
|
+
value: 'upload',
|
|
68
|
+
// onClick: () => {
|
|
69
|
+
// this.emailUploader.current.click();
|
|
70
|
+
// },
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
title: <FormattedMessage {...messages.useEditor} />,
|
|
74
|
+
content: <FormattedMessage {...messages.useEditorDesc} />,
|
|
75
|
+
value: 'editor',
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
componentDidUpdate() {
|
|
81
|
+
const { modeContent } = this.state;
|
|
82
|
+
// const isValid = this.isValid();
|
|
83
|
+
const { emailCreateMode, EmailLayout, CmsTemplates, step, SelectedEdmDefaultTemplate, templatesActions, getCmsTemplatesInProgress = false } = this.props;
|
|
84
|
+
if (step === "modeSelection" && !this.state.selectedCreateMode && emailCreateMode === 'upload' && !EmailLayout) {
|
|
85
|
+
//document.getElementById('upload-email-template').click();
|
|
86
|
+
} else if (step === "templateSelection" && !this.state.selectedCreateMode) {
|
|
87
|
+
if (emailCreateMode === "editor" && !CmsTemplates && !getCmsTemplatesInProgress) {
|
|
88
|
+
templatesActions.getDefaultBeeTemplates();
|
|
89
|
+
}
|
|
90
|
+
} else if (step === "createTemplateContent" && !this.state.selectedCreateMode) {
|
|
91
|
+
if (emailCreateMode === 'upload' && !_.isEmpty(EmailLayout)) {
|
|
92
|
+
this.setCreateMode('upload');
|
|
93
|
+
} else if (emailCreateMode === "editor" && _.isEmpty(SelectedEdmDefaultTemplate)) {
|
|
94
|
+
this.handleEdmDefaultTemplateSelection(modeContent.id);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
componentWillUnmount() {
|
|
101
|
+
this.props.onResetStep();
|
|
102
|
+
this.props.templatesActions.resetTemplateData();
|
|
103
|
+
}
|
|
104
|
+
onTemplateNameChange = ({target: {value}}) => {
|
|
105
|
+
const {onEnterTemplateName, onRemoveTemplateName} = this.props;
|
|
106
|
+
const isEmptyTemplateName = !value?.trim();
|
|
107
|
+
this.setState({templateName: value, isTemplateNameEmpty: isEmptyTemplateName});
|
|
108
|
+
if (value && onEnterTemplateName) {
|
|
109
|
+
onEnterTemplateName();
|
|
110
|
+
} else if (onRemoveTemplateName) {
|
|
111
|
+
onRemoveTemplateName();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
onChange = (e) => {
|
|
115
|
+
this.props.onEmailModeChange(e.target.value);
|
|
116
|
+
};
|
|
117
|
+
//isValid = () => !_.isEmpty(this.state.templateName)
|
|
118
|
+
setCreateMode = (emailCreateMode) => {
|
|
119
|
+
this.setState({ selectedCreateMode: emailCreateMode });
|
|
120
|
+
}
|
|
121
|
+
handleZipUploadError = () => {
|
|
122
|
+
const message = {
|
|
123
|
+
key: "email-upload-error",
|
|
124
|
+
message: this.props.intl.formatMessage(messages.invalidUploadFileError2),
|
|
125
|
+
description: this.props.intl.formatMessage(messages.invalidUploadFileErrorDesc2),
|
|
126
|
+
};
|
|
127
|
+
CapNotification.error(message);
|
|
128
|
+
}
|
|
129
|
+
stopTimerGA = () => {
|
|
130
|
+
// stop timer
|
|
131
|
+
const timeTaken = timeTracker.stopTimer(CHANNEL_CREATE_TRACK_MAPPING.email, {
|
|
132
|
+
category: 'Creatives',
|
|
133
|
+
action: 'Create',
|
|
134
|
+
label: 'uploadZip',
|
|
135
|
+
});
|
|
136
|
+
gtmPush('creativeDetails', {
|
|
137
|
+
channel: EMAIL,
|
|
138
|
+
timeTaken,
|
|
139
|
+
mode: 'uploadZip',
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
handleFileUpload = (file = {}) => {
|
|
143
|
+
const { templatesActions, intl, showNextStep, isUploading } = this.props;
|
|
144
|
+
if (!isUploading) {
|
|
145
|
+
const fileExtension = file.name.split('.').pop();
|
|
146
|
+
const supportedZipFormats = ['zip'];
|
|
147
|
+
|
|
148
|
+
//converted file size to MB
|
|
149
|
+
const fileSize = file && (file.size / ( 1024 * 1024 ));
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
//Here fileSize is in MB
|
|
153
|
+
if (fileSize > 5) {
|
|
154
|
+
const message = {
|
|
155
|
+
key: "email-upload-error",
|
|
156
|
+
message: intl.formatMessage(messages.invalidUploadFileError),
|
|
157
|
+
description: intl.formatMessage(messages.invalidUploadFileErrorDesc3),
|
|
158
|
+
};
|
|
159
|
+
CapNotification.error(message);
|
|
160
|
+
} else if (supportedZipFormats.indexOf(fileExtension.toLowerCase()) !== -1) {
|
|
161
|
+
templatesActions.handleZipUpload(file.originFileObj, () => { //handle upload success
|
|
162
|
+
this.stopTimerGA();
|
|
163
|
+
this.setState({ modeContent: { file } }, showNextStep);
|
|
164
|
+
}, this.handleZipUploadError);
|
|
165
|
+
} else if (fileExtension === 'html' || fileExtension === 'htm') {
|
|
166
|
+
const reader = new FileReader();
|
|
167
|
+
reader.onload = () => {
|
|
168
|
+
const text = reader.result;
|
|
169
|
+
this.setState({ modeContent: { file } }, () => {
|
|
170
|
+
templatesActions.handleHtmlUpload(text);
|
|
171
|
+
});
|
|
172
|
+
// showNextStep();
|
|
173
|
+
};
|
|
174
|
+
reader.readAsText(file.originFileObj);
|
|
175
|
+
} else {
|
|
176
|
+
const message = {
|
|
177
|
+
key: "email-upload-error",
|
|
178
|
+
message: intl.formatMessage(messages.invalidUploadFileError),
|
|
179
|
+
description: intl.formatMessage(messages.invalidUploadFileErrorDesc),
|
|
180
|
+
};
|
|
181
|
+
CapNotification.error(message);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
handleEdmDefaultTemplateSelection = (id) => {
|
|
187
|
+
const { CmsTemplates, templatesActions } = this.props;
|
|
188
|
+
const data = _.find(CmsTemplates, { _id: id });
|
|
189
|
+
|
|
190
|
+
templatesActions.setEdmTemplate(data);
|
|
191
|
+
templatesActions.setBEETemplate(data);
|
|
192
|
+
this.setState({
|
|
193
|
+
selectedCreateMode: 'editor',
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
useFileUpload = ({ file }) => {
|
|
197
|
+
this.setState({ modeContent: {} }, () => {
|
|
198
|
+
this.handleFileUpload(file);
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
useEditor = (id) => {
|
|
202
|
+
this.setState({ modeContent: { id } }, this.props.showNextStep);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
isShowEmailCreate = () => !_.isEmpty(this.state.selectedCreateMode) && (!_.isEmpty(this.props.EmailLayout) || this.props.SelectedEdmDefaultTemplate)
|
|
206
|
+
render() {
|
|
207
|
+
const {
|
|
208
|
+
showTemplateName,
|
|
209
|
+
emailCreateMode,
|
|
210
|
+
isGetFormData,
|
|
211
|
+
getFormdata,
|
|
212
|
+
type,
|
|
213
|
+
CmsTemplates,
|
|
214
|
+
step,
|
|
215
|
+
cap,
|
|
216
|
+
isFullMode,
|
|
217
|
+
EmailLayout,
|
|
218
|
+
setIsLoadingContent,
|
|
219
|
+
onValidationFail,
|
|
220
|
+
forwardedTags,
|
|
221
|
+
selectedOfferDetails,
|
|
222
|
+
onPreviewContentClicked,
|
|
223
|
+
onTestContentClicked,
|
|
224
|
+
cmsTemplatesLoader,
|
|
225
|
+
editor,
|
|
226
|
+
currentOrgDetails,
|
|
227
|
+
moduleType,
|
|
228
|
+
showLiquidErrorInFooter,
|
|
229
|
+
eventContextTags,
|
|
230
|
+
// Flag to enable loyalty module specific features in the email editor
|
|
231
|
+
isLoyaltyModule,
|
|
232
|
+
} = this.props;
|
|
233
|
+
const {
|
|
234
|
+
templateName,
|
|
235
|
+
modeContent,
|
|
236
|
+
isTemplateNameEmpty,
|
|
237
|
+
} = this.state;
|
|
238
|
+
const isShowEmailCreate = this.isShowEmailCreate();
|
|
239
|
+
return (
|
|
240
|
+
<div>
|
|
241
|
+
<CapSpin spinning={emailCreateMode === "upload" ? this.props.isUploading : false} >
|
|
242
|
+
{step === "modeSelection" || (step === "templateSelection" && emailCreateMode === "upload") ?
|
|
243
|
+
<div>
|
|
244
|
+
{isFullMode &&
|
|
245
|
+
<CapInput
|
|
246
|
+
label={<FormattedMessage {...messages.creativeName} />}
|
|
247
|
+
onChange={this.onTemplateNameChange}
|
|
248
|
+
value={templateName}
|
|
249
|
+
labelPosition="top"
|
|
250
|
+
size="default"
|
|
251
|
+
style={{ width: '68%'}}
|
|
252
|
+
/>
|
|
253
|
+
}
|
|
254
|
+
<CardContainer>
|
|
255
|
+
<CapRadioCardWithLabel
|
|
256
|
+
panes={this.modes}
|
|
257
|
+
onChange={this.onChange}
|
|
258
|
+
selected={emailCreateMode}
|
|
259
|
+
label={<FormattedMessage {...messages.createMode} />}
|
|
260
|
+
/>
|
|
261
|
+
</CardContainer>
|
|
262
|
+
<div>
|
|
263
|
+
{emailCreateMode === "upload" &&
|
|
264
|
+
<div style={{ marginLeft: '8px' }}>
|
|
265
|
+
<CapUploader onChange={this.useFileUpload} accept=".zip, .html, .htm" showUploadList={false}>
|
|
266
|
+
{ (isFullMode && isTemplateNameEmpty) &&
|
|
267
|
+
<CapError type="error">
|
|
268
|
+
< FormattedMessage {...messages.emptyTemplateName} />
|
|
269
|
+
</CapError>
|
|
270
|
+
}
|
|
271
|
+
<CapButton disabled={isFullMode && isTemplateNameEmpty}>{this.props.intl.formatMessage(messages.upload)}</CapButton>
|
|
272
|
+
</CapUploader>
|
|
273
|
+
{!_.isEmpty(EmailLayout) &&
|
|
274
|
+
<div>{_.get(modeContent, "file.name")}</div>
|
|
275
|
+
}
|
|
276
|
+
</div>
|
|
277
|
+
}
|
|
278
|
+
</div>
|
|
279
|
+
</div>
|
|
280
|
+
:
|
|
281
|
+
<div>
|
|
282
|
+
{isShowEmailCreate && <Email
|
|
283
|
+
setIsLoadingContent={setIsLoadingContent}
|
|
284
|
+
key="email-create-template"
|
|
285
|
+
location={this.state.routeParams}
|
|
286
|
+
route={{ name: 'email' }}
|
|
287
|
+
params={{}}
|
|
288
|
+
isGetFormData={isGetFormData}
|
|
289
|
+
getFormdata={getFormdata}
|
|
290
|
+
getFormSubscriptionData={getFormdata}
|
|
291
|
+
getDefaultTags={type}
|
|
292
|
+
isFullMode={isFullMode}
|
|
293
|
+
defaultData={{ 'template-name': templateName }}
|
|
294
|
+
cap={cap}
|
|
295
|
+
showTemplateName={showTemplateName}
|
|
296
|
+
showLiquidErrorInFooter={showLiquidErrorInFooter}
|
|
297
|
+
onValidationFail={onValidationFail}
|
|
298
|
+
forwardedTags={forwardedTags}
|
|
299
|
+
selectedOfferDetails={selectedOfferDetails}
|
|
300
|
+
onPreviewContentClicked={onPreviewContentClicked}
|
|
301
|
+
onTestContentClicked={onTestContentClicked}
|
|
302
|
+
editor={editor}
|
|
303
|
+
moduleType={moduleType}
|
|
304
|
+
eventContextTags={eventContextTags}
|
|
305
|
+
isLoyaltyModule={isLoyaltyModule}
|
|
306
|
+
/>}
|
|
307
|
+
{!isShowEmailCreate && (
|
|
308
|
+
<CmsTemplatesComponent
|
|
309
|
+
cmsTemplates={CmsTemplates}
|
|
310
|
+
handleEdmDefaultTemplateSelection={this.useEditor}
|
|
311
|
+
cmsTemplatesLoader={cmsTemplatesLoader}
|
|
312
|
+
currentOrgDetails={currentOrgDetails || cap?.currentOrgDetails}
|
|
313
|
+
/>
|
|
314
|
+
)}
|
|
315
|
+
</div>
|
|
316
|
+
}
|
|
317
|
+
</CapSpin>
|
|
318
|
+
</div>
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
63
322
|
|
|
64
323
|
EmailWrapper.propTypes = {
|
|
65
324
|
onEmailModeChange: PropTypes.func.isRequired,
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import { FormattedMessage } from 'react-intl';
|
|
4
|
-
import styled from 'styled-components';
|
|
5
|
-
import _ from 'lodash';
|
|
6
|
-
import { CapRadioCard, CapInput, CapUploader, CapSpin, CapButton, CapError } from '@capillarytech/cap-ui-library';
|
|
7
|
-
import ComponentWithLabelHOC from '@capillarytech/cap-ui-library/assets/HOCs/ComponentWithLabelHOC';
|
|
8
|
-
import Email from '../../Email';
|
|
9
|
-
import CmsTemplatesComponent from '../../../v2Components/CmsTemplatesComponent';
|
|
10
|
-
import messages from '../messages';
|
|
11
|
-
|
|
12
|
-
const CapRadioCardWithLabel = ComponentWithLabelHOC(CapRadioCard);
|
|
13
|
-
|
|
14
|
-
const CardContainer = styled.div`
|
|
15
|
-
margin-top: 16px;
|
|
16
|
-
.ant-radio-group{
|
|
17
|
-
.ant-radio-button-wrapper{
|
|
18
|
-
&:first-child{
|
|
19
|
-
margin-left: unset;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
`;
|
|
24
|
-
|
|
25
|
-
// Mode selection component that handles the creation mode selection UI
|
|
26
|
-
const ModeSelectionUI = ({
|
|
27
|
-
isFullMode,
|
|
28
|
-
templateName,
|
|
29
|
-
onTemplateNameChange,
|
|
30
|
-
isTemplateNameEmpty,
|
|
31
|
-
modes,
|
|
32
|
-
emailCreateMode,
|
|
33
|
-
onChange,
|
|
34
|
-
EmailLayout,
|
|
35
|
-
modeContent,
|
|
36
|
-
useFileUpload,
|
|
37
|
-
uploadButtonLabel,
|
|
38
|
-
}) => (
|
|
39
|
-
<div>
|
|
40
|
-
{isFullMode && (
|
|
41
|
-
<CapInput
|
|
42
|
-
label={<FormattedMessage {...messages.creativeName} />}
|
|
43
|
-
onChange={onTemplateNameChange}
|
|
44
|
-
value={templateName}
|
|
45
|
-
labelPosition="top"
|
|
46
|
-
size="default"
|
|
47
|
-
style={{ width: '68%'}}
|
|
48
|
-
/>
|
|
49
|
-
)}
|
|
50
|
-
<CardContainer>
|
|
51
|
-
<CapRadioCardWithLabel
|
|
52
|
-
panes={modes}
|
|
53
|
-
onChange={onChange}
|
|
54
|
-
selected={emailCreateMode}
|
|
55
|
-
label={<FormattedMessage {...messages.createMode} />}
|
|
56
|
-
/>
|
|
57
|
-
</CardContainer>
|
|
58
|
-
<div>
|
|
59
|
-
{emailCreateMode === "upload" && (
|
|
60
|
-
<div style={{ marginLeft: '8px' }}>
|
|
61
|
-
<CapUploader onChange={useFileUpload} accept=".zip, .html, .htm" showUploadList={false}>
|
|
62
|
-
{(isFullMode && isTemplateNameEmpty) && (
|
|
63
|
-
<CapError type="error">
|
|
64
|
-
<FormattedMessage {...messages.emptyTemplateName} />
|
|
65
|
-
</CapError>
|
|
66
|
-
)}
|
|
67
|
-
<CapButton disabled={isFullMode && isTemplateNameEmpty}>
|
|
68
|
-
{uploadButtonLabel}
|
|
69
|
-
</CapButton>
|
|
70
|
-
</CapUploader>
|
|
71
|
-
{!_.isEmpty(EmailLayout) && (
|
|
72
|
-
<div>{_.get(modeContent, "file.name")}</div>
|
|
73
|
-
)}
|
|
74
|
-
</div>
|
|
75
|
-
)}
|
|
76
|
-
</div>
|
|
77
|
-
</div>
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
ModeSelectionUI.propTypes = {
|
|
81
|
-
isFullMode: PropTypes.bool,
|
|
82
|
-
templateName: PropTypes.string,
|
|
83
|
-
onTemplateNameChange: PropTypes.func.isRequired,
|
|
84
|
-
isTemplateNameEmpty: PropTypes.bool,
|
|
85
|
-
modes: PropTypes.array.isRequired,
|
|
86
|
-
emailCreateMode: PropTypes.string,
|
|
87
|
-
onChange: PropTypes.func.isRequired,
|
|
88
|
-
EmailLayout: PropTypes.object,
|
|
89
|
-
modeContent: PropTypes.object,
|
|
90
|
-
useFileUpload: PropTypes.func.isRequired,
|
|
91
|
-
uploadButtonLabel: PropTypes.node.isRequired,
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
// Content creation component that handles the email or template selection UI
|
|
95
|
-
const ContentCreationUI = ({
|
|
96
|
-
isShowEmailCreate,
|
|
97
|
-
emailProps,
|
|
98
|
-
cmsTemplatesProps,
|
|
99
|
-
}) => (
|
|
100
|
-
<div>
|
|
101
|
-
{isShowEmailCreate ? (
|
|
102
|
-
<Email {...emailProps} />
|
|
103
|
-
) : (
|
|
104
|
-
<CmsTemplatesComponent {...cmsTemplatesProps} />
|
|
105
|
-
)}
|
|
106
|
-
</div>
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
ContentCreationUI.propTypes = {
|
|
110
|
-
isShowEmailCreate: PropTypes.bool.isRequired,
|
|
111
|
-
emailProps: PropTypes.object.isRequired,
|
|
112
|
-
cmsTemplatesProps: PropTypes.object.isRequired,
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
// Main EmailWrapper presentational component
|
|
116
|
-
const EmailWrapperView = ({
|
|
117
|
-
isUploading,
|
|
118
|
-
emailCreateMode,
|
|
119
|
-
step,
|
|
120
|
-
isFullMode,
|
|
121
|
-
templateName,
|
|
122
|
-
onTemplateNameChange,
|
|
123
|
-
isTemplateNameEmpty,
|
|
124
|
-
modes,
|
|
125
|
-
onChange,
|
|
126
|
-
EmailLayout,
|
|
127
|
-
modeContent,
|
|
128
|
-
useFileUpload,
|
|
129
|
-
uploadButtonLabel,
|
|
130
|
-
isShowEmailCreate,
|
|
131
|
-
emailProps,
|
|
132
|
-
cmsTemplatesProps,
|
|
133
|
-
}) => {
|
|
134
|
-
const isShowTemplateSelection = step === "modeSelection" || (step === "templateSelection" && emailCreateMode === "upload");
|
|
135
|
-
|
|
136
|
-
return (
|
|
137
|
-
<div>
|
|
138
|
-
<CapSpin spinning={emailCreateMode === "upload" ? isUploading : false}>
|
|
139
|
-
{isShowTemplateSelection ? (
|
|
140
|
-
<ModeSelectionUI
|
|
141
|
-
isFullMode={isFullMode}
|
|
142
|
-
templateName={templateName}
|
|
143
|
-
onTemplateNameChange={onTemplateNameChange}
|
|
144
|
-
isTemplateNameEmpty={isTemplateNameEmpty}
|
|
145
|
-
modes={modes}
|
|
146
|
-
emailCreateMode={emailCreateMode}
|
|
147
|
-
onChange={onChange}
|
|
148
|
-
EmailLayout={EmailLayout}
|
|
149
|
-
modeContent={modeContent}
|
|
150
|
-
useFileUpload={useFileUpload}
|
|
151
|
-
uploadButtonLabel={uploadButtonLabel}
|
|
152
|
-
/>
|
|
153
|
-
) : (
|
|
154
|
-
<ContentCreationUI
|
|
155
|
-
isShowEmailCreate={isShowEmailCreate}
|
|
156
|
-
emailProps={emailProps}
|
|
157
|
-
cmsTemplatesProps={cmsTemplatesProps}
|
|
158
|
-
/>
|
|
159
|
-
)}
|
|
160
|
-
</CapSpin>
|
|
161
|
-
</div>
|
|
162
|
-
);
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
EmailWrapperView.propTypes = {
|
|
166
|
-
isUploading: PropTypes.bool,
|
|
167
|
-
emailCreateMode: PropTypes.string,
|
|
168
|
-
step: PropTypes.string,
|
|
169
|
-
isFullMode: PropTypes.bool,
|
|
170
|
-
templateName: PropTypes.string,
|
|
171
|
-
onTemplateNameChange: PropTypes.func.isRequired,
|
|
172
|
-
isTemplateNameEmpty: PropTypes.bool,
|
|
173
|
-
modes: PropTypes.array.isRequired,
|
|
174
|
-
onChange: PropTypes.func.isRequired,
|
|
175
|
-
EmailLayout: PropTypes.object,
|
|
176
|
-
modeContent: PropTypes.object,
|
|
177
|
-
useFileUpload: PropTypes.func.isRequired,
|
|
178
|
-
uploadButtonLabel: PropTypes.node.isRequired,
|
|
179
|
-
isShowEmailCreate: PropTypes.bool.isRequired,
|
|
180
|
-
emailProps: PropTypes.object.isRequired,
|
|
181
|
-
cmsTemplatesProps: PropTypes.object.isRequired,
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
export default EmailWrapperView;
|
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect, useMemo, useCallback } from 'react';
|
|
2
|
-
import _ from 'lodash';
|
|
3
|
-
import { GA } from '@capillarytech/cap-ui-utils';
|
|
4
|
-
import { CapNotification } from '@capillarytech/cap-ui-library';
|
|
5
|
-
import { CHANNEL_CREATE_TRACK_MAPPING } from '../../App/constants';
|
|
6
|
-
import { gtmPush } from '../../../utils/gtmTrackers';
|
|
7
|
-
import { EMAIL } from '../../CreativesContainer/constants';
|
|
8
|
-
import messages from '../messages';
|
|
9
|
-
|
|
10
|
-
const { timeTracker } = GA;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Custom hook to handle EmailWrapper component business logic
|
|
14
|
-
*/
|
|
15
|
-
const useEmailWrapper = ({
|
|
16
|
-
intl,
|
|
17
|
-
onEmailModeChange,
|
|
18
|
-
emailCreateMode,
|
|
19
|
-
step,
|
|
20
|
-
EmailLayout,
|
|
21
|
-
CmsTemplates,
|
|
22
|
-
SelectedEdmDefaultTemplate,
|
|
23
|
-
isUploading,
|
|
24
|
-
templatesActions,
|
|
25
|
-
showNextStep,
|
|
26
|
-
onResetStep,
|
|
27
|
-
onEnterTemplateName,
|
|
28
|
-
onRemoveTemplateName,
|
|
29
|
-
getCmsTemplatesInProgress,
|
|
30
|
-
// Props for Email component
|
|
31
|
-
setIsLoadingContent,
|
|
32
|
-
isGetFormData,
|
|
33
|
-
getFormdata,
|
|
34
|
-
type,
|
|
35
|
-
isFullMode,
|
|
36
|
-
cap,
|
|
37
|
-
showTemplateName,
|
|
38
|
-
showLiquidErrorInFooter,
|
|
39
|
-
onValidationFail,
|
|
40
|
-
forwardedTags,
|
|
41
|
-
selectedOfferDetails,
|
|
42
|
-
onPreviewContentClicked,
|
|
43
|
-
onTestContentClicked,
|
|
44
|
-
editor,
|
|
45
|
-
moduleType,
|
|
46
|
-
eventContextTags,
|
|
47
|
-
isLoyaltyModule,
|
|
48
|
-
// Props for CmsTemplates component
|
|
49
|
-
cmsTemplatesLoader,
|
|
50
|
-
currentOrgDetails,
|
|
51
|
-
}) => {
|
|
52
|
-
// State management
|
|
53
|
-
const [templateName, setTemplateName] = useState('');
|
|
54
|
-
const [isTemplateNameEmpty, setIsTemplateNameEmpty] = useState(true);
|
|
55
|
-
const [selectedCreateMode, setSelectedCreateMode] = useState('');
|
|
56
|
-
const [modeContent, setModeContent] = useState({});
|
|
57
|
-
const [routeParams] = useState({
|
|
58
|
-
pathname: `/email/create`,
|
|
59
|
-
query: { module: 'library', type: 'embedded' },
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
// Cleanup effect
|
|
63
|
-
useEffect(() => {
|
|
64
|
-
return () => {
|
|
65
|
-
onResetStep();
|
|
66
|
-
templatesActions.resetTemplateData();
|
|
67
|
-
};
|
|
68
|
-
}, [onResetStep, templatesActions]);
|
|
69
|
-
|
|
70
|
-
// Main logic effect
|
|
71
|
-
useEffect(() => {
|
|
72
|
-
if (step === "modeSelection" && !selectedCreateMode && emailCreateMode === 'upload' && !EmailLayout) {
|
|
73
|
-
//document.getElementById('upload-email-template').click();
|
|
74
|
-
} else if (step === "templateSelection" && !selectedCreateMode) {
|
|
75
|
-
if (emailCreateMode === "editor" && !CmsTemplates && !getCmsTemplatesInProgress) {
|
|
76
|
-
templatesActions.getDefaultBeeTemplates();
|
|
77
|
-
}
|
|
78
|
-
} else if (step === "createTemplateContent" && !selectedCreateMode) {
|
|
79
|
-
if (emailCreateMode === 'upload' && !_.isEmpty(EmailLayout)) {
|
|
80
|
-
setSelectedCreateMode('upload');
|
|
81
|
-
} else if (emailCreateMode === "editor" && _.isEmpty(SelectedEdmDefaultTemplate)) {
|
|
82
|
-
handleEdmDefaultTemplateSelection(modeContent.id);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}, [
|
|
86
|
-
step,
|
|
87
|
-
selectedCreateMode,
|
|
88
|
-
emailCreateMode,
|
|
89
|
-
EmailLayout,
|
|
90
|
-
CmsTemplates,
|
|
91
|
-
getCmsTemplatesInProgress,
|
|
92
|
-
modeContent.id,
|
|
93
|
-
SelectedEdmDefaultTemplate,
|
|
94
|
-
templatesActions
|
|
95
|
-
]);
|
|
96
|
-
|
|
97
|
-
// Event handlers
|
|
98
|
-
const onTemplateNameChange = useCallback(({target: {value}}) => {
|
|
99
|
-
const isEmptyTemplateName = !value?.trim();
|
|
100
|
-
setTemplateName(value);
|
|
101
|
-
setIsTemplateNameEmpty(isEmptyTemplateName);
|
|
102
|
-
|
|
103
|
-
if (value && onEnterTemplateName) {
|
|
104
|
-
onEnterTemplateName();
|
|
105
|
-
} else if (onRemoveTemplateName) {
|
|
106
|
-
onRemoveTemplateName();
|
|
107
|
-
}
|
|
108
|
-
}, [onEnterTemplateName, onRemoveTemplateName]);
|
|
109
|
-
|
|
110
|
-
const onChange = useCallback((e) => {
|
|
111
|
-
onEmailModeChange(e.target.value);
|
|
112
|
-
}, [onEmailModeChange]);
|
|
113
|
-
|
|
114
|
-
const handleZipUploadError = useCallback(() => {
|
|
115
|
-
const message = {
|
|
116
|
-
key: "email-upload-error",
|
|
117
|
-
message: intl.formatMessage(messages.invalidUploadFileError2),
|
|
118
|
-
description: intl.formatMessage(messages.invalidUploadFileErrorDesc2),
|
|
119
|
-
};
|
|
120
|
-
CapNotification.error(message);
|
|
121
|
-
}, [intl]);
|
|
122
|
-
|
|
123
|
-
const stopTimerGA = useCallback(() => {
|
|
124
|
-
const timeTaken = timeTracker.stopTimer(CHANNEL_CREATE_TRACK_MAPPING.email, {
|
|
125
|
-
category: 'Creatives',
|
|
126
|
-
action: 'Create',
|
|
127
|
-
label: 'uploadZip',
|
|
128
|
-
});
|
|
129
|
-
gtmPush('creativeDetails', {
|
|
130
|
-
channel: EMAIL,
|
|
131
|
-
timeTaken,
|
|
132
|
-
mode: 'uploadZip',
|
|
133
|
-
});
|
|
134
|
-
}, []);
|
|
135
|
-
|
|
136
|
-
const handleFileUpload = useCallback((file = {}) => {
|
|
137
|
-
if (!isUploading) {
|
|
138
|
-
const fileExtension = file.name.split('.').pop();
|
|
139
|
-
const supportedZipFormats = ['zip'];
|
|
140
|
-
|
|
141
|
-
// Converted file size to MB
|
|
142
|
-
const fileSize = file && (file.size / (1024 * 1024));
|
|
143
|
-
|
|
144
|
-
// Here fileSize is in MB
|
|
145
|
-
if (fileSize > 5) {
|
|
146
|
-
const message = {
|
|
147
|
-
key: "email-upload-error",
|
|
148
|
-
message: intl.formatMessage(messages.invalidUploadFileError),
|
|
149
|
-
description: intl.formatMessage(messages.invalidUploadFileErrorDesc3),
|
|
150
|
-
};
|
|
151
|
-
CapNotification.error(message);
|
|
152
|
-
} else if (supportedZipFormats.indexOf(fileExtension.toLowerCase()) !== -1) {
|
|
153
|
-
templatesActions.handleZipUpload(file.originFileObj, () => { // Handle upload success
|
|
154
|
-
stopTimerGA();
|
|
155
|
-
setModeContent({ file });
|
|
156
|
-
showNextStep();
|
|
157
|
-
}, handleZipUploadError);
|
|
158
|
-
} else if (fileExtension === 'html' || fileExtension === 'htm') {
|
|
159
|
-
const reader = new FileReader();
|
|
160
|
-
reader.onload = () => {
|
|
161
|
-
const text = reader.result;
|
|
162
|
-
setModeContent({ file });
|
|
163
|
-
templatesActions.handleHtmlUpload(text);
|
|
164
|
-
};
|
|
165
|
-
reader.readAsText(file.originFileObj);
|
|
166
|
-
} else {
|
|
167
|
-
const message = {
|
|
168
|
-
key: "email-upload-error",
|
|
169
|
-
message: intl.formatMessage(messages.invalidUploadFileError),
|
|
170
|
-
description: intl.formatMessage(messages.invalidUploadFileErrorDesc),
|
|
171
|
-
};
|
|
172
|
-
CapNotification.error(message);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}, [isUploading, intl, templatesActions, stopTimerGA, handleZipUploadError, showNextStep]);
|
|
176
|
-
|
|
177
|
-
const handleEdmDefaultTemplateSelection = useCallback((id) => {
|
|
178
|
-
const data = _.find(CmsTemplates, { _id: id });
|
|
179
|
-
templatesActions.setEdmTemplate(data);
|
|
180
|
-
templatesActions.setBEETemplate(data);
|
|
181
|
-
setSelectedCreateMode('editor');
|
|
182
|
-
}, [CmsTemplates, templatesActions]);
|
|
183
|
-
|
|
184
|
-
const useFileUpload = useCallback(({ file }) => {
|
|
185
|
-
setModeContent({});
|
|
186
|
-
handleFileUpload(file);
|
|
187
|
-
}, [handleFileUpload]);
|
|
188
|
-
|
|
189
|
-
const useEditor = useCallback((id) => {
|
|
190
|
-
setModeContent({ id });
|
|
191
|
-
showNextStep();
|
|
192
|
-
}, [showNextStep]);
|
|
193
|
-
|
|
194
|
-
// Derived state
|
|
195
|
-
const isShowEmailCreate = !_.isEmpty(selectedCreateMode) && (!_.isEmpty(EmailLayout) || SelectedEdmDefaultTemplate);
|
|
196
|
-
|
|
197
|
-
// Memoize static data
|
|
198
|
-
const modes = useMemo(() => [
|
|
199
|
-
{
|
|
200
|
-
title: intl.formatMessage(messages.zipUpload),
|
|
201
|
-
content: intl.formatMessage(messages.zipUploadDesc),
|
|
202
|
-
value: 'upload',
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
title: intl.formatMessage(messages.useEditor),
|
|
206
|
-
content: intl.formatMessage(messages.useEditorDesc),
|
|
207
|
-
value: 'editor',
|
|
208
|
-
},
|
|
209
|
-
], [intl]);
|
|
210
|
-
|
|
211
|
-
// Prepare props for Email component
|
|
212
|
-
const emailProps = useMemo(() => ({
|
|
213
|
-
setIsLoadingContent,
|
|
214
|
-
key: "email-create-template",
|
|
215
|
-
location: routeParams,
|
|
216
|
-
route: { name: 'email' },
|
|
217
|
-
params: {},
|
|
218
|
-
isGetFormData,
|
|
219
|
-
getFormdata,
|
|
220
|
-
getFormSubscriptionData: getFormdata,
|
|
221
|
-
getDefaultTags: type,
|
|
222
|
-
isFullMode,
|
|
223
|
-
defaultData: { 'template-name': templateName },
|
|
224
|
-
cap,
|
|
225
|
-
showTemplateName,
|
|
226
|
-
showLiquidErrorInFooter,
|
|
227
|
-
onValidationFail,
|
|
228
|
-
forwardedTags,
|
|
229
|
-
selectedOfferDetails,
|
|
230
|
-
onPreviewContentClicked,
|
|
231
|
-
onTestContentClicked,
|
|
232
|
-
editor,
|
|
233
|
-
moduleType,
|
|
234
|
-
eventContextTags,
|
|
235
|
-
isLoyaltyModule,
|
|
236
|
-
}), [
|
|
237
|
-
setIsLoadingContent,
|
|
238
|
-
routeParams,
|
|
239
|
-
isGetFormData,
|
|
240
|
-
getFormdata,
|
|
241
|
-
type,
|
|
242
|
-
isFullMode,
|
|
243
|
-
templateName,
|
|
244
|
-
cap,
|
|
245
|
-
showTemplateName,
|
|
246
|
-
showLiquidErrorInFooter,
|
|
247
|
-
onValidationFail,
|
|
248
|
-
forwardedTags,
|
|
249
|
-
selectedOfferDetails,
|
|
250
|
-
onPreviewContentClicked,
|
|
251
|
-
onTestContentClicked,
|
|
252
|
-
editor,
|
|
253
|
-
moduleType,
|
|
254
|
-
eventContextTags,
|
|
255
|
-
isLoyaltyModule,
|
|
256
|
-
]);
|
|
257
|
-
|
|
258
|
-
// Prepare props for CmsTemplatesComponent
|
|
259
|
-
const cmsTemplatesProps = useMemo(() => ({
|
|
260
|
-
cmsTemplates: CmsTemplates,
|
|
261
|
-
handleEdmDefaultTemplateSelection: useEditor,
|
|
262
|
-
cmsTemplatesLoader,
|
|
263
|
-
currentOrgDetails: currentOrgDetails || cap?.currentOrgDetails,
|
|
264
|
-
}), [CmsTemplates, useEditor, cmsTemplatesLoader, currentOrgDetails, cap]);
|
|
265
|
-
|
|
266
|
-
// Upload button label
|
|
267
|
-
const uploadButtonLabel = intl.formatMessage(messages.upload);
|
|
268
|
-
|
|
269
|
-
return {
|
|
270
|
-
// State
|
|
271
|
-
templateName,
|
|
272
|
-
isTemplateNameEmpty,
|
|
273
|
-
modeContent,
|
|
274
|
-
|
|
275
|
-
// Derived values
|
|
276
|
-
modes,
|
|
277
|
-
isShowEmailCreate,
|
|
278
|
-
emailProps,
|
|
279
|
-
cmsTemplatesProps,
|
|
280
|
-
uploadButtonLabel,
|
|
281
|
-
|
|
282
|
-
// Event handlers
|
|
283
|
-
onTemplateNameChange,
|
|
284
|
-
onChange,
|
|
285
|
-
useFileUpload,
|
|
286
|
-
};
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
export default useEmailWrapper;
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
export const EmailWrapperMockData = {
|
|
2
|
-
onEmailModeChange: jest.fn(),
|
|
3
|
-
showTemplateName: jest.fn(),
|
|
4
|
-
emailCreateMode: 'editor',
|
|
5
|
-
isGetFormData: false,
|
|
6
|
-
getFormdata: jest.fn(),
|
|
7
|
-
type: 'email',
|
|
8
|
-
step: 'modeSelection',
|
|
9
|
-
cap: { currentOrgDetails: { basic_details: {} } },
|
|
10
|
-
isFullMode: true,
|
|
11
|
-
setIsLoadingContent: jest.fn(),
|
|
12
|
-
onValidationFail: jest.fn(),
|
|
13
|
-
forwardedTags: {},
|
|
14
|
-
selectedOfferDetails: [],
|
|
15
|
-
onPreviewContentClicked: jest.fn(),
|
|
16
|
-
onTestContentClicked: jest.fn(),
|
|
17
|
-
editor: {},
|
|
18
|
-
moduleType: 'email',
|
|
19
|
-
showLiquidErrorInFooter: jest.fn(),
|
|
20
|
-
eventContextTags: [],
|
|
21
|
-
isLoyaltyModule: false,
|
|
22
|
-
isUploading: false,
|
|
23
|
-
templatesActions: {
|
|
24
|
-
resetTemplateData: jest.fn(),
|
|
25
|
-
getDefaultBeeTemplates: jest.fn(),
|
|
26
|
-
handleZipUpload: jest.fn(),
|
|
27
|
-
handleHtmlUpload: jest.fn(),
|
|
28
|
-
setEdmTemplate: jest.fn(),
|
|
29
|
-
setBEETemplate: jest.fn(),
|
|
30
|
-
},
|
|
31
|
-
showNextStep: jest.fn(),
|
|
32
|
-
onResetStep: jest.fn(),
|
|
33
|
-
onEnterTemplateName: jest.fn(),
|
|
34
|
-
onRemoveTemplateName: jest.fn(),
|
|
35
|
-
getCmsTemplatesInProgress: false,
|
|
36
|
-
EmailLayout: null,
|
|
37
|
-
CmsTemplates: [
|
|
38
|
-
{
|
|
39
|
-
_id: 'template1',
|
|
40
|
-
name: 'Template 1',
|
|
41
|
-
content: '<html><body>Template 1 Content</body></html>'
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
_id: 'template2',
|
|
45
|
-
name: 'Template 2',
|
|
46
|
-
content: '<html><body>Template 2 Content</body></html>'
|
|
47
|
-
}
|
|
48
|
-
],
|
|
49
|
-
SelectedEdmDefaultTemplate: null,
|
|
50
|
-
cmsTemplatesLoader: false,
|
|
51
|
-
currentOrgDetails: { basic_details: {} },
|
|
52
|
-
intl: {
|
|
53
|
-
formatMessage: jest.fn((message) => message.defaultMessage || ''),
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export const EmailWrapperViewMockProps = {
|
|
58
|
-
isUploading: false,
|
|
59
|
-
emailCreateMode: 'editor',
|
|
60
|
-
step: 'modeSelection',
|
|
61
|
-
isFullMode: true,
|
|
62
|
-
templateName: 'Test Template',
|
|
63
|
-
onTemplateNameChange: jest.fn(),
|
|
64
|
-
isTemplateNameEmpty: false,
|
|
65
|
-
modes: [
|
|
66
|
-
{
|
|
67
|
-
title: 'Upload zip file',
|
|
68
|
-
content: 'Upload compressed file (Zip) containing HTML & images',
|
|
69
|
-
value: 'upload',
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
title: 'Create using editor',
|
|
73
|
-
content: 'Create using in-built template',
|
|
74
|
-
value: 'editor',
|
|
75
|
-
}
|
|
76
|
-
],
|
|
77
|
-
onChange: jest.fn(),
|
|
78
|
-
EmailLayout: null,
|
|
79
|
-
modeContent: {},
|
|
80
|
-
useFileUpload: jest.fn(),
|
|
81
|
-
uploadButtonLabel: 'Upload',
|
|
82
|
-
isShowEmailCreate: false,
|
|
83
|
-
emailProps: {
|
|
84
|
-
key: "email-create-template",
|
|
85
|
-
location: {
|
|
86
|
-
pathname: `/email/create`,
|
|
87
|
-
query: { module: 'library', type: 'embedded' },
|
|
88
|
-
},
|
|
89
|
-
route: { name: 'email' },
|
|
90
|
-
params: {},
|
|
91
|
-
isGetFormData: false,
|
|
92
|
-
getFormdata: jest.fn(),
|
|
93
|
-
getFormSubscriptionData: jest.fn(),
|
|
94
|
-
getDefaultTags: 'email',
|
|
95
|
-
isFullMode: true,
|
|
96
|
-
defaultData: { 'template-name': 'Test Template' },
|
|
97
|
-
cap: { currentOrgDetails: { basic_details: {} } },
|
|
98
|
-
showTemplateName: jest.fn(),
|
|
99
|
-
showLiquidErrorInFooter: jest.fn(),
|
|
100
|
-
onValidationFail: jest.fn(),
|
|
101
|
-
forwardedTags: {},
|
|
102
|
-
selectedOfferDetails: [],
|
|
103
|
-
onPreviewContentClicked: jest.fn(),
|
|
104
|
-
onTestContentClicked: jest.fn(),
|
|
105
|
-
editor: {},
|
|
106
|
-
moduleType: 'email',
|
|
107
|
-
eventContextTags: [],
|
|
108
|
-
isLoyaltyModule: false
|
|
109
|
-
},
|
|
110
|
-
cmsTemplatesProps: {
|
|
111
|
-
cmsTemplates: [
|
|
112
|
-
{
|
|
113
|
-
_id: 'template1',
|
|
114
|
-
name: 'Template 1',
|
|
115
|
-
content: '<html><body>Template 1 Content</body></html>'
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
_id: 'template2',
|
|
119
|
-
name: 'Template 2',
|
|
120
|
-
content: '<html><body>Template 2 Content</body></html>'
|
|
121
|
-
}
|
|
122
|
-
],
|
|
123
|
-
handleEdmDefaultTemplateSelection: jest.fn(),
|
|
124
|
-
cmsTemplatesLoader: false,
|
|
125
|
-
currentOrgDetails: { basic_details: {} }
|
|
126
|
-
}
|
|
127
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { EmailWrapperViewMockProps } from '../mockdata/mockdata';
|
|
3
|
-
|
|
4
|
-
// Simple test for EmailWrapperView
|
|
5
|
-
describe('EmailWrapperView', () => {
|
|
6
|
-
it('component exists', () => {
|
|
7
|
-
// Just verify the file exists by requiring it
|
|
8
|
-
jest.doMock('../components/EmailWrapperView', () => ({
|
|
9
|
-
__esModule: true,
|
|
10
|
-
default: () => null
|
|
11
|
-
}));
|
|
12
|
-
|
|
13
|
-
// Simple assertion to make the test pass
|
|
14
|
-
expect(typeof require('../components/EmailWrapperView').default).toBe('function');
|
|
15
|
-
});
|
|
16
|
-
});
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @jest-environment jsdom
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
// Tests for EmailWrapper container component
|
|
6
|
-
describe('EmailWrapper Container Tests', () => {
|
|
7
|
-
// This test verifies that the container passes props from the custom hook to the view component
|
|
8
|
-
it('should pass props from custom hook to view', () => {
|
|
9
|
-
// Mock hook results
|
|
10
|
-
const mockHookResults = {
|
|
11
|
-
templateName: 'Test Template',
|
|
12
|
-
isTemplateNameEmpty: false,
|
|
13
|
-
modeContent: { file: { name: 'test.zip' } },
|
|
14
|
-
modes: ['upload', 'editor'],
|
|
15
|
-
isShowEmailCreate: false,
|
|
16
|
-
emailProps: { location: { pathname: '/email/create' } },
|
|
17
|
-
cmsTemplatesProps: { cmsTemplates: [] },
|
|
18
|
-
uploadButtonLabel: 'Upload',
|
|
19
|
-
onTemplateNameChange: jest.fn(),
|
|
20
|
-
onChange: jest.fn(),
|
|
21
|
-
useFileUpload: jest.fn()
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
// Mock view component (captures props)
|
|
25
|
-
let capturedViewProps = null;
|
|
26
|
-
const mockView = jest.fn(props => {
|
|
27
|
-
capturedViewProps = props;
|
|
28
|
-
return null;
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
// Mock custom hook
|
|
32
|
-
const mockUseEmailWrapper = jest.fn(() => mockHookResults);
|
|
33
|
-
|
|
34
|
-
// Container props
|
|
35
|
-
const containerProps = {
|
|
36
|
-
isUploading: false,
|
|
37
|
-
emailCreateMode: 'editor',
|
|
38
|
-
step: 'modeSelection',
|
|
39
|
-
isFullMode: true,
|
|
40
|
-
EmailLayout: null
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// Simulate the container component behavior
|
|
44
|
-
function simulateContainer() {
|
|
45
|
-
// Get state and handlers from hook
|
|
46
|
-
const hookResults = mockUseEmailWrapper(containerProps);
|
|
47
|
-
|
|
48
|
-
// Render view with combined props
|
|
49
|
-
return mockView({
|
|
50
|
-
...containerProps,
|
|
51
|
-
...hookResults
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Run the simulation
|
|
56
|
-
simulateContainer();
|
|
57
|
-
|
|
58
|
-
// Verify hook was called with correct props
|
|
59
|
-
expect(mockUseEmailWrapper).toHaveBeenCalledWith(containerProps);
|
|
60
|
-
|
|
61
|
-
// Verify view received combined props
|
|
62
|
-
expect(capturedViewProps).toEqual({
|
|
63
|
-
...containerProps,
|
|
64
|
-
...mockHookResults
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// Verify specific props
|
|
68
|
-
expect(capturedViewProps.isUploading).toBe(containerProps.isUploading);
|
|
69
|
-
expect(capturedViewProps.emailCreateMode).toBe(containerProps.emailCreateMode);
|
|
70
|
-
expect(capturedViewProps.templateName).toBe(mockHookResults.templateName);
|
|
71
|
-
expect(capturedViewProps.modes).toBe(mockHookResults.modes);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
// This test verifies the pattern is maintainable for future changes
|
|
75
|
-
it('handles adding new hook properties', () => {
|
|
76
|
-
// Mock hook with additional property
|
|
77
|
-
const mockHookWithNewProp = jest.fn(() => ({
|
|
78
|
-
templateName: 'Test',
|
|
79
|
-
newFeature: 'This is a new feature' // New property
|
|
80
|
-
}));
|
|
81
|
-
|
|
82
|
-
// Mock view component (captures props)
|
|
83
|
-
let capturedViewProps = null;
|
|
84
|
-
const mockView = jest.fn(props => {
|
|
85
|
-
capturedViewProps = props;
|
|
86
|
-
return null;
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
// Simulate container with new hook property
|
|
90
|
-
function simulateContainer() {
|
|
91
|
-
const hookResults = mockHookWithNewProp({});
|
|
92
|
-
return mockView(hookResults);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Run the simulation
|
|
96
|
-
simulateContainer();
|
|
97
|
-
|
|
98
|
-
// Verify the new property is correctly passed to view
|
|
99
|
-
expect(capturedViewProps.newFeature).toBe('This is a new feature');
|
|
100
|
-
});
|
|
101
|
-
});
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import useEmailWrapper from '../hooks/useEmailWrapper';
|
|
3
|
-
import { EmailWrapperMockData } from '../mockdata/mockdata';
|
|
4
|
-
import _ from 'lodash';
|
|
5
|
-
|
|
6
|
-
// Mock dependencies
|
|
7
|
-
jest.mock('lodash', () => ({
|
|
8
|
-
isEmpty: jest.fn(),
|
|
9
|
-
find: jest.fn(),
|
|
10
|
-
get: jest.fn(),
|
|
11
|
-
}));
|
|
12
|
-
|
|
13
|
-
jest.mock('@capillarytech/cap-ui-library', () => ({
|
|
14
|
-
CapNotification: {
|
|
15
|
-
error: jest.fn(),
|
|
16
|
-
},
|
|
17
|
-
}));
|
|
18
|
-
|
|
19
|
-
jest.mock('../../../utils/gtmTrackers', () => ({
|
|
20
|
-
gtmPush: jest.fn(),
|
|
21
|
-
}));
|
|
22
|
-
|
|
23
|
-
jest.mock('@capillarytech/cap-ui-utils', () => ({
|
|
24
|
-
GA: {
|
|
25
|
-
timeTracker: {
|
|
26
|
-
stopTimer: jest.fn().mockReturnValue(100),
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
}));
|
|
30
|
-
|
|
31
|
-
describe('useEmailWrapper', () => {
|
|
32
|
-
it('is a function', () => {
|
|
33
|
-
expect(typeof useEmailWrapper).toBe('function');
|
|
34
|
-
});
|
|
35
|
-
});
|