@capillarytech/creatives-library 7.17.93 → 7.17.95
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/containers/Ebill/index.js +1 -0
- package/containers/MobilePush/Edit/index.js +1 -0
- package/index.js +6 -0
- package/package.json +1 -1
- package/routes.js +5 -0
- package/v2Components/CapDeviceContent/index.js +311 -0
- package/v2Components/CapDeviceContent/index.scss +115 -0
- package/v2Components/CapDeviceContent/messages.js +94 -0
- package/v2Components/CapDeviceContent/tests/index.test.js +85 -0
- package/v2Components/CapImageUpload/index.js +11 -4
- package/v2Components/CapImageUpload/messages.js +6 -2
- package/v2Components/CapInAppCTA/constants.js +25 -0
- package/v2Components/CapInAppCTA/index.js +280 -0
- package/v2Components/CapInAppCTA/index.scss +93 -0
- package/v2Components/CapInAppCTA/messages.js +85 -0
- package/v2Components/FormBuilder/index.js +3 -4
- package/v2Components/MobilePushPreviewV2/index.js +78 -23
- package/v2Components/TemplatePreview/_templatePreview.scss +449 -0
- package/v2Components/TemplatePreview/assets/images/inapp_mobile_android_bottom.svg +11 -0
- package/v2Components/TemplatePreview/assets/images/inapp_mobile_android_full.svg +11 -0
- package/v2Components/TemplatePreview/assets/images/inapp_mobile_android_modal.svg +11 -0
- package/v2Components/TemplatePreview/assets/images/inapp_mobile_android_top.svg +11 -0
- package/v2Components/TemplatePreview/assets/images/inapp_mobile_ios_bottom.svg +6 -0
- package/v2Components/TemplatePreview/assets/images/inapp_mobile_ios_full.svg +18 -0
- package/v2Components/TemplatePreview/assets/images/inapp_mobile_ios_modal.svg +7 -0
- package/v2Components/TemplatePreview/assets/images/inapp_mobile_ios_top.svg +13 -0
- package/v2Components/TemplatePreview/index.js +660 -375
- package/v2Components/TemplatePreview/messages.js +4 -0
- package/v2Containers/App/constants.js +1 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +43 -0
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -1
- package/v2Containers/CreativesContainer/constants.js +1 -0
- package/v2Containers/CreativesContainer/index.js +42 -19
- package/v2Containers/CreativesContainer/messages.js +4 -0
- package/v2Containers/InApp/actions.js +64 -0
- package/v2Containers/InApp/constants.js +125 -0
- package/v2Containers/InApp/index.js +762 -0
- package/v2Containers/InApp/index.scss +48 -0
- package/v2Containers/InApp/messages.js +99 -0
- package/v2Containers/InApp/reducer.js +109 -0
- package/v2Containers/InApp/sagas.js +143 -0
- package/v2Containers/InApp/selectors.js +12 -0
- package/v2Containers/InApp/tests/action.test.js +53 -0
- package/v2Containers/InApp/tests/index.test.js +142 -0
- package/v2Containers/InApp/tests/mockData.js +898 -0
- package/v2Containers/InApp/tests/reducer.test.js +177 -0
- package/v2Containers/InApp/tests/sagas.test.js +391 -0
- package/v2Containers/MobilePush/Edit/index.js +3 -1
- package/v2Containers/Templates/_templates.scss +14 -0
- package/v2Containers/Templates/index.js +86 -32
- package/v2Containers/Templates/messages.js +20 -0
- package/v2Containers/TemplatesV2/index.js +2 -1
- package/v2Containers/TemplatesV2/messages.js +4 -0
|
@@ -956,6 +956,7 @@ export class Ebill extends React.Component { // eslint-disable-line react/prefer
|
|
|
956
956
|
}
|
|
957
957
|
temp.injectedEvents = {};
|
|
958
958
|
_.forEach(col.supportedEvents, (event) => {
|
|
959
|
+
console.log('injected event for ', col, event, this.getMappedEvent(col.id, event));
|
|
959
960
|
temp.injectedEvents[event] = this.getMappedEvent(col.id, event);
|
|
960
961
|
});
|
|
961
962
|
|
|
@@ -1779,6 +1779,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1779
1779
|
temp.content.appName = this.props.Templates.selectedWeChatAccount.name;
|
|
1780
1780
|
}
|
|
1781
1781
|
_.forEach(col.supportedEvents, (event) => {
|
|
1782
|
+
console.log('injected event for ', col, event, this.getMappedEvent(col.id, event));
|
|
1782
1783
|
temp.injectedEvents[event] = this.getMappedEvent(col.id, event);
|
|
1783
1784
|
});
|
|
1784
1785
|
return true;
|
package/index.js
CHANGED
|
@@ -95,6 +95,10 @@ import Zalo from './v2Containers/Zalo';
|
|
|
95
95
|
import zaloReducer from './v2Containers/Zalo/reducer';
|
|
96
96
|
import zaloSaga from './v2Containers/Zalo/saga';
|
|
97
97
|
|
|
98
|
+
import InApp from './v2Containers/InApp';
|
|
99
|
+
import inAppReducer from './v2Containers/InApp/reducer';
|
|
100
|
+
import inAppSaga from './v2Containers/InApp/sagas';
|
|
101
|
+
|
|
98
102
|
import Rcs from './v2Containers/Rcs';
|
|
99
103
|
import rcsReducer from './v2Containers/Rcs/reducer';
|
|
100
104
|
import rcsSaga from './v2Containers/Rcs/sagas';
|
|
@@ -126,6 +130,7 @@ const SmsTraiContainer = {SmsTraiCreate, SmsTraiCreateReducer, SmsTraiCreateSaga
|
|
|
126
130
|
const WhatsappContainer = { Whatsapp, whatsappReducer, whatsappSaga };
|
|
127
131
|
const RcsContainer = { Rcs, rcsReducer, rcsSaga };
|
|
128
132
|
const ZaloContainer = { Zalo, zaloReducer, zaloSaga };
|
|
133
|
+
const InAppContainer = { InApp, inAppReducer, inAppSaga };
|
|
129
134
|
|
|
130
135
|
const GalleryContainer = {Gallery, galleryReducer, gallerySagas};
|
|
131
136
|
const FTPContainer = {FTP, FTPReducer, FTPSagas};
|
|
@@ -175,4 +180,5 @@ export { CapContainer,
|
|
|
175
180
|
WhatsappContainer,
|
|
176
181
|
RcsContainer,
|
|
177
182
|
ZaloContainer,
|
|
183
|
+
InAppContainer,
|
|
178
184
|
};
|
package/package.json
CHANGED
package/routes.js
CHANGED
|
@@ -665,6 +665,8 @@ export default function createRoutes(store) {
|
|
|
665
665
|
import('v2Containers/Whatsapp/reducer'),
|
|
666
666
|
import('v2Containers/Zalo/saga'),
|
|
667
667
|
import('v2Containers/Zalo/reducer'),
|
|
668
|
+
import('v2Containers/InApp/sagas'),
|
|
669
|
+
import('v2Containers/InApp/reducer'),
|
|
668
670
|
import('v2Containers/Rcs/sagas'),
|
|
669
671
|
import('v2Containers/Rcs/reducer'),
|
|
670
672
|
]);
|
|
@@ -692,6 +694,7 @@ export default function createRoutes(store) {
|
|
|
692
694
|
smsTraiSagas, smsTraiReducer,
|
|
693
695
|
whatsappSagas, whatsappReducer,
|
|
694
696
|
zaloSagas, zaloReducer,
|
|
697
|
+
inAppSagas, inAppReducer,
|
|
695
698
|
rcsSagas, rcsReducer,
|
|
696
699
|
]) => {
|
|
697
700
|
injectReducer('templates', reducer.default);
|
|
@@ -714,6 +717,7 @@ export default function createRoutes(store) {
|
|
|
714
717
|
injectReducer('smsTrai', smsTraiReducer.default);
|
|
715
718
|
injectReducer('whatsapp', whatsappReducer.default);
|
|
716
719
|
injectReducer('zalo', zaloReducer.default);
|
|
720
|
+
injectReducer('inapp', inAppReducer.default);
|
|
717
721
|
injectReducer('rcs', rcsReducer.default);
|
|
718
722
|
injectSagas(gallerySagas.default);
|
|
719
723
|
injectSagas(sagas.default);
|
|
@@ -735,6 +739,7 @@ export default function createRoutes(store) {
|
|
|
735
739
|
injectSagas(smsTraiSagas.default);
|
|
736
740
|
injectSagas(whatsappSagas.default);
|
|
737
741
|
injectSagas(zaloSagas.default);
|
|
742
|
+
injectSagas(inAppSagas.default);
|
|
738
743
|
injectSagas(rcsSagas.default);
|
|
739
744
|
renderRoute(component);
|
|
740
745
|
});
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import React, { useCallback } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { injectIntl, intlShape } from "react-intl";
|
|
4
|
+
import cloneDeep from "lodash/cloneDeep";
|
|
5
|
+
import isEmpty from "lodash/isEmpty";
|
|
6
|
+
import CapHeading from "@capillarytech/cap-ui-library/CapHeading";
|
|
7
|
+
import CapHeader from "@capillarytech/cap-ui-library/CapHeader";
|
|
8
|
+
import CapInput from "@capillarytech/cap-ui-library/CapInput";
|
|
9
|
+
import CapRadioGroup from "@capillarytech/cap-ui-library/CapRadioGroup";
|
|
10
|
+
import CapRow from "@capillarytech/cap-ui-library/CapRow";
|
|
11
|
+
import CapColumn from "@capillarytech/cap-ui-library/CapColumn";
|
|
12
|
+
import CapLabel from "@capillarytech/cap-ui-library/CapLabel";
|
|
13
|
+
import CapLink from "@capillarytech/cap-ui-library/CapLink";
|
|
14
|
+
import CapError from "@capillarytech/cap-ui-library/CapError";
|
|
15
|
+
import CapCheckbox from "@capillarytech/cap-ui-library/CapCheckbox";
|
|
16
|
+
import CapSelect from "@capillarytech/cap-ui-library/CapSelect";
|
|
17
|
+
import TagList from "../../v2Containers/TagList";
|
|
18
|
+
import messages from "./messages";
|
|
19
|
+
import {
|
|
20
|
+
ANDROID,
|
|
21
|
+
INAPP_MEDIA_TYPES,
|
|
22
|
+
INAPP_BUTTON_TYPES,
|
|
23
|
+
ALLOWED_IMAGE_EXTENSIONS_REGEX,
|
|
24
|
+
INAPP_IMG_SIZE,
|
|
25
|
+
INITIAL_CTA_DATA,
|
|
26
|
+
MEDIA_RADIO_OPTIONS,
|
|
27
|
+
BUTTON_RADIO_OPTIONS,
|
|
28
|
+
} from "../../v2Containers/InApp/constants";
|
|
29
|
+
import { INAPP } from "../../v2Containers/CreativesContainer/constants";
|
|
30
|
+
import CapImageUpload from "../CapImageUpload";
|
|
31
|
+
import CapInAppCTA from "../CapInAppCTA";
|
|
32
|
+
import './index.scss';
|
|
33
|
+
|
|
34
|
+
const CapDeviceContent = (props) => {
|
|
35
|
+
const {
|
|
36
|
+
intl,
|
|
37
|
+
location,
|
|
38
|
+
injectedTags,
|
|
39
|
+
selectedOfferDetails,
|
|
40
|
+
panes,
|
|
41
|
+
actions,
|
|
42
|
+
editData,
|
|
43
|
+
isFullMode,
|
|
44
|
+
inAppImageSrc,
|
|
45
|
+
setInAppImageSrc,
|
|
46
|
+
isEditFlow,
|
|
47
|
+
ctaData,
|
|
48
|
+
setCtaData,
|
|
49
|
+
buttonType,
|
|
50
|
+
setButtonType,
|
|
51
|
+
templateMediaType,
|
|
52
|
+
setTemplateMediaType,
|
|
53
|
+
title,
|
|
54
|
+
setTitle,
|
|
55
|
+
templateMessageError,
|
|
56
|
+
templateMessage,
|
|
57
|
+
setTemplateMessage,
|
|
58
|
+
setTemplateMessageError,
|
|
59
|
+
addActionLink,
|
|
60
|
+
setAddActionLink,
|
|
61
|
+
deepLink,
|
|
62
|
+
deepLinkValue,
|
|
63
|
+
setDeepLinkValue,
|
|
64
|
+
onCopyTitleAndContent,
|
|
65
|
+
tags,
|
|
66
|
+
onTagSelect,
|
|
67
|
+
handleOnTagsContextChange,
|
|
68
|
+
} = props || {};
|
|
69
|
+
const { TextArea } = CapInput;
|
|
70
|
+
const { formatMessage } = intl;
|
|
71
|
+
|
|
72
|
+
const isAndroid = panes === ANDROID;
|
|
73
|
+
const isMediaTypeImage = INAPP_MEDIA_TYPES.IMAGE === templateMediaType;
|
|
74
|
+
const isBtnTypeCta = buttonType === INAPP_BUTTON_TYPES.CTA;
|
|
75
|
+
const onTemplateMessageChange = ({ target: { value } }) => {
|
|
76
|
+
let error = '';
|
|
77
|
+
if (value === '') {
|
|
78
|
+
error = formatMessage(messages.emptyTemplateMessageErrorMessage);
|
|
79
|
+
}
|
|
80
|
+
setTemplateMessage(value);
|
|
81
|
+
setTemplateMessageError(error);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const setUpdateInAppImageSrc = useCallback(
|
|
85
|
+
(filePath) => {
|
|
86
|
+
const templateType = 0;
|
|
87
|
+
setInAppImageSrc(filePath);
|
|
88
|
+
actions.clearInAppAsset(templateType);
|
|
89
|
+
},
|
|
90
|
+
[inAppImageSrc]
|
|
91
|
+
);
|
|
92
|
+
const updateOnInAppImageReUpload = useCallback(() => {
|
|
93
|
+
setInAppImageSrc("");
|
|
94
|
+
}, [inAppImageSrc]);
|
|
95
|
+
|
|
96
|
+
const updateHandler = (ctaDataParam, index) => {
|
|
97
|
+
setCtaData((prevState) => {
|
|
98
|
+
const clonedCta = cloneDeep(prevState);
|
|
99
|
+
clonedCta[index] = ctaDataParam;
|
|
100
|
+
return clonedCta;
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// function to delete CTA button
|
|
105
|
+
const deleteHandler = (index) => {
|
|
106
|
+
setCtaData((prevState) => {
|
|
107
|
+
const clonedCta = cloneDeep(prevState);
|
|
108
|
+
const filteredCta = clonedCta.filter((cta) => cta.index !== index);
|
|
109
|
+
if (filteredCta.length === 1) {
|
|
110
|
+
// updates the index of the cta buttons present in case there's a cta button deleted
|
|
111
|
+
filteredCta[0].index = 0;
|
|
112
|
+
}
|
|
113
|
+
if (isEmpty(filteredCta)) {
|
|
114
|
+
onChangeButtonType({target: { value: INAPP_BUTTON_TYPES.NONE } });
|
|
115
|
+
}
|
|
116
|
+
return filteredCta;
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const onTitleChange = ({ target: { value } }) => {
|
|
121
|
+
setTitle(value);
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const onTemplateMediaTypeChange = ({ target: { value } }) => {
|
|
125
|
+
setTemplateMediaType(value);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const onChangeButtonType = ({ target: { value } }) => {
|
|
129
|
+
setButtonType(value);
|
|
130
|
+
setCtaData(INITIAL_CTA_DATA);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const uploadInAppAsset = (file, type, fileParams) => {
|
|
134
|
+
actions.uploadInAppAsset(file, type, fileParams, 0);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const getTagList = (index) => (
|
|
138
|
+
<TagList
|
|
139
|
+
moduleFilterEnabled={
|
|
140
|
+
location && location?.query && location?.query?.type !== "embedded"
|
|
141
|
+
}
|
|
142
|
+
label={formatMessage(messages.addLabel)}
|
|
143
|
+
onTagSelect={(value) => onTagSelect(value, index)}
|
|
144
|
+
onContextChange={handleOnTagsContextChange}
|
|
145
|
+
location={location}
|
|
146
|
+
tags={tags || []}
|
|
147
|
+
injectedTags={injectedTags || {}}
|
|
148
|
+
selectedOfferDetails={selectedOfferDetails}
|
|
149
|
+
/>
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<>
|
|
154
|
+
<CapRow className="creatives-device-content">
|
|
155
|
+
<CapLink
|
|
156
|
+
title={isAndroid
|
|
157
|
+
? formatMessage(messages.copyContentFromIOS)
|
|
158
|
+
: formatMessage(messages.copyCotentFromAndroid)}
|
|
159
|
+
className="inapp-copy-content"
|
|
160
|
+
onClick={onCopyTitleAndContent}
|
|
161
|
+
/>
|
|
162
|
+
<CapRow className="creatives-inapp-title">
|
|
163
|
+
<CapColumn
|
|
164
|
+
className="inapp-content-main"
|
|
165
|
+
>
|
|
166
|
+
<CapHeading type="h5" className="inapp-title">
|
|
167
|
+
{formatMessage(messages.title)}
|
|
168
|
+
</CapHeading>
|
|
169
|
+
{getTagList(0)} {/* here 0 signifies the tags for template title */}
|
|
170
|
+
</CapColumn>
|
|
171
|
+
<CapInput
|
|
172
|
+
id="inapp-title-name-input"
|
|
173
|
+
onChange={onTitleChange}
|
|
174
|
+
placeholder={formatMessage(messages.titlePlaceholder)}
|
|
175
|
+
value={title}
|
|
176
|
+
size="default"
|
|
177
|
+
isRequired
|
|
178
|
+
/>
|
|
179
|
+
</CapRow>
|
|
180
|
+
<CapRow className="creatives-inapp-media">
|
|
181
|
+
<CapRow className="inapp-content-media">
|
|
182
|
+
<CapHeading type="h5" className="inapp-media-header">
|
|
183
|
+
{formatMessage(messages.mediaLabel)}
|
|
184
|
+
</CapHeading>
|
|
185
|
+
<CapRadioGroup
|
|
186
|
+
id="inapp-media-radio"
|
|
187
|
+
options={MEDIA_RADIO_OPTIONS}
|
|
188
|
+
value={templateMediaType}
|
|
189
|
+
onChange={onTemplateMediaTypeChange}
|
|
190
|
+
className="inapp-media-radio"
|
|
191
|
+
/>
|
|
192
|
+
</CapRow>
|
|
193
|
+
</CapRow>
|
|
194
|
+
<CapRow className={`creatives-inapp-message ${!isMediaTypeImage && "message-bottom-margin"}`}>
|
|
195
|
+
<CapColumn
|
|
196
|
+
className="inapp-message-header"
|
|
197
|
+
>
|
|
198
|
+
<CapHeading type="h5" className="inapp-message-header-style">
|
|
199
|
+
{formatMessage(messages.message)}
|
|
200
|
+
</CapHeading>
|
|
201
|
+
{getTagList(1)} {/* here 1 signifies the tags for template message */}
|
|
202
|
+
</CapColumn>
|
|
203
|
+
<TextArea
|
|
204
|
+
id="inapp-create-template-message-input"
|
|
205
|
+
className="inapp-create-template-message-input"
|
|
206
|
+
placeholder={formatMessage(messages.textAreaInputPlaceholder)}
|
|
207
|
+
onChange={onTemplateMessageChange}
|
|
208
|
+
value={templateMessage || ''}
|
|
209
|
+
autosize={{ minRows: 5, maxRows: 5 }}
|
|
210
|
+
errorMessage={templateMessageError && (
|
|
211
|
+
<CapError className="inapp-template-message-error">
|
|
212
|
+
{templateMessageError}
|
|
213
|
+
</CapError>
|
|
214
|
+
)}
|
|
215
|
+
/>
|
|
216
|
+
{isMediaTypeImage && (
|
|
217
|
+
<>
|
|
218
|
+
<CapHeading type="h4" className="cover-img">
|
|
219
|
+
{formatMessage(messages.coverImage)}
|
|
220
|
+
</CapHeading>
|
|
221
|
+
<CapImageUpload
|
|
222
|
+
allowedExtensionsRegex={ALLOWED_IMAGE_EXTENSIONS_REGEX}
|
|
223
|
+
imgSize={INAPP_IMG_SIZE}
|
|
224
|
+
uploadAsset={uploadInAppAsset}
|
|
225
|
+
isFullMode={isFullMode}
|
|
226
|
+
imageSrc={inAppImageSrc}
|
|
227
|
+
updateImageSrc={setUpdateInAppImageSrc}
|
|
228
|
+
updateOnReUpload={updateOnInAppImageReUpload}
|
|
229
|
+
index={0}
|
|
230
|
+
className="cap-custom-image-upload"
|
|
231
|
+
key="inapp-uploaded-image"
|
|
232
|
+
imageData={editData}
|
|
233
|
+
channel={INAPP}
|
|
234
|
+
channelSpecificStyle={!isFullMode}
|
|
235
|
+
/>
|
|
236
|
+
</>
|
|
237
|
+
)}
|
|
238
|
+
</CapRow>
|
|
239
|
+
</CapRow>
|
|
240
|
+
<CapRow className="inapp-action-link">
|
|
241
|
+
<CapCheckbox onChange={() => setAddActionLink(!addActionLink)} checked={addActionLink} />
|
|
242
|
+
<CapRow className="inapp-render-heading">
|
|
243
|
+
<CapHeader
|
|
244
|
+
title={<CapRow type="flex">
|
|
245
|
+
<CapHeading type="h4">
|
|
246
|
+
{formatMessage(messages.addActionLink)}
|
|
247
|
+
</CapHeading>
|
|
248
|
+
</CapRow>}
|
|
249
|
+
description={<CapLabel type="label3">{formatMessage(messages.addActionLinkDesc)}</CapLabel>}
|
|
250
|
+
/>
|
|
251
|
+
{addActionLink && (
|
|
252
|
+
<CapRow className="inapp-action-deep-link">
|
|
253
|
+
<CapHeading type="h4">
|
|
254
|
+
{formatMessage(messages.actionDeepLink)}
|
|
255
|
+
</CapHeading>
|
|
256
|
+
<CapSelect
|
|
257
|
+
id="inapp-add-action-link-type"
|
|
258
|
+
placeholder={formatMessage(messages.deepLinkOptionsPlaceholder)}
|
|
259
|
+
options={deepLink || []}
|
|
260
|
+
value={deepLinkValue}
|
|
261
|
+
onChange={(value) => { setDeepLinkValue(value); }}
|
|
262
|
+
/>
|
|
263
|
+
</CapRow>
|
|
264
|
+
)}
|
|
265
|
+
</CapRow>
|
|
266
|
+
</CapRow>
|
|
267
|
+
<CapRow className="inapp-cta-button">
|
|
268
|
+
<CapHeader
|
|
269
|
+
className="inapp-render-heading-cta-button"
|
|
270
|
+
title={<CapRow type="flex">
|
|
271
|
+
<CapHeading type="h4">
|
|
272
|
+
{formatMessage(messages.btnLabel)}
|
|
273
|
+
</CapHeading>
|
|
274
|
+
<CapHeading
|
|
275
|
+
type="h6"
|
|
276
|
+
className="inapp-optional-label"
|
|
277
|
+
>
|
|
278
|
+
{formatMessage(messages.optional)}
|
|
279
|
+
</CapHeading>
|
|
280
|
+
</CapRow>}
|
|
281
|
+
description={<CapLabel type="label3">{formatMessage(messages.btnDesc)}</CapLabel>}
|
|
282
|
+
/>
|
|
283
|
+
<CapRadioGroup
|
|
284
|
+
options={BUTTON_RADIO_OPTIONS}
|
|
285
|
+
value={buttonType}
|
|
286
|
+
onChange={onChangeButtonType}
|
|
287
|
+
className="inapp-btn-radio-group"
|
|
288
|
+
/>
|
|
289
|
+
{isBtnTypeCta && (
|
|
290
|
+
<CapInAppCTA
|
|
291
|
+
ctaData={ctaData}
|
|
292
|
+
updateHandler={updateHandler}
|
|
293
|
+
deleteHandler={deleteHandler}
|
|
294
|
+
isEditFlow={isEditFlow}
|
|
295
|
+
deepLink={deepLink || []}
|
|
296
|
+
/>
|
|
297
|
+
)}
|
|
298
|
+
</CapRow>
|
|
299
|
+
</>
|
|
300
|
+
);
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
CapDeviceContent.propTypes = {
|
|
304
|
+
intl: intlShape.isRequierd,
|
|
305
|
+
location: PropTypes.string,
|
|
306
|
+
injectedTags: PropTypes.object,
|
|
307
|
+
selectedOfferDetails: PropTypes.array,
|
|
308
|
+
panes: PropTypes.string,
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
export default injectIntl(CapDeviceContent);
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
@import '~@capillarytech/cap-ui-library/styles/_variables.scss';
|
|
2
|
+
|
|
3
|
+
.creatives-device-content {
|
|
4
|
+
.inapp-copy-content {
|
|
5
|
+
margin-top: $CAP_SPACE_08;
|
|
6
|
+
margin-bottom: $CAP_SPACE_16;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.creatives-inapp-title {
|
|
10
|
+
.inapp-content-main {
|
|
11
|
+
display: flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
justify-content: space-between;
|
|
14
|
+
margin-top: $CAP_SPACE_08;
|
|
15
|
+
}
|
|
16
|
+
.inapp-title {
|
|
17
|
+
font-weight: 500;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.creatives-inapp-media {
|
|
22
|
+
.inapp-media-header {
|
|
23
|
+
font-weight: 500;
|
|
24
|
+
}
|
|
25
|
+
.inapp-content-media {
|
|
26
|
+
margin-top: $CAP_SPACE_16;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.inapp-media-radio {
|
|
30
|
+
font-weight: 500;
|
|
31
|
+
margin-top: $CAP_SPACE_16;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
.creatives-inapp-message {
|
|
35
|
+
margin-top : $CAP_SPACE_12;
|
|
36
|
+
.inapp-message-header {
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
justify-content: space-between;
|
|
40
|
+
|
|
41
|
+
.inapp-message-header-style {
|
|
42
|
+
font-weight: 500;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
.inapp-create-template-message-input {
|
|
46
|
+
min-height: 5.214rem;
|
|
47
|
+
margin-bottom: $CAP_SPACE_08;
|
|
48
|
+
}
|
|
49
|
+
.cap-custom-image-upload {
|
|
50
|
+
.dragger-button.re-upload {
|
|
51
|
+
top: 12rem;
|
|
52
|
+
position: absolute;
|
|
53
|
+
right: $CAP_SPACE_20;
|
|
54
|
+
color: $FONT_COLOR_05;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
.message-bottom-margin{
|
|
59
|
+
margin-bottom: 0.857rem;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.inapp-action-link {
|
|
64
|
+
display: flex;
|
|
65
|
+
margin-top: 2rem;
|
|
66
|
+
|
|
67
|
+
.inapp-render-heading {
|
|
68
|
+
width: 100%;
|
|
69
|
+
|
|
70
|
+
.inapp-action-deep-link {
|
|
71
|
+
margin-top: $CAP_SPACE_12;
|
|
72
|
+
|
|
73
|
+
#inapp-add-action-link-type {
|
|
74
|
+
width: 100%;
|
|
75
|
+
margin-top: $CAP_SPACE_12;
|
|
76
|
+
}
|
|
77
|
+
.cap-select-v2 {
|
|
78
|
+
.ant-select-selection__placeholder {
|
|
79
|
+
display: block;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
.inapp-cta-button {
|
|
86
|
+
margin-top: 2rem;
|
|
87
|
+
|
|
88
|
+
.inapp-render-heading-cta-button {
|
|
89
|
+
.inapp-optional-label {
|
|
90
|
+
font-size: $CAP_SPACE_12;
|
|
91
|
+
color: $CAP_G06;
|
|
92
|
+
margin-left: $CAP_SPACE_04;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
.inapp-btn-radio-group{
|
|
96
|
+
display: grid;
|
|
97
|
+
}
|
|
98
|
+
.inapp-button-none {
|
|
99
|
+
display: inline-grid;
|
|
100
|
+
margin-top: $CAP_SPACE_16;
|
|
101
|
+
}
|
|
102
|
+
.inapp-button-cta {
|
|
103
|
+
display: inline-grid;
|
|
104
|
+
margin-top: $CAP_SPACE_24;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
.inapp-template-message-error {
|
|
108
|
+
margin-bottom: 1rem;
|
|
109
|
+
}
|
|
110
|
+
.image-container {
|
|
111
|
+
margin-top: 1.5rem;
|
|
112
|
+
}
|
|
113
|
+
.cover-img {
|
|
114
|
+
margin-top: 2rem;
|
|
115
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { defineMessages } from "react-intl";
|
|
2
|
+
|
|
3
|
+
const prefix = "app.v2Components.CapDeviceContent";
|
|
4
|
+
|
|
5
|
+
export default defineMessages({
|
|
6
|
+
copyContentFromIOS: {
|
|
7
|
+
id: `${prefix}.copyContentFromIOS`,
|
|
8
|
+
defaultMessage: "Copy title and content from iOS",
|
|
9
|
+
},
|
|
10
|
+
copyCotentFromAndroid: {
|
|
11
|
+
id: `${prefix}.copyContentFromAndriod`,
|
|
12
|
+
defaultMessage: "Copy title and content from Android",
|
|
13
|
+
},
|
|
14
|
+
title: {
|
|
15
|
+
id: `${prefix}.title`,
|
|
16
|
+
defaultMessage: "Title",
|
|
17
|
+
},
|
|
18
|
+
addLabel: {
|
|
19
|
+
id: `${prefix}.addLabel`,
|
|
20
|
+
defaultMessage: "Add labels",
|
|
21
|
+
},
|
|
22
|
+
titlePlaceholder: {
|
|
23
|
+
id: `${prefix}.titlePlaceholder`,
|
|
24
|
+
defaultMessage: "Please input message title name",
|
|
25
|
+
},
|
|
26
|
+
message: {
|
|
27
|
+
id: `${prefix}.message`,
|
|
28
|
+
defaultMessage: "Message",
|
|
29
|
+
},
|
|
30
|
+
textAreaInputPlaceholder: {
|
|
31
|
+
id: `${prefix}.textAreaInputPlaceholder`,
|
|
32
|
+
defaultMessage: "Please input in-app notification message content",
|
|
33
|
+
},
|
|
34
|
+
addActionLink: {
|
|
35
|
+
id: `${prefix}.addActionLink`,
|
|
36
|
+
defaultMessage: 'Add action link to content',
|
|
37
|
+
},
|
|
38
|
+
addActionLinkDesc: {
|
|
39
|
+
id: `${prefix}.addActionLinkDesc`,
|
|
40
|
+
defaultMessage: 'Add a deep link of the page which customer will be directed to',
|
|
41
|
+
},
|
|
42
|
+
select: {
|
|
43
|
+
id: `${prefix}.select`,
|
|
44
|
+
defaultMessage: "Select",
|
|
45
|
+
},
|
|
46
|
+
mediaLabel: {
|
|
47
|
+
id: `${prefix}.mediaLabel`,
|
|
48
|
+
defaultMessage: "Media",
|
|
49
|
+
},
|
|
50
|
+
mediaText: {
|
|
51
|
+
id: `${prefix}.mediaText`,
|
|
52
|
+
defaultMessage: "Text",
|
|
53
|
+
},
|
|
54
|
+
mediaImage: {
|
|
55
|
+
id: `${prefix}.mediaImage`,
|
|
56
|
+
defaultMessage: "Image",
|
|
57
|
+
},
|
|
58
|
+
emptyTemplateMessageErrorMessage: {
|
|
59
|
+
id: `${prefix}.emptyTemplateMessageErrorMessage`,
|
|
60
|
+
defaultMessage: "Template message cannot be empty",
|
|
61
|
+
},
|
|
62
|
+
templateMessageLabel: {
|
|
63
|
+
id: `${prefix}.templateMessageLabel`,
|
|
64
|
+
defaultMessage: 'Message',
|
|
65
|
+
},
|
|
66
|
+
btnDisabledTooltip: {
|
|
67
|
+
id: `${prefix}.btnDisabledTooltip`,
|
|
68
|
+
defaultMessage: 'Please add all mandatory fields to proceed further',
|
|
69
|
+
},
|
|
70
|
+
btnLabel: {
|
|
71
|
+
id: `${prefix}.btnLabel`,
|
|
72
|
+
defaultMessage: 'Buttons',
|
|
73
|
+
},
|
|
74
|
+
btnDesc: {
|
|
75
|
+
id: `${prefix}.btnDesc`,
|
|
76
|
+
defaultMessage: 'These will be show clickable buttons below your message.',
|
|
77
|
+
},
|
|
78
|
+
optional: {
|
|
79
|
+
id: `${prefix}.optional`,
|
|
80
|
+
defaultMessage: '(Optional)',
|
|
81
|
+
},
|
|
82
|
+
actionDeepLink: {
|
|
83
|
+
id: `${prefix}.actionDeepLink`,
|
|
84
|
+
defaultMessage: 'Deep Link',
|
|
85
|
+
},
|
|
86
|
+
deepLinkOptionsPlaceholder: {
|
|
87
|
+
id: `${prefix}.deepLinkOptionsPlaceholder`,
|
|
88
|
+
defaultMessage: 'Select deep link',
|
|
89
|
+
},
|
|
90
|
+
coverImage: {
|
|
91
|
+
id: `${prefix}.coverImage`,
|
|
92
|
+
defaultMessage: 'Cover image',
|
|
93
|
+
},
|
|
94
|
+
});
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { injectIntl } from 'react-intl';
|
|
3
|
+
import { browserHistory } from 'react-router';
|
|
4
|
+
import '@testing-library/jest-dom';
|
|
5
|
+
import { Provider } from 'react-redux';
|
|
6
|
+
import configureStore from '../../../store';
|
|
7
|
+
import CapDeviceContent from '../index';
|
|
8
|
+
import { render, screen, fireEvent } from '../../../utils/test-utils';
|
|
9
|
+
import { deviceContentProps } from '../../../v2Containers/InApp/tests/mockData';
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
let store;
|
|
13
|
+
beforeAll(() => {
|
|
14
|
+
store = configureStore({}, browserHistory);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const ComponentToRender = injectIntl(CapDeviceContent);
|
|
18
|
+
const renderComponent = (props) =>
|
|
19
|
+
render(
|
|
20
|
+
<Provider store={store}>
|
|
21
|
+
<ComponentToRender {...props} />
|
|
22
|
+
</Provider>,
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
describe('Test CapDeviceContent', () => {
|
|
26
|
+
it('test case for CapDeviceContent component Android pane', async () => {
|
|
27
|
+
renderComponent(deviceContentProps);
|
|
28
|
+
const msgBox = screen.getAllByPlaceholderText(/Please input in-app notification message content/i);
|
|
29
|
+
fireEvent.change(msgBox[0], 'val');
|
|
30
|
+
const copyLink = screen.getByRole('link', {
|
|
31
|
+
name: /copy title and content from ios/i,
|
|
32
|
+
});
|
|
33
|
+
fireEvent.click(copyLink);
|
|
34
|
+
expect(copyLink).toBeInTheDocument();
|
|
35
|
+
});
|
|
36
|
+
it("test case for CapDeviceContent component Ios pane", () => {
|
|
37
|
+
renderComponent({
|
|
38
|
+
...deviceContentProps,
|
|
39
|
+
panes: "iOS",
|
|
40
|
+
buttonType: "CTA",
|
|
41
|
+
setTemplateMediaType: jest.fn(),
|
|
42
|
+
setButtonType: jest.fn(),
|
|
43
|
+
setCtaData: jest.fn(),
|
|
44
|
+
setTemplateMessage: jest.fn(),
|
|
45
|
+
setTemplateMessageError: jest.fn(),
|
|
46
|
+
setTitle: jest.fn(),
|
|
47
|
+
templateMediType: "IMAGE",
|
|
48
|
+
addActionLink: true,
|
|
49
|
+
ctaData: [
|
|
50
|
+
{
|
|
51
|
+
index: 0,
|
|
52
|
+
ctaType: "WEBSITE",
|
|
53
|
+
text: "test",
|
|
54
|
+
urlType: "DEEP_LINK",
|
|
55
|
+
url: "link",
|
|
56
|
+
isSaved: true,
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
deepLink: [
|
|
60
|
+
{
|
|
61
|
+
label: "Test_1",
|
|
62
|
+
value: "link",
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
});
|
|
66
|
+
const msgBox = screen.getAllByPlaceholderText(
|
|
67
|
+
/Please input in-app notification message content/i
|
|
68
|
+
);
|
|
69
|
+
msgBox[0].focus();
|
|
70
|
+
fireEvent.change(msgBox[0], { target: { value: "val" } });
|
|
71
|
+
fireEvent.change(msgBox[0], { target: { value: "" } });
|
|
72
|
+
const titleBox = screen.getAllByPlaceholderText(
|
|
73
|
+
/Please input message title name/i
|
|
74
|
+
);
|
|
75
|
+
titleBox[0].focus();
|
|
76
|
+
fireEvent.change(titleBox[0], { target: { value: "val" } });
|
|
77
|
+
const img = screen.getByText(/image/i);
|
|
78
|
+
fireEvent.click(img);
|
|
79
|
+
const none = screen.getByText(/None/i);
|
|
80
|
+
fireEvent.click(none);
|
|
81
|
+
const editIcon = screen.getByText(/Test_1/i).nextSibling.firstChild;
|
|
82
|
+
fireEvent.click(editIcon);
|
|
83
|
+
expect(screen.getByText(/Test_1/i)).toBeInTheDocument();
|
|
84
|
+
});
|
|
85
|
+
});
|