@capillarytech/creatives-library 7.10.10 → 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.
@@ -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,20 @@ 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
+ 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
241
242
  }
242
243
  }
243
244
  }
244
- setUpdatedSmsEditor(updatedSmsArray);
245
+ setUpdatedSmsEditor(arr);
245
246
  };
246
247
 
247
248
  //Saving on done start
@@ -315,21 +316,19 @@ export const SmsTraiEdit = (props) => {
315
316
 
316
317
  const onTagSelect = (data) => {
317
318
  if (textAreaId && varMap && updatedSmsEditor) {
318
- const tempArr = [...updatedSmsEditor];
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;
319
322
  //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] = '';
323
+ for (let i = textAreaId; i < loopIndex; i += 1) {
324
+ if (arr[i] === SMS_TRAI_VAR) {
325
+ arr[i] = '';
327
326
  }
328
327
  }
329
- const messageData = `${tempArr[textAreaId]} {{${data}}}`;
330
- tempArr[textAreaId] = messageData;
328
+ const messageData = `${arr[textAreaId]}{{${data}}}`;
329
+ arr[textAreaId] = messageData;
331
330
  varMap[`${SMS_TRAI_VAR}_${textAreaId}`].data = messageData;
332
- setUpdatedSmsEditor(tempArr);
331
+ setUpdatedSmsEditor(arr);
333
332
  }
334
333
  };
335
334
  //setting the id of currently selected text area, is used onTagSelect
@@ -341,23 +340,33 @@ export const SmsTraiEdit = (props) => {
341
340
  // on change event of Text Area
342
341
  const textAreaValueChange = ({ target: { value, id } }) => {
343
342
  const _id = Number(id);
343
+ const _value = value.replace(/[\r\n]+/gm, "");//skip newlines eg: '/n'
344
344
  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;
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
+ }
349
357
  }
350
358
  } 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] = '';
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] = '';
356
364
  }
357
365
  }
358
366
  }
359
367
  setUpdatedSmsEditor(arr);
360
368
  calculateTotalMessageLength();
369
+ updateshowMsgLengthNote(arr[_id]?.length > selectedVarCount * CHARLIMIT);
361
370
  };
362
371
 
363
372
  const textAreaValue = (idValue) => {
@@ -398,11 +407,11 @@ export const SmsTraiEdit = (props) => {
398
407
  let varCount = 0;
399
408
  tempMsgArray.forEach((elem, index) => {
400
409
  let prevElem = '';
410
+ prevElem =
411
+ tempMsgArray[[index === 0 ? -1 : index - 1]];
401
412
  if (elem.includes(SMS_TRAI_VAR)) {
402
- prevElem =
403
- tempMsgArray[[index === 0 ? tempMsgArray.length - 1 : index - 1]];
404
413
  varCount += 1;
405
- if (prevElem !== SMS_TRAI_VAR) {
414
+ if (prevElem !== SMS_TRAI_VAR && prevElem?.replace(/[^\S\r\n]/gm, '') !== '') {
406
415
  renderArray.push(
407
416
  <TextArea
408
417
  id={index}
@@ -426,18 +435,18 @@ export const SmsTraiEdit = (props) => {
426
435
  renderArray.push(capHeading(index, varCount));
427
436
  varCount = 0;
428
437
  }
429
- } else if (varCount > 0) {
438
+ } else if (varCount > 0 && elem.replace(/[^\S\r\n]/gm, '') !== '') {
430
439
  renderArray.push(
431
440
  capHeading(index, varCount),
432
441
  <CapHeading
433
442
  key={`${elem}${index}`}
434
- style={{ margin: `${CAP_SPACE_16} 0` }}
443
+ style={{ margin: `${CAP_SPACE_16} 0`, clear: 'both' }}
435
444
  >
436
445
  {elem}
437
446
  </CapHeading>,
438
447
  );
439
448
  varCount = 0;
440
- } else {
449
+ } else if (elem.replace(/[^\S\r\n]/gm, '') !== '') {
441
450
  renderArray.push(
442
451
  <CapHeading
443
452
  key={`${elem}${index}`}
@@ -468,9 +477,8 @@ export const SmsTraiEdit = (props) => {
468
477
  const msgLenWithoutVar = tempMsgArray
469
478
  ?.filter((i) => i !== SMS_TRAI_VAR)
470
479
  .join('');
471
- const charDetails = updateCharCount(msgLenWithoutVar, false);
472
480
  const varLen = calculateLenForTextBox();
473
- const totalMsgLen = charDetails.chars_used + varLen;
481
+ const totalMsgLen = msgLenWithoutVar?.length + varLen;
474
482
  setTotalMessageLength(totalMsgLen);
475
483
  };
476
484
 
@@ -478,14 +486,14 @@ export const SmsTraiEdit = (props) => {
478
486
  let countVarChar = 0;
479
487
  Object.keys(varMap).forEach((i) => {
480
488
  if (varMap[i].data) {
481
- const charDetails = updateCharCount(varMap[i].data, false);
482
- countVarChar += charDetails.chars_used;
489
+ countVarChar += varMap[i].data?.length;
483
490
  } else {
484
491
  countVarChar += varMap[i].count * CHARLIMIT;
485
492
  }
486
493
  });
487
494
  return countVarChar;
488
495
  };
496
+
489
497
  const tagValidationErrorMessage = () => {
490
498
  const { unsupportedTags = [] } = tagValidationResponse;
491
499
  let tagError = '';
@@ -497,6 +505,18 @@ export const SmsTraiEdit = (props) => {
497
505
  return <CapError>{tagError}</CapError>;
498
506
  };
499
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
+
500
520
  const unicodeHandler = ({ target: { checked } }) => {
501
521
  updateIsUnicodeAllowed(checked);
502
522
  };
@@ -511,7 +531,7 @@ export const SmsTraiEdit = (props) => {
511
531
  {formatMessage(messages.templateLabel)}
512
532
  </CapLabelInline>
513
533
  <CapLabelInline type="label2">
514
- {traiData.versions.base.template_name}
534
+ {get(traiData, `versions.base.template_name`, '')}
515
535
  </CapLabelInline>
516
536
 
517
537
  <CapLabelInline type="label1">
@@ -522,7 +542,7 @@ export const SmsTraiEdit = (props) => {
522
542
  {formatMessage(messages.senderIdlabel)}
523
543
  </CapLabelInline>
524
544
  <CapLabelInline type="label2">
525
- {traiData.versions.base.header.join(', ')}
545
+ {[...get(traiData, `versions.base.header`, [])].join(', ')}
526
546
  </CapLabelInline>
527
547
  </TraiEditTemplateDetails>
528
548
  )}
@@ -539,6 +559,7 @@ export const SmsTraiEdit = (props) => {
539
559
  tags={tags || []}
540
560
  onContextChange={handleOnTagsContextChange}
541
561
  injectedTags={injectedTags || {}}
562
+ hidePopover={disablehandler()}
542
563
  />
543
564
  }
544
565
  />
@@ -554,9 +575,10 @@ export const SmsTraiEdit = (props) => {
554
575
  </CapRow>
555
576
  <CapRow>{smsLengthForVar()}</CapRow>
556
577
  {isTagValidationError && tagValidationErrorMessage()}
557
- <CapCheckbox onChange={unicodeHandler} checked={isUnicodeAllowed}>
578
+ <CapCheckbox onChange={unicodeHandler} checked={isUnicodeAllowed} disabled={disablehandler()}>
558
579
  {formatMessage(messages.unicodeLabel)}
559
580
  </CapCheckbox>
581
+ {showMsgLengthNote && <CapInfoNote message={<FormattedMessage {...messages.msgLengthNote} />} />}
560
582
  <div style={{ marginBottom: '100px' }} />
561
583
  </CapColumn>
562
584
  <CapColumn span={10}>
@@ -564,7 +586,7 @@ export const SmsTraiEdit = (props) => {
564
586
  channel={SMS}
565
587
  content={updatedSmsEditor.join('')}
566
588
  unicodeEnabled={isUnicodeAllowed}
567
- charCounterEnabled={true}
589
+ charCounterEnabled
568
590
  />
569
591
  </CapColumn>
570
592
  </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
  });