@capillarytech/creatives-library 8.0.87-alpha.19 → 8.0.87-alpha.2
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/initialState.js +0 -1
- package/package.json +1 -1
- package/services/api.js +10 -9
- package/v2Components/CapWhatsappCTA/messages.js +4 -0
- package/v2Components/CapWhatsappCarouselButton/constant.js +51 -0
- package/v2Components/CapWhatsappCarouselButton/index.js +446 -0
- package/v2Components/CapWhatsappCarouselButton/index.scss +39 -0
- package/v2Components/FormBuilder/index.js +3 -7
- package/v2Components/TemplatePreview/_templatePreview.scss +9 -0
- package/v2Components/TemplatePreview/assets/images/empty_image_preview.svg +4 -0
- package/v2Components/TemplatePreview/assets/images/empty_video_preview.svg +4 -0
- package/v2Components/TemplatePreview/index.js +169 -104
- package/v2Containers/Cap/actions.js +0 -8
- package/v2Containers/Cap/constants.js +0 -4
- package/v2Containers/Cap/reducer.js +0 -6
- package/v2Containers/Cap/sagas.js +0 -23
- package/v2Containers/Cap/selectors.js +0 -6
- package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +0 -1
- package/v2Containers/CreativesContainer/SlideBoxContent.js +1 -11
- package/v2Containers/CreativesContainer/constants.js +0 -3
- package/v2Containers/CreativesContainer/index.js +88 -78
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +0 -25
- package/v2Containers/CreativesContainer/tests/index.test.js +0 -2
- package/v2Containers/Email/index.js +0 -1
- package/v2Containers/EmailWrapper/index.js +0 -2
- package/v2Containers/MobilePush/Create/index.js +0 -1
- package/v2Containers/MobilePush/Edit/index.js +0 -1
- package/v2Containers/MobilepushWrapper/index.js +1 -2
- package/v2Containers/Sms/Create/index.js +0 -1
- package/v2Containers/Sms/Edit/index.js +0 -1
- package/v2Containers/SmsWrapper/index.js +0 -2
- package/v2Containers/Templates/_templates.scss +35 -0
- package/v2Containers/Templates/index.js +64 -5
- package/v2Containers/TemplatesV2/index.js +0 -7
- package/v2Containers/Whatsapp/constants.js +83 -1
- package/v2Containers/Whatsapp/index.js +709 -182
- package/v2Containers/Whatsapp/index.scss +52 -1
- package/v2Containers/Whatsapp/messages.js +38 -2
- package/v2Containers/Whatsapp/utils.js +34 -0
- package/v2Containers/mockdata.js +0 -3
- package/utils/transformerUtils.js +0 -524
package/initialState.js
CHANGED
package/package.json
CHANGED
package/services/api.js
CHANGED
|
@@ -118,7 +118,7 @@ function request(url, options, handleUnauthorizedStatus) {
|
|
|
118
118
|
.catch((error) => error);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
function getAPICallObject(method, body, isFileUpload = false, loadCampaignHeaders = false, orgUnitId = false
|
|
121
|
+
function getAPICallObject(method, body, isFileUpload = false, loadCampaignHeaders = false, orgUnitId = false) {
|
|
122
122
|
const token = loadItem('token');
|
|
123
123
|
const orgID = loadItem('orgID');
|
|
124
124
|
const user = loadItem('user');
|
|
@@ -145,8 +145,8 @@ function getAPICallObject(method, body, isFileUpload = false, loadCampaignHeader
|
|
|
145
145
|
headers['X-CAP-REMOTE-USER'] = user.refID;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
if (
|
|
149
|
-
headers[
|
|
148
|
+
if (process.env.NODE_ENV !== 'production' && orgID !== undefined) {
|
|
149
|
+
headers['X-CAP-API-AUTH-ORG-ID'] = orgID;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
if (process.env.NODE_ENV !== 'production' && token !== undefined) {
|
|
@@ -520,7 +520,13 @@ export const checkBulkDuplicates = (data) => {
|
|
|
520
520
|
export const createWhatsappTemplate = ({payload, gupshupMediaFile }) => {
|
|
521
521
|
const data = new FormData();
|
|
522
522
|
data.append('payload', JSON.stringify(payload));
|
|
523
|
-
|
|
523
|
+
if (Array.isArray(gupshupMediaFile) && gupshupMediaFile.length) {
|
|
524
|
+
gupshupMediaFile.forEach((file, index) => {
|
|
525
|
+
data.append(`gupshupMediaFile_${index}`, file);
|
|
526
|
+
});
|
|
527
|
+
} else {
|
|
528
|
+
data.append('gupshupMediaFile', gupshupMediaFile);
|
|
529
|
+
}
|
|
524
530
|
const url = `${API_ENDPOINT}/templates/WHATSAPP`;
|
|
525
531
|
return request(url, getAPICallObject('POST', data, true));
|
|
526
532
|
};
|
|
@@ -569,9 +575,4 @@ export const getLiquidTags = (content) => {
|
|
|
569
575
|
return request(url, getAPICallObject("POST", { content }, false, true));
|
|
570
576
|
};
|
|
571
577
|
|
|
572
|
-
export const createCentralCommsMetaId = (payload, metaId = 'TRANSACTION') => {
|
|
573
|
-
const url = `${API_ENDPOINT}/common/central-comms/meta-id/${metaId}`;
|
|
574
|
-
return request(url, getAPICallObject('POST', payload, false, false, false, true));
|
|
575
|
-
};
|
|
576
|
-
|
|
577
578
|
export {request, getAPICallObject};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FormattedMessage } from 'react-intl';
|
|
3
|
+
import capWhatsappCTAMsg from '../CapWhatsappCTA/messages';
|
|
4
|
+
import capWhatsappMsg from '../../v2Containers/Whatsapp/messages';
|
|
5
|
+
|
|
6
|
+
export const PHONE_NUMBER = 'PHONE_NUMBER';
|
|
7
|
+
export const URL = 'URL';
|
|
8
|
+
export const QUICK_REPLY = 'QUICK_REPLY';
|
|
9
|
+
export const STATIC_URL = 'STATIC_URL';
|
|
10
|
+
export const BTN_MAX_LENGTH = 20;
|
|
11
|
+
export const PHONE_NUMBER_MAX_LENGTH = 15;
|
|
12
|
+
export const URL_MAX_LENGTH = 2000;
|
|
13
|
+
export const carouselButtonOptions = [
|
|
14
|
+
{
|
|
15
|
+
value: PHONE_NUMBER,
|
|
16
|
+
label: <FormattedMessage {...capWhatsappCTAMsg.ctaPhoneNo} />,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
value: URL,
|
|
20
|
+
label: <FormattedMessage {...capWhatsappCTAMsg.url} />,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
value: QUICK_REPLY,
|
|
24
|
+
label: <FormattedMessage {...capWhatsappMsg.btnTypeQuickReply} />,
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
export const INITIAL_CAROUSEL_PHONE_NUMBER_DATA = {
|
|
29
|
+
buttonType: PHONE_NUMBER,
|
|
30
|
+
text: '',
|
|
31
|
+
phone_number: '',
|
|
32
|
+
isSaved: false,
|
|
33
|
+
textError: "",
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const INITIAL_CAROUSEL_URL_DATA = {
|
|
37
|
+
buttonType: URL,
|
|
38
|
+
text: '',
|
|
39
|
+
urlType: STATIC_URL,
|
|
40
|
+
url: '',
|
|
41
|
+
isSaved: false,
|
|
42
|
+
textError: "",
|
|
43
|
+
urlError: "",
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const INITIAL_CAROUSEL_QUICK_REPLY_DATA = {
|
|
47
|
+
text: "",
|
|
48
|
+
buttonType: QUICK_REPLY,
|
|
49
|
+
isSaved: false,
|
|
50
|
+
textError: "",
|
|
51
|
+
};
|
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { injectIntl } from "react-intl";
|
|
3
|
+
import PhoneInput from 'react-phone-input-2';
|
|
4
|
+
import { cloneDeep } from "lodash";
|
|
5
|
+
import 'react-phone-input-2/lib/style.css';
|
|
6
|
+
import CapRow from "@capillarytech/cap-ui-library/CapRow";
|
|
7
|
+
import CapRadioGroup from "@capillarytech/cap-ui-library/CapRadioGroup";
|
|
8
|
+
import CapLabel from "@capillarytech/cap-ui-library/CapLabel";
|
|
9
|
+
import CapColumn from "@capillarytech/cap-ui-library/CapColumn";
|
|
10
|
+
import CapInput from "@capillarytech/cap-ui-library/CapInput";
|
|
11
|
+
import CapHeading from "@capillarytech/cap-ui-library/CapHeading";
|
|
12
|
+
import CapTooltipWithInfo from "@capillarytech/cap-ui-library/CapTooltipWithInfo";
|
|
13
|
+
import CapSelect from "@capillarytech/cap-ui-library/CapSelect";
|
|
14
|
+
import CapButton from "@capillarytech/cap-ui-library/CapButton";
|
|
15
|
+
import CapTooltip from "@capillarytech/cap-ui-library/CapTooltip";
|
|
16
|
+
import CapIcon from "@capillarytech/cap-ui-library/CapIcon";
|
|
17
|
+
import { CAP_SPACE_04 } from "@capillarytech/cap-ui-library/styled/variables";
|
|
18
|
+
import TagList from "../../v2Containers/TagList";
|
|
19
|
+
import {
|
|
20
|
+
carouselButtonOptions,
|
|
21
|
+
INITIAL_CAROUSEL_PHONE_NUMBER_DATA,
|
|
22
|
+
INITIAL_CAROUSEL_QUICK_REPLY_DATA,
|
|
23
|
+
INITIAL_CAROUSEL_URL_DATA,
|
|
24
|
+
PHONE_NUMBER,
|
|
25
|
+
URL,
|
|
26
|
+
BTN_MAX_LENGTH,
|
|
27
|
+
PHONE_NUMBER_MAX_LENGTH,
|
|
28
|
+
URL_MAX_LENGTH,
|
|
29
|
+
QUICK_REPLY,
|
|
30
|
+
} from "./constant";
|
|
31
|
+
import capWhatsappMsg from '../../v2Containers/Whatsapp/messages';
|
|
32
|
+
import capWhatsappCTAMsg from '../CapWhatsappCTA/messages';
|
|
33
|
+
import {
|
|
34
|
+
KARIX_GUPSHUP_URL_OPTIONS, TWILIO_URL_OPTIONS, DYNAMIC_URL, STATIC_URL,
|
|
35
|
+
} from "../CapWhatsappCTA/constants";
|
|
36
|
+
import globalMessages from '../../v2Containers/Cap/messages';
|
|
37
|
+
import { isUrl, isValidText } from '../../v2Containers/Line/Container/Wrapper/utils';
|
|
38
|
+
import { HOST_TWILIO } from "../../v2Containers/Whatsapp/constants";
|
|
39
|
+
import "./index.scss";
|
|
40
|
+
|
|
41
|
+
export const CapWhatsappCarouselButton = (props) => {
|
|
42
|
+
const {
|
|
43
|
+
intl,
|
|
44
|
+
carouselData = [],
|
|
45
|
+
setCarouselData,
|
|
46
|
+
carouselIndex = 0,
|
|
47
|
+
hostName = '',
|
|
48
|
+
isEditFlow = false,
|
|
49
|
+
tags = [],
|
|
50
|
+
injectedTags = {},
|
|
51
|
+
selectedOfferDetails = [],
|
|
52
|
+
} = props;
|
|
53
|
+
const { formatMessage } = intl;
|
|
54
|
+
const buttonData = carouselData[carouselIndex]?.buttons || [];
|
|
55
|
+
const invalidVarRegex = /{{(.*?)}}/g;
|
|
56
|
+
|
|
57
|
+
const handleButtonType = ({ target: { value } }, buttonIndex) => {
|
|
58
|
+
const cloneCarouselData = cloneDeep(carouselData);
|
|
59
|
+
const dataMap = {
|
|
60
|
+
[PHONE_NUMBER]: INITIAL_CAROUSEL_PHONE_NUMBER_DATA,
|
|
61
|
+
[URL]: INITIAL_CAROUSEL_URL_DATA,
|
|
62
|
+
[QUICK_REPLY]: INITIAL_CAROUSEL_QUICK_REPLY_DATA,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const updatedCarouselData = cloneCarouselData.map((carousel) => {
|
|
66
|
+
carousel.buttons[buttonIndex] = dataMap[value] || dataMap.default;
|
|
67
|
+
return carousel;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
setCarouselData(updatedCarouselData);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const onValueChange = (buttonIndex, fields = []) => {
|
|
74
|
+
const updatedButtonData = cloneDeep(buttonData);
|
|
75
|
+
fields.forEach((field) => {
|
|
76
|
+
updatedButtonData[buttonIndex][field.fieldName] = field.value;
|
|
77
|
+
});
|
|
78
|
+
setCarouselData(
|
|
79
|
+
carouselData.map((item, index) => index === carouselIndex
|
|
80
|
+
? { ...item, buttons: updatedButtonData }
|
|
81
|
+
: item)
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const onTagSelect = (data, index, url) => {
|
|
86
|
+
onValueChange(index, [{fieldName: 'url', value: url.replace('{{1}}', `{{${data}}}`)}]);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const revertTagSelect = (index, url) => {
|
|
90
|
+
onValueChange(index, [{fieldName: 'url', value: url.replace(invalidVarRegex, `{{1}}`)}]);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const renderLength = (len, max) => (
|
|
94
|
+
<CapHeading type="label1" className="whatsapp-render-btn-length">
|
|
95
|
+
{formatMessage(capWhatsappMsg.templateMessageLength, {
|
|
96
|
+
currentLength: len,
|
|
97
|
+
maxLength: max,
|
|
98
|
+
})}
|
|
99
|
+
</CapHeading>
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const onUrlChange = ({ target }, urlType, buttonIndex) => {
|
|
103
|
+
let { value } = target;
|
|
104
|
+
if (urlType === DYNAMIC_URL) {
|
|
105
|
+
value = value.replace(invalidVarRegex, '');
|
|
106
|
+
value = `${value}{{1}}`;
|
|
107
|
+
}
|
|
108
|
+
let errorMessage = false;
|
|
109
|
+
if (!isUrl(value)) {
|
|
110
|
+
errorMessage = formatMessage(capWhatsappCTAMsg.ctaWebsiteUrlErrorMessage);
|
|
111
|
+
} else if (
|
|
112
|
+
urlType === STATIC_URL
|
|
113
|
+
&& value.match(invalidVarRegex)?.length > 0
|
|
114
|
+
) {
|
|
115
|
+
errorMessage = formatMessage(capWhatsappCTAMsg.staticUrlWithVarErrorMessage);
|
|
116
|
+
}
|
|
117
|
+
onValueChange(buttonIndex, [{fieldName: 'url', value}, {fieldName: 'urlError', value: errorMessage}]);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const onButtonTextChange = (value, buttonIndex) => {
|
|
121
|
+
let errorMessage = '';
|
|
122
|
+
if (!isValidText(value)) {
|
|
123
|
+
errorMessage = formatMessage(capWhatsappCTAMsg.ctaButtonErrorMessage);
|
|
124
|
+
}
|
|
125
|
+
onValueChange(buttonIndex, [{fieldName: 'text', value}, {fieldName: 'textError', value: errorMessage}]);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const ctaSaveDisabled = (index) => {
|
|
129
|
+
const {
|
|
130
|
+
buttonType, text, phone_number, url, textError, urlError,
|
|
131
|
+
} = buttonData[index] || {};
|
|
132
|
+
if (text === '' || textError) {
|
|
133
|
+
return true;
|
|
134
|
+
} if (buttonType === PHONE_NUMBER && phone_number.length < 5) {
|
|
135
|
+
return true;
|
|
136
|
+
} if (buttonType === URL && (url === '' || urlError)) {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
return false;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const handleSaveButton = (buttonIndex) => {
|
|
143
|
+
onValueChange(buttonIndex, [{fieldName: 'isSaved', value: true}]);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const handleEditButton = (buttonIndex) => {
|
|
147
|
+
onValueChange(buttonIndex, [{fieldName: 'isSaved', value: false}]);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const handleDeleteButton = (buttonIndex) => {
|
|
151
|
+
setCarouselData((prevData) => prevData.map((carousel) => ({
|
|
152
|
+
...carousel,
|
|
153
|
+
buttons: carousel.buttons.filter((_, index) => index !== buttonIndex),
|
|
154
|
+
})));
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const addCarouselButton = () => {
|
|
158
|
+
setCarouselData(
|
|
159
|
+
carouselData.map((item, index) => index === carouselIndex
|
|
160
|
+
? { ...item, buttons: [...buttonData, INITIAL_CAROUSEL_PHONE_NUMBER_DATA] }
|
|
161
|
+
: item)
|
|
162
|
+
);
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const renderButtonContent = (buttonType, buttonIndex) => (
|
|
166
|
+
<>
|
|
167
|
+
<CapRow className="text-box-container">
|
|
168
|
+
<CapColumn span={24}>
|
|
169
|
+
{/* Button text */}
|
|
170
|
+
<CapHeading type="h4" className="cta-label">
|
|
171
|
+
{formatMessage(capWhatsappCTAMsg.ctaButtonText)}
|
|
172
|
+
<CapTooltipWithInfo
|
|
173
|
+
infoIconProps={{
|
|
174
|
+
style: { marginLeft: CAP_SPACE_04 },
|
|
175
|
+
}}
|
|
176
|
+
autoAdjustOverflow
|
|
177
|
+
placement="right"
|
|
178
|
+
title={formatMessage(capWhatsappCTAMsg.ctaButtonTextTooltip)}
|
|
179
|
+
/>
|
|
180
|
+
</CapHeading>
|
|
181
|
+
<CapInput
|
|
182
|
+
className="whatsapp-cta-button-text"
|
|
183
|
+
onChange={({ target: { value } }) => onButtonTextChange(value, buttonIndex)}
|
|
184
|
+
placeholder={formatMessage(capWhatsappCTAMsg.ctaButtonTextPlaceholder)}
|
|
185
|
+
value={buttonData[buttonIndex].text}
|
|
186
|
+
size="large"
|
|
187
|
+
maxLength={BTN_MAX_LENGTH}
|
|
188
|
+
errorMessage={buttonData[buttonIndex]?.textError}
|
|
189
|
+
/>
|
|
190
|
+
{renderLength(buttonData[buttonIndex]?.text?.length, BTN_MAX_LENGTH)}
|
|
191
|
+
</CapColumn>
|
|
192
|
+
</CapRow>
|
|
193
|
+
{buttonType === PHONE_NUMBER && (
|
|
194
|
+
<CapRow className="text-box-container">
|
|
195
|
+
<CapColumn span={24}>
|
|
196
|
+
{/* phone number */}
|
|
197
|
+
<CapHeading type="h4" className="cta-label">
|
|
198
|
+
{formatMessage(capWhatsappCTAMsg.ctaPhoneNo)}
|
|
199
|
+
</CapHeading>
|
|
200
|
+
<PhoneInput
|
|
201
|
+
placeholder={formatMessage(capWhatsappCTAMsg.ctaPhoneNoPlaceholder)}
|
|
202
|
+
autoFormat={false}
|
|
203
|
+
countryCodeEditable={false}
|
|
204
|
+
value={buttonData[buttonIndex].phone_number}
|
|
205
|
+
onChange={(value) => onValueChange(buttonIndex, [{fieldName: 'phone_number', value}])}
|
|
206
|
+
country="in"
|
|
207
|
+
className="cta-phone-number carousel-button-phone-number"
|
|
208
|
+
/>
|
|
209
|
+
{renderLength(buttonData[buttonIndex]?.phone_number.length, PHONE_NUMBER_MAX_LENGTH)}
|
|
210
|
+
</CapColumn>
|
|
211
|
+
</CapRow>
|
|
212
|
+
)}
|
|
213
|
+
{buttonType === URL
|
|
214
|
+
&& (
|
|
215
|
+
<CapRow className="text-box-container">
|
|
216
|
+
<CapColumn span={6}>
|
|
217
|
+
{/* URL Type */}
|
|
218
|
+
<CapHeading type="h4" className="cta-label">
|
|
219
|
+
{formatMessage(capWhatsappCTAMsg.ctaWebsiteType)}
|
|
220
|
+
</CapHeading>
|
|
221
|
+
<CapSelect
|
|
222
|
+
id="whatsapp-carousel-button-url-type"
|
|
223
|
+
options={
|
|
224
|
+
hostName === HOST_TWILIO
|
|
225
|
+
? TWILIO_URL_OPTIONS
|
|
226
|
+
: KARIX_GUPSHUP_URL_OPTIONS
|
|
227
|
+
}
|
|
228
|
+
onChange={(value) => onValueChange(buttonIndex, [{fieldName: 'urlType', value}])}
|
|
229
|
+
value={buttonData[buttonIndex]?.urlType}
|
|
230
|
+
/>
|
|
231
|
+
</CapColumn>
|
|
232
|
+
<CapColumn span={18}>
|
|
233
|
+
{/* cta url */}
|
|
234
|
+
<CapHeading type="h4" className="cta-label">
|
|
235
|
+
{formatMessage(capWhatsappCTAMsg.ctaWebsiteUrl)}
|
|
236
|
+
{buttonData[buttonIndex]?.urlType === DYNAMIC_URL && (
|
|
237
|
+
<CapTooltipWithInfo
|
|
238
|
+
infoIconProps={{
|
|
239
|
+
style: { marginLeft: CAP_SPACE_04 },
|
|
240
|
+
}}
|
|
241
|
+
autoAdjustOverflow
|
|
242
|
+
placement="right"
|
|
243
|
+
title={formatMessage(capWhatsappCTAMsg.dynamicUrlTooltip, { one: '{{1}}' })}
|
|
244
|
+
/>
|
|
245
|
+
)}
|
|
246
|
+
</CapHeading>
|
|
247
|
+
<CapInput
|
|
248
|
+
className="whatsapp-cta-url"
|
|
249
|
+
onChange={(event) => onUrlChange(event, buttonData[buttonIndex]?.urlType, buttonIndex)}
|
|
250
|
+
placeholder={
|
|
251
|
+
buttonData[buttonIndex]?.urlType === DYNAMIC_URL
|
|
252
|
+
? formatMessage(capWhatsappCTAMsg.ctaDynamicPlaceholder)
|
|
253
|
+
: formatMessage(capWhatsappCTAMsg.ctaStaticPlaceholder)
|
|
254
|
+
}
|
|
255
|
+
value={buttonData[buttonIndex]?.url}
|
|
256
|
+
size="large"
|
|
257
|
+
maxLength={URL_MAX_LENGTH}
|
|
258
|
+
errorMessage={buttonData[buttonIndex]?.urlError || ''}
|
|
259
|
+
/>
|
|
260
|
+
{renderLength(buttonData[buttonIndex]?.url?.length, URL_MAX_LENGTH)}
|
|
261
|
+
</CapColumn>
|
|
262
|
+
</CapRow>
|
|
263
|
+
)
|
|
264
|
+
}
|
|
265
|
+
{/* it render save and delete button */}
|
|
266
|
+
<CapRow className="whatsapp-cta-save-delete-btn whatsapp-carousel-save-edit-btn">
|
|
267
|
+
<CapTooltip
|
|
268
|
+
title={
|
|
269
|
+
ctaSaveDisabled(buttonIndex)
|
|
270
|
+
&& formatMessage(capWhatsappCTAMsg.ctaSaveDisabled)
|
|
271
|
+
}
|
|
272
|
+
placement="bottom"
|
|
273
|
+
>
|
|
274
|
+
<div className="button-disabled-tooltip-wrapper">
|
|
275
|
+
<CapButton
|
|
276
|
+
onClick={() => {
|
|
277
|
+
handleSaveButton(buttonIndex);
|
|
278
|
+
}}
|
|
279
|
+
disabled={ctaSaveDisabled(buttonIndex)}
|
|
280
|
+
className="whatsapp-cta-save-btn"
|
|
281
|
+
>
|
|
282
|
+
{formatMessage(globalMessages.save)}
|
|
283
|
+
</CapButton>
|
|
284
|
+
{buttonData.length > 1 && buttonIndex > 0 && parseInt(carouselIndex) === 0 && (
|
|
285
|
+
<CapButton
|
|
286
|
+
onClick={() => {
|
|
287
|
+
handleDeleteButton(buttonIndex);
|
|
288
|
+
}}
|
|
289
|
+
className="whatsapp-cta-delete-btn whatsapp-carousel-delete-button"
|
|
290
|
+
type="secondary"
|
|
291
|
+
>
|
|
292
|
+
{formatMessage(globalMessages.delete)}
|
|
293
|
+
</CapButton>
|
|
294
|
+
)}
|
|
295
|
+
</div>
|
|
296
|
+
</CapTooltip>
|
|
297
|
+
</CapRow>
|
|
298
|
+
</>
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
const isCarouselAddButtonDisable = buttonData?.length === 1 && !buttonData?.[0]?.isSaved;
|
|
302
|
+
|
|
303
|
+
return (
|
|
304
|
+
<CapRow>
|
|
305
|
+
{buttonData.map((button, index) => {
|
|
306
|
+
const isPhoneNumberType = button?.buttonType === PHONE_NUMBER;
|
|
307
|
+
const isURLtype = button?.buttonType === URL;
|
|
308
|
+
if (button.isSaved || isEditFlow) {
|
|
309
|
+
return (
|
|
310
|
+
<CapRow
|
|
311
|
+
key={`${button.buttonType}_${index}`}
|
|
312
|
+
className="cap-whatsapp-saved-cta cap-whatsapp-saved-carousel-button margin-t-12"
|
|
313
|
+
align="middle"
|
|
314
|
+
type="flex"
|
|
315
|
+
style={{ marginLeft: isEditFlow ? 0 : '' }}
|
|
316
|
+
>
|
|
317
|
+
<CapColumn
|
|
318
|
+
span={1}
|
|
319
|
+
className={`${isPhoneNumberType ? 'whatsapp-saved-cta-phone-icon' : ''}`}
|
|
320
|
+
>
|
|
321
|
+
<CapIcon size="s" type={isPhoneNumberType ? 'call' : isURLtype ? 'launch' : 'six-dots'} />
|
|
322
|
+
</CapColumn>
|
|
323
|
+
<CapColumn span={6}>
|
|
324
|
+
<CapLabel
|
|
325
|
+
type="label2"
|
|
326
|
+
className="whatsapp-saved-cta-button-text"
|
|
327
|
+
>
|
|
328
|
+
{button?.text}
|
|
329
|
+
</CapLabel>
|
|
330
|
+
</CapColumn>
|
|
331
|
+
{isPhoneNumberType && (
|
|
332
|
+
<CapColumn span={10} align="left">
|
|
333
|
+
<CapLabel className="phone">
|
|
334
|
+
{button?.phone_number}
|
|
335
|
+
</CapLabel>
|
|
336
|
+
</CapColumn>
|
|
337
|
+
)}
|
|
338
|
+
{isURLtype && (
|
|
339
|
+
<>
|
|
340
|
+
<CapColumn span={3}>
|
|
341
|
+
<CapLabel className="url-type" type="label2">
|
|
342
|
+
{button?.urlType === STATIC_URL
|
|
343
|
+
? formatMessage(capWhatsappCTAMsg.ctaWebsiteTypeStatic)
|
|
344
|
+
: formatMessage(capWhatsappCTAMsg.ctaWebsiteTypeDynamic)}
|
|
345
|
+
</CapLabel>
|
|
346
|
+
</CapColumn>
|
|
347
|
+
<CapTooltip title={button?.url} placement="top">
|
|
348
|
+
<CapColumn span={7} style={{ marginRight: '0px' }}>
|
|
349
|
+
<CapLabel className="url">{button?.url}</CapLabel>
|
|
350
|
+
</CapColumn>
|
|
351
|
+
</CapTooltip>
|
|
352
|
+
</>
|
|
353
|
+
)}
|
|
354
|
+
{!isEditFlow && (
|
|
355
|
+
<>
|
|
356
|
+
<CapColumn
|
|
357
|
+
span={1}
|
|
358
|
+
className="whatsapp-saved-cta-edit-icon"
|
|
359
|
+
onClick={() => handleEditButton(index)}
|
|
360
|
+
>
|
|
361
|
+
<CapIcon size="s" type="edit" />
|
|
362
|
+
</CapColumn>
|
|
363
|
+
{parseInt(carouselIndex) === 0 && (
|
|
364
|
+
<CapColumn span={1}>
|
|
365
|
+
<CapButton type="flat" className="whatsapp-carousel-delete-icon-btn" onClick={() => handleDeleteButton(index)} disabled={buttonData?.length === 1}>
|
|
366
|
+
<CapIcon size="s" type="delete" />
|
|
367
|
+
</CapButton>
|
|
368
|
+
</CapColumn>
|
|
369
|
+
)}
|
|
370
|
+
</>
|
|
371
|
+
)}
|
|
372
|
+
{isEditFlow && button?.urlType === DYNAMIC_URL && button?.url.includes('{{1}}') && (
|
|
373
|
+
<CapColumn>
|
|
374
|
+
<TagList
|
|
375
|
+
className="whatsapp-cta-taglist"
|
|
376
|
+
label={formatMessage(capWhatsappCTAMsg.whatsappCtaTagListLabel)}
|
|
377
|
+
onTagSelect={(data) => onTagSelect(data, index, button?.url)}
|
|
378
|
+
tags={tags}
|
|
379
|
+
injectedTags={injectedTags}
|
|
380
|
+
selectedOfferDetails={selectedOfferDetails}
|
|
381
|
+
/>
|
|
382
|
+
</CapColumn>
|
|
383
|
+
)}
|
|
384
|
+
{isEditFlow && button?.urlType === DYNAMIC_URL && !button?.url.includes('{{1}}') && (
|
|
385
|
+
<CapColumn
|
|
386
|
+
span={1}
|
|
387
|
+
onClick={() => revertTagSelect(index, button?.url)}
|
|
388
|
+
className="whatsapp-cta-tag-revert"
|
|
389
|
+
>
|
|
390
|
+
<CapTooltip
|
|
391
|
+
title={formatMessage(capWhatsappCTAMsg.whatsappCtaTagListRevert)}
|
|
392
|
+
placement="top"
|
|
393
|
+
>
|
|
394
|
+
<CapIcon size="s" type="return" />
|
|
395
|
+
</CapTooltip>
|
|
396
|
+
</CapColumn>
|
|
397
|
+
)}
|
|
398
|
+
</CapRow>
|
|
399
|
+
);
|
|
400
|
+
} return (
|
|
401
|
+
<CapRow
|
|
402
|
+
key={`${button.buttonType}_${index}`}
|
|
403
|
+
className="cap-whatsapp-carousel-button"
|
|
404
|
+
>
|
|
405
|
+
<CapLabel type="label16" className="button-type-heading">{formatMessage(capWhatsappMsg.buttonType)}</CapLabel>
|
|
406
|
+
<CapRadioGroup
|
|
407
|
+
id="carousel-button-radio"
|
|
408
|
+
options={carouselButtonOptions}
|
|
409
|
+
value={button.buttonType}
|
|
410
|
+
onChange={(e) => handleButtonType(e, index)}
|
|
411
|
+
className="whatsapp-media-radio"
|
|
412
|
+
/>
|
|
413
|
+
{renderButtonContent(button.buttonType, index)}
|
|
414
|
+
</CapRow>
|
|
415
|
+
);
|
|
416
|
+
})}
|
|
417
|
+
<CapRow>
|
|
418
|
+
{buttonData?.length < 2 && !isEditFlow && parseInt(carouselIndex) === 0 && (
|
|
419
|
+
<CapRow>
|
|
420
|
+
<CapTooltip
|
|
421
|
+
title={
|
|
422
|
+
isCarouselAddButtonDisable ? formatMessage(capWhatsappCTAMsg.ctaAddDisabled) : ""
|
|
423
|
+
}
|
|
424
|
+
placement="right"
|
|
425
|
+
>
|
|
426
|
+
<div className="button-disabled-tooltip-wrapper">
|
|
427
|
+
<CapButton
|
|
428
|
+
type="flat"
|
|
429
|
+
id="whatsapp-quick-reply-add-button"
|
|
430
|
+
disabled={isCarouselAddButtonDisable}
|
|
431
|
+
className="margin-t-12 margin-l-24"
|
|
432
|
+
isAddBtn
|
|
433
|
+
onClick={addCarouselButton}
|
|
434
|
+
>
|
|
435
|
+
{formatMessage(capWhatsappCTAMsg.addButton)}
|
|
436
|
+
</CapButton>
|
|
437
|
+
</div>
|
|
438
|
+
</CapTooltip>
|
|
439
|
+
</CapRow>
|
|
440
|
+
)}
|
|
441
|
+
</CapRow>
|
|
442
|
+
</CapRow>
|
|
443
|
+
);
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
export default injectIntl(CapWhatsappCarouselButton);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
@import "~@capillarytech/cap-ui-library/styles/_variables";
|
|
2
|
+
|
|
3
|
+
.cap-whatsapp-carousel-button {
|
|
4
|
+
border: solid 0.063rem $CAP_G06;
|
|
5
|
+
padding: $CAP_SPACE_24;
|
|
6
|
+
border-radius: 0.285rem;
|
|
7
|
+
margin-top: $CAP_SPACE_12;
|
|
8
|
+
.button-type-heading {
|
|
9
|
+
margin-bottom: $CAP_SPACE_12;
|
|
10
|
+
}
|
|
11
|
+
.carousel-button-phone-number {
|
|
12
|
+
.form-control {
|
|
13
|
+
width: 100%;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
.text-box-container {
|
|
17
|
+
margin-top: $CAP_SPACE_16;
|
|
18
|
+
}
|
|
19
|
+
#whatsapp-carousel-button-url-type {
|
|
20
|
+
width: 90%;
|
|
21
|
+
}
|
|
22
|
+
.whatsapp-carousel-save-edit-btn {
|
|
23
|
+
margin-top: $CAP_SPACE_24;
|
|
24
|
+
}
|
|
25
|
+
.whatsapp-carousel-delete-button {
|
|
26
|
+
margin-left: $CAP_SPACE_12;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.cap-whatsapp-saved-carousel-button {
|
|
31
|
+
width: 100%;
|
|
32
|
+
margin-left: 0;
|
|
33
|
+
margin-top: $CAP_SPACE_12;
|
|
34
|
+
.whatsapp-carousel-delete-icon-btn {
|
|
35
|
+
padding: 0;
|
|
36
|
+
margin: 0;
|
|
37
|
+
height: auto;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -44,7 +44,7 @@ import EDMEditor from "../Edmeditor";
|
|
|
44
44
|
import BeeEditor from '../../v2Containers/BeeEditor';
|
|
45
45
|
import CustomPopOver from '../CustomPopOver';
|
|
46
46
|
import messages from './messages';
|
|
47
|
-
import { makeSelectMetaEntities, selectCurrentOrgDetails, selectLiquidStateDetails
|
|
47
|
+
import { makeSelectMetaEntities, selectCurrentOrgDetails, selectLiquidStateDetails } from "../../v2Containers/Cap/selectors";
|
|
48
48
|
import * as actions from "../../v2Containers/Cap/actions";
|
|
49
49
|
import './_formBuilder.scss';
|
|
50
50
|
import {updateCharCount, checkUnicode} from "../../utils/smsCharCountV2";
|
|
@@ -56,7 +56,6 @@ import { OUTBOUND } from './constants';
|
|
|
56
56
|
import { GET_TRANSLATION_MAPPED } from '../../containers/TagList/constants';
|
|
57
57
|
import moment from 'moment';
|
|
58
58
|
import { CUSTOMER_BARCODE_TAG , COPY_OF, ENTRY_TRIGGER_TAG_REGEX} from '../../containers/App/constants';
|
|
59
|
-
import { REQUEST } from '../../v2Containers/Cap/constants'
|
|
60
59
|
import { hasLiquidSupportFeature, isEmailUnsubscribeTagMandatory } from '../../utils/common';
|
|
61
60
|
import { isUrl } from '../../v2Containers/Line/Container/Wrapper/utils';
|
|
62
61
|
import { bindActionCreators } from 'redux';
|
|
@@ -1083,7 +1082,6 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1083
1082
|
}
|
|
1084
1083
|
});}
|
|
1085
1084
|
}
|
|
1086
|
-
|
|
1087
1085
|
saveForm(saveForm) {
|
|
1088
1086
|
if (this.props.isNewVersionFlow && !saveForm) {
|
|
1089
1087
|
this.props.getValidationData();
|
|
@@ -3795,7 +3793,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
3795
3793
|
|
|
3796
3794
|
|
|
3797
3795
|
return (
|
|
3798
|
-
<CapSpin spinning={Boolean(
|
|
3796
|
+
<CapSpin spinning={Boolean(this.liquidFlow && this.props.liquidExtractionInProgress)} tip={this.props.intl.formatMessage(messages.liquidSpinText)} >
|
|
3799
3797
|
<CapRow>
|
|
3800
3798
|
{this.props.schema && this.renderForm()}
|
|
3801
3799
|
<SlideBox
|
|
@@ -3829,7 +3827,6 @@ FormBuilder.defaultProps = {
|
|
|
3829
3827
|
isNewVersionFlow: false,
|
|
3830
3828
|
userLocale: localStorage.getItem('jlocale') || 'en',
|
|
3831
3829
|
showLiquidErrorInFooter: () => {},
|
|
3832
|
-
metaIdStatus: false,
|
|
3833
3830
|
};
|
|
3834
3831
|
|
|
3835
3832
|
FormBuilder.propTypes = {
|
|
@@ -3877,13 +3874,12 @@ FormBuilder.propTypes = {
|
|
|
3877
3874
|
isFullMode: PropTypes.bool,
|
|
3878
3875
|
currentOrgDetails: PropTypes.object,
|
|
3879
3876
|
liquidExtractionInProgress: PropTypes.bool,
|
|
3880
|
-
showLiquidErrorInFooter: PropTypes.func
|
|
3877
|
+
showLiquidErrorInFooter: PropTypes.func,
|
|
3881
3878
|
};
|
|
3882
3879
|
|
|
3883
3880
|
const mapStateToProps = createStructuredSelector({
|
|
3884
3881
|
currentOrgDetails: selectCurrentOrgDetails(),
|
|
3885
3882
|
liquidExtractionInProgress: selectLiquidStateDetails(),
|
|
3886
|
-
metaIdStatus: selectMetaTagsStatus(),
|
|
3887
3883
|
metaEntities: makeSelectMetaEntities(),
|
|
3888
3884
|
});
|
|
3889
3885
|
|
|
@@ -567,6 +567,10 @@
|
|
|
567
567
|
font-size: 10px;
|
|
568
568
|
font-family: 'open-sans';
|
|
569
569
|
}
|
|
570
|
+
&.message-pop-carousel {
|
|
571
|
+
position: relative;
|
|
572
|
+
margin-right: 4px;
|
|
573
|
+
}
|
|
570
574
|
}
|
|
571
575
|
}
|
|
572
576
|
.android-push-message-Container, .iphone-push-message-Container{
|
|
@@ -747,6 +751,11 @@
|
|
|
747
751
|
width: 153px;
|
|
748
752
|
}
|
|
749
753
|
}
|
|
754
|
+
|
|
755
|
+
.msg-container-carousel {
|
|
756
|
+
display: flex;
|
|
757
|
+
flex-direction: column;
|
|
758
|
+
}
|
|
750
759
|
}
|
|
751
760
|
|
|
752
761
|
.align-center {
|