@capillarytech/creatives-library 7.12.18 → 7.12.19
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 +2 -1
- package/v2Components/CapActionButton/index.js +116 -0
- package/v2Components/CapActionButton/index.scss +12 -0
- package/v2Components/CapActionButton/messages.js +29 -0
- package/v2Containers/Cap/messages.js +4 -0
- package/v2Containers/Rcs/constants.js +3 -0
- package/v2Containers/Rcs/index.js +78 -8
- package/v2Containers/Rcs/messages.js +31 -3
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capillarytech/creatives-library",
|
|
3
3
|
"author": "meharaj",
|
|
4
|
-
"version": "7.12.
|
|
4
|
+
"version": "7.12.19",
|
|
5
5
|
"description": "Capillary creatives ui",
|
|
6
6
|
"main": "./index.js",
|
|
7
7
|
"module": "./index.es.js",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"@capillarytech/cap-ui-utils": "1.4.2",
|
|
19
19
|
"@mailupinc/bee-plugin": "^1.2.0",
|
|
20
20
|
"babel-cli": "^6.26.0",
|
|
21
|
+
"babel-node": "0.0.1-security",
|
|
21
22
|
"chalk": "1.1.3",
|
|
22
23
|
"flow": "^0.2.3",
|
|
23
24
|
"git": "^0.1.5",
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { injectIntl, intlShape, FormattedMessage } from 'react-intl';
|
|
4
|
+
import {
|
|
5
|
+
CapRow,
|
|
6
|
+
CapHeading,
|
|
7
|
+
CapInput,
|
|
8
|
+
CapDivider,
|
|
9
|
+
CapButton,
|
|
10
|
+
CapTooltip,
|
|
11
|
+
CapLabel,
|
|
12
|
+
} from '@capillarytech/cap-ui-library';
|
|
13
|
+
|
|
14
|
+
import { isUrl } from '../../v2Containers/Line/Container/Wrapper/utils';
|
|
15
|
+
import globalMessages from '../../v2Containers/Cap/messages';
|
|
16
|
+
import messages from './messages';
|
|
17
|
+
import './index.scss';
|
|
18
|
+
const CapActionButton = (props) => {
|
|
19
|
+
const {
|
|
20
|
+
intl,
|
|
21
|
+
buttonTextlen,
|
|
22
|
+
type,
|
|
23
|
+
updateButtonChange,
|
|
24
|
+
suggestions = [],
|
|
25
|
+
} = props;
|
|
26
|
+
const {text = "", url = "" } = suggestions[0] || {};
|
|
27
|
+
const [buttonText, setButtonText] = useState(text || '');
|
|
28
|
+
const [buttonLink, setButtonLink] = useState(url || '');
|
|
29
|
+
const [buttonURLErrorMessage, updateButtonURLErrorMessage] = useState(false);
|
|
30
|
+
|
|
31
|
+
const { formatMessage } = intl;
|
|
32
|
+
|
|
33
|
+
const onButtonTextChange = (e) => {
|
|
34
|
+
const val = e.target.value;
|
|
35
|
+
setButtonText(val);
|
|
36
|
+
updateButtonChange([{
|
|
37
|
+
type,
|
|
38
|
+
text: val,
|
|
39
|
+
url: buttonLink,
|
|
40
|
+
}]);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const onButtonLinkChange = (e) => {
|
|
44
|
+
const val = e.target.value;
|
|
45
|
+
setButtonLink(val);
|
|
46
|
+
let errorMessage = false;
|
|
47
|
+
if (!isUrl(val)) {
|
|
48
|
+
errorMessage = formatMessage(messages.inValidUrliErrorMessage);
|
|
49
|
+
} else {
|
|
50
|
+
updateButtonChange([{
|
|
51
|
+
type,
|
|
52
|
+
text: buttonText,
|
|
53
|
+
url: val,
|
|
54
|
+
}]);
|
|
55
|
+
}
|
|
56
|
+
updateButtonURLErrorMessage(errorMessage);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return (<CapRow
|
|
60
|
+
className="cap-action-button"
|
|
61
|
+
>
|
|
62
|
+
{/* Button text */}
|
|
63
|
+
<CapHeading type="h4">
|
|
64
|
+
<FormattedMessage {...messages.templateButtonText} />
|
|
65
|
+
</CapHeading>
|
|
66
|
+
<CapInput
|
|
67
|
+
id="rcs-template-Button-Text"
|
|
68
|
+
onChange={onButtonTextChange}
|
|
69
|
+
placeholder={formatMessage(messages.templateButtonTextPlaceholder)}
|
|
70
|
+
value={buttonText}
|
|
71
|
+
size="default"
|
|
72
|
+
maxLength={buttonTextlen}
|
|
73
|
+
suffix={
|
|
74
|
+
<CapLabel type="label1">{`${buttonText?.length} / ${buttonTextlen}`}</CapLabel>
|
|
75
|
+
}
|
|
76
|
+
/>
|
|
77
|
+
|
|
78
|
+
{/* button Link */}
|
|
79
|
+
<CapHeading
|
|
80
|
+
type="h4"
|
|
81
|
+
style={{paddingTop: "20px"}}
|
|
82
|
+
><FormattedMessage {...messages.templateButtonLink} /></CapHeading>
|
|
83
|
+
<CapInput
|
|
84
|
+
id="rcs-template-Button-link"
|
|
85
|
+
onChange={onButtonLinkChange}
|
|
86
|
+
placeholder={formatMessage(messages.templateButtonLinkPlaceholder)}
|
|
87
|
+
value={buttonLink}
|
|
88
|
+
size="default"
|
|
89
|
+
errorMessage={buttonURLErrorMessage}
|
|
90
|
+
/>
|
|
91
|
+
|
|
92
|
+
{/* divider */}
|
|
93
|
+
<CapDivider style={{ marginBottom: 16, marginTop: 23 }}/>
|
|
94
|
+
|
|
95
|
+
{/* Add button */}
|
|
96
|
+
<CapTooltip
|
|
97
|
+
placement="topLeft"
|
|
98
|
+
title={formatMessage(globalMessages.comingSoonTooltip)}
|
|
99
|
+
>
|
|
100
|
+
<CapButton
|
|
101
|
+
type="flat" style={{ opacity: "0.5",
|
|
102
|
+
cursor: "not-allowed"}} isAddBtn>
|
|
103
|
+
{formatMessage(messages.addButton)}
|
|
104
|
+
</CapButton>
|
|
105
|
+
</CapTooltip>
|
|
106
|
+
</CapRow>);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
CapActionButton.propTypes = {
|
|
110
|
+
intl: intlShape.isRequired,
|
|
111
|
+
buttonTextlen: intlShape.isRequired,
|
|
112
|
+
type: PropTypes.string,
|
|
113
|
+
updateButtonChange: PropTypes.fun,
|
|
114
|
+
suggestions: PropTypes.array,
|
|
115
|
+
};
|
|
116
|
+
export default injectIntl(CapActionButton);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl';
|
|
2
|
+
const prefix = `creatives.componentsV2.CapActionButton`;
|
|
3
|
+
|
|
4
|
+
export default defineMessages({
|
|
5
|
+
templateButtonText: {
|
|
6
|
+
id: `${prefix}.templateButtonText`,
|
|
7
|
+
defaultMessage: 'Button text',
|
|
8
|
+
},
|
|
9
|
+
templateButtonTextPlaceholder: {
|
|
10
|
+
id: `${prefix}.templateButtonTextPlaceholder`,
|
|
11
|
+
defaultMessage: 'Enter button text',
|
|
12
|
+
},
|
|
13
|
+
templateButtonLink: {
|
|
14
|
+
id: `${prefix}.templateButtonLink`,
|
|
15
|
+
defaultMessage: 'Button link',
|
|
16
|
+
},
|
|
17
|
+
templateButtonLinkPlaceholder: {
|
|
18
|
+
id: `${prefix}.templateButtonLinkPlaceholder`,
|
|
19
|
+
defaultMessage: 'Enter button link',
|
|
20
|
+
},
|
|
21
|
+
addButton: {
|
|
22
|
+
id: `${prefix}.addButton`,
|
|
23
|
+
defaultMessage: 'Add button',
|
|
24
|
+
},
|
|
25
|
+
inValidUrliErrorMessage: {
|
|
26
|
+
id: `${prefix}.inValidUrliErrorMessage`,
|
|
27
|
+
defaultMessage: 'Button URL is not valid',
|
|
28
|
+
},
|
|
29
|
+
});
|
|
@@ -185,5 +185,9 @@ export default defineMessages({
|
|
|
185
185
|
defaultMessage:
|
|
186
186
|
'Unsupported tags: {unsupportedTags}. Please remove them from this message.',
|
|
187
187
|
},
|
|
188
|
+
"comingSoonTooltip": {
|
|
189
|
+
id: `creatives.containersV2.comingSoonTooltip`,
|
|
190
|
+
defaultMessage: 'Not enabled yet. Coming soon!',
|
|
191
|
+
},
|
|
188
192
|
});
|
|
189
193
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
export const RCS = 'RCS';
|
|
2
3
|
export const SMS = 'SMS';
|
|
3
4
|
export const MEDIUM = 'MEDIUM';
|
|
@@ -17,6 +18,8 @@ export const RCS_DLT_MODE = {
|
|
|
17
18
|
export const TEMPLATE_DESC_MAX_LENGTH = 1000;
|
|
18
19
|
export const FALLBACK_MESSAGE_MAX_LENGTH = 160;
|
|
19
20
|
export const TEMPLATE_TITLE_MAX_LENGTH = 200;
|
|
21
|
+
export const TEMPLATE_BUTTON_TEXT_MAX_LENGTH = 20;
|
|
22
|
+
|
|
20
23
|
export const TAG = 'TAG';
|
|
21
24
|
export const EMBEDDED = 'embedded';
|
|
22
25
|
export const DEFAULT = 'default';
|
|
@@ -26,6 +26,9 @@ import CapMenu from '@capillarytech/cap-ui-library/CapMenu';
|
|
|
26
26
|
import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
|
|
27
27
|
import CapTooltipWithInfo from '@capillarytech/cap-ui-library/CapTooltipWithInfo';
|
|
28
28
|
import CapError from '@capillarytech/cap-ui-library/CapError';
|
|
29
|
+
import CapCheckbox from '@capillarytech/cap-ui-library/CapCheckbox';
|
|
30
|
+
import CapActionButton from '../../v2Components/CapActionButton';
|
|
31
|
+
|
|
29
32
|
import {
|
|
30
33
|
CAP_G01,
|
|
31
34
|
CAP_SPACE_16,
|
|
@@ -49,6 +52,7 @@ import {
|
|
|
49
52
|
SMS,
|
|
50
53
|
RCS_MEDIA_TYPES,
|
|
51
54
|
TEMPLATE_TITLE_MAX_LENGTH,
|
|
55
|
+
TEMPLATE_BUTTON_TEXT_MAX_LENGTH,
|
|
52
56
|
TEMPLATE_DESC_MAX_LENGTH,
|
|
53
57
|
FALLBACK_MESSAGE_MAX_LENGTH,
|
|
54
58
|
TAG,
|
|
@@ -64,7 +68,6 @@ import {
|
|
|
64
68
|
RCS_DLT_MODE,
|
|
65
69
|
MEDIUM,
|
|
66
70
|
VERTICAL,
|
|
67
|
-
RIGHT,
|
|
68
71
|
STANDALONE,
|
|
69
72
|
RICHCARD,
|
|
70
73
|
} from './constants';
|
|
@@ -78,6 +81,7 @@ import Templates from '../Templates';
|
|
|
78
81
|
import SmsTraiEdit from '../SmsTrai/Edit';
|
|
79
82
|
import TagList from '../TagList';
|
|
80
83
|
import { validateTags } from '../../utils/tagValidations';
|
|
84
|
+
const { Group: CapCheckboxGroup } = CapCheckbox;
|
|
81
85
|
export const Rcs = (props) => {
|
|
82
86
|
const {
|
|
83
87
|
intl,
|
|
@@ -126,7 +130,8 @@ export const Rcs = (props) => {
|
|
|
126
130
|
const [showDltCard, setShowDltCard] = useState(false);
|
|
127
131
|
const [fallbackPreviewmode, setFallbackPreviewmode] = useState(false);
|
|
128
132
|
const [dltPreviewData, setDltPreviewData] = useState('');
|
|
129
|
-
|
|
133
|
+
const [suggestions, setSuggestions] = useState([]);
|
|
134
|
+
const [buttonType, setButtonType] = useState('');
|
|
130
135
|
const mediaRadioOptions = [
|
|
131
136
|
{
|
|
132
137
|
value: RCS_MEDIA_TYPES.NONE,
|
|
@@ -161,12 +166,49 @@ export const Rcs = (props) => {
|
|
|
161
166
|
}
|
|
162
167
|
}
|
|
163
168
|
`;
|
|
164
|
-
|
|
169
|
+
const updateButtonChange = (val) => {
|
|
170
|
+
setSuggestions(val);
|
|
171
|
+
};
|
|
165
172
|
const RcsLabel = styled.div`
|
|
166
173
|
display: flex;
|
|
167
174
|
margin-top: 20px;
|
|
168
|
-
margin-bottom: 6px;
|
|
169
175
|
`;
|
|
176
|
+
const rcsButtonTypeOptions = [
|
|
177
|
+
{
|
|
178
|
+
label: <>
|
|
179
|
+
<div style={{display: "inline-grid"}}>
|
|
180
|
+
<CapHeading type="h4"><FormattedMessage {...messages.templateCTAButton} /></CapHeading>
|
|
181
|
+
<CapLabel type="label3" style={{ marginBottom: "17px"}}>
|
|
182
|
+
<FormattedMessage {...messages.templateCTAButtonDesc} />
|
|
183
|
+
</CapLabel>
|
|
184
|
+
</div>
|
|
185
|
+
{buttonType && <CapActionButton
|
|
186
|
+
type="CTA"
|
|
187
|
+
buttonTextlen={TEMPLATE_BUTTON_TEXT_MAX_LENGTH}
|
|
188
|
+
updateButtonChange={updateButtonChange}
|
|
189
|
+
suggestions={suggestions}
|
|
190
|
+
/>}
|
|
191
|
+
</>,
|
|
192
|
+
value: "CTA",
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
label: <CapTooltip
|
|
196
|
+
placement="topLeft"
|
|
197
|
+
title={<FormattedMessage {...globalMessages.comingSoonTooltip} />}
|
|
198
|
+
>
|
|
199
|
+
<div style={{display: "inline-grid", opacity: "0.5"}}>
|
|
200
|
+
<CapHeading type="h4" disabled>
|
|
201
|
+
<FormattedMessage {...messages.templateQRButton} />
|
|
202
|
+
</CapHeading>
|
|
203
|
+
<CapLabel type="label3" style={{ marginBottom: "17px"}} disabled>
|
|
204
|
+
<FormattedMessage {...messages.templateQRButtonDesc} />
|
|
205
|
+
</CapLabel>
|
|
206
|
+
</div>
|
|
207
|
+
</CapTooltip>,
|
|
208
|
+
value: "QR",
|
|
209
|
+
disabled: "true",
|
|
210
|
+
},
|
|
211
|
+
];
|
|
170
212
|
|
|
171
213
|
//gets template details
|
|
172
214
|
const paramObj = params || {};
|
|
@@ -303,7 +345,7 @@ export const Rcs = (props) => {
|
|
|
303
345
|
};
|
|
304
346
|
// tag Code end
|
|
305
347
|
|
|
306
|
-
const renderLabel = (value, showLabel) => (
|
|
348
|
+
const renderLabel = (value, showLabel, desc) => (<>
|
|
307
349
|
<RcsLabel>
|
|
308
350
|
<CapHeading type="h4">{formatMessage(messages[value])}</CapHeading>
|
|
309
351
|
{showLabel && (
|
|
@@ -312,6 +354,12 @@ export const Rcs = (props) => {
|
|
|
312
354
|
</CapHeading>
|
|
313
355
|
)}
|
|
314
356
|
</RcsLabel>
|
|
357
|
+
{desc && (
|
|
358
|
+
<CapLabel type="label3" style={{ marginBottom: "17px"}}>
|
|
359
|
+
{formatMessage(messages[desc])}
|
|
360
|
+
</CapLabel>
|
|
361
|
+
)}
|
|
362
|
+
</>
|
|
315
363
|
);
|
|
316
364
|
|
|
317
365
|
const onTemplateNameChange = ({ target: { value } }) => {
|
|
@@ -399,7 +447,9 @@ export const Rcs = (props) => {
|
|
|
399
447
|
}
|
|
400
448
|
return errorMessage;
|
|
401
449
|
};
|
|
402
|
-
|
|
450
|
+
const onChangeButtonTypes = (val) => {
|
|
451
|
+
setButtonType(val[0]);
|
|
452
|
+
};
|
|
403
453
|
const renderTextComponent = (
|
|
404
454
|
<>
|
|
405
455
|
{/* template title */}
|
|
@@ -452,6 +502,14 @@ export const Rcs = (props) => {
|
|
|
452
502
|
value={templateDesc || ''}
|
|
453
503
|
maxLength={1000}
|
|
454
504
|
/>
|
|
505
|
+
{renderLabel("templateButton", true, "templateButtonDesc")}
|
|
506
|
+
<CapCheckboxGroup
|
|
507
|
+
style={{display: "grid"}}
|
|
508
|
+
options={rcsButtonTypeOptions}
|
|
509
|
+
value={buttonType}
|
|
510
|
+
onChange={onChangeButtonTypes}
|
|
511
|
+
/>
|
|
512
|
+
|
|
455
513
|
</>
|
|
456
514
|
);
|
|
457
515
|
|
|
@@ -815,6 +873,7 @@ export const Rcs = (props) => {
|
|
|
815
873
|
title: templateTitle,
|
|
816
874
|
description: templateDesc,
|
|
817
875
|
mediaType: templateMediaType,
|
|
876
|
+
...(suggestions.length > 0 && {suggestions}),
|
|
818
877
|
...(!isMediaTypeNone && {
|
|
819
878
|
media: {
|
|
820
879
|
mediaUrl: rcsImageSrc,
|
|
@@ -930,6 +989,12 @@ export const Rcs = (props) => {
|
|
|
930
989
|
if (!isMediaTypeNone && rcsImageSrc === '') {
|
|
931
990
|
return true;
|
|
932
991
|
}
|
|
992
|
+
|
|
993
|
+
// if call to action (Button text & link) is not added
|
|
994
|
+
const {text, url} = suggestions[0] || {};
|
|
995
|
+
if (buttonType && !(text && url) ) {
|
|
996
|
+
return true;
|
|
997
|
+
}
|
|
933
998
|
if (templateDescError || fallbackMessageError) {
|
|
934
999
|
return true;
|
|
935
1000
|
}
|
|
@@ -951,7 +1016,12 @@ export const Rcs = (props) => {
|
|
|
951
1016
|
);
|
|
952
1017
|
}
|
|
953
1018
|
const tempMsg = dltPreviewData === '' ? fallbackMessage : dltPreviewData;
|
|
954
|
-
|
|
1019
|
+
let mediaTypeMsg = isMediaTypeNone ? 'textMessage' : 'image';
|
|
1020
|
+
mediaTypeMsg = formatMessage(messages[mediaTypeMsg]);
|
|
1021
|
+
const {text, url} = suggestions[0] || {};
|
|
1022
|
+
if (buttonType && !(text && url) ) {
|
|
1023
|
+
mediaTypeMsg = `${formatMessage(messages.buttonTextAndUrl)} ${mediaTypeMsg} `;
|
|
1024
|
+
}
|
|
955
1025
|
return (
|
|
956
1026
|
<>
|
|
957
1027
|
<CapRow className="cap-rcs-creatives">
|
|
@@ -993,7 +1063,7 @@ export const Rcs = (props) => {
|
|
|
993
1063
|
title={
|
|
994
1064
|
isDisableDone()
|
|
995
1065
|
? formatMessage(messages.rcsDoneBtnToolTip, {
|
|
996
|
-
type:
|
|
1066
|
+
type: mediaTypeMsg,
|
|
997
1067
|
})
|
|
998
1068
|
: ''
|
|
999
1069
|
}
|
|
@@ -16,7 +16,7 @@ export default defineMessages({
|
|
|
16
16
|
},
|
|
17
17
|
image: {
|
|
18
18
|
id: `${prefix}.image`,
|
|
19
|
-
defaultMessage: 'image',
|
|
19
|
+
defaultMessage: 'and image',
|
|
20
20
|
},
|
|
21
21
|
mediaVideo: {
|
|
22
22
|
id: `${prefix}.mediaVideo`,
|
|
@@ -52,7 +52,7 @@ export default defineMessages({
|
|
|
52
52
|
},
|
|
53
53
|
textMessage: {
|
|
54
54
|
id: `${prefix}.textMessage`,
|
|
55
|
-
defaultMessage: 'text message',
|
|
55
|
+
defaultMessage: 'and text message',
|
|
56
56
|
},
|
|
57
57
|
templateDescLengthError: {
|
|
58
58
|
id: `${prefix}.templateDescLengthError`,
|
|
@@ -60,7 +60,7 @@ export default defineMessages({
|
|
|
60
60
|
},
|
|
61
61
|
rcsDoneBtnToolTip: {
|
|
62
62
|
id: `${prefix}.rcsDoneBtnToolTip`,
|
|
63
|
-
defaultMessage: 'Please add template name
|
|
63
|
+
defaultMessage: 'Please add template name {type} to proceed further',
|
|
64
64
|
},
|
|
65
65
|
fallbackLabel: {
|
|
66
66
|
id: `${prefix}.fallbackLabel`,
|
|
@@ -119,4 +119,32 @@ export default defineMessages({
|
|
|
119
119
|
id: `${prefix}.fallbackPreviewtitle`,
|
|
120
120
|
defaultMessage: 'Preview of fallback SMS',
|
|
121
121
|
},
|
|
122
|
+
templateButton: {
|
|
123
|
+
id: `${prefix}.templateTitle`,
|
|
124
|
+
defaultMessage: 'Buttons',
|
|
125
|
+
},
|
|
126
|
+
templateButtonDesc: {
|
|
127
|
+
id: `${prefix}.templateButtonDesc`,
|
|
128
|
+
defaultMessage: 'These will be show clickable buttons below your message.',
|
|
129
|
+
},
|
|
130
|
+
templateCTAButton: {
|
|
131
|
+
id: `${prefix}.templateCTAButton`,
|
|
132
|
+
defaultMessage: 'Call to action',
|
|
133
|
+
},
|
|
134
|
+
templateCTAButtonDesc: {
|
|
135
|
+
id: `${prefix}.templateCTAButtonDesc`,
|
|
136
|
+
defaultMessage: 'Create up to 3 buttons that let customers respond to your messages or take action.',
|
|
137
|
+
},
|
|
138
|
+
templateQRButton: {
|
|
139
|
+
id: `${prefix}.templateQRButton`,
|
|
140
|
+
defaultMessage: 'Quick reply',
|
|
141
|
+
},
|
|
142
|
+
templateQRButtonDesc: {
|
|
143
|
+
id: `${prefix}.templateQRButtonDesc`,
|
|
144
|
+
defaultMessage: 'Create up to 3 buttons that let customers respond to your messages or take action.',
|
|
145
|
+
},
|
|
146
|
+
buttonTextAndUrl: {
|
|
147
|
+
id: `${prefix}.buttonTextAndUrl`,
|
|
148
|
+
defaultMessage: ', CTA button text & url ',
|
|
149
|
+
},
|
|
122
150
|
});
|