@capillarytech/creatives-library 7.12.18 → 7.12.20

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "7.12.18",
4
+ "version": "7.12.20",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -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,12 @@
1
+
2
+ @import'~@capillarytech/cap-ui-library/styles/_variables';
3
+
4
+
5
+ .cap-action-button {
6
+ border: solid 1px $CAP_G06;
7
+ margin-left: 20px;
8
+ width: 478px;
9
+ height: 246px;
10
+ padding: 20px 20px 55px;
11
+ border-radius: 4px;
12
+ }
@@ -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 || {};
@@ -194,6 +236,7 @@ export const Rcs = (props) => {
194
236
  mediaType = RCS_MEDIA_TYPES.NONE,
195
237
  title = '',
196
238
  description = '',
239
+ suggestions: rcsSuggestions = [],
197
240
  } = cardContent[0] || {};
198
241
  const { message, templateConfigs = {} } = smsFallBackContent;
199
242
  setTemplateName(name);
@@ -203,6 +246,11 @@ export const Rcs = (props) => {
203
246
  setTemplateDesc(description);
204
247
  setFallbackMessage(message);
205
248
  setEditFlow(true);
249
+ if (rcsSuggestions.length > 0) {
250
+ setSuggestions(rcsSuggestions);
251
+ setButtonType(["CTA"]);
252
+ }
253
+
206
254
  // for DLT Fallback message
207
255
  if (isDltEnabled) {
208
256
  const {
@@ -303,7 +351,7 @@ export const Rcs = (props) => {
303
351
  };
304
352
  // tag Code end
305
353
 
306
- const renderLabel = (value, showLabel) => (
354
+ const renderLabel = (value, showLabel, desc) => (<>
307
355
  <RcsLabel>
308
356
  <CapHeading type="h4">{formatMessage(messages[value])}</CapHeading>
309
357
  {showLabel && (
@@ -312,6 +360,12 @@ export const Rcs = (props) => {
312
360
  </CapHeading>
313
361
  )}
314
362
  </RcsLabel>
363
+ {desc && (
364
+ <CapLabel type="label3" style={{ marginBottom: "17px"}}>
365
+ {formatMessage(messages[desc])}
366
+ </CapLabel>
367
+ )}
368
+ </>
315
369
  );
316
370
 
317
371
  const onTemplateNameChange = ({ target: { value } }) => {
@@ -399,7 +453,10 @@ export const Rcs = (props) => {
399
453
  }
400
454
  return errorMessage;
401
455
  };
402
-
456
+ const onChangeButtonTypes = (val) => {
457
+ setButtonType(val[0]);
458
+ setSuggestions([]);
459
+ };
403
460
  const renderTextComponent = (
404
461
  <>
405
462
  {/* template title */}
@@ -452,6 +509,14 @@ export const Rcs = (props) => {
452
509
  value={templateDesc || ''}
453
510
  maxLength={1000}
454
511
  />
512
+ {renderLabel("templateButton", true, "templateButtonDesc")}
513
+ <CapCheckboxGroup
514
+ style={{display: "grid"}}
515
+ options={rcsButtonTypeOptions}
516
+ value={buttonType}
517
+ onChange={onChangeButtonTypes}
518
+ />
519
+
455
520
  </>
456
521
  );
457
522
 
@@ -815,6 +880,7 @@ export const Rcs = (props) => {
815
880
  title: templateTitle,
816
881
  description: templateDesc,
817
882
  mediaType: templateMediaType,
883
+ ...(suggestions.length > 0 && {suggestions}),
818
884
  ...(!isMediaTypeNone && {
819
885
  media: {
820
886
  mediaUrl: rcsImageSrc,
@@ -930,6 +996,12 @@ export const Rcs = (props) => {
930
996
  if (!isMediaTypeNone && rcsImageSrc === '') {
931
997
  return true;
932
998
  }
999
+
1000
+ // if call to action (Button text & link) is not added
1001
+ const {text, url} = suggestions[0] || {};
1002
+ if (buttonType && !(text && url) ) {
1003
+ return true;
1004
+ }
933
1005
  if (templateDescError || fallbackMessageError) {
934
1006
  return true;
935
1007
  }
@@ -951,7 +1023,12 @@ export const Rcs = (props) => {
951
1023
  );
952
1024
  }
953
1025
  const tempMsg = dltPreviewData === '' ? fallbackMessage : dltPreviewData;
954
- const mediaTypeMsg = isMediaTypeNone ? 'textMessage' : 'image';
1026
+ let mediaTypeMsg = isMediaTypeNone ? 'textMessage' : 'image';
1027
+ mediaTypeMsg = formatMessage(messages[mediaTypeMsg]);
1028
+ const {text, url} = suggestions[0] || {};
1029
+ if (buttonType && !(text && url) ) {
1030
+ mediaTypeMsg = `${formatMessage(messages.buttonTextAndUrl)} ${mediaTypeMsg} `;
1031
+ }
955
1032
  return (
956
1033
  <>
957
1034
  <CapRow className="cap-rcs-creatives">
@@ -993,7 +1070,7 @@ export const Rcs = (props) => {
993
1070
  title={
994
1071
  isDisableDone()
995
1072
  ? formatMessage(messages.rcsDoneBtnToolTip, {
996
- type: formatMessage(messages[mediaTypeMsg]),
1073
+ type: mediaTypeMsg,
997
1074
  })
998
1075
  : ''
999
1076
  }
@@ -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 & {type} to proceed further',
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
  });