@capillarytech/creatives-library 7.10.10 → 7.10.12

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.
@@ -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
- "'1107160277332377515'",
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
- 'Active',
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
  ],
@@ -15,6 +15,7 @@ import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
15
15
  import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
16
16
  import CapError from '@capillarytech/cap-ui-library/CapError';
17
17
  import CapCheckbox from '@capillarytech/cap-ui-library/CapCheckbox';
18
+ import CapInfoNote from '@capillarytech/cap-ui-library/CapInfoNote';
18
19
  import {
19
20
  CAP_SPACE_16,
20
21
  CAP_SPACE_12,
@@ -32,7 +33,6 @@ import TagList from '../../TagList';
32
33
  import TemplatePreview from '../../../v2Components/TemplatePreview';
33
34
  import withCreatives from '../../../hoc/withCreatives';
34
35
  import { validateTags } from '../../../utils/tagValidations';
35
- import { updateCharCount } from '../../../utils/smsCharCountV2';
36
36
  import {
37
37
  CHARLIMIT,
38
38
  SMS,
@@ -78,7 +78,8 @@ export const SmsTraiEdit = (props) => {
78
78
  const [isValidationError, updateIsValidationError] = useState(false);
79
79
  const [isTagValidationError, updateIsTagValidationError] = useState(false);
80
80
  const [totalMessageLength, setTotalMessageLength] = useState(0);
81
- const [isUnicodeAllowed, updateIsUnicodeAllowed] = useState(false);
81
+ const [isUnicodeAllowed, updateIsUnicodeAllowed] = useState(true);
82
+ const [showMsgLengthNote, updateshowMsgLengthNote] = useState(false);
82
83
  const SMSTraiFooter = styled.div`
83
84
  background-color: ${CAP_WHITE};
84
85
  position: fixed;
@@ -128,7 +129,7 @@ export const SmsTraiEdit = (props) => {
128
129
  useEffect(() => {
129
130
  traiData = isFullMode ? templateDetails : templateData;
130
131
  if (traiData && !isEmpty(traiData)) {
131
- let msg = get(traiData, `versions.base.sms-editor`);
132
+ let msg = get(traiData, `versions.base.sms-editor`, '');
132
133
  const templateMessageArray = [];
133
134
  //converting sms-editor string to an array split at '{#var#}'
134
135
  //split and push string before '{#var#}[0 to index]', push '{#var#}',
@@ -144,14 +145,8 @@ export const SmsTraiEdit = (props) => {
144
145
  break;
145
146
  }
146
147
  }
147
- const filteredTemplateMessageArray = templateMessageArray.filter(
148
- (i) => i.trim() !== '',
149
- );
148
+ const filteredTemplateMessageArray = templateMessageArray.filter((i) => i === 0 || i);
150
149
  updateTempMsgArray(filteredTemplateMessageArray);
151
- //updating unicode-validity
152
- updateIsUnicodeAllowed(
153
- get(traiData, `versions.base.unicode-validity`, false),
154
- );
155
150
  //stop spinner
156
151
  updateLoading(false);
157
152
  }
@@ -175,19 +170,24 @@ export const SmsTraiEdit = (props) => {
175
170
  }
176
171
  } else {
177
172
  //computing and setting varMap for first edit
178
- let counter = 1;
173
+ let varCount = 1;
174
+ let horizontalSpaceCount = 0;
179
175
  for (let i = 0; i < tempMsgArray.length; i += 1) {
180
176
  if (tempMsgArray[i] === SMS_TRAI_VAR) {
181
177
  const nextElem =
182
- tempMsgArray[i === tempMsgArray.length - 1 ? 0 : i + 1];
183
- if (tempMsgArray[i] !== nextElem) {
184
- varMap[`${tempMsgArray[i]}_${(i - counter) + 1}`] = {
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}`] = {
185
184
  data: '',
186
- count: counter,
185
+ count: varCount,
187
186
  };
188
- counter = 1;
187
+ varCount = 1;
188
+ horizontalSpaceCount = 0;
189
189
  } else {
190
- counter += 1;
190
+ varCount += 1;
191
191
  }
192
192
  }
193
193
  }
@@ -229,19 +229,23 @@ export const SmsTraiEdit = (props) => {
229
229
  }, [updatedSmsEditor, tags]);
230
230
 
231
231
  const computeUpdatedSmsEditor = () => {
232
- const updatedSmsArray = [...tempMsgArray];
232
+ const arr = [...tempMsgArray];
233
+ const varMapKeys = Object.keys(varMap)?.map((key) => Number(key.slice(8)))?.sort((a, b) => a - b) || [];
233
234
  for (const key in varMap) {
234
- const index = Number(key.slice(8)); //Eg: -> extracting index 1 from keys like {#var# } _1
235
- for (let i = 0; i < varMap[key].count; i += 1) {
236
- //when multiple "#var#" come continuously ,it is considered as 1 textbox
237
- if (i === 0) {
238
- updatedSmsArray[index] = varMap[key].data; //data for first #var# of the textbox
239
- } else {
240
- updatedSmsArray[index + i] = ''; //"" for remaining #var# of a textbox
235
+ if (varMap[key].data !== '') {
236
+ const _id = Number(key.slice(8)); //Eg: -> extracting index 1 from keys like {#var# } _1
237
+ const loopIndex =
238
+ varMapKeys[varMapKeys?.indexOf(_id) + 1] || arr.length;
239
+ for (let i = _id; i < loopIndex; i += 1) {
240
+ if (i === _id) {
241
+ arr[i] = varMap[key].data; //data for first #var# of the textbox
242
+ } else if (arr[i] === SMS_TRAI_VAR) {
243
+ arr[i] = ''; //'' for remaining #var# of a textbox
244
+ }
241
245
  }
242
246
  }
243
247
  }
244
- setUpdatedSmsEditor(updatedSmsArray);
248
+ setUpdatedSmsEditor(arr);
245
249
  };
246
250
 
247
251
  //Saving on done start
@@ -315,21 +319,19 @@ export const SmsTraiEdit = (props) => {
315
319
 
316
320
  const onTagSelect = (data) => {
317
321
  if (textAreaId && varMap && updatedSmsEditor) {
318
- const tempArr = [...updatedSmsEditor];
322
+ const arr = [...updatedSmsEditor];
323
+ const varMapKeys = Object.keys(varMap)?.map((key) => Number(key.slice(8)))?.sort((a, b) => a - b) || [];
324
+ const loopIndex = varMapKeys[varMapKeys?.indexOf(textAreaId) + 1] || arr.length;
319
325
  //when trying to insert tag in empty textarea,{#var#} is replaced with "" and then tag is added
320
- if (tempArr[textAreaId] === SMS_TRAI_VAR) {
321
- for (
322
- let i = 0;
323
- i < varMap[`${SMS_TRAI_VAR}_${textAreaId}`].count;
324
- i += 1
325
- ) {
326
- tempArr[textAreaId + i] = '';
326
+ for (let i = textAreaId; i < loopIndex; i += 1) {
327
+ if (arr[i] === SMS_TRAI_VAR) {
328
+ arr[i] = '';
327
329
  }
328
330
  }
329
- const messageData = `${tempArr[textAreaId]} {{${data}}}`;
330
- tempArr[textAreaId] = messageData;
331
+ const messageData = `${arr[textAreaId]}{{${data}}}`;
332
+ arr[textAreaId] = messageData;
331
333
  varMap[`${SMS_TRAI_VAR}_${textAreaId}`].data = messageData;
332
- setUpdatedSmsEditor(tempArr);
334
+ setUpdatedSmsEditor(arr);
333
335
  }
334
336
  };
335
337
  //setting the id of currently selected text area, is used onTagSelect
@@ -341,23 +343,33 @@ export const SmsTraiEdit = (props) => {
341
343
  // on change event of Text Area
342
344
  const textAreaValueChange = ({ target: { value, id } }) => {
343
345
  const _id = Number(id);
346
+ const _value = value.replace(/[\r\n]+/gm, "");//skip newlines eg: '/n'
344
347
  const arr = [...updatedSmsEditor];
345
- varMap[`${SMS_TRAI_VAR}_${_id}`].data = value;
346
- if (value === '') {
347
- for (let i = 0; i < varMap[`${SMS_TRAI_VAR}_${_id}`].count; i += 1) {
348
- arr[_id + i] = SMS_TRAI_VAR;
348
+ const selectedVarCount = varMap[`${SMS_TRAI_VAR}_${_id}`].count;
349
+ const varMapKeys = Object.keys(varMap)?.map((key) => Number(key.slice(8)))?.sort((a, b) => a - b) || [];
350
+ const loopIndex = varMapKeys[varMapKeys?.indexOf(_id) + 1] || arr.length;
351
+
352
+ //assign entered value to varMap
353
+ varMap[`${SMS_TRAI_VAR}_${_id}`].data = _value;
354
+ //based on entered value update updatedSmsEditor
355
+ if (_value === '') {
356
+ for (let i = _id; i < loopIndex; i += 1) {
357
+ if (i === _id || arr[i] === '') {
358
+ arr[i] = SMS_TRAI_VAR;
359
+ }
349
360
  }
350
361
  } else {
351
- for (let i = 0; i < varMap[`${SMS_TRAI_VAR}_${id}`].count; i += 1) {
352
- if (i === 0) {
353
- arr[_id] = varMap[`${SMS_TRAI_VAR}_${_id}`].data;
354
- } else {
355
- arr[_id + i] = '';
362
+ for (let i = _id; i < loopIndex; i += 1) {
363
+ if (i === _id) {
364
+ arr[i] = varMap[`${SMS_TRAI_VAR}_${_id}`].data;
365
+ } else if (arr[i] === SMS_TRAI_VAR) {
366
+ arr[i] = '';
356
367
  }
357
368
  }
358
369
  }
359
370
  setUpdatedSmsEditor(arr);
360
371
  calculateTotalMessageLength();
372
+ updateshowMsgLengthNote(arr[_id]?.length > selectedVarCount * CHARLIMIT);
361
373
  };
362
374
 
363
375
  const textAreaValue = (idValue) => {
@@ -398,11 +410,11 @@ export const SmsTraiEdit = (props) => {
398
410
  let varCount = 0;
399
411
  tempMsgArray.forEach((elem, index) => {
400
412
  let prevElem = '';
413
+ prevElem =
414
+ tempMsgArray[[index === 0 ? -1 : index - 1]];
401
415
  if (elem.includes(SMS_TRAI_VAR)) {
402
- prevElem =
403
- tempMsgArray[[index === 0 ? tempMsgArray.length - 1 : index - 1]];
404
416
  varCount += 1;
405
- if (prevElem !== SMS_TRAI_VAR) {
417
+ if (prevElem !== SMS_TRAI_VAR && prevElem?.replace(/[^\S\r\n]/gm, '') !== '') {
406
418
  renderArray.push(
407
419
  <TextArea
408
420
  id={index}
@@ -426,18 +438,18 @@ export const SmsTraiEdit = (props) => {
426
438
  renderArray.push(capHeading(index, varCount));
427
439
  varCount = 0;
428
440
  }
429
- } else if (varCount > 0) {
441
+ } else if (varCount > 0 && elem.replace(/[^\S\r\n]/gm, '') !== '') {
430
442
  renderArray.push(
431
443
  capHeading(index, varCount),
432
444
  <CapHeading
433
445
  key={`${elem}${index}`}
434
- style={{ margin: `${CAP_SPACE_16} 0` }}
446
+ style={{ margin: `${CAP_SPACE_16} 0`, clear: 'both' }}
435
447
  >
436
448
  {elem}
437
449
  </CapHeading>,
438
450
  );
439
451
  varCount = 0;
440
- } else {
452
+ } else if (elem.replace(/[^\S\r\n]/gm, '') !== '') {
441
453
  renderArray.push(
442
454
  <CapHeading
443
455
  key={`${elem}${index}`}
@@ -468,9 +480,8 @@ export const SmsTraiEdit = (props) => {
468
480
  const msgLenWithoutVar = tempMsgArray
469
481
  ?.filter((i) => i !== SMS_TRAI_VAR)
470
482
  .join('');
471
- const charDetails = updateCharCount(msgLenWithoutVar, false);
472
483
  const varLen = calculateLenForTextBox();
473
- const totalMsgLen = charDetails.chars_used + varLen;
484
+ const totalMsgLen = msgLenWithoutVar?.length + varLen;
474
485
  setTotalMessageLength(totalMsgLen);
475
486
  };
476
487
 
@@ -478,14 +489,14 @@ export const SmsTraiEdit = (props) => {
478
489
  let countVarChar = 0;
479
490
  Object.keys(varMap).forEach((i) => {
480
491
  if (varMap[i].data) {
481
- const charDetails = updateCharCount(varMap[i].data, false);
482
- countVarChar += charDetails.chars_used;
492
+ countVarChar += varMap[i].data?.length;
483
493
  } else {
484
494
  countVarChar += varMap[i].count * CHARLIMIT;
485
495
  }
486
496
  });
487
497
  return countVarChar;
488
498
  };
499
+
489
500
  const tagValidationErrorMessage = () => {
490
501
  const { unsupportedTags = [] } = tagValidationResponse;
491
502
  let tagError = '';
@@ -497,6 +508,18 @@ export const SmsTraiEdit = (props) => {
497
508
  return <CapError>{tagError}</CapError>;
498
509
  };
499
510
 
511
+ const disablehandler = () => {
512
+ if (traiData && !isEmpty(traiData)) {
513
+ const msg = get(traiData, `versions.base.sms-editor`, '');
514
+ const index = msg.search(SMS_TRAI_VAR);
515
+ if (index === -1) {
516
+ return true;
517
+ }
518
+ return false;
519
+ }
520
+ return true;
521
+ };
522
+
500
523
  const unicodeHandler = ({ target: { checked } }) => {
501
524
  updateIsUnicodeAllowed(checked);
502
525
  };
@@ -511,7 +534,7 @@ export const SmsTraiEdit = (props) => {
511
534
  {formatMessage(messages.templateLabel)}
512
535
  </CapLabelInline>
513
536
  <CapLabelInline type="label2">
514
- {traiData.versions.base.template_name}
537
+ {get(traiData, `versions.base.template_name`, '')}
515
538
  </CapLabelInline>
516
539
 
517
540
  <CapLabelInline type="label1">
@@ -522,7 +545,7 @@ export const SmsTraiEdit = (props) => {
522
545
  {formatMessage(messages.senderIdlabel)}
523
546
  </CapLabelInline>
524
547
  <CapLabelInline type="label2">
525
- {traiData.versions.base.header.join(', ')}
548
+ {[...get(traiData, `versions.base.header`, [])].join(', ')}
526
549
  </CapLabelInline>
527
550
  </TraiEditTemplateDetails>
528
551
  )}
@@ -539,6 +562,7 @@ export const SmsTraiEdit = (props) => {
539
562
  tags={tags || []}
540
563
  onContextChange={handleOnTagsContextChange}
541
564
  injectedTags={injectedTags || {}}
565
+ hidePopover={disablehandler()}
542
566
  />
543
567
  }
544
568
  />
@@ -554,9 +578,10 @@ export const SmsTraiEdit = (props) => {
554
578
  </CapRow>
555
579
  <CapRow>{smsLengthForVar()}</CapRow>
556
580
  {isTagValidationError && tagValidationErrorMessage()}
557
- <CapCheckbox onChange={unicodeHandler} checked={isUnicodeAllowed}>
581
+ <CapCheckbox onChange={unicodeHandler} checked={isUnicodeAllowed} disabled={disablehandler()}>
558
582
  {formatMessage(messages.unicodeLabel)}
559
583
  </CapCheckbox>
584
+ {showMsgLengthNote && <CapInfoNote message={<FormattedMessage {...messages.msgLengthNote} />} />}
560
585
  <div style={{ marginBottom: '100px' }} />
561
586
  </CapColumn>
562
587
  <CapColumn span={10}>
@@ -564,7 +589,7 @@ export const SmsTraiEdit = (props) => {
564
589
  channel={SMS}
565
590
  content={updatedSmsEditor.join('')}
566
591
  unicodeEnabled={isUnicodeAllowed}
567
- charCounterEnabled={true}
592
+ charCounterEnabled
568
593
  />
569
594
  </CapColumn>
570
595
  </CapRow>
@@ -29,7 +29,7 @@ export default defineMessages({
29
29
  },
30
30
  textAreaCounts: {
31
31
  id: `${prefix}.textAreaCounts`,
32
- defaultMessage: '{varCounts} Variables {var}: max. {charCounts} characters',
32
+ defaultMessage: '{varCounts} variable{varCounts, plural, one {} other {s}} {var}: max. {charCounts} characters',
33
33
  },
34
34
  totalCharacters: {
35
35
  id: `${prefix}.totalCharacters`,
@@ -55,11 +55,6 @@ export default defineMessages({
55
55
  id: `${prefix}.senderIdlabel`,
56
56
  defaultMessage: 'Sender ID',
57
57
  },
58
- missingTagsValidationError: {
59
- id: `${prefix}.missingTagsValidationError`,
60
- defaultMessage:
61
- 'Missing tags: {missingTags}. Please add them to this message.',
62
- },
63
58
  unsupportedTagsValidationError: {
64
59
  id: `${prefix}.unsupportedTagsValidationError`,
65
60
  defaultMessage:
@@ -69,4 +64,8 @@ export default defineMessages({
69
64
  id: `${prefix}.unicodeLabel`,
70
65
  defaultMessage: 'Allow unicode characters',
71
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
+ },
72
71
  });