@capillarytech/creatives-library 7.10.9 → 7.10.11
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/config/app.js +1 -0
- package/package.json +2 -3
- package/utils/common.js +7 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +16 -4
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +6 -4
- package/v2Containers/CreativesContainer/index.js +53 -8
- package/v2Containers/SmsTrai/Create/constants.js +32 -37
- package/v2Containers/SmsTrai/Create/index.js +95 -45
- package/v2Containers/SmsTrai/Create/messages.js +20 -17
- package/v2Containers/SmsTrai/Create/tests/__snapshots__/index.test.js.snap +3996 -875
- package/v2Containers/SmsTrai/Create/tests/index.test.js +10 -0
- package/v2Containers/SmsTrai/Create/tests/mockData.js +2 -2
- package/v2Containers/SmsTrai/Edit/index.js +249 -103
- package/v2Containers/SmsTrai/Edit/messages.js +14 -1
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +12487 -810
- package/v2Containers/SmsTrai/Edit/tests/index.test.js +8 -1
- package/v2Containers/SmsWrapper/index.js +14 -10
- package/v2Containers/Templates/index.js +13 -6
- package/v2Containers/TemplatesV2/index.js +2 -1
|
@@ -22,12 +22,14 @@ describe('Creatives SmsTraiCreate test/>', () => {
|
|
|
22
22
|
const clearCreateResponse = jest.fn();
|
|
23
23
|
const createSMSTRAITemplates = jest.fn();
|
|
24
24
|
const onCreateComplete = jest.fn();
|
|
25
|
+
const onShowTemplates = jest.fn();
|
|
25
26
|
const setAttribute = jest.fn();
|
|
26
27
|
beforeEach(() => {
|
|
27
28
|
renderedComponent = mountWithIntl(
|
|
28
29
|
<SmsTraiCreate
|
|
29
30
|
actions={{ clearCreateResponse, createSMSTRAITemplates }}
|
|
30
31
|
onCreateComplete={onCreateComplete}
|
|
32
|
+
onShowTemplates={onShowTemplates}
|
|
31
33
|
/>,
|
|
32
34
|
);
|
|
33
35
|
});
|
|
@@ -60,6 +62,9 @@ describe('Creatives SmsTraiCreate test/>', () => {
|
|
|
60
62
|
|
|
61
63
|
it('valid file drop', async () => {
|
|
62
64
|
const event = { target: { setAttribute } };
|
|
65
|
+
createSMSTRAITemplates.mockImplementation((obj, callback) => {
|
|
66
|
+
callback();
|
|
67
|
+
})
|
|
63
68
|
renderHelper(mockData.validFile);
|
|
64
69
|
const dropZone = renderedComponent.find('Dropzone').props();
|
|
65
70
|
await dropZone.onDrop([file]);
|
|
@@ -70,6 +75,11 @@ describe('Creatives SmsTraiCreate test/>', () => {
|
|
|
70
75
|
);
|
|
71
76
|
renderedComponent.find('a.download-issues-csv-link').props().onClick(event);
|
|
72
77
|
expect(setAttribute).toHaveBeenCalledWith('download', DOWNLOAD_ISSUES_CSV);
|
|
78
|
+
renderedComponent.setProps({ isFullMode: true });
|
|
79
|
+
renderedComponent.find('button.done-button').props().onClick();
|
|
80
|
+
renderedComponent.update();
|
|
81
|
+
expect(renderedComponent).toMatchSnapshot();
|
|
82
|
+
renderedComponent.setProps({ isFullMode: false });
|
|
73
83
|
renderedComponent.find('button.done-button').props().onClick();
|
|
74
84
|
renderedComponent.update();
|
|
75
85
|
expect(renderedComponent).toMatchSnapshot();
|
|
@@ -24,7 +24,7 @@ export const mockData = {
|
|
|
24
24
|
'CONSENT TYPE',
|
|
25
25
|
],
|
|
26
26
|
[
|
|
27
|
-
"
|
|
27
|
+
"12345678912345678901",
|
|
28
28
|
'--',
|
|
29
29
|
'CAP71871_12',
|
|
30
30
|
'Service-Explicit',
|
|
@@ -49,7 +49,7 @@ export const mockData = {
|
|
|
49
49
|
'07/10/20 17:52',
|
|
50
50
|
'13/10/20 21:55',
|
|
51
51
|
'',
|
|
52
|
-
'
|
|
52
|
+
'',
|
|
53
53
|
'DUSSEHRA DEALS@VISHAL\n\nBUY1GET1 FREE\n{#var#}\n{#var#}\n{#var#}\n{#var#}\n+\n{#var#}\n{#var#}\n{#var#}\nTC',
|
|
54
54
|
'Explicit',
|
|
55
55
|
],
|
|
@@ -13,6 +13,9 @@ import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
|
|
|
13
13
|
import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
|
|
14
14
|
import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
|
|
15
15
|
import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
|
|
16
|
+
import CapError from '@capillarytech/cap-ui-library/CapError';
|
|
17
|
+
import CapCheckbox from '@capillarytech/cap-ui-library/CapCheckbox';
|
|
18
|
+
import CapInfoNote from '@capillarytech/cap-ui-library/CapInfoNote';
|
|
16
19
|
import {
|
|
17
20
|
CAP_SPACE_16,
|
|
18
21
|
CAP_SPACE_12,
|
|
@@ -24,12 +27,12 @@ import {
|
|
|
24
27
|
} from '@capillarytech/cap-ui-library/styled/variables';
|
|
25
28
|
import { makeSelectTemplateDetailsResponse } from '../../Sms/Edit/selectors';
|
|
26
29
|
import { makeSelectMetaEntities, setInjectedTags } from '../../Cap/selectors';
|
|
27
|
-
import * as
|
|
30
|
+
import * as smsEditActions from '../../Sms/Edit/actions';
|
|
28
31
|
import messages from './messages';
|
|
29
32
|
import TagList from '../../TagList';
|
|
30
33
|
import TemplatePreview from '../../../v2Components/TemplatePreview';
|
|
31
34
|
import withCreatives from '../../../hoc/withCreatives';
|
|
32
|
-
|
|
35
|
+
import { validateTags } from '../../../utils/tagValidations';
|
|
33
36
|
import {
|
|
34
37
|
CHARLIMIT,
|
|
35
38
|
SMS,
|
|
@@ -41,9 +44,13 @@ import {
|
|
|
41
44
|
ALL,
|
|
42
45
|
LIBRARY,
|
|
43
46
|
} from './constants';
|
|
47
|
+
|
|
44
48
|
let varMap = {};
|
|
49
|
+
let traiData = {};
|
|
50
|
+
let tagValidationResponse = {};
|
|
45
51
|
const { TextArea } = CapInput;
|
|
46
52
|
const { CapLabelInline } = CapLabel;
|
|
53
|
+
|
|
47
54
|
export const SmsTraiEdit = (props) => {
|
|
48
55
|
const {
|
|
49
56
|
intl,
|
|
@@ -58,6 +65,9 @@ export const SmsTraiEdit = (props) => {
|
|
|
58
65
|
metaEntities,
|
|
59
66
|
injectedTags,
|
|
60
67
|
onCreateComplete,
|
|
68
|
+
isFullMode,
|
|
69
|
+
getFormSubscriptionData,
|
|
70
|
+
templateData = {},
|
|
61
71
|
} = props || {};
|
|
62
72
|
const { formatMessage } = intl;
|
|
63
73
|
const [loading, updateLoading] = useState(true);
|
|
@@ -66,7 +76,10 @@ export const SmsTraiEdit = (props) => {
|
|
|
66
76
|
const [tags, updateTags] = useState([]);
|
|
67
77
|
const [textAreaId, updateTextAreaId] = useState();
|
|
68
78
|
const [isValidationError, updateIsValidationError] = useState(false);
|
|
69
|
-
|
|
79
|
+
const [isTagValidationError, updateIsTagValidationError] = useState(false);
|
|
80
|
+
const [totalMessageLength, setTotalMessageLength] = useState(0);
|
|
81
|
+
const [isUnicodeAllowed, updateIsUnicodeAllowed] = useState(true);
|
|
82
|
+
const [showMsgLengthNote, updateshowMsgLengthNote] = useState(false);
|
|
70
83
|
const SMSTraiFooter = styled.div`
|
|
71
84
|
background-color: ${CAP_WHITE};
|
|
72
85
|
position: fixed;
|
|
@@ -85,32 +98,38 @@ export const SmsTraiEdit = (props) => {
|
|
|
85
98
|
margin-right: ${CAP_SPACE_12};
|
|
86
99
|
}
|
|
87
100
|
`;
|
|
101
|
+
|
|
88
102
|
useEffect(() => {
|
|
103
|
+
//fetching tags
|
|
104
|
+
const { type, module } = location.query || {};
|
|
105
|
+
const isEmbedded = type === EMBEDDED;
|
|
106
|
+
const query = {
|
|
107
|
+
layout: SMS,
|
|
108
|
+
type: TAG,
|
|
109
|
+
context: isEmbedded ? module : DEFAULT,
|
|
110
|
+
embedded: isEmbedded ? type : FULL,
|
|
111
|
+
};
|
|
112
|
+
if (getDefaultTags) {
|
|
113
|
+
query.context = getDefaultTags;
|
|
114
|
+
}
|
|
115
|
+
globalActions.fetchSchemaForEntity(query);
|
|
116
|
+
//fetching template data in fullmode
|
|
89
117
|
const { id } = params || {};
|
|
90
118
|
if (id) {
|
|
91
119
|
actions.getTemplateDetails(id);
|
|
92
|
-
//fetching tags
|
|
93
|
-
const query = {
|
|
94
|
-
layout: SMS,
|
|
95
|
-
type: TAG,
|
|
96
|
-
context:
|
|
97
|
-
location.query.type === EMBEDDED ? location.query.module : DEFAULT,
|
|
98
|
-
embedded: location.query.type === EMBEDDED ? location.query.type : FULL,
|
|
99
|
-
};
|
|
100
|
-
if (getDefaultTags) {
|
|
101
|
-
query.context = getDefaultTags;
|
|
102
|
-
}
|
|
103
|
-
globalActions.fetchSchemaForEntity(query);
|
|
104
120
|
}
|
|
121
|
+
//cleanup code
|
|
105
122
|
return () => {
|
|
106
123
|
actions.resetEditTemplate();
|
|
124
|
+
varMap = {};
|
|
107
125
|
};
|
|
108
126
|
}, []);
|
|
109
127
|
|
|
110
128
|
//computing placeholder array for mapping values and rendering dynamic form
|
|
111
129
|
useEffect(() => {
|
|
112
|
-
|
|
113
|
-
|
|
130
|
+
traiData = isFullMode ? templateDetails : templateData;
|
|
131
|
+
if (traiData && !isEmpty(traiData)) {
|
|
132
|
+
let msg = get(traiData, `versions.base.sms-editor`, '');
|
|
114
133
|
const templateMessageArray = [];
|
|
115
134
|
//converting sms-editor string to an array split at '{#var#}'
|
|
116
135
|
//split and push string before '{#var#}[0 to index]', push '{#var#}',
|
|
@@ -126,44 +145,56 @@ export const SmsTraiEdit = (props) => {
|
|
|
126
145
|
break;
|
|
127
146
|
}
|
|
128
147
|
}
|
|
129
|
-
|
|
130
|
-
const filteredTemplateMessageArray = templateMessageArray.filter(
|
|
131
|
-
(i) => i.trim() !== '',
|
|
132
|
-
);
|
|
148
|
+
const filteredTemplateMessageArray = templateMessageArray.filter((i) => i === 0 || i);
|
|
133
149
|
updateTempMsgArray(filteredTemplateMessageArray);
|
|
134
150
|
//stop spinner
|
|
135
151
|
updateLoading(false);
|
|
136
152
|
}
|
|
137
|
-
}, [templateDetails]);
|
|
153
|
+
}, [templateDetails || templateData]);
|
|
138
154
|
|
|
155
|
+
//compute/get varMapped and updated-sms-editor
|
|
139
156
|
useEffect(() => {
|
|
140
157
|
if (tempMsgArray.length !== 0) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
158
|
+
const traiBase = traiData?.versions?.base || {};
|
|
159
|
+
const {
|
|
160
|
+
'var-mapped': varMapped = {},
|
|
161
|
+
'updated-sms-editor': traiSmsEditor = '',
|
|
162
|
+
} = traiBase;
|
|
163
|
+
//if varMap and updated-sms-editor is already present on non first edits,use those values
|
|
164
|
+
if (!isEmpty(varMapped)) {
|
|
165
|
+
varMap = cloneDeep(varMapped);
|
|
166
|
+
if (isFullMode) {
|
|
167
|
+
setUpdatedSmsEditor(traiSmsEditor);
|
|
168
|
+
} else {
|
|
169
|
+
computeUpdatedSmsEditor();
|
|
170
|
+
}
|
|
147
171
|
} else {
|
|
148
|
-
//computing varMap for first edit
|
|
149
|
-
let
|
|
150
|
-
|
|
172
|
+
//computing and setting varMap for first edit
|
|
173
|
+
let varCount = 1;
|
|
174
|
+
let horizontalSpaceCount = 0;
|
|
175
|
+
for (let i = 0; i < tempMsgArray.length; i += 1) {
|
|
151
176
|
if (tempMsgArray[i] === SMS_TRAI_VAR) {
|
|
152
177
|
const nextElem =
|
|
153
|
-
tempMsgArray[i === tempMsgArray.length - 1 ?
|
|
154
|
-
if (
|
|
155
|
-
|
|
178
|
+
tempMsgArray[i === tempMsgArray.length - 1 ? -1 : i + 1];
|
|
179
|
+
if (nextElem?.replace(/[^\S\r\n]/gm, '') === '') {
|
|
180
|
+
horizontalSpaceCount += 1;
|
|
181
|
+
}
|
|
182
|
+
if (tempMsgArray[i] !== nextElem && nextElem?.replace(/[^\S\r\n]/gm, '') !== '') {
|
|
183
|
+
varMap[`${tempMsgArray[i]}_${(i - varCount - horizontalSpaceCount) + 1}`] = {
|
|
156
184
|
data: '',
|
|
157
|
-
count:
|
|
185
|
+
count: varCount,
|
|
158
186
|
};
|
|
159
|
-
|
|
187
|
+
varCount = 1;
|
|
188
|
+
horizontalSpaceCount = 0;
|
|
160
189
|
} else {
|
|
161
|
-
|
|
190
|
+
varCount += 1;
|
|
162
191
|
}
|
|
163
192
|
}
|
|
164
193
|
}
|
|
165
194
|
setUpdatedSmsEditor(tempMsgArray);
|
|
166
195
|
}
|
|
196
|
+
// calcaulate message length here
|
|
197
|
+
calculateTotalMessageLength();
|
|
167
198
|
}
|
|
168
199
|
}, [tempMsgArray]);
|
|
169
200
|
|
|
@@ -176,6 +207,44 @@ export const SmsTraiEdit = (props) => {
|
|
|
176
207
|
}
|
|
177
208
|
}, []);
|
|
178
209
|
|
|
210
|
+
//performs tag validation
|
|
211
|
+
useEffect(() => {
|
|
212
|
+
if (
|
|
213
|
+
!isFullMode &&
|
|
214
|
+
updatedSmsEditor?.length > 0 &&
|
|
215
|
+
!updatedSmsEditor.includes(SMS_TRAI_VAR)
|
|
216
|
+
) {
|
|
217
|
+
tagValidationResponse =
|
|
218
|
+
validateTags({
|
|
219
|
+
content: updatedSmsEditor.join(''),
|
|
220
|
+
tagsParam: tags,
|
|
221
|
+
injectedTagsParams: injectedTags,
|
|
222
|
+
location,
|
|
223
|
+
tagModule: getDefaultTags,
|
|
224
|
+
}) || {};
|
|
225
|
+
updateIsTagValidationError(
|
|
226
|
+
tagValidationResponse.unsupportedTags.length > 0,
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
}, [updatedSmsEditor, tags]);
|
|
230
|
+
|
|
231
|
+
const computeUpdatedSmsEditor = () => {
|
|
232
|
+
const arr = [...tempMsgArray];
|
|
233
|
+
const varMapKeys = Object.keys(varMap)?.map((key) => Number(key.slice(8)))?.sort((a, b) => a - b) || [];
|
|
234
|
+
for (const key in varMap) {
|
|
235
|
+
const _id = Number(key.slice(8)); //Eg: -> extracting index 1 from keys like {#var# } _1
|
|
236
|
+
const loopIndex = varMapKeys[varMapKeys?.indexOf(_id) + 1] || arr.length;
|
|
237
|
+
for (let i = _id; i < loopIndex; i += 1) {
|
|
238
|
+
if (i === _id) {
|
|
239
|
+
arr[i] = varMap[key].data; //data for first #var# of the textbox
|
|
240
|
+
} else if (arr[i] === SMS_TRAI_VAR) {
|
|
241
|
+
arr[i] = '';//'' for remaining #var# of a textbox
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
setUpdatedSmsEditor(arr);
|
|
246
|
+
};
|
|
247
|
+
|
|
179
248
|
//Saving on done start
|
|
180
249
|
const onUpdateTemplateComplete = (editResponse, errorMsg) => {
|
|
181
250
|
if (editResponse?.templateId) {
|
|
@@ -191,16 +260,30 @@ export const SmsTraiEdit = (props) => {
|
|
|
191
260
|
}
|
|
192
261
|
};
|
|
193
262
|
const onDoneCallback = () => {
|
|
194
|
-
if (updatedSmsEditor.includes(SMS_TRAI_VAR)) {
|
|
263
|
+
if (updatedSmsEditor.includes(SMS_TRAI_VAR) && !isFullMode) {
|
|
195
264
|
//during save textbox should not be empty
|
|
196
265
|
updateIsValidationError(true);
|
|
197
266
|
} else {
|
|
198
267
|
//start spinner
|
|
199
268
|
updateLoading(true);
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
269
|
+
const traiVersions = traiData.versions || {};
|
|
270
|
+
traiVersions.base = {
|
|
271
|
+
...traiVersions.base,
|
|
272
|
+
'var-mapped': varMap,
|
|
273
|
+
'updated-sms-editor': updatedSmsEditor,
|
|
274
|
+
'unicode-validity': isUnicodeAllowed,
|
|
275
|
+
};
|
|
276
|
+
traiVersions.history = [traiVersions.base];
|
|
277
|
+
if (isFullMode) {
|
|
278
|
+
actions.editTemplate(traiData, onUpdateTemplateComplete);
|
|
279
|
+
} else {
|
|
280
|
+
getFormSubscriptionData({
|
|
281
|
+
value: traiData.versions,
|
|
282
|
+
_id: params && params.id,
|
|
283
|
+
validity: true,
|
|
284
|
+
type: SMS,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
204
287
|
}
|
|
205
288
|
};
|
|
206
289
|
//Saving on done end
|
|
@@ -209,17 +292,16 @@ export const SmsTraiEdit = (props) => {
|
|
|
209
292
|
useEffect(() => {
|
|
210
293
|
let tag =
|
|
211
294
|
metaEntities && metaEntities.tags ? metaEntities.tags.standard : [];
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
location.query.module === LIBRARY &&
|
|
215
|
-
!getDefaultTags
|
|
216
|
-
) {
|
|
295
|
+
const { type, module } = location.query || {};
|
|
296
|
+
if (type === EMBEDDED && module === LIBRARY && !getDefaultTags) {
|
|
217
297
|
tag = supportedTags;
|
|
218
298
|
}
|
|
219
299
|
updateTags(tag);
|
|
220
300
|
}, [metaEntities]);
|
|
221
301
|
|
|
222
302
|
const handleOnTagsContextChange = (data) => {
|
|
303
|
+
const { type } = location.query || {};
|
|
304
|
+
const isEmbedded = type === EMBEDDED;
|
|
223
305
|
const query = {
|
|
224
306
|
layout: SMS,
|
|
225
307
|
type: TAG,
|
|
@@ -227,28 +309,26 @@ export const SmsTraiEdit = (props) => {
|
|
|
227
309
|
(data || '').toLowerCase() === ALL
|
|
228
310
|
? DEFAULT
|
|
229
311
|
: (data || '').toLowerCase(),
|
|
230
|
-
embedded:
|
|
312
|
+
embedded: isEmbedded ? type : FULL,
|
|
231
313
|
};
|
|
232
314
|
globalActions.fetchSchemaForEntity(query);
|
|
233
315
|
};
|
|
234
316
|
|
|
235
317
|
const onTagSelect = (data) => {
|
|
236
318
|
if (textAreaId && varMap && updatedSmsEditor) {
|
|
237
|
-
const
|
|
319
|
+
const arr = [...updatedSmsEditor];
|
|
320
|
+
const varMapKeys = Object.keys(varMap)?.map((key) => Number(key.slice(8)))?.sort((a, b) => a - b) || [];
|
|
321
|
+
const loopIndex = varMapKeys[varMapKeys?.indexOf(textAreaId) + 1] || arr.length;
|
|
238
322
|
//when trying to insert tag in empty textarea,{#var#} is replaced with "" and then tag is added
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
i < varMap[`${SMS_TRAI_VAR}_${textAreaId}`].count;
|
|
243
|
-
i++
|
|
244
|
-
) {
|
|
245
|
-
tempArr[textAreaId + i] = '';
|
|
323
|
+
for (let i = textAreaId; i < loopIndex; i += 1) {
|
|
324
|
+
if (arr[i] === SMS_TRAI_VAR) {
|
|
325
|
+
arr[i] = '';
|
|
246
326
|
}
|
|
247
327
|
}
|
|
248
|
-
const messageData = `${
|
|
249
|
-
|
|
328
|
+
const messageData = `${arr[textAreaId]}{{${data}}}`;
|
|
329
|
+
arr[textAreaId] = messageData;
|
|
250
330
|
varMap[`${SMS_TRAI_VAR}_${textAreaId}`].data = messageData;
|
|
251
|
-
setUpdatedSmsEditor(
|
|
331
|
+
setUpdatedSmsEditor(arr);
|
|
252
332
|
}
|
|
253
333
|
};
|
|
254
334
|
//setting the id of currently selected text area, is used onTagSelect
|
|
@@ -259,23 +339,34 @@ export const SmsTraiEdit = (props) => {
|
|
|
259
339
|
|
|
260
340
|
// on change event of Text Area
|
|
261
341
|
const textAreaValueChange = ({ target: { value, id } }) => {
|
|
262
|
-
|
|
342
|
+
const _id = Number(id);
|
|
343
|
+
const _value = value.replace(/[\r\n]+/gm, "");//skip newlines eg: '/n'
|
|
263
344
|
const arr = [...updatedSmsEditor];
|
|
264
|
-
varMap[`${SMS_TRAI_VAR}_${
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
345
|
+
const selectedVarCount = varMap[`${SMS_TRAI_VAR}_${_id}`].count;
|
|
346
|
+
const varMapKeys = Object.keys(varMap)?.map((key) => Number(key.slice(8)))?.sort((a, b) => a - b) || [];
|
|
347
|
+
const loopIndex = varMapKeys[varMapKeys?.indexOf(_id) + 1] || arr.length;
|
|
348
|
+
|
|
349
|
+
//assign entered value to varMap
|
|
350
|
+
varMap[`${SMS_TRAI_VAR}_${_id}`].data = _value;
|
|
351
|
+
//based on entered value update updatedSmsEditor
|
|
352
|
+
if (_value === '') {
|
|
353
|
+
for (let i = _id; i < loopIndex; i += 1) {
|
|
354
|
+
if (i === _id || arr[i] === '') {
|
|
355
|
+
arr[i] = SMS_TRAI_VAR;
|
|
356
|
+
}
|
|
268
357
|
}
|
|
269
358
|
} else {
|
|
270
|
-
for (let i =
|
|
271
|
-
if (i ===
|
|
272
|
-
arr[
|
|
273
|
-
} else {
|
|
274
|
-
arr[
|
|
359
|
+
for (let i = _id; i < loopIndex; i += 1) {
|
|
360
|
+
if (i === _id) {
|
|
361
|
+
arr[i] = varMap[`${SMS_TRAI_VAR}_${_id}`].data;
|
|
362
|
+
} else if (arr[i] === SMS_TRAI_VAR) {
|
|
363
|
+
arr[i] = '';
|
|
275
364
|
}
|
|
276
365
|
}
|
|
277
366
|
}
|
|
278
367
|
setUpdatedSmsEditor(arr);
|
|
368
|
+
calculateTotalMessageLength();
|
|
369
|
+
updateshowMsgLengthNote(arr[_id]?.length > selectedVarCount * CHARLIMIT);
|
|
279
370
|
};
|
|
280
371
|
|
|
281
372
|
const textAreaValue = (idValue) => {
|
|
@@ -285,9 +376,8 @@ export const SmsTraiEdit = (props) => {
|
|
|
285
376
|
updatedSmsEditor[idValue] !== SMS_TRAI_VAR
|
|
286
377
|
) {
|
|
287
378
|
return updatedSmsEditor[idValue];
|
|
288
|
-
} else {
|
|
289
|
-
return '';
|
|
290
379
|
}
|
|
380
|
+
return '';
|
|
291
381
|
}
|
|
292
382
|
return '';
|
|
293
383
|
};
|
|
@@ -308,20 +398,20 @@ export const SmsTraiEdit = (props) => {
|
|
|
308
398
|
</CapHeading>
|
|
309
399
|
);
|
|
310
400
|
}
|
|
401
|
+
return <></>;
|
|
311
402
|
};
|
|
312
403
|
|
|
313
404
|
const renderedContent = () => {
|
|
314
405
|
const renderArray = [];
|
|
315
406
|
if (tempMsgArray?.length !== 0) {
|
|
316
407
|
let varCount = 0;
|
|
317
|
-
tempMsgArray.
|
|
408
|
+
tempMsgArray.forEach((elem, index) => {
|
|
318
409
|
let prevElem = '';
|
|
410
|
+
prevElem =
|
|
411
|
+
tempMsgArray[[index === 0 ? -1 : index - 1]];
|
|
319
412
|
if (elem.includes(SMS_TRAI_VAR)) {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
varCount++;
|
|
323
|
-
totalVarCount++;
|
|
324
|
-
if (prevElem !== SMS_TRAI_VAR) {
|
|
413
|
+
varCount += 1;
|
|
414
|
+
if (prevElem !== SMS_TRAI_VAR && prevElem?.replace(/[^\S\r\n]/gm, '') !== '') {
|
|
325
415
|
renderArray.push(
|
|
326
416
|
<TextArea
|
|
327
417
|
id={index}
|
|
@@ -345,18 +435,18 @@ export const SmsTraiEdit = (props) => {
|
|
|
345
435
|
renderArray.push(capHeading(index, varCount));
|
|
346
436
|
varCount = 0;
|
|
347
437
|
}
|
|
348
|
-
} else if (varCount > 0) {
|
|
438
|
+
} else if (varCount > 0 && elem.replace(/[^\S\r\n]/gm, '') !== '') {
|
|
349
439
|
renderArray.push(
|
|
350
440
|
capHeading(index, varCount),
|
|
351
441
|
<CapHeading
|
|
352
442
|
key={`${elem}${index}`}
|
|
353
|
-
style={{ margin: `${CAP_SPACE_16} 0
|
|
443
|
+
style={{ margin: `${CAP_SPACE_16} 0`, clear: 'both' }}
|
|
354
444
|
>
|
|
355
445
|
{elem}
|
|
356
446
|
</CapHeading>,
|
|
357
447
|
);
|
|
358
448
|
varCount = 0;
|
|
359
|
-
} else {
|
|
449
|
+
} else if (elem.replace(/[^\S\r\n]/gm, '') !== '') {
|
|
360
450
|
renderArray.push(
|
|
361
451
|
<CapHeading
|
|
362
452
|
key={`${elem}${index}`}
|
|
@@ -371,42 +461,88 @@ export const SmsTraiEdit = (props) => {
|
|
|
371
461
|
return renderArray;
|
|
372
462
|
};
|
|
373
463
|
|
|
464
|
+
const smsLengthForVar = () => (
|
|
465
|
+
<CapHeading type="h5" style={{ marginTop: CAP_SPACE_04, float: 'right' }}>
|
|
466
|
+
{formatMessage(messages.totalCharacters, {
|
|
467
|
+
smsCount: Math.ceil(totalMessageLength / 160),
|
|
468
|
+
number: totalMessageLength,
|
|
469
|
+
})}
|
|
470
|
+
</CapHeading>
|
|
471
|
+
);
|
|
472
|
+
|
|
374
473
|
// to compute the length of the message
|
|
375
|
-
//30 characters is blocked per'{#var#}'
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
474
|
+
//30 characters is blocked per'{#var#}' if textbox is empty otherwise it will be textbox length
|
|
475
|
+
// and the remaining string length is added to it
|
|
476
|
+
const calculateTotalMessageLength = () => {
|
|
477
|
+
const msgLenWithoutVar = tempMsgArray
|
|
478
|
+
?.filter((i) => i !== SMS_TRAI_VAR)
|
|
479
|
+
.join('');
|
|
480
|
+
const varLen = calculateLenForTextBox();
|
|
481
|
+
const totalMsgLen = msgLenWithoutVar?.length + varLen;
|
|
482
|
+
setTotalMessageLength(totalMsgLen);
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
const calculateLenForTextBox = () => {
|
|
486
|
+
let countVarChar = 0;
|
|
487
|
+
Object.keys(varMap).forEach((i) => {
|
|
488
|
+
if (varMap[i].data) {
|
|
489
|
+
countVarChar += varMap[i].data?.length;
|
|
490
|
+
} else {
|
|
491
|
+
countVarChar += varMap[i].count * CHARLIMIT;
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
return countVarChar;
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
const tagValidationErrorMessage = () => {
|
|
498
|
+
const { unsupportedTags = [] } = tagValidationResponse;
|
|
499
|
+
let tagError = '';
|
|
500
|
+
if (unsupportedTags.length > 0) {
|
|
501
|
+
tagError = formatMessage(messages.unsupportedTagsValidationError, {
|
|
502
|
+
unsupportedTags,
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
return <CapError>{tagError}</CapError>;
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
const disablehandler = () => {
|
|
509
|
+
if (traiData && !isEmpty(traiData)) {
|
|
510
|
+
const msg = get(traiData, `versions.base.sms-editor`, '');
|
|
511
|
+
const index = msg.search(SMS_TRAI_VAR);
|
|
512
|
+
if (index === -1) {
|
|
513
|
+
return true;
|
|
514
|
+
}
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
return true;
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
const unicodeHandler = ({ target: { checked } }) => {
|
|
521
|
+
updateIsUnicodeAllowed(checked);
|
|
388
522
|
};
|
|
389
523
|
|
|
390
524
|
return (
|
|
391
525
|
<>
|
|
392
526
|
<CapSpin spinning={loading}>
|
|
393
527
|
<CapRow>
|
|
394
|
-
{
|
|
528
|
+
{traiData && !isEmpty(traiData) && (
|
|
395
529
|
<TraiEditTemplateDetails>
|
|
396
530
|
<CapLabelInline type="label1">
|
|
397
531
|
{formatMessage(messages.templateLabel)}
|
|
398
532
|
</CapLabelInline>
|
|
399
533
|
<CapLabelInline type="label2">
|
|
400
|
-
{
|
|
534
|
+
{get(traiData, `versions.base.template_name`, '')}
|
|
401
535
|
</CapLabelInline>
|
|
536
|
+
|
|
402
537
|
<CapLabelInline type="label1">
|
|
403
538
|
{formatMessage(messages.traiEditSeperator)}
|
|
404
539
|
</CapLabelInline>
|
|
540
|
+
|
|
405
541
|
<CapLabelInline type="label1">
|
|
406
542
|
{formatMessage(messages.senderIdlabel)}
|
|
407
543
|
</CapLabelInline>
|
|
408
544
|
<CapLabelInline type="label2">
|
|
409
|
-
{
|
|
545
|
+
{[...get(traiData, `versions.base.header`, [])].join(', ')}
|
|
410
546
|
</CapLabelInline>
|
|
411
547
|
</TraiEditTemplateDetails>
|
|
412
548
|
)}
|
|
@@ -423,6 +559,7 @@ export const SmsTraiEdit = (props) => {
|
|
|
423
559
|
tags={tags || []}
|
|
424
560
|
onContextChange={handleOnTagsContextChange}
|
|
425
561
|
injectedTags={injectedTags || {}}
|
|
562
|
+
hidePopover={disablehandler()}
|
|
426
563
|
/>
|
|
427
564
|
}
|
|
428
565
|
/>
|
|
@@ -437,17 +574,28 @@ export const SmsTraiEdit = (props) => {
|
|
|
437
574
|
{renderedContent()}
|
|
438
575
|
</CapRow>
|
|
439
576
|
<CapRow>{smsLengthForVar()}</CapRow>
|
|
577
|
+
{isTagValidationError && tagValidationErrorMessage()}
|
|
578
|
+
<CapCheckbox onChange={unicodeHandler} checked={isUnicodeAllowed} disabled={disablehandler()}>
|
|
579
|
+
{formatMessage(messages.unicodeLabel)}
|
|
580
|
+
</CapCheckbox>
|
|
581
|
+
{showMsgLengthNote && <CapInfoNote message={<FormattedMessage {...messages.msgLengthNote} />} />}
|
|
440
582
|
<div style={{ marginBottom: '100px' }} />
|
|
441
583
|
</CapColumn>
|
|
442
584
|
<CapColumn span={10}>
|
|
443
585
|
<TemplatePreview
|
|
444
586
|
channel={SMS}
|
|
445
|
-
content={
|
|
587
|
+
content={updatedSmsEditor.join('')}
|
|
588
|
+
unicodeEnabled={isUnicodeAllowed}
|
|
589
|
+
charCounterEnabled
|
|
446
590
|
/>
|
|
447
591
|
</CapColumn>
|
|
448
592
|
</CapRow>
|
|
449
593
|
<SMSTraiFooter>
|
|
450
|
-
<CapButton
|
|
594
|
+
<CapButton
|
|
595
|
+
onClick={onDoneCallback}
|
|
596
|
+
className="create-msg"
|
|
597
|
+
disabled={isTagValidationError}
|
|
598
|
+
>
|
|
451
599
|
<FormattedMessage {...messages.saveButtonLabel} />
|
|
452
600
|
</CapButton>
|
|
453
601
|
<CapButton
|
|
@@ -469,11 +617,9 @@ const mapStateToProps = createStructuredSelector({
|
|
|
469
617
|
injectedTags: setInjectedTags(),
|
|
470
618
|
});
|
|
471
619
|
|
|
472
|
-
const mapDispatchToProps = (dispatch) => {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
};
|
|
476
|
-
};
|
|
620
|
+
const mapDispatchToProps = (dispatch) => ({
|
|
621
|
+
actions: bindActionCreators(smsEditActions, dispatch),
|
|
622
|
+
});
|
|
477
623
|
|
|
478
624
|
export default withCreatives({
|
|
479
625
|
WrappedComponent: injectIntl(SmsTraiEdit),
|
|
@@ -29,7 +29,7 @@ export default defineMessages({
|
|
|
29
29
|
},
|
|
30
30
|
textAreaCounts: {
|
|
31
31
|
id: `${prefix}.textAreaCounts`,
|
|
32
|
-
defaultMessage: '{varCounts}
|
|
32
|
+
defaultMessage: '{varCounts} variable{varCounts, plural, one {} other {s}} {var}: max. {charCounts} characters',
|
|
33
33
|
},
|
|
34
34
|
totalCharacters: {
|
|
35
35
|
id: `${prefix}.totalCharacters`,
|
|
@@ -55,4 +55,17 @@ export default defineMessages({
|
|
|
55
55
|
id: `${prefix}.senderIdlabel`,
|
|
56
56
|
defaultMessage: 'Sender ID',
|
|
57
57
|
},
|
|
58
|
+
unsupportedTagsValidationError: {
|
|
59
|
+
id: `${prefix}.unsupportedTagsValidationError`,
|
|
60
|
+
defaultMessage:
|
|
61
|
+
'Unsupported tags: {unsupportedTags}. Please remove them from this message.',
|
|
62
|
+
},
|
|
63
|
+
unicodeLabel: {
|
|
64
|
+
id: `${prefix}.unicodeLabel`,
|
|
65
|
+
defaultMessage: 'Allow unicode characters',
|
|
66
|
+
},
|
|
67
|
+
msgLengthNote: {
|
|
68
|
+
id: `${prefix}.msgLengthNote`,
|
|
69
|
+
defaultMessage: 'Only 30 characters are allowed per variable {#var#} field. In case the field resolves to more than 30 characters the message is bound to fail. Hence will not be sent by the Capillary system.',
|
|
70
|
+
},
|
|
58
71
|
});
|