@capillarytech/creatives-library 6.9.2 → 6.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/TemplatePreview/_templatePreview.scss +6 -0
- package/components/TemplatePreview/index.js +35 -28
- package/config/app.js +1 -1
- package/index.html +0 -2
- package/package.json +1 -1
- package/v2Components/Carousel/index.js +120 -0
- package/v2Components/Carousel/style.scss +40 -0
- package/v2Components/TemplatePreview/_templatePreview.scss +1 -0
- package/v2Components/TemplatePreview/index.js +36 -29
- package/v2Containers/CreativesContainer/SlideBoxContent.js +7 -1
- package/v2Containers/Line/Container/Image/index.js +21 -19
- package/v2Containers/Line/Container/ImageCarousel/Content.js +554 -0
- package/v2Containers/Line/Container/ImageCarousel/constants.js +10 -0
- package/v2Containers/Line/Container/ImageCarousel/index.js +526 -0
- package/v2Containers/Line/Container/ImageCarousel/messages.js +178 -0
- package/v2Containers/Line/Container/ImageCarousel/style.js +61 -0
- package/v2Containers/Line/Container/ImageMap/constants.js +2 -1
- package/v2Containers/Line/Container/ImageMap/index.js +31 -6
- package/v2Containers/Line/Container/ImageMap/messages.js +12 -0
- package/v2Containers/Line/Container/Wrapper/index.js +5 -1
- package/v2Containers/Line/Container/Wrapper/messages.js +4 -0
- package/v2Containers/Line/Container/Wrapper/utils.js +15 -16
- package/v2Containers/Line/Container/_lineCreate.scss +2 -2
- package/v2Containers/Line/Container/actions.js +4 -2
- package/v2Containers/Line/Container/constants.js +3 -0
- package/v2Containers/Line/Container/index.js +49 -11
- package/v2Containers/Line/Container/reducer.js +2 -2
- package/v2Containers/Line/Container/sagas.js +2 -2
- package/v2Containers/Line/Container/style.js +2 -1
- package/v2Containers/Templates/_templates.scss +9 -0
- package/v2Containers/Templates/index.js +28 -1
- package/v2Containers/Templates/messages.js +4 -0
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
|
+
import { injectIntl, FormattedMessage } from 'react-intl';
|
|
3
|
+
import get from 'lodash/get';
|
|
4
|
+
import CapInput from '@capillarytech/cap-ui-library/CapInput';
|
|
5
|
+
import CapTab from '@capillarytech/cap-ui-library/CapTab';
|
|
6
|
+
import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
|
|
7
|
+
import CapButton from '@capillarytech/cap-ui-library/CapButton';
|
|
8
|
+
import CapIcon from '@capillarytech/cap-ui-library/CapIcon';
|
|
9
|
+
import CapDrawer from '@capillarytech/cap-ui-library/CapDrawer';
|
|
10
|
+
import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
|
|
11
|
+
import CapTooltip from '@capillarytech/cap-ui-library/CapTooltip';
|
|
12
|
+
import CapTooltipWithInfo from '@capillarytech/cap-ui-library/CapTooltipWithInfo';
|
|
13
|
+
import LineDrawer from '../Drawer';
|
|
14
|
+
import style from './style';
|
|
15
|
+
import { CAP_G06, FONT_COLOR_01, FONT_COLOR_02, CAP_SPACE_08, CAP_WHITE } from '@capillarytech/cap-ui-library/styled/variables';
|
|
16
|
+
import withStyles from '../../../../hoc/withStyles';
|
|
17
|
+
|
|
18
|
+
import LineImageCarouselContent from './Content';
|
|
19
|
+
|
|
20
|
+
import messages from './messages';
|
|
21
|
+
import {
|
|
22
|
+
MAX_CAROUSEL_ALLOWED,
|
|
23
|
+
TEXT_ACTION_TYPE,
|
|
24
|
+
MESSAGE_ACTION_TYPE,
|
|
25
|
+
URL_ACTION_TYPE,
|
|
26
|
+
MAX_ALLOWED_TITLE_LENGTH,
|
|
27
|
+
} from './constants';
|
|
28
|
+
|
|
29
|
+
export const LineImageCarousel = (props) => {
|
|
30
|
+
|
|
31
|
+
const {
|
|
32
|
+
className,
|
|
33
|
+
id,
|
|
34
|
+
intl: { formatMessage },
|
|
35
|
+
isFullMode,
|
|
36
|
+
inheritedTitleStyle,
|
|
37
|
+
Line,
|
|
38
|
+
index,
|
|
39
|
+
updateMessageState,
|
|
40
|
+
content,
|
|
41
|
+
activeKey,
|
|
42
|
+
Templates,
|
|
43
|
+
getAllTemplates,
|
|
44
|
+
} = props;
|
|
45
|
+
|
|
46
|
+
if (activeKey !== 'template') {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const defaultActiveIndex = 0;
|
|
51
|
+
|
|
52
|
+
const defaultCarouselContent = {
|
|
53
|
+
messageTitle: '',
|
|
54
|
+
originalContentUrl: '',
|
|
55
|
+
previewImageUrl: '',
|
|
56
|
+
type: 'image_carousel',
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const [carouselImages, updateCarouselImage] = useState([defaultCarouselContent]);
|
|
60
|
+
const [activeIndex, updateActiveIndex] = useState(`${defaultActiveIndex}`);
|
|
61
|
+
const [errorMessageTitle, updateErrorMessageTitle] = useState(false);
|
|
62
|
+
const [messageTitle, updateTextMessageTitle] = useState('');
|
|
63
|
+
const [isTemplateDrawerRequired, updateTemplateDrawerRequirement] = useState(false);
|
|
64
|
+
const [isCreateNew, updateCreateNew] = useState(isFullMode);
|
|
65
|
+
const [selectedTemplate, updateSelectedTemplate] = useState();
|
|
66
|
+
const [altText, updateTitle] = useState('');
|
|
67
|
+
const [errorTitle, updateErrorTitle] = useState(false);
|
|
68
|
+
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
const { messageTitle = '', type, template, altText } = content;
|
|
71
|
+
if (type === 'template') {
|
|
72
|
+
updateCreateNew(!isFullMode ? !!template : true);
|
|
73
|
+
if (messageTitle) {
|
|
74
|
+
updateTextMessageTitle(messageTitle);
|
|
75
|
+
}
|
|
76
|
+
if (altText) {
|
|
77
|
+
updateTitle(altText);
|
|
78
|
+
}
|
|
79
|
+
if (template) {
|
|
80
|
+
const { columns } = template;
|
|
81
|
+
if (columns && columns.length) {
|
|
82
|
+
const validCarouselImages = [];
|
|
83
|
+
columns.forEach((column = {}, index) => {
|
|
84
|
+
const {
|
|
85
|
+
action: {
|
|
86
|
+
label,
|
|
87
|
+
text,
|
|
88
|
+
type,
|
|
89
|
+
uri,
|
|
90
|
+
} = {},
|
|
91
|
+
imageUrl,
|
|
92
|
+
} = column;
|
|
93
|
+
|
|
94
|
+
validCarouselImages.push({
|
|
95
|
+
activeIndex: index,
|
|
96
|
+
originalContentUrl: imageUrl,
|
|
97
|
+
selectedActionType: type ? (type === MESSAGE_ACTION_TYPE ? TEXT_ACTION_TYPE : URL_ACTION_TYPE) : '',
|
|
98
|
+
actionContent: text || uri,
|
|
99
|
+
actionLabel: label,
|
|
100
|
+
type: 'image_carousel',
|
|
101
|
+
});
|
|
102
|
+
})
|
|
103
|
+
updateCarouselImage(validCarouselImages);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}, [content]);
|
|
108
|
+
|
|
109
|
+
const getFormattedCarouselMessagePayload = (newCarouselImages, inheritedMessageTitle, inheritedTitle) => {
|
|
110
|
+
const existingMessageTitle = inheritedMessageTitle !== undefined ? inheritedMessageTitle : messageTitle;
|
|
111
|
+
const existingTitle = inheritedTitle !== undefined ? inheritedTitle : altText;
|
|
112
|
+
let isErrorIndex;
|
|
113
|
+
const columns = [];
|
|
114
|
+
(newCarouselImages || carouselImages).forEach(({
|
|
115
|
+
originalContentUrl,
|
|
116
|
+
selectedActionType,
|
|
117
|
+
actionLabel,
|
|
118
|
+
actionContent,
|
|
119
|
+
actionContentErrorMessage,
|
|
120
|
+
actionLabelErrorMessage,
|
|
121
|
+
activeIndex,
|
|
122
|
+
}) => {
|
|
123
|
+
isErrorIndex = (isErrorIndex !== undefined)
|
|
124
|
+
? isErrorIndex
|
|
125
|
+
: ((!originalContentUrl || !selectedActionType || actionContentErrorMessage || actionLabelErrorMessage) && activeIndex);
|
|
126
|
+
columns.push({
|
|
127
|
+
imageUrl: originalContentUrl,
|
|
128
|
+
action: {
|
|
129
|
+
type: selectedActionType ? (selectedActionType === TEXT_ACTION_TYPE ? MESSAGE_ACTION_TYPE : URL_ACTION_TYPE) : '',
|
|
130
|
+
label: actionLabel,
|
|
131
|
+
[selectedActionType]: actionContent
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const payload = {
|
|
137
|
+
isError: isErrorIndex !== undefined && isErrorIndex !== false,
|
|
138
|
+
messageTitle: existingMessageTitle,
|
|
139
|
+
altText: existingTitle,
|
|
140
|
+
type: 'template',
|
|
141
|
+
index,
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (columns.length) {
|
|
145
|
+
payload.template = {
|
|
146
|
+
columns,
|
|
147
|
+
type: 'image_carousel',
|
|
148
|
+
};
|
|
149
|
+
} else {
|
|
150
|
+
payload.isError = true;
|
|
151
|
+
}
|
|
152
|
+
payload.isError = payload.isError || (isFullMode ? !existingMessageTitle : false) || !existingTitle;
|
|
153
|
+
updateMessageState(payload);
|
|
154
|
+
return payload;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const updateCarouselMessageState = (config) => {
|
|
158
|
+
const newCarouselImages = [...carouselImages];
|
|
159
|
+
newCarouselImages.splice(config.activeIndex, 1, config);
|
|
160
|
+
updateCarouselImage(newCarouselImages);
|
|
161
|
+
getFormattedCarouselMessagePayload(newCarouselImages);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const addContent = () => {
|
|
165
|
+
const newCarouselImages = [
|
|
166
|
+
...carouselImages,
|
|
167
|
+
{
|
|
168
|
+
...defaultCarouselContent,
|
|
169
|
+
activeIndex: carouselImages.length,
|
|
170
|
+
},
|
|
171
|
+
]
|
|
172
|
+
updateCarouselImage(newCarouselImages);
|
|
173
|
+
getFormattedCarouselMessagePayload(newCarouselImages);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const duplicateContent = () => {
|
|
177
|
+
const contentToDuplicate = {
|
|
178
|
+
...carouselImages[activeIndex],
|
|
179
|
+
activeIndex: carouselImages.length,
|
|
180
|
+
};
|
|
181
|
+
const newCarouselImages = [
|
|
182
|
+
...carouselImages,
|
|
183
|
+
contentToDuplicate,
|
|
184
|
+
];
|
|
185
|
+
updateCarouselImage(newCarouselImages);
|
|
186
|
+
getFormattedCarouselMessagePayload(newCarouselImages);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const shiftRightContent = () => {
|
|
190
|
+
const newActiveIndex = Number(activeIndex) + 1;
|
|
191
|
+
updateActiveIndex(`${newActiveIndex}`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const shiftLeftContent = () => {
|
|
195
|
+
const newActiveIndex = Number(activeIndex) - 1;
|
|
196
|
+
updateActiveIndex(`${newActiveIndex}`);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const deleteContent = () => {
|
|
200
|
+
const newCarouselImages = [...carouselImages];
|
|
201
|
+
newCarouselImages.splice(activeIndex, 1);
|
|
202
|
+
updateCarouselImage(newCarouselImages);
|
|
203
|
+
getFormattedCarouselMessagePayload(newCarouselImages);
|
|
204
|
+
|
|
205
|
+
const parsedActiveIndex = Number(activeIndex);
|
|
206
|
+
const newActiveIndex = parsedActiveIndex === 0 ? parsedActiveIndex : parsedActiveIndex - 1;
|
|
207
|
+
updateActiveIndex(`${newActiveIndex}`);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const onTabChange = (index) => {
|
|
211
|
+
updateActiveIndex(index);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const operations = (
|
|
215
|
+
<>
|
|
216
|
+
<CapButton
|
|
217
|
+
onClick={addContent}
|
|
218
|
+
type="flat"
|
|
219
|
+
disabled={MAX_CAROUSEL_ALLOWED === carouselImages.length}
|
|
220
|
+
isAddBtn
|
|
221
|
+
style={{ padding: 0, marginTop: 12 }}
|
|
222
|
+
>
|
|
223
|
+
<FormattedMessage {...messages.addCard} />
|
|
224
|
+
</CapButton>
|
|
225
|
+
<div
|
|
226
|
+
style={{
|
|
227
|
+
position: 'absolute',
|
|
228
|
+
top: 54,
|
|
229
|
+
right: 0,
|
|
230
|
+
}}
|
|
231
|
+
className="extra-button-group"
|
|
232
|
+
>
|
|
233
|
+
<CapTooltip
|
|
234
|
+
title={<FormattedMessage {...messages.duplicateTooltipLabel} />}
|
|
235
|
+
>
|
|
236
|
+
<CapButton
|
|
237
|
+
onClick={duplicateContent}
|
|
238
|
+
disabled={MAX_CAROUSEL_ALLOWED === carouselImages.length}
|
|
239
|
+
type="flat"
|
|
240
|
+
>
|
|
241
|
+
<CapIcon type="copy" size="s" />
|
|
242
|
+
</CapButton>
|
|
243
|
+
</CapTooltip>
|
|
244
|
+
<CapTooltip
|
|
245
|
+
title={<FormattedMessage {...messages.shiftLeftTooltipLabel} />}
|
|
246
|
+
>
|
|
247
|
+
<CapButton
|
|
248
|
+
onClick={shiftLeftContent}
|
|
249
|
+
disabled={defaultActiveIndex === Number(activeIndex)}
|
|
250
|
+
type="flat"
|
|
251
|
+
>
|
|
252
|
+
<CapIcon type="left" size="s" />
|
|
253
|
+
</CapButton>
|
|
254
|
+
</CapTooltip>
|
|
255
|
+
<CapTooltip
|
|
256
|
+
title={<FormattedMessage {...messages.shiftRightTooltipLabel} />}
|
|
257
|
+
>
|
|
258
|
+
<CapButton
|
|
259
|
+
onClick={shiftRightContent}
|
|
260
|
+
disabled={carouselImages.length === (Number(activeIndex) + 1)}
|
|
261
|
+
type="flat"
|
|
262
|
+
>
|
|
263
|
+
<CapIcon type="right" size="s" />
|
|
264
|
+
</CapButton>
|
|
265
|
+
</CapTooltip>
|
|
266
|
+
<CapTooltip
|
|
267
|
+
title={<FormattedMessage {...messages.deleteTooltipLabel} />}
|
|
268
|
+
>
|
|
269
|
+
<CapButton
|
|
270
|
+
onClick={deleteContent}
|
|
271
|
+
disabled={1 === carouselImages.length}
|
|
272
|
+
type="flat"
|
|
273
|
+
>
|
|
274
|
+
<CapIcon type="delete" size="s" />
|
|
275
|
+
</CapButton>
|
|
276
|
+
</CapTooltip>
|
|
277
|
+
</div>
|
|
278
|
+
</>
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
const getTabPanes = () => {
|
|
282
|
+
return carouselImages.map((carouselImage, index) => {
|
|
283
|
+
const isSelected = Number(activeIndex) === index;
|
|
284
|
+
return {
|
|
285
|
+
key: index,
|
|
286
|
+
tab: (
|
|
287
|
+
<span
|
|
288
|
+
style={{
|
|
289
|
+
display: 'inline-block',
|
|
290
|
+
borderRadius: '50%',
|
|
291
|
+
color: CAP_WHITE,
|
|
292
|
+
backgroundColor: !isSelected ? FONT_COLOR_02 : FONT_COLOR_01,
|
|
293
|
+
padding: '5px 10px',
|
|
294
|
+
}}
|
|
295
|
+
>
|
|
296
|
+
{index + 1}
|
|
297
|
+
</span>
|
|
298
|
+
),
|
|
299
|
+
content: (
|
|
300
|
+
<LineImageCarouselContent
|
|
301
|
+
{...props}
|
|
302
|
+
content={carouselImage}
|
|
303
|
+
activeIndex={index}
|
|
304
|
+
updateCarouselMessageState={updateCarouselMessageState}
|
|
305
|
+
/>
|
|
306
|
+
),
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
const onTextTitleChange = ({ target: { value } }) => {
|
|
312
|
+
updateTextMessageTitle(value);
|
|
313
|
+
let errorMessage = false;
|
|
314
|
+
if (value === '') {
|
|
315
|
+
errorMessage = formatMessage(messages.emptyTitleErrorMessage);
|
|
316
|
+
}
|
|
317
|
+
getFormattedCarouselMessagePayload(carouselImages, value);
|
|
318
|
+
updateErrorMessageTitle(errorMessage);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const onTitleChange = ({ target: { value } }) => {
|
|
322
|
+
updateTitle(value);
|
|
323
|
+
let errorMessage;
|
|
324
|
+
if (value === '') {
|
|
325
|
+
errorMessage = formatMessage(messages.emptyAltTextErrorMessage);
|
|
326
|
+
}
|
|
327
|
+
updateErrorTitle(errorMessage);
|
|
328
|
+
getFormattedCarouselMessagePayload(carouselImages, undefined, value);
|
|
329
|
+
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const getLineImageDrawerContent = () => {
|
|
333
|
+
const lineTextTemplates = Templates.templates;
|
|
334
|
+
if (!lineTextTemplates) {
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const cardDataList = [];
|
|
339
|
+
lineTextTemplates.forEach(template => {
|
|
340
|
+
let templateData = {};
|
|
341
|
+
const {
|
|
342
|
+
content: {
|
|
343
|
+
messages: [{
|
|
344
|
+
template: imageCarouselTemplate,
|
|
345
|
+
}] = [{}],
|
|
346
|
+
} = {},
|
|
347
|
+
} = template.versions.base;
|
|
348
|
+
templateData.url = (imageCarouselTemplate ? get(imageCarouselTemplate, 'columns.0.imageUrl', '') : '');
|
|
349
|
+
templateData.title = template.name;
|
|
350
|
+
templateData.key = template.name;
|
|
351
|
+
templateData.hoverOption = (
|
|
352
|
+
<CapButton onClick={() => onTemplateSelection(template)}>
|
|
353
|
+
<FormattedMessage {...messages.select} />
|
|
354
|
+
</CapButton>
|
|
355
|
+
);
|
|
356
|
+
if (imageCarouselTemplate) {
|
|
357
|
+
cardDataList.push(templateData);
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
return (
|
|
361
|
+
<>
|
|
362
|
+
<CapHeading type="h3" className="drawer-head">
|
|
363
|
+
{formatMessage(messages.lineTemplateImage)}
|
|
364
|
+
</CapHeading>
|
|
365
|
+
<LineDrawer
|
|
366
|
+
getAllTemplates={getAllTemplates}
|
|
367
|
+
cardDataList={cardDataList}
|
|
368
|
+
isDrawer={isTemplateDrawerRequired}
|
|
369
|
+
Templates={Templates}
|
|
370
|
+
searchPlaceholder={formatMessage(messages.searchImages)}
|
|
371
|
+
/>
|
|
372
|
+
</>
|
|
373
|
+
);
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
const onSelectTemplate = (event) => {
|
|
377
|
+
event.stopPropagation();
|
|
378
|
+
updateTemplateDrawerRequirement(true);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const onTemplateSelection = (templateData) => {
|
|
382
|
+
const template = get(templateData, 'versions.base.content.messages[0].template', {});
|
|
383
|
+
const altText = get(templateData, 'versions.base.content.messages[0].altText', '');
|
|
384
|
+
const { columns } = template;
|
|
385
|
+
if (columns && columns.length) {
|
|
386
|
+
const validCarouselImages = [];
|
|
387
|
+
columns.forEach((column = {}, index) => {
|
|
388
|
+
const {
|
|
389
|
+
action: {
|
|
390
|
+
label,
|
|
391
|
+
text,
|
|
392
|
+
type,
|
|
393
|
+
uri,
|
|
394
|
+
} = {},
|
|
395
|
+
imageUrl,
|
|
396
|
+
} = column;
|
|
397
|
+
|
|
398
|
+
validCarouselImages.push({
|
|
399
|
+
activeIndex: index,
|
|
400
|
+
originalContentUrl: imageUrl,
|
|
401
|
+
selectedActionType: type ? (type === MESSAGE_ACTION_TYPE ? TEXT_ACTION_TYPE : URL_ACTION_TYPE) : '',
|
|
402
|
+
actionContent: text || uri,
|
|
403
|
+
actionLabel: label,
|
|
404
|
+
type: 'image_carousel',
|
|
405
|
+
});
|
|
406
|
+
})
|
|
407
|
+
updateCarouselImage(validCarouselImages);
|
|
408
|
+
}
|
|
409
|
+
updateSelectedTemplate(template);
|
|
410
|
+
updateTitle(altText);
|
|
411
|
+
updateTemplateDrawerRequirement(false);
|
|
412
|
+
updateCreateNew(true);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const setNewContent = () => updateCreateNew(true);
|
|
416
|
+
|
|
417
|
+
const getTemplateSection = () => {
|
|
418
|
+
if (!isCreateNew) {
|
|
419
|
+
return (
|
|
420
|
+
<div className="form-builder-dragger" style={{
|
|
421
|
+
textAlign: 'center',
|
|
422
|
+
border: `1px dashed ${CAP_G06}`,
|
|
423
|
+
minHeight: 120,
|
|
424
|
+
padding: 60
|
|
425
|
+
}}>
|
|
426
|
+
<CapHeader
|
|
427
|
+
className="choice-title"
|
|
428
|
+
size="regular"
|
|
429
|
+
title={formatMessage(messages.textMessageAddLabel)}
|
|
430
|
+
style={{ marginBottom: 12 }}
|
|
431
|
+
/>
|
|
432
|
+
|
|
433
|
+
<CapButton
|
|
434
|
+
className="dragger-button create-button"
|
|
435
|
+
type="secondary"
|
|
436
|
+
style={{ marginRight: CAP_SPACE_08 }}
|
|
437
|
+
onClick={setNewContent}
|
|
438
|
+
isAddBtn
|
|
439
|
+
>
|
|
440
|
+
<FormattedMessage {...messages.textMessageCreateNew} />
|
|
441
|
+
</CapButton>
|
|
442
|
+
|
|
443
|
+
<CapHeading className="dragger-or" type="label6" style={{ display: 'inline-block' }}>
|
|
444
|
+
<FormattedMessage {...messages.textMessageORLabel} />
|
|
445
|
+
</CapHeading>
|
|
446
|
+
|
|
447
|
+
<CapButton
|
|
448
|
+
className="dragger-button select-template-button"
|
|
449
|
+
type="secondary"
|
|
450
|
+
style={{ marginLeft: CAP_SPACE_08 }}
|
|
451
|
+
onClick={onSelectTemplate}
|
|
452
|
+
>
|
|
453
|
+
<FormattedMessage {...messages.textMessageSelectTemplate} />
|
|
454
|
+
</CapButton>
|
|
455
|
+
</div>
|
|
456
|
+
)
|
|
457
|
+
} else {
|
|
458
|
+
return (
|
|
459
|
+
<>
|
|
460
|
+
<CapInput.TextArea
|
|
461
|
+
maxLength={MAX_ALLOWED_TITLE_LENGTH}
|
|
462
|
+
label={<FormattedMessage {...messages.titleLabel} />}
|
|
463
|
+
inductiveText={<FormattedMessage {...messages.titleDescription} />}
|
|
464
|
+
onChange={onTitleChange}
|
|
465
|
+
value={altText}
|
|
466
|
+
errorMessage={errorTitle}
|
|
467
|
+
className="title-textarea"
|
|
468
|
+
/>
|
|
469
|
+
<CapTab
|
|
470
|
+
defaultActiveKey={`${defaultActiveIndex}`}
|
|
471
|
+
activeKey={activeIndex}
|
|
472
|
+
tabBarExtraContent={operations}
|
|
473
|
+
onChange={onTabChange}
|
|
474
|
+
panes={getTabPanes()}
|
|
475
|
+
/>
|
|
476
|
+
</>
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
return (
|
|
482
|
+
<div className={className}>
|
|
483
|
+
<CapHeader
|
|
484
|
+
title={(
|
|
485
|
+
<>
|
|
486
|
+
<span style={{ paddingRight: 6 }}>
|
|
487
|
+
{formatMessage(messages.cardMessageTitle)}
|
|
488
|
+
</span>
|
|
489
|
+
<CapTooltipWithInfo title={formatMessage(messages.cardMessageInfo)} />
|
|
490
|
+
</>
|
|
491
|
+
)}
|
|
492
|
+
size="regular"
|
|
493
|
+
description={formatMessage(messages.cardMessageDescription)}
|
|
494
|
+
className="card-message-header"
|
|
495
|
+
/>
|
|
496
|
+
{
|
|
497
|
+
isFullMode
|
|
498
|
+
? (
|
|
499
|
+
<CapInput
|
|
500
|
+
id={`${id}_input`}
|
|
501
|
+
onChange={onTextTitleChange}
|
|
502
|
+
errorMessage={errorMessageTitle}
|
|
503
|
+
className="image-template-title"
|
|
504
|
+
style={inheritedTitleStyle || {}}
|
|
505
|
+
placeholder={formatMessage(messages.textMessageTitlePlaceholder)}
|
|
506
|
+
defaultValue={messageTitle || ''}
|
|
507
|
+
value={messageTitle || ''}
|
|
508
|
+
size="default"
|
|
509
|
+
label={formatMessage(messages.textMessageTitleLabel)}
|
|
510
|
+
/>
|
|
511
|
+
)
|
|
512
|
+
: null
|
|
513
|
+
}
|
|
514
|
+
{getTemplateSection()}
|
|
515
|
+
<CapDrawer
|
|
516
|
+
content={getLineImageDrawerContent()}
|
|
517
|
+
visible={isTemplateDrawerRequired}
|
|
518
|
+
width={624}
|
|
519
|
+
onClose={() => updateTemplateDrawerRequirement(false)}
|
|
520
|
+
/>
|
|
521
|
+
</div>
|
|
522
|
+
|
|
523
|
+
)
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
export default injectIntl(withStyles(LineImageCarousel, style));
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* LineImageCarousel Messages
|
|
3
|
+
*
|
|
4
|
+
* This contains all the text for the LineImageCarousel component.
|
|
5
|
+
*/
|
|
6
|
+
import { defineMessages } from 'react-intl';
|
|
7
|
+
const scope = `creatives.containersV2.LineImageCarousel`;
|
|
8
|
+
|
|
9
|
+
export default defineMessages({
|
|
10
|
+
"textMessageAddLabel": {
|
|
11
|
+
id: `${scope}.textMessageAddLabel`,
|
|
12
|
+
defaultMessage: 'How do you want to upload the "Card message"?',
|
|
13
|
+
},
|
|
14
|
+
"textMessageCreateNew": {
|
|
15
|
+
id: `${scope}.textMessageCreateNew`,
|
|
16
|
+
defaultMessage: 'Create new',
|
|
17
|
+
},
|
|
18
|
+
"textMessageSelectTemplate": {
|
|
19
|
+
id: `${scope}.textMessageSelectTemplate`,
|
|
20
|
+
defaultMessage: 'Select template',
|
|
21
|
+
},
|
|
22
|
+
"textMessageORLabel": {
|
|
23
|
+
id: `${scope}.textMessageORLabel`,
|
|
24
|
+
defaultMessage: 'OR',
|
|
25
|
+
},
|
|
26
|
+
"textMessageTitlePlaceholder": {
|
|
27
|
+
id: `${scope}.textMessageTitlePlaceholder`,
|
|
28
|
+
defaultMessage: 'Enter template name',
|
|
29
|
+
},
|
|
30
|
+
"textMessageTitleLabel": {
|
|
31
|
+
id: `${scope}.textMessageTitleLabel`,
|
|
32
|
+
defaultMessage: 'Template name',
|
|
33
|
+
},
|
|
34
|
+
"emptyTitleErrorMessage": {
|
|
35
|
+
id: `${scope}.emptyTitleErrorMessage`,
|
|
36
|
+
defaultMessage: 'Template title can not be empty',
|
|
37
|
+
},
|
|
38
|
+
"imageDimenstionDescription": {
|
|
39
|
+
id: `${scope}.imageDimenstionDescription`,
|
|
40
|
+
defaultMessage: 'Format: JPEG, PNG Aspect Ratio: 1:1 Dimensions: 1024px x 1024px Size: 1 MB',
|
|
41
|
+
},
|
|
42
|
+
"imageReUpload": {
|
|
43
|
+
id: `${scope}.imageReUpload`,
|
|
44
|
+
defaultMessage: 'Re upload',
|
|
45
|
+
},
|
|
46
|
+
"uploadGallery": {
|
|
47
|
+
id: `${scope}.uploadGallery`,
|
|
48
|
+
defaultMessage: 'Gallery',
|
|
49
|
+
},
|
|
50
|
+
"uploadComputer": {
|
|
51
|
+
id: `${scope}.uploadComputer`,
|
|
52
|
+
defaultMessage: 'Your computer',
|
|
53
|
+
},
|
|
54
|
+
"or": {
|
|
55
|
+
id: `${scope}.or`,
|
|
56
|
+
defaultMessage: 'OR',
|
|
57
|
+
},
|
|
58
|
+
"dragAndDrop": {
|
|
59
|
+
id: `${scope}.dragAndDrop`,
|
|
60
|
+
defaultMessage: 'Drag and drop image here',
|
|
61
|
+
},
|
|
62
|
+
"lineImageIncorrectSize": {
|
|
63
|
+
id: `${scope}.lineImageIncorrectSize`,
|
|
64
|
+
defaultMessage: 'Please upload the image with correct type, size and dimension',
|
|
65
|
+
},
|
|
66
|
+
"imageGallery": {
|
|
67
|
+
id: `${scope}.imageGallery`,
|
|
68
|
+
defaultMessage: 'Gallery',
|
|
69
|
+
},
|
|
70
|
+
"uploadImageLabel": {
|
|
71
|
+
id: `${scope}.uploadImageLabel`,
|
|
72
|
+
defaultMessage: 'Upload Image',
|
|
73
|
+
},
|
|
74
|
+
"uploadImageDescription": {
|
|
75
|
+
id: `${scope}.uploadImageDescription`,
|
|
76
|
+
defaultMessage: 'The relevant image that complements the message context.',
|
|
77
|
+
},
|
|
78
|
+
"select": {
|
|
79
|
+
id: `${scope}.select`,
|
|
80
|
+
defaultMessage: 'Select',
|
|
81
|
+
},
|
|
82
|
+
"lineTemplateImage": {
|
|
83
|
+
id: `${scope}.lineTemplateImage`,
|
|
84
|
+
defaultMessage: 'Line templates - Image',
|
|
85
|
+
},
|
|
86
|
+
"searchImages": {
|
|
87
|
+
id: `${scope}.searchImages`,
|
|
88
|
+
defaultMessage: 'Search Images',
|
|
89
|
+
},
|
|
90
|
+
"addCard": {
|
|
91
|
+
id: `${scope}.addCard`,
|
|
92
|
+
defaultMessage: 'Add card',
|
|
93
|
+
},
|
|
94
|
+
"actionLabelPlaceholder": {
|
|
95
|
+
id: `${scope}.actionLabelPlaceholder`,
|
|
96
|
+
defaultMessage: 'Enter action label',
|
|
97
|
+
},
|
|
98
|
+
"actionLabelTitle": {
|
|
99
|
+
id: `${scope}.actionLabelTitle`,
|
|
100
|
+
defaultMessage: 'Action',
|
|
101
|
+
},
|
|
102
|
+
"actionTypePlaceholder": {
|
|
103
|
+
id: `${scope}.actionTypePlaceholder`,
|
|
104
|
+
defaultMessage: 'Select the action',
|
|
105
|
+
},
|
|
106
|
+
"actionTypeTitle": {
|
|
107
|
+
id: `${scope}.actionTypeTitle`,
|
|
108
|
+
defaultMessage: 'Action Type',
|
|
109
|
+
},
|
|
110
|
+
"textActionTypeTitle": {
|
|
111
|
+
id: `${scope}.textActionTypeTitle`,
|
|
112
|
+
defaultMessage: 'TEXT',
|
|
113
|
+
},
|
|
114
|
+
"enterTextActionTypeTitle": {
|
|
115
|
+
id: `${scope}.enterTextActionTypeTitle`,
|
|
116
|
+
defaultMessage: 'Enter text',
|
|
117
|
+
},
|
|
118
|
+
"enterUrlActionTypeTitle": {
|
|
119
|
+
id: `${scope}.enterUriActionTypeTitle`,
|
|
120
|
+
defaultMessage: 'Enter url',
|
|
121
|
+
},
|
|
122
|
+
"urlActionTypeTitle": {
|
|
123
|
+
id: `${scope}.urlActionTypeTitle`,
|
|
124
|
+
defaultMessage: 'URL',
|
|
125
|
+
},
|
|
126
|
+
"emptyActionContentErrorMessage": {
|
|
127
|
+
id: `${scope}.emptyActionContentErrorMessage`,
|
|
128
|
+
defaultMessage: 'Action content can not be empty',
|
|
129
|
+
},
|
|
130
|
+
"inValidUrliErrorMessage": {
|
|
131
|
+
id: `${scope}.inValidUrliErrorMessage`,
|
|
132
|
+
defaultMessage: 'Action content uri is not valid',
|
|
133
|
+
},
|
|
134
|
+
"maxActionLabelErrorMessage": {
|
|
135
|
+
id: `${scope}.maxActionLabelErrorMessage`,
|
|
136
|
+
defaultMessage: 'Action label can not be more than 12 character',
|
|
137
|
+
},
|
|
138
|
+
"duplicateTooltipLabel": {
|
|
139
|
+
id: `${scope}.duplicateTooltipLabel`,
|
|
140
|
+
defaultMessage: 'Duplicate',
|
|
141
|
+
},
|
|
142
|
+
"shiftLeftTooltipLabel": {
|
|
143
|
+
id: `${scope}.shiftLeftTooltipLabel`,
|
|
144
|
+
defaultMessage: 'Shift Left',
|
|
145
|
+
},
|
|
146
|
+
"shiftRightTooltipLabel": {
|
|
147
|
+
id: `${scope}.shiftRightTooltipLabel`,
|
|
148
|
+
defaultMessage: 'Shift Right',
|
|
149
|
+
},
|
|
150
|
+
"deleteTooltipLabel": {
|
|
151
|
+
id: `${scope}.deleteTooltipLabel`,
|
|
152
|
+
defaultMessage: 'Delete',
|
|
153
|
+
},
|
|
154
|
+
"cardMessageTitle": {
|
|
155
|
+
id: `${scope}.cardMessageTitle`,
|
|
156
|
+
defaultMessage: 'Card Message',
|
|
157
|
+
},
|
|
158
|
+
"cardMessageDescription": {
|
|
159
|
+
id: `${scope}.cardMessageDescription`,
|
|
160
|
+
defaultMessage: 'Use this to present content with multiple cards in carousel format, packed into a single chat bubble.',
|
|
161
|
+
},
|
|
162
|
+
"cardMessageInfo": {
|
|
163
|
+
id: `${scope}.cardMessageInfo`,
|
|
164
|
+
defaultMessage: 'If your message contains multiple cards, all cards will be as tall as the tallest card.',
|
|
165
|
+
},
|
|
166
|
+
"titleLabel": {
|
|
167
|
+
id: `${scope}.titleLabel`,
|
|
168
|
+
defaultMessage: 'Title',
|
|
169
|
+
},
|
|
170
|
+
"titleDescription": {
|
|
171
|
+
id: `${scope}.titleDescription`,
|
|
172
|
+
defaultMessage: 'The title is shown in push notifications and in the user\'s chat list.',
|
|
173
|
+
},
|
|
174
|
+
"emptyAltTextErrorMessage": {
|
|
175
|
+
id: `${scope}.emptyAltTextErrorMessage`,
|
|
176
|
+
defaultMessage: 'Title can not be empty',
|
|
177
|
+
},
|
|
178
|
+
});
|