@capillarytech/creatives-library 7.5.6 → 7.5.8
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/v2Components/CapVideoUpload/index.js +5 -0
- package/v2Components/CapVideoUpload/index.scss +4 -1
- package/v2Components/CapVideoUpload/messages.js +4 -0
- package/v2Containers/CapFacebookPreview/index.js +45 -9
- package/v2Containers/CapFacebookPreview/messages.js +8 -0
- package/v2Containers/CapFacebookPreview/reducer.js +12 -4
- package/v2Containers/CapFacebookPreview/sagas.js +9 -9
- package/v2Containers/Facebook/Advertisement/constant.js +1 -0
- package/v2Containers/Facebook/Advertisement/index.js +17 -14
- package/v2Containers/Facebook/Advertisement/index.scss +18 -4
- package/v2Containers/Facebook/index.js +2 -0
- package/v2Containers/Templates/index.js +2 -2
package/package.json
CHANGED
|
@@ -274,6 +274,11 @@ function CapVideoUpload(props) {
|
|
|
274
274
|
<CapHeading.CapHeadingSpan type="h6" className="video-description">
|
|
275
275
|
<FormattedMessage {...messages.videoRatioDescription} />
|
|
276
276
|
|
|
277
|
+
</CapHeading.CapHeadingSpan>
|
|
278
|
+
{' '}
|
|
279
|
+
<CapHeading.CapHeadingSpan type="h6" className="video-description file-format">
|
|
280
|
+
<FormattedMessage {...messages.fileFormat} />
|
|
281
|
+
|
|
277
282
|
</CapHeading.CapHeadingSpan>
|
|
278
283
|
<CapHeading.CapHeadingSpan type="h6" className="video-description video-details">
|
|
279
284
|
<FormattedMessage {...messages.videoSizeDescription} values={{size: bytes2Size(videoSize)}} />
|
|
@@ -20,15 +20,17 @@ import {
|
|
|
20
20
|
CapImage,
|
|
21
21
|
CapSpin,
|
|
22
22
|
CapIcon,
|
|
23
|
+
CapNotification,
|
|
24
|
+
CapTooltip,
|
|
23
25
|
} from "@capillarytech/cap-ui-library";
|
|
24
26
|
import facebookEmptyPlaceholder from '../../assets/facebookEmptyPlaceholder.png';
|
|
25
27
|
import {
|
|
26
28
|
IMAGE,
|
|
27
29
|
VIDEO,
|
|
28
30
|
CAROUSEL,
|
|
31
|
+
NO_CALL_TO_ACTION,
|
|
29
32
|
} from '../../v2Containers/Facebook/Advertisement/constant';
|
|
30
33
|
|
|
31
|
-
const NO_CALL_TO_ACTION = 'NO_CALL_TO_ACTION';
|
|
32
34
|
|
|
33
35
|
export const CapFacebookPreview = (props) => {
|
|
34
36
|
const {
|
|
@@ -48,9 +50,10 @@ export const CapFacebookPreview = (props) => {
|
|
|
48
50
|
formatMessage,
|
|
49
51
|
} = intl || {};
|
|
50
52
|
const [adPreviewFormat, setAdPreviewFormat] = useState("DESKTOP_FEED_STANDARD");
|
|
53
|
+
const [disableAfterPreviewGenerate, setDisableAfterPreviewGenerate] = useState(false);
|
|
51
54
|
const [random, setRandom] = useState(0);
|
|
52
55
|
const {pageAccessToken, pageId} = orgUnitFacebookPageSettingsMap;
|
|
53
|
-
const {previewIframe = "", isFetchingPreview = false} = facebookPreviewData;
|
|
56
|
+
const {previewIframe = "", isFetchingPreview = false, previewIframeError = ""} = facebookPreviewData;
|
|
54
57
|
const facebookAdOptions = [
|
|
55
58
|
{
|
|
56
59
|
value: "DESKTOP_FEED_STANDARD",
|
|
@@ -271,11 +274,14 @@ export const CapFacebookPreview = (props) => {
|
|
|
271
274
|
};
|
|
272
275
|
facebookPreviewActions.getCarouselPreview(data);
|
|
273
276
|
}
|
|
277
|
+
setDisableAfterPreviewGenerate(true);
|
|
274
278
|
};
|
|
279
|
+
|
|
275
280
|
const resetIframe = () => {
|
|
276
281
|
const r = random + 1;
|
|
277
282
|
setRandom(r);
|
|
278
283
|
};
|
|
284
|
+
|
|
279
285
|
const getIframe = (iframe) => {
|
|
280
286
|
const divTag = document.createElement('div');
|
|
281
287
|
divTag.innerHTML = iframe;
|
|
@@ -294,6 +300,7 @@ export const CapFacebookPreview = (props) => {
|
|
|
294
300
|
/>
|
|
295
301
|
</>);
|
|
296
302
|
};
|
|
303
|
+
|
|
297
304
|
const showRefreshButton = () => {
|
|
298
305
|
let isRefresh = false;
|
|
299
306
|
props.previewData.forEach((obj) => {
|
|
@@ -305,9 +312,28 @@ export const CapFacebookPreview = (props) => {
|
|
|
305
312
|
return isRefresh && previewIframe !== "";
|
|
306
313
|
};
|
|
307
314
|
const isRefreshButton = showRefreshButton();
|
|
315
|
+
|
|
308
316
|
useEffect(() => {
|
|
309
317
|
facebookPreviewActions.clearPreview();
|
|
310
318
|
}, []);
|
|
319
|
+
|
|
320
|
+
useEffect(() => {
|
|
321
|
+
if (disableAfterPreviewGenerate) {
|
|
322
|
+
setDisableAfterPreviewGenerate(false);
|
|
323
|
+
}
|
|
324
|
+
}, [previewData,
|
|
325
|
+
primaryText,
|
|
326
|
+
callToAction]);
|
|
327
|
+
|
|
328
|
+
useEffect(() => {
|
|
329
|
+
if (previewIframeError) {
|
|
330
|
+
CapNotification.error({
|
|
331
|
+
message: formatMessage(messages.generatePreviewError),
|
|
332
|
+
});
|
|
333
|
+
setDisableAfterPreviewGenerate(false);
|
|
334
|
+
}
|
|
335
|
+
}, [previewIframeError]);
|
|
336
|
+
|
|
311
337
|
return (
|
|
312
338
|
<CapSpin spinning={isFetchingPreview}>
|
|
313
339
|
<div style={{display: 'inline-block'}}>
|
|
@@ -328,13 +354,23 @@ export const CapFacebookPreview = (props) => {
|
|
|
328
354
|
{formatMessage(messages.previewAdDesc)}
|
|
329
355
|
</CapLabel>
|
|
330
356
|
<div style={{marginBottom: 16}}>
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
357
|
+
{(disablePreviewButton || disableAfterPreviewGenerate) ?
|
|
358
|
+
<CapTooltip title={formatMessage(messages.generatePreviewDisableToolTip)}>
|
|
359
|
+
<div className="button-disabled-tooltip-wrapper">
|
|
360
|
+
<CapButton
|
|
361
|
+
type="secondary"
|
|
362
|
+
disabled
|
|
363
|
+
>
|
|
364
|
+
<FormattedMessage {...messages.generatePreview} />
|
|
365
|
+
</CapButton>
|
|
366
|
+
</div>
|
|
367
|
+
</CapTooltip> :
|
|
368
|
+
<CapButton
|
|
369
|
+
type="secondary"
|
|
370
|
+
onClick={generatePreview}
|
|
371
|
+
>
|
|
372
|
+
<FormattedMessage {...messages.generatePreview} />
|
|
373
|
+
</CapButton>}
|
|
338
374
|
{isRefreshButton && (<CapButton
|
|
339
375
|
onClick={resetIframe}
|
|
340
376
|
type="secondary"
|
|
@@ -135,4 +135,12 @@ export default defineMessages({
|
|
|
135
135
|
id: `${messagePrefix}.videoNotePreview`,
|
|
136
136
|
defaultMessage: 'Facebook may take time to upload the video. Please try Refreshing.',
|
|
137
137
|
},
|
|
138
|
+
generatePreviewError: {
|
|
139
|
+
id: `${messagePrefix}.generatePreviewError`,
|
|
140
|
+
defaultMessage: 'Error in generating preview',
|
|
141
|
+
},
|
|
142
|
+
generatePreviewDisableToolTip: {
|
|
143
|
+
id: `${messagePrefix}.generatePreviewDisableToolTip`,
|
|
144
|
+
defaultMessage: 'Looks like either all the mandatory fields are not filled or there is no new change',
|
|
145
|
+
},
|
|
138
146
|
});
|
|
@@ -11,6 +11,7 @@ import * as types from './constants';
|
|
|
11
11
|
const initialState = fromJS({
|
|
12
12
|
isFetchingPreview: false,
|
|
13
13
|
previewIframe: "",
|
|
14
|
+
previewIframeError: "",
|
|
14
15
|
});
|
|
15
16
|
|
|
16
17
|
function capFacebookPreviewReducer(state = initialState, action) {
|
|
@@ -18,17 +19,24 @@ function capFacebookPreviewReducer(state = initialState, action) {
|
|
|
18
19
|
case types.GENERATE_IMAGE_PREVIEW_REQUEST:
|
|
19
20
|
case types.GENERATE_VIDEO_PREVIEW_REQUEST:
|
|
20
21
|
case types.GENERATE_CAROUSEL_PREVIEW_REQUEST:
|
|
21
|
-
return state.set('isFetchingPreview', true)
|
|
22
|
+
return state.set('isFetchingPreview', true)
|
|
23
|
+
.set('previewIframe', "")
|
|
24
|
+
.set("previewIframeError", "");
|
|
22
25
|
case types.GENERATE_IMAGE_PREVIEW_SUCCESS:
|
|
23
26
|
case types.GENERATE_VIDEO_PREVIEW_SUCCESS:
|
|
24
27
|
case types.GENERATE_CAROUSEL_PREVIEW_SUCCESS:
|
|
25
|
-
return state.set('isFetchingPreview', false)
|
|
28
|
+
return state.set('isFetchingPreview', false)
|
|
29
|
+
.set('previewIframe', get(action, 'payload.fbPreview[0].body', ""));
|
|
26
30
|
case types.GENERATE_IMAGE_PREVIEW_FAILURE:
|
|
27
31
|
case types.GENERATE_VIDEO_PREVIEW_FAILURE:
|
|
28
32
|
case types.GENERATE_CAROUSEL_PREVIEW_FAILURE:
|
|
29
|
-
return state.set('isFetchingPreview', false)
|
|
33
|
+
return state.set('isFetchingPreview', false)
|
|
34
|
+
.set('previewIframe', "")
|
|
35
|
+
.set("previewIframeError", get(action, 'payload.message', ""));
|
|
30
36
|
case types.CLEAR_PREVIEW:
|
|
31
|
-
return state.set('isFetchingPreview', false)
|
|
37
|
+
return state.set('isFetchingPreview', false)
|
|
38
|
+
.set('previewIframe', "")
|
|
39
|
+
.set("previewIframeError", "");
|
|
32
40
|
default:
|
|
33
41
|
return state;
|
|
34
42
|
}
|
|
@@ -6,11 +6,11 @@ import * as type from './constants';
|
|
|
6
6
|
export function* getImageFacebookPreview(previewData) {
|
|
7
7
|
try {
|
|
8
8
|
const response = yield call(Api.getImageFacebookPreview, previewData );
|
|
9
|
-
const {
|
|
10
|
-
if (
|
|
9
|
+
const { status, response: responsePreview } = response;
|
|
10
|
+
if (status && status.isError) {
|
|
11
11
|
yield put({
|
|
12
12
|
type: type.GENERATE_IMAGE_PREVIEW_FAILURE,
|
|
13
|
-
payload:
|
|
13
|
+
payload: status,
|
|
14
14
|
});
|
|
15
15
|
} else {
|
|
16
16
|
yield put({
|
|
@@ -29,11 +29,11 @@ export function* getImageFacebookPreview(previewData) {
|
|
|
29
29
|
export function* getVideoFacebookPreview(previewData) {
|
|
30
30
|
try {
|
|
31
31
|
const response = yield call(Api.getVideoFacebookPreview, previewData);
|
|
32
|
-
const {
|
|
33
|
-
if (
|
|
32
|
+
const { status, response: responsePreview } = response;
|
|
33
|
+
if (status && status.isError) {
|
|
34
34
|
yield put({
|
|
35
35
|
type: type.GENERATE_VIDEO_PREVIEW_FAILURE,
|
|
36
|
-
payload:
|
|
36
|
+
payload: status,
|
|
37
37
|
});
|
|
38
38
|
} else {
|
|
39
39
|
yield put({
|
|
@@ -52,11 +52,11 @@ export function* getVideoFacebookPreview(previewData) {
|
|
|
52
52
|
export function* getCarouselFacebookPreview(previewData) {
|
|
53
53
|
try {
|
|
54
54
|
const response = yield call(Api.getCarouselFacebookPreview, previewData);
|
|
55
|
-
const {
|
|
56
|
-
if (
|
|
55
|
+
const { status, response: responsePreview } = response;
|
|
56
|
+
if (status && status.isError) {
|
|
57
57
|
yield put({
|
|
58
58
|
type: type.GENERATE_CAROUSEL_PREVIEW_FAILURE,
|
|
59
|
-
payload:
|
|
59
|
+
payload: status,
|
|
60
60
|
});
|
|
61
61
|
} else {
|
|
62
62
|
yield put({
|
|
@@ -52,6 +52,7 @@ import {
|
|
|
52
52
|
VIDEO,
|
|
53
53
|
CAROUSEL,
|
|
54
54
|
IMAGE_VIDEO,
|
|
55
|
+
NO_CALL_TO_ACTION,
|
|
55
56
|
} from './constant';
|
|
56
57
|
|
|
57
58
|
export const Advertisement = (props) => {
|
|
@@ -105,9 +106,8 @@ export const Advertisement = (props) => {
|
|
|
105
106
|
const [primaryText, setPrimaryText] = useState('');
|
|
106
107
|
const [pageId, setPageId] = useState(false);
|
|
107
108
|
const [displayLink, setDisplayLink] = useState('');
|
|
108
|
-
const [callToAction, setCallToAction] = useState(
|
|
109
|
+
const [callToAction, setCallToAction] = useState(NO_CALL_TO_ACTION);
|
|
109
110
|
const [callToActionError, setCallToActionError] = useState(false);
|
|
110
|
-
|
|
111
111
|
const [messageTitle, updateMessageTitle] = useState('');
|
|
112
112
|
const [step, updateStep] = useState('modeSelection');
|
|
113
113
|
const [activeIndex, updateActiveIndex] = useState(`${defaultActiveIndex}`);
|
|
@@ -116,7 +116,6 @@ export const Advertisement = (props) => {
|
|
|
116
116
|
const [editNameState, setEditNameState] = useState(false);
|
|
117
117
|
const isCarouselSelectedAd = selectedAd === CAROUSEL;
|
|
118
118
|
const isImgVideoSelectedAd = selectedAd === IMAGE_VIDEO;
|
|
119
|
-
|
|
120
119
|
const activeCarouselData = carouselData[activeIndex];
|
|
121
120
|
|
|
122
121
|
const uploadFbAdAsset = useCallback(( file,
|
|
@@ -430,6 +429,7 @@ export const Advertisement = (props) => {
|
|
|
430
429
|
flag = true;
|
|
431
430
|
return flag;
|
|
432
431
|
}
|
|
432
|
+
const subTypes = [];
|
|
433
433
|
carouselData.forEach((obj) => {
|
|
434
434
|
const {
|
|
435
435
|
webSiteLink,
|
|
@@ -446,17 +446,19 @@ export const Advertisement = (props) => {
|
|
|
446
446
|
} else if (Object.keys(videoData).length === 0 && subType === VIDEO) {
|
|
447
447
|
flag = true;
|
|
448
448
|
}
|
|
449
|
-
|
|
450
|
-
if (callToAction === "NO_CALL_TO_ACTION" && !callToActionError) {
|
|
451
|
-
setCallToActionError(messages.callToActionMandatoryError);
|
|
452
|
-
flag = true;
|
|
453
|
-
} else if (callToAction !== "NO_CALL_TO_ACTION" && callToActionError) {
|
|
454
|
-
setCallToActionError(false);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
449
|
+
subTypes.push(subType);
|
|
457
450
|
});
|
|
458
|
-
if (
|
|
459
|
-
|
|
451
|
+
if (subTypes.includes(VIDEO) ) {
|
|
452
|
+
if (callToAction === NO_CALL_TO_ACTION && !callToActionError) {
|
|
453
|
+
setCallToActionError(messages.callToActionMandatoryError);
|
|
454
|
+
flag = true;
|
|
455
|
+
} else if (callToAction !== NO_CALL_TO_ACTION && callToActionError) {
|
|
456
|
+
setCallToActionError(false);
|
|
457
|
+
flag = false;
|
|
458
|
+
}
|
|
459
|
+
} else if (callToActionError) {
|
|
460
|
+
setCallToActionError(false);
|
|
461
|
+
flag = false;
|
|
460
462
|
}
|
|
461
463
|
return flag;
|
|
462
464
|
}, [
|
|
@@ -549,6 +551,7 @@ export const Advertisement = (props) => {
|
|
|
549
551
|
onChange={onChangePrimaryText}
|
|
550
552
|
defaultValue={primaryText || ''}
|
|
551
553
|
value={primaryText || ''}
|
|
554
|
+
maxLength={125}
|
|
552
555
|
rows={3}
|
|
553
556
|
cols={2}
|
|
554
557
|
placeholder={formatMessage(messages.primaryTextPlaceholder)}
|
|
@@ -858,7 +861,7 @@ export const Advertisement = (props) => {
|
|
|
858
861
|
<div className="cap-header-facebook-ad">
|
|
859
862
|
<CapHeading
|
|
860
863
|
type="h2"
|
|
861
|
-
|
|
864
|
+
className="truncate-text"
|
|
862
865
|
>
|
|
863
866
|
{editNameState ? <CapInput
|
|
864
867
|
type="input"
|
|
@@ -12,6 +12,13 @@ $classPrefix: add-facebook-ad-section;
|
|
|
12
12
|
padding: 0;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
+
.truncate-text{
|
|
16
|
+
overflow: hidden;
|
|
17
|
+
text-overflow: ellipsis;
|
|
18
|
+
white-space: nowrap;
|
|
19
|
+
min-width: 112px;
|
|
20
|
+
max-width: 920px;
|
|
21
|
+
}
|
|
15
22
|
.cap-header-facebook-ad{
|
|
16
23
|
position: fixed;
|
|
17
24
|
top: 27px;
|
|
@@ -29,15 +36,22 @@ $classPrefix: add-facebook-ad-section;
|
|
|
29
36
|
margin-left: 6px;
|
|
30
37
|
}
|
|
31
38
|
}
|
|
32
|
-
.cap-image-upload
|
|
39
|
+
.cap-custom-image-upload{
|
|
33
40
|
.dragger-button.re-upload{
|
|
34
|
-
margin-top:
|
|
35
|
-
top:
|
|
41
|
+
margin-top: 50px;
|
|
42
|
+
top: 0px;
|
|
36
43
|
position: absolute;
|
|
37
|
-
right:
|
|
44
|
+
right: 60px;
|
|
38
45
|
color: $FONT_COLOR_05;
|
|
39
46
|
}
|
|
47
|
+
.cap-image-upload-CAROUSEL{
|
|
48
|
+
.dragger-button.re-upload{
|
|
49
|
+
margin-top: 90px;
|
|
50
|
+
right: 0px;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
40
53
|
}
|
|
54
|
+
|
|
41
55
|
.facebook-ad-type-card{
|
|
42
56
|
.ant-card-body {
|
|
43
57
|
display:flex;
|
|
@@ -358,6 +358,7 @@ Facebook.propTypes = {
|
|
|
358
358
|
templateData: PropTypes.object,
|
|
359
359
|
cap: PropTypes.object,
|
|
360
360
|
messageDetails: PropTypes.object,
|
|
361
|
+
params: PropTypes.object,
|
|
361
362
|
onFacebookSubmit: PropTypes.func,
|
|
362
363
|
marketingObjectiveList: PropTypes.arrayOf(PropTypes.string),
|
|
363
364
|
facebookActions: PropTypes.func,
|
|
@@ -365,6 +366,7 @@ Facebook.propTypes = {
|
|
|
365
366
|
isFullMode: PropTypes.boolean,
|
|
366
367
|
fbADData: PropTypes.object,
|
|
367
368
|
onCreateComplete: PropTypes.func,
|
|
369
|
+
facebookTemplateData: PropTypes.object,
|
|
368
370
|
};
|
|
369
371
|
|
|
370
372
|
Facebook.defaultProps = {
|
|
@@ -422,7 +422,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
422
422
|
}
|
|
423
423
|
if (!nextProps.Templates.deleteTemplateInProgress && !isEqual(nextProps.Templates.deleteTemplateInProgress, this.props.Templates.deleteTemplateInProgress) &&
|
|
424
424
|
nextProps.Templates.deleteResponse) {
|
|
425
|
-
const message = `${this.state.channel
|
|
425
|
+
const message = `${this.state.channel} ${this.props.intl.formatMessage(messages['Template deleted successfully'])}`;
|
|
426
426
|
CapNotification.success({key: 'deleteSucess', message});
|
|
427
427
|
this.getAllTemplates({params, resetPage: true});
|
|
428
428
|
}
|
|
@@ -1802,7 +1802,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1802
1802
|
const isMobilePushChannel = channel === MOBILE_PUSH;
|
|
1803
1803
|
const isLineChannel = channel === LINE;
|
|
1804
1804
|
|
|
1805
|
-
|
|
1805
|
+
|
|
1806
1806
|
if ((isWechatChannel || isMobilePushChannel || isLineChannel) && !isEmpty(weCrmAccounts)) {
|
|
1807
1807
|
forEach(weCrmAccounts, (account) => {
|
|
1808
1808
|
if ((isWechatChannel && account.configs && account.configs.is_wecrm_enabled) || isMobilePushChannel || isLineChannel) {
|