@capillarytech/creatives-library 8.0.345-alpha.12 → 8.0.345-alpha.14
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/constants/unified.js +0 -29
- package/package.json +1 -1
- package/services/tests/api.test.js +0 -13
- package/utils/commonUtils.js +1 -19
- package/v2Components/CapActionButton/constants.js +0 -7
- package/v2Components/CapActionButton/index.js +109 -167
- package/v2Components/CapActionButton/index.scss +6 -157
- package/v2Components/CapActionButton/messages.js +3 -19
- package/v2Components/CapActionButton/tests/index.test.js +17 -41
- package/v2Components/CapTagList/index.js +0 -10
- package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +49 -70
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -207
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +0 -16
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +10 -85
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +0 -30
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +11 -79
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +5 -10
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +15 -160
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +76 -341
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +4 -133
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +0 -11
- package/v2Components/CommonTestAndPreview/constants.js +2 -38
- package/v2Components/CommonTestAndPreview/index.js +186 -676
- package/v2Components/CommonTestAndPreview/messages.js +3 -49
- package/v2Components/CommonTestAndPreview/sagas.js +6 -15
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +284 -308
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +65 -231
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +5 -118
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +0 -341
- package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +1 -8
- package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +13 -34
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +283 -281
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +1 -199
- package/v2Components/CommonTestAndPreview/tests/index.test.js +4 -132
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
- package/v2Components/FormBuilder/index.js +10 -8
- package/v2Components/TemplatePreview/_templatePreview.scss +23 -33
- package/v2Components/TemplatePreview/index.js +28 -143
- package/v2Components/TemplatePreview/tests/index.test.js +0 -142
- package/v2Components/TestAndPreviewSlidebox/index.js +1 -13
- package/v2Components/TestAndPreviewSlidebox/sagas.js +4 -11
- package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +1 -3
- package/v2Containers/CreativesContainer/SlideBoxContent.js +4 -36
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +1 -10
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -29
- package/v2Containers/CreativesContainer/constants.js +0 -9
- package/v2Containers/CreativesContainer/index.js +103 -300
- package/v2Containers/CreativesContainer/index.scss +1 -51
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +34 -78
- package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +16 -79
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -8
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +98 -357
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +15 -20
- package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
- package/v2Containers/Email/reducer.js +11 -3
- package/v2Containers/Email/sagas.js +9 -5
- package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +4 -0
- package/v2Containers/Email/tests/sagas.test.js +21 -3
- package/v2Containers/Rcs/constants.js +8 -119
- package/v2Containers/Rcs/index.js +812 -2375
- package/v2Containers/Rcs/index.scss +6 -276
- package/v2Containers/Rcs/messages.js +3 -38
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +70345 -98302
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +5 -0
- package/v2Containers/Rcs/tests/index.test.js +121 -152
- package/v2Containers/Rcs/tests/mockData.js +0 -38
- package/v2Containers/Rcs/tests/utils.test.js +30 -646
- package/v2Containers/Rcs/utils.js +11 -478
- package/v2Containers/Sms/Create/index.js +40 -100
- package/v2Containers/SmsTrai/Create/index.js +4 -9
- package/v2Containers/SmsTrai/Edit/constants.js +0 -2
- package/v2Containers/SmsTrai/Edit/index.js +130 -636
- package/v2Containers/SmsTrai/Edit/messages.js +4 -14
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2296 -4249
- package/v2Containers/SmsWrapper/index.js +8 -37
- package/v2Containers/TagList/index.js +0 -6
- package/v2Containers/Templates/_templates.scss +2 -163
- package/v2Containers/Templates/actions.js +0 -11
- package/v2Containers/Templates/constants.js +0 -2
- package/v2Containers/Templates/index.js +54 -119
- package/v2Containers/Templates/sagas.js +12 -57
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1079 -1043
- package/v2Containers/Templates/tests/sagas.test.js +123 -193
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -72
- package/v2Containers/TemplatesV2/index.js +23 -86
- package/v2Containers/Whatsapp/index.js +20 -3
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +34 -578
- package/utils/rcsPayloadUtils.js +0 -92
- package/utils/templateVarUtils.js +0 -201
- package/utils/tests/templateVarUtils.test.js +0 -204
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js.rej +0 -18
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +0 -67
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +0 -87
- package/v2Components/SmsFallback/constants.js +0 -73
- package/v2Components/SmsFallback/index.js +0 -955
- package/v2Components/SmsFallback/index.scss +0 -265
- package/v2Components/SmsFallback/messages.js +0 -78
- package/v2Components/SmsFallback/smsFallbackUtils.js +0 -118
- package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +0 -50
- package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +0 -147
- package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +0 -304
- package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +0 -197
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -277
- package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +0 -422
- package/v2Components/SmsFallback/useLocalTemplateList.js +0 -92
- package/v2Components/TemplatePreview/constants.js +0 -2
- package/v2Components/VarSegmentMessageEditor/constants.js +0 -2
- package/v2Components/VarSegmentMessageEditor/index.js +0 -125
- package/v2Components/VarSegmentMessageEditor/index.scss +0 -46
- package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +0 -43
- package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +0 -67
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +0 -90
- package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +0 -258
- package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +0 -125
- package/v2Containers/Rcs/index.js.rej +0 -1336
- package/v2Containers/Rcs/index.scss.rej +0 -74
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +0 -225
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap.rej +0 -128
- package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +0 -318
- package/v2Containers/Sms/smsFormDataHelpers.js +0 -67
- package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +0 -253
- package/v2Containers/SmsTrai/Edit/index.scss +0 -121
- package/v2Containers/Templates/TemplatesActionBar.js +0 -101
- package/v2Containers/Templates/tests/TemplatesActionBar.test.js +0 -120
- package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +0 -180
- package/v2Containers/Templates/utils/smsTemplatesListApi.js +0 -79
- package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +0 -131
package/constants/unified.js
CHANGED
|
@@ -159,24 +159,6 @@ export const TAG_CONTENT_REGEX = /{{([^}]+)}}/g;
|
|
|
159
159
|
export const ENTRY_TRIGGER_TAG_REGEX = /\bentryTrigger\.\w+(?:\.\w+)?(?:\(\w+\))?/g;
|
|
160
160
|
export const SKIP_TAGS_REGEX_GROUPS = ["dynamic_expiry_date_after_\\d+_days.FORMAT_\\d", "unsubscribe\\(#[a-zA-Z\\d]{6}\\)", "Link_to_[a-zA-Z]", "SURVEY.*.TOKEN", "^[A-Za-z].*\\([a-zA-Z\\d]*\\)", "referral_unique_(code|url).*userid"];
|
|
161
161
|
|
|
162
|
-
// --- Template variable tokens (`{{var}}`, DLT `{#var#}`) ---
|
|
163
|
-
/** Global: all `{{…}}` placeholders in a string. */
|
|
164
|
-
export const DEFAULT_MUSTACHE_VAR_REGEX = /\{\{[^}]+\}\}/g;
|
|
165
|
-
/** Global: `{{…}}` or DLT `{#…#}` tokens (SMS combined mode). */
|
|
166
|
-
export const COMBINED_SMS_TEMPLATE_VAR_REGEX = /\{\{[^}]+\}\}|\{\#[^#]*\#\}/g;
|
|
167
|
-
/** Full-string check: one mustache token. */
|
|
168
|
-
export const MUSTACHE_VAR_TOKEN_FULL_STRING_REGEX = /^\{\{[^}]+\}\}$/;
|
|
169
|
-
/** Full-string check: one DLT hash token. */
|
|
170
|
-
export const DLT_HASH_VAR_TOKEN_FULL_STRING_REGEX = /^\{\#[^#]*\#\}$/;
|
|
171
|
-
/** Full-string with capture group: inner name for `{{ name }}`-style tokens (whitespace-tolerant). */
|
|
172
|
-
export const MUSTACHE_TOKEN_INNER_NAME_REGEX = /^\{\{\s*([^}]+?)\s*\}\}$/;
|
|
173
|
-
/** Full-string with capture group: inner name/body for `{# name #}` DLT tokens (whitespace-tolerant). */
|
|
174
|
-
export const DLT_HASH_TOKEN_INNER_NAME_REGEX = /^\{#\s*(.*?)\s*#\}$/;
|
|
175
|
-
/** Global with capture group: inner name inside `{{name}}`. */
|
|
176
|
-
export const MUSTACHE_VAR_NAME_CAPTURE_REGEX = /\{\{([^}]+)\}\}/g;
|
|
177
|
-
/** Global with capture group: inner body inside `{#body#}`. */
|
|
178
|
-
export const DLT_VAR_BODY_CAPTURE_REGEX = /\{\#([^#]*)\#\}/g;
|
|
179
|
-
|
|
180
162
|
export const GET_TRANSLATION_MAPPED = {
|
|
181
163
|
'en': 'en-US',
|
|
182
164
|
'zh-cn': 'zh',
|
|
@@ -214,14 +196,3 @@ export const LOGOUT_FAILURE = 'cap/LOGOUT_FAILURE';
|
|
|
214
196
|
export const JAPANESE_HELP_TEXT = 'ヘルプ :トークンの定義';
|
|
215
197
|
|
|
216
198
|
export const TAG_TRANSLATION_DOC = 'https://docs.capillarytech.com/docs/tags-translation';
|
|
217
|
-
|
|
218
|
-
// --- RCS SMS fallback API contract (shared across modules: campaigns, journey, etc.) ---
|
|
219
|
-
|
|
220
|
-
/** Keys on `messageContent.*.smsFallBackContent` sent to the API: only `message` + `templateConfigs`.
|
|
221
|
-
* `rcsSmsFallbackVarMapped` is editor-only — merged into `message` at normalize, not sent on the wire. */
|
|
222
|
-
export const RCS_API_SMS_FALLBACK_KEYS = Object.freeze({
|
|
223
|
-
MESSAGE: 'message',
|
|
224
|
-
TEMPLATE_CONFIGS: 'templateConfigs',
|
|
225
|
-
RCS_SMS_FALLBACK_VAR_MAPPED: 'rcsSmsFallbackVarMapped',
|
|
226
|
-
});
|
|
227
|
-
|
package/package.json
CHANGED
|
@@ -1042,19 +1042,6 @@ describe('getMembersLookup', () => {
|
|
|
1042
1042
|
getMembersLookup('email', 'user+test@example.com');
|
|
1043
1043
|
expect(global.fetch).toHaveBeenCalled();
|
|
1044
1044
|
const calls = global.fetch.mock.calls;
|
|
1045
|
-
const withEncoding = calls.find(
|
|
1046
|
-
(c) =>
|
|
1047
|
-
c[0] &&
|
|
1048
|
-
String(c[0]).includes('members') &&
|
|
1049
|
-
String(c[0]).includes('identifierType=email') &&
|
|
1050
|
-
String(c[0]).includes('user%2Btest%40example.com')
|
|
1051
|
-
);
|
|
1052
|
-
if (withEncoding) {
|
|
1053
|
-
const [url, options] = withEncoding;
|
|
1054
|
-
expect(url).toContain('identifierType=email');
|
|
1055
|
-
expect(url).toContain('identifierValue=user%2Btest%40example.com');
|
|
1056
|
-
expect(options?.method || 'GET').toBe('GET');
|
|
1057
|
-
}
|
|
1058
1045
|
const anyMembersCall = calls.find((c) => c[0] && String(c[0]).includes('members'));
|
|
1059
1046
|
expect(anyMembersCall).toBeDefined();
|
|
1060
1047
|
expect(anyMembersCall[0]).toContain('identifierType=');
|
package/utils/commonUtils.js
CHANGED
|
@@ -539,22 +539,4 @@ export const isValidMobile = (mobile) => PHONE_REGEX.test(mobile);
|
|
|
539
539
|
export const formatPhoneNumber = (phone) => {
|
|
540
540
|
if (!phone) return '';
|
|
541
541
|
return String(phone).replace(/[^\d]/g, '');
|
|
542
|
-
};
|
|
543
|
-
|
|
544
|
-
/**
|
|
545
|
-
* TRAI sender IDs on persisted RCS SMS fallback: may live on the merged object, under
|
|
546
|
-
* `templateConfigs`, or (legacy) `templateConfigs.header`. Same resolution order as
|
|
547
|
-
* `createPayload` in `Rcs/index.js`.
|
|
548
|
-
*/
|
|
549
|
-
export function extractRegisteredSenderIdsFromSmsFallbackRecord(record) {
|
|
550
|
-
if (!record || typeof record !== 'object') return null;
|
|
551
|
-
const tc = record.templateConfigs && typeof record.templateConfigs === 'object'
|
|
552
|
-
? record.templateConfigs
|
|
553
|
-
: {};
|
|
554
|
-
const candidates = [record.registeredSenderIds, tc.registeredSenderIds, tc.header];
|
|
555
|
-
for (let i = 0; i < candidates.length; i += 1) {
|
|
556
|
-
const a = candidates[i];
|
|
557
|
-
if (Array.isArray(a) && a.length > 0) return a;
|
|
558
|
-
}
|
|
559
|
-
return null;
|
|
560
|
-
}
|
|
542
|
+
};
|
|
@@ -32,13 +32,6 @@ export const CTA_OPTIONS = [
|
|
|
32
32
|
];
|
|
33
33
|
|
|
34
34
|
export const invalidVarRegex = /{{(.*?)}}/g;
|
|
35
|
-
|
|
36
|
-
/** URL CTA subtype (Figma: URL type dropdown). */
|
|
37
|
-
export const RCS_CTA_URL_TYPE = {
|
|
38
|
-
STATIC: 'STATIC',
|
|
39
|
-
DYNAMIC: 'DYNAMIC',
|
|
40
|
-
};
|
|
41
|
-
|
|
42
35
|
export const BTN_MAX_LENGTH = 25;
|
|
43
36
|
export const PHONE_NUMBER_MAX_LENGTH = 15;
|
|
44
37
|
export const URL_MAX_LENGTH = 2000;
|
|
@@ -8,7 +8,6 @@ import CapRow from '@capillarytech/cap-ui-library/CapRow';
|
|
|
8
8
|
import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
|
|
9
9
|
import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
|
|
10
10
|
import CapHeader from "@capillarytech/cap-ui-library/CapHeader";
|
|
11
|
-
import CapRadioGroup from '@capillarytech/cap-ui-library/CapRadioGroup';
|
|
12
11
|
import CapSelect from '@capillarytech/cap-ui-library/CapSelect';
|
|
13
12
|
import CapInput from '@capillarytech/cap-ui-library/CapInput';
|
|
14
13
|
import CapIcon from '@capillarytech/cap-ui-library/CapIcon';
|
|
@@ -21,16 +20,9 @@ import globalMessages from '../../v2Containers/Cap/messages';import CapTagListWi
|
|
|
21
20
|
|
|
22
21
|
import { isUrl, isValidText } from '../../v2Containers/Line/Container/Wrapper/utils';
|
|
23
22
|
import messages from './messages';
|
|
24
|
-
import {
|
|
25
|
-
BTN_MAX_LENGTH,
|
|
26
|
-
URL_MAX_LENGTH,
|
|
27
|
-
PHONE_NUMBER_MAX_LENGTH,
|
|
28
|
-
invalidVarRegex,
|
|
29
|
-
HANDLERS,
|
|
30
|
-
RCS_CTA_URL_TYPE,
|
|
31
|
-
} from './constants';
|
|
23
|
+
import { CTA_OPTIONS, BTN_MAX_LENGTH, URL_MAX_LENGTH, PHONE_NUMBER_MAX_LENGTH,invalidVarRegex, HANDLERS } from './constants';
|
|
32
24
|
import './index.scss';
|
|
33
|
-
import { INITIAL_SUGGESTIONS, RCS_BUTTON_TYPES
|
|
25
|
+
import { INITIAL_SUGGESTIONS, RCS_BUTTON_TYPES} from '../../v2Containers/Rcs/constants';
|
|
34
26
|
|
|
35
27
|
const { TextArea } = CapInput;
|
|
36
28
|
|
|
@@ -49,12 +41,9 @@ export const CapActionButton = (props) => {
|
|
|
49
41
|
injectedTags = {},
|
|
50
42
|
location = {},
|
|
51
43
|
selectedOfferDetails = [],
|
|
52
|
-
|
|
44
|
+
|
|
53
45
|
onContextChange,
|
|
54
|
-
minSavedSuggestions = 0,
|
|
55
|
-
hideDeleteSuggestionIndexes = [],
|
|
56
46
|
} = props;
|
|
57
|
-
const isHostIcs = host === HOST_ICS;
|
|
58
47
|
const [urlError, setUrlError] = useState(false);
|
|
59
48
|
const [buttonError, setButtonError] = useState(false);
|
|
60
49
|
const updateHandler = (type, value, index) => {
|
|
@@ -77,7 +66,6 @@ export const CapActionButton = (props) => {
|
|
|
77
66
|
|
|
78
67
|
const onCtaTypeChange = (value, index) => {
|
|
79
68
|
let clonedCta = cloneDeep(suggestions[index]);
|
|
80
|
-
const isCta = value === RCS_BUTTON_TYPES.CTA;
|
|
81
69
|
clonedCta = {
|
|
82
70
|
...clonedCta,
|
|
83
71
|
type: value,
|
|
@@ -85,7 +73,6 @@ export const CapActionButton = (props) => {
|
|
|
85
73
|
phoneNumber: '',
|
|
86
74
|
postback: '',
|
|
87
75
|
url: value === RCS_BUTTON_TYPES.PHONE_NUMBER ? null : '',
|
|
88
|
-
urlType: isCta ? RCS_CTA_URL_TYPE.STATIC : undefined,
|
|
89
76
|
isSaved: false,
|
|
90
77
|
};
|
|
91
78
|
setUrlError(false);
|
|
@@ -105,61 +92,39 @@ export const CapActionButton = (props) => {
|
|
|
105
92
|
updateDisplayAndPostback(value, id);
|
|
106
93
|
};
|
|
107
94
|
|
|
108
|
-
const
|
|
109
|
-
<
|
|
110
|
-
{formatMessage(messages.
|
|
111
|
-
|
|
95
|
+
const renderLength = (len, max) => (
|
|
96
|
+
<CapHeading type="label1" className="rcs-render-btn-length">
|
|
97
|
+
{formatMessage(messages.templateMessageLength, {
|
|
98
|
+
currentLength: len,
|
|
99
|
+
maxLength: max,
|
|
100
|
+
})}
|
|
101
|
+
</CapHeading>
|
|
112
102
|
);
|
|
113
103
|
|
|
114
|
-
const validateCtaUrlValue = (value, urlSubtype) => {
|
|
115
|
-
const v = String(value || '').trim();
|
|
116
|
-
if (!v) {
|
|
117
|
-
return formatMessage(messages.ctaWebsiteUrlErrorMessage);
|
|
118
|
-
}
|
|
119
|
-
if (v.length > URL_MAX_LENGTH) {
|
|
120
|
-
return formatMessage(messages.ctaWebsiteUrlErrorMessage);
|
|
121
|
-
}
|
|
122
|
-
if (urlSubtype === RCS_CTA_URL_TYPE.DYNAMIC) {
|
|
123
|
-
return false;
|
|
124
|
-
}
|
|
125
|
-
if (!isUrl(v)) {
|
|
126
|
-
return formatMessage(messages.ctaWebsiteUrlErrorMessage);
|
|
127
|
-
}
|
|
128
|
-
if (v.match(invalidVarRegex)?.length > 0) {
|
|
129
|
-
return formatMessage(messages.staticUrlWithVarErrorMessage);
|
|
130
|
-
}
|
|
131
|
-
return false;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
104
|
const onUrlChange = ({ target }) => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
105
|
+
let { value, id } = target;
|
|
106
|
+
let errorMessage = false;
|
|
107
|
+
if (!isUrl(value)) {
|
|
108
|
+
errorMessage = formatMessage(messages.ctaWebsiteUrlErrorMessage);
|
|
109
|
+
} else if (value.match(invalidVarRegex)?.length > 0) {
|
|
110
|
+
errorMessage = formatMessage(messages.staticUrlWithVarErrorMessage);
|
|
111
|
+
}
|
|
112
|
+
setUrlError(errorMessage);
|
|
139
113
|
updateHandler(HANDLERS.URL, value, id);
|
|
140
114
|
};
|
|
141
115
|
|
|
142
|
-
const onUrlSubtypeChange = (nextSubtype, index) => {
|
|
143
|
-
const cloned = cloneDeep(suggestions[index]);
|
|
144
|
-
cloned.urlType = nextSubtype;
|
|
145
|
-
cloned.isSaved = false;
|
|
146
|
-
setUrlError(validateCtaUrlValue(cloned.url || '', nextSubtype));
|
|
147
|
-
updateButtonChange(cloned, index);
|
|
148
|
-
};
|
|
149
|
-
|
|
150
116
|
const onPhoneNoChange = (value, index) => {
|
|
151
117
|
updateHandler(HANDLERS.PHONE_NUMBER, value, index);
|
|
152
118
|
};
|
|
153
119
|
|
|
154
120
|
const ctaSaveDisabled = (index) => {
|
|
155
|
-
const { type, text, phoneNumber, url
|
|
121
|
+
const { type, text, phoneNumber, url } = suggestions[index] || {};
|
|
156
122
|
if (text === '' || buttonError) {
|
|
157
123
|
return true;
|
|
158
|
-
} if (type === RCS_BUTTON_TYPES.PHONE_NUMBER &&
|
|
124
|
+
} if (type === RCS_BUTTON_TYPES.PHONE_NUMBER && phoneNumber.length < 5) {
|
|
125
|
+
return true;
|
|
126
|
+
} if (type === RCS_BUTTON_TYPES.CTA && (url === '' || urlError)) {
|
|
159
127
|
return true;
|
|
160
|
-
} if (type === RCS_BUTTON_TYPES.CTA) {
|
|
161
|
-
const subtype = urlType || RCS_CTA_URL_TYPE.STATIC;
|
|
162
|
-
return !!validateCtaUrlValue(url, subtype);
|
|
163
128
|
}
|
|
164
129
|
return false;
|
|
165
130
|
};
|
|
@@ -178,58 +143,64 @@ export const CapActionButton = (props) => {
|
|
|
178
143
|
updateButtonChange(newSuggestion, suggestions?.length);
|
|
179
144
|
};
|
|
180
145
|
|
|
146
|
+
const renderCtaOptions = (label, tooltipLabel, isDisabled) => {
|
|
147
|
+
if (isDisabled) {
|
|
148
|
+
return (
|
|
149
|
+
<CapRow>
|
|
150
|
+
<CapColumn span={23}>{label}</CapColumn>
|
|
151
|
+
<CapColumn span={1}>
|
|
152
|
+
<CapTooltipWithInfo
|
|
153
|
+
// autoAdjustOverflow
|
|
154
|
+
placement="right"
|
|
155
|
+
title={tooltipLabel}
|
|
156
|
+
/>
|
|
157
|
+
</CapColumn>
|
|
158
|
+
</CapRow>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
return label;
|
|
162
|
+
};
|
|
163
|
+
|
|
181
164
|
const { formatMessage } = intl;
|
|
182
165
|
const renderedContent = () => {
|
|
183
166
|
const renderArray = [];
|
|
184
|
-
const addBtnDisabled = suggestions
|
|
185
|
-
const savedSuggestionsCount = (suggestions || []).filter((s) => s && s.isSaved).length;
|
|
186
|
-
const cannotDeleteSavedMandatory = (idx) => {
|
|
187
|
-
const row = suggestions[idx];
|
|
188
|
-
if (!row || !row.isSaved) return false;
|
|
189
|
-
return minSavedSuggestions > 0 && savedSuggestionsCount <= minSavedSuggestions;
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
const hideDeleteForSuggestionIndex = (idx) =>
|
|
193
|
-
Array.isArray(hideDeleteSuggestionIndexes) && hideDeleteSuggestionIndexes.includes(idx);
|
|
194
|
-
|
|
195
|
-
const ctaTypeRadioOptions = [
|
|
196
|
-
{ label: formatMessage(messages.ctaPhoneNo), value: RCS_BUTTON_TYPES.PHONE_NUMBER },
|
|
197
|
-
{ label: formatMessage(messages.ctaUrlRadio), value: RCS_BUTTON_TYPES.CTA },
|
|
198
|
-
{ label: formatMessage(messages.ctaQr), value: RCS_BUTTON_TYPES.QUICK_REPLY },
|
|
199
|
-
];
|
|
167
|
+
const addBtnDisabled = suggestions.length >= maxButtons || !suggestions[suggestions.length - 1]?.isSaved;
|
|
200
168
|
|
|
201
|
-
const
|
|
202
|
-
{ value
|
|
203
|
-
|
|
204
|
-
|
|
169
|
+
const ctaOptions = CTA_OPTIONS.map((option) => {
|
|
170
|
+
const { value, label } = option;
|
|
171
|
+
const isDisabled = suggestions.length >= maxButtons && !suggestions[suggestions.length - 1];
|
|
172
|
+
return {
|
|
173
|
+
value,
|
|
174
|
+
label: renderCtaOptions(label, formatMessage(messages.ctaButtonTypeDisabled), isDisabled),
|
|
175
|
+
disabled: isDisabled,
|
|
176
|
+
};
|
|
177
|
+
});
|
|
205
178
|
|
|
206
|
-
suggestions
|
|
179
|
+
suggestions.forEach((cta) => {
|
|
207
180
|
const {
|
|
208
181
|
index, type, text, isSaved,
|
|
209
182
|
} = cta || {};
|
|
210
183
|
|
|
211
184
|
const url = type !== RCS_BUTTON_TYPES.CTA ? null : cta.url;
|
|
212
|
-
const urlSubtype = type === RCS_BUTTON_TYPES.CTA
|
|
213
|
-
? (cta.urlType || RCS_CTA_URL_TYPE.STATIC)
|
|
214
|
-
: RCS_CTA_URL_TYPE.STATIC;
|
|
215
185
|
const phoneNumber = type !== RCS_BUTTON_TYPES.PHONE_NUMBER ? null : cta.phoneNumber;
|
|
216
186
|
if (isFullMode && !isEditFlow && !isSaved) {
|
|
217
187
|
renderArray.push(
|
|
218
|
-
<
|
|
219
|
-
<CapRow className="rcs-button-cta-create"
|
|
220
|
-
<CapColumn span={
|
|
221
|
-
|
|
188
|
+
<div className="rcs-button-cta-create-container" key={`cta-edit-${index}`}>
|
|
189
|
+
<CapRow className="rcs-button-cta-create margin-t-16">
|
|
190
|
+
<CapColumn span={12}>
|
|
191
|
+
{/* Type of action */}
|
|
192
|
+
<CapHeading type="h4" className="cta-label">
|
|
222
193
|
{formatMessage(messages.ctaType)}
|
|
223
194
|
</CapHeading>
|
|
224
|
-
<
|
|
225
|
-
id=
|
|
226
|
-
|
|
227
|
-
|
|
195
|
+
<CapSelect
|
|
196
|
+
id="rcs-cta-type"
|
|
197
|
+
options={ctaOptions || []}
|
|
198
|
+
onChange={(value) => onCtaTypeChange(value, index)}
|
|
228
199
|
value={type}
|
|
229
|
-
|
|
200
|
+
disabled={false}
|
|
230
201
|
/>
|
|
231
202
|
</CapColumn>
|
|
232
|
-
<CapColumn span={
|
|
203
|
+
<CapColumn span={12}>
|
|
233
204
|
<CapHeading type="h4" className="cta-label">
|
|
234
205
|
{formatMessage(messages.ctaButtonText)}
|
|
235
206
|
<CapTooltipWithInfo
|
|
@@ -250,34 +221,28 @@ export const CapActionButton = (props) => {
|
|
|
250
221
|
size="large"
|
|
251
222
|
maxLength={BTN_MAX_LENGTH}
|
|
252
223
|
errorMessage={buttonError}
|
|
253
|
-
suffix={renderInnerCharCount((text || '').length, BTN_MAX_LENGTH)}
|
|
254
224
|
/>
|
|
225
|
+
{renderLength(text.length, BTN_MAX_LENGTH)}
|
|
255
226
|
</CapColumn>
|
|
256
227
|
</CapRow>
|
|
257
228
|
{type === RCS_BUTTON_TYPES.PHONE_NUMBER && (
|
|
258
229
|
<>
|
|
259
230
|
<CapRow>
|
|
260
|
-
<CapColumn span={
|
|
231
|
+
<CapColumn span={11}>
|
|
232
|
+
{/* phone number */}
|
|
261
233
|
<CapHeading type="h4" className="cta-label">
|
|
262
234
|
{formatMessage(messages.ctaPhoneNo)}
|
|
263
235
|
</CapHeading>
|
|
264
|
-
<
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
onChange={(value) => onPhoneNoChange(value, index)}
|
|
275
|
-
country="in"
|
|
276
|
-
className="cta-phone-number rcs-cta-phone-input"
|
|
277
|
-
/>
|
|
278
|
-
{renderInnerCharCount((phoneNumber || '').length, PHONE_NUMBER_MAX_LENGTH)}
|
|
279
|
-
</CapColumn>
|
|
280
|
-
</CapRow>
|
|
236
|
+
<PhoneInput
|
|
237
|
+
placeholder={formatMessage(messages.ctaPhoneNoPlaceholder)}
|
|
238
|
+
autoFormat={false}
|
|
239
|
+
countryCodeEditable={false}
|
|
240
|
+
value={phoneNumber}
|
|
241
|
+
onChange={(value) => onPhoneNoChange(value, index)}
|
|
242
|
+
country="in"
|
|
243
|
+
className="cta-phone-number"
|
|
244
|
+
/>
|
|
245
|
+
{renderLength(phoneNumber.length, PHONE_NUMBER_MAX_LENGTH)}
|
|
281
246
|
</CapColumn>
|
|
282
247
|
</CapRow>
|
|
283
248
|
<CapRow className="rcs-cta-save-delete-btn">
|
|
@@ -285,7 +250,7 @@ export const CapActionButton = (props) => {
|
|
|
285
250
|
title={ctaSaveDisabled(index) && formatMessage(messages.ctaSaveDisabled)}
|
|
286
251
|
placement="bottom"
|
|
287
252
|
>
|
|
288
|
-
<
|
|
253
|
+
<div className="button-disabled-tooltip-wrapper">
|
|
289
254
|
<CapButton
|
|
290
255
|
onClick={() => saveCta(index)}
|
|
291
256
|
disabled={ctaSaveDisabled(index)}
|
|
@@ -293,49 +258,36 @@ export const CapActionButton = (props) => {
|
|
|
293
258
|
>
|
|
294
259
|
{formatMessage(globalMessages.save)}
|
|
295
260
|
</CapButton>
|
|
296
|
-
</
|
|
261
|
+
</div>
|
|
297
262
|
</CapTooltip>
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
</CapButton>
|
|
306
|
-
)}
|
|
263
|
+
<CapButton
|
|
264
|
+
onClick={() => deleteButtonHandler(index)}
|
|
265
|
+
className="rcs-cta-delete-btn"
|
|
266
|
+
type="secondary"
|
|
267
|
+
>
|
|
268
|
+
{formatMessage(globalMessages.delete)}
|
|
269
|
+
</CapButton>
|
|
307
270
|
</CapRow>
|
|
308
271
|
</>
|
|
309
272
|
)}
|
|
310
273
|
{type === RCS_BUTTON_TYPES.CTA && (
|
|
311
274
|
<>
|
|
312
|
-
<CapRow
|
|
313
|
-
<CapColumn span={
|
|
314
|
-
<CapHeading type="h4" className="cta-label">
|
|
315
|
-
{formatMessage(messages.ctaWebsiteType)}
|
|
316
|
-
</CapHeading>
|
|
317
|
-
<CapSelect
|
|
318
|
-
id={`rcs-cta-url-type-${index}`}
|
|
319
|
-
options={urlTypeSelectOptions}
|
|
320
|
-
value={urlSubtype}
|
|
321
|
-
onChange={(value) => onUrlSubtypeChange(value, index)}
|
|
322
|
-
/>
|
|
323
|
-
</CapColumn>
|
|
324
|
-
<CapColumn span={18} className="rcs-cta-url-value-col">
|
|
275
|
+
<CapRow>
|
|
276
|
+
<CapColumn span={24}>
|
|
325
277
|
<CapHeading type="h4" className="cta-label">
|
|
326
|
-
{formatMessage(messages.
|
|
278
|
+
{formatMessage(messages.ctaWebsite)}
|
|
327
279
|
</CapHeading>
|
|
328
280
|
<CapInput
|
|
329
281
|
id={index}
|
|
330
282
|
className="rcs-cta-url"
|
|
331
283
|
onChange={onUrlChange}
|
|
332
|
-
placeholder={formatMessage(messages.
|
|
333
|
-
value={url
|
|
284
|
+
placeholder={formatMessage(messages.ctaStaticPlaceholder)}
|
|
285
|
+
value={url}
|
|
334
286
|
size="large"
|
|
335
287
|
maxLength={URL_MAX_LENGTH}
|
|
336
288
|
errorMessage={urlError}
|
|
337
|
-
suffix={renderInnerCharCount((url || '').length, URL_MAX_LENGTH)}
|
|
338
289
|
/>
|
|
290
|
+
{renderLength(url.length, URL_MAX_LENGTH)}
|
|
339
291
|
</CapColumn>
|
|
340
292
|
</CapRow>
|
|
341
293
|
<CapRow className="rcs-cta-save-delete-btn">
|
|
@@ -345,7 +297,7 @@ export const CapActionButton = (props) => {
|
|
|
345
297
|
}
|
|
346
298
|
placement="bottom"
|
|
347
299
|
>
|
|
348
|
-
<
|
|
300
|
+
<div className="button-disabled-tooltip-wrapper">
|
|
349
301
|
<CapButton
|
|
350
302
|
onClick={() => saveCta(index)}
|
|
351
303
|
disabled={ctaSaveDisabled(index)}
|
|
@@ -353,17 +305,15 @@ export const CapActionButton = (props) => {
|
|
|
353
305
|
>
|
|
354
306
|
{formatMessage(globalMessages.save)}
|
|
355
307
|
</CapButton>
|
|
356
|
-
</
|
|
308
|
+
</div>
|
|
357
309
|
</CapTooltip>
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
</CapButton>
|
|
366
|
-
)}
|
|
310
|
+
<CapButton
|
|
311
|
+
onClick={() => deleteButtonHandler(index)}
|
|
312
|
+
className="rcs-cta-delete-btn"
|
|
313
|
+
type="secondary"
|
|
314
|
+
>
|
|
315
|
+
{formatMessage(globalMessages.delete)}
|
|
316
|
+
</CapButton>
|
|
367
317
|
</CapRow>
|
|
368
318
|
</>
|
|
369
319
|
)}
|
|
@@ -373,7 +323,7 @@ export const CapActionButton = (props) => {
|
|
|
373
323
|
title={ctaSaveDisabled(index) && formatMessage(messages.ctaSaveDisabled)}
|
|
374
324
|
placement="bottom"
|
|
375
325
|
>
|
|
376
|
-
<
|
|
326
|
+
<div className="button-disabled-tooltip-wrapper">
|
|
377
327
|
<CapButton
|
|
378
328
|
onClick={() => saveCta(index)}
|
|
379
329
|
disabled={ctaSaveDisabled(index)}
|
|
@@ -381,9 +331,9 @@ export const CapActionButton = (props) => {
|
|
|
381
331
|
>
|
|
382
332
|
{formatMessage(globalMessages.save)}
|
|
383
333
|
</CapButton>
|
|
384
|
-
</
|
|
334
|
+
</div>
|
|
385
335
|
</CapTooltip>
|
|
386
|
-
{
|
|
336
|
+
{index !== 0 && (
|
|
387
337
|
<CapButton
|
|
388
338
|
onClick={() => deleteButtonHandler(index)}
|
|
389
339
|
className="rcs-cta-delete-btn"
|
|
@@ -394,12 +344,12 @@ export const CapActionButton = (props) => {
|
|
|
394
344
|
)}
|
|
395
345
|
</CapRow>
|
|
396
346
|
)}
|
|
397
|
-
</
|
|
347
|
+
</div>
|
|
398
348
|
);
|
|
399
349
|
} else {
|
|
400
350
|
const ctaIsPhone = type === RCS_BUTTON_TYPES.PHONE_NUMBER;
|
|
401
351
|
const ctaIsReply = type === RCS_BUTTON_TYPES.QUICK_REPLY;
|
|
402
|
-
|
|
352
|
+
renderArray.push(
|
|
403
353
|
<CapRow
|
|
404
354
|
key={`cta-saved-${index}`}
|
|
405
355
|
className="cap-rcs-saved-cta margin-t-12"
|
|
@@ -429,9 +379,7 @@ export const CapActionButton = (props) => {
|
|
|
429
379
|
<>
|
|
430
380
|
<CapColumn span={3}>
|
|
431
381
|
<CapLabel className="url-type" type="label2">
|
|
432
|
-
{(
|
|
433
|
-
? formatMessage(messages.ctaWebsiteTypeDynamic)
|
|
434
|
-
: formatMessage(messages.ctaWebsiteTypeStatic)}
|
|
382
|
+
{formatMessage(messages.ctaWebsiteTypeStatic)}
|
|
435
383
|
</CapLabel>
|
|
436
384
|
</CapColumn>
|
|
437
385
|
<CapTooltip title={url} placement={'top'}>
|
|
@@ -450,7 +398,7 @@ export const CapActionButton = (props) => {
|
|
|
450
398
|
>
|
|
451
399
|
<CapIcon size="s" type="edit" />
|
|
452
400
|
</CapColumn>
|
|
453
|
-
{
|
|
401
|
+
{index !== 0 && (
|
|
454
402
|
<CapColumn className="rcs-saved-cta-delete-icon" span={1} onClick={() => deleteButtonHandler(index)}>
|
|
455
403
|
<CapIcon size="s" type="delete" />
|
|
456
404
|
</CapColumn>
|
|
@@ -462,7 +410,7 @@ export const CapActionButton = (props) => {
|
|
|
462
410
|
}
|
|
463
411
|
});
|
|
464
412
|
{
|
|
465
|
-
suggestions
|
|
413
|
+
suggestions.length < maxButtons &&
|
|
466
414
|
(isFullMode && !isEditFlow)
|
|
467
415
|
&& renderArray.push(
|
|
468
416
|
<CapRow>
|
|
@@ -472,7 +420,7 @@ export const CapActionButton = (props) => {
|
|
|
472
420
|
}
|
|
473
421
|
placement={'right'}
|
|
474
422
|
>
|
|
475
|
-
<
|
|
423
|
+
<div className="button-disabled-tooltip-wrapper">
|
|
476
424
|
<CapButton
|
|
477
425
|
type="flat"
|
|
478
426
|
id="rcs-cta-add-button"
|
|
@@ -483,7 +431,7 @@ export const CapActionButton = (props) => {
|
|
|
483
431
|
>
|
|
484
432
|
{formatMessage(messages.addButton)}
|
|
485
433
|
</CapButton>
|
|
486
|
-
</
|
|
434
|
+
</div>
|
|
487
435
|
</CapTooltip>
|
|
488
436
|
</CapRow>,
|
|
489
437
|
);
|
|
@@ -496,8 +444,6 @@ export const CapActionButton = (props) => {
|
|
|
496
444
|
CapActionButton.propTypes = {
|
|
497
445
|
intl: intlShape.isRequired,
|
|
498
446
|
updateButtonChange: PropTypes.func,
|
|
499
|
-
minSavedSuggestions: PropTypes.number,
|
|
500
|
-
hideDeleteSuggestionIndexes: PropTypes.arrayOf(PropTypes.number),
|
|
501
447
|
suggestions: PropTypes.array,
|
|
502
448
|
tags: PropTypes.array,
|
|
503
449
|
injectedTags: PropTypes.object,
|
|
@@ -505,15 +451,12 @@ CapActionButton.propTypes = {
|
|
|
505
451
|
selectedOfferDetails: PropTypes.array,
|
|
506
452
|
onTagSelect: PropTypes.func,
|
|
507
453
|
onContextChange: PropTypes.func,
|
|
508
|
-
host: PropTypes.string,
|
|
509
454
|
};
|
|
510
455
|
|
|
511
456
|
CapActionButton.defaultProps = {
|
|
512
457
|
buttonTextlen: 20,
|
|
513
458
|
type: '',
|
|
514
459
|
updateButtonChange: () => {},
|
|
515
|
-
minSavedSuggestions: 0,
|
|
516
|
-
hideDeleteSuggestionIndexes: [],
|
|
517
460
|
suggestions: [],
|
|
518
461
|
tags: [],
|
|
519
462
|
injectedTags: {},
|
|
@@ -521,7 +464,6 @@ CapActionButton.defaultProps = {
|
|
|
521
464
|
selectedOfferDetails: [],
|
|
522
465
|
onTagSelect: () => {},
|
|
523
466
|
onContextChange: () => {},
|
|
524
|
-
host: '',
|
|
525
467
|
};
|
|
526
468
|
|
|
527
469
|
export default injectIntl(CapActionButton);
|