@capillarytech/creatives-library 9.0.45 → 9.0.46
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 +1 -0
- package/package.json +1 -1
- package/v2Components/CommonTestAndPreview/UnifiedPreview/SmsPreviewContent.js +21 -1
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +5 -0
- package/v2Components/CommonTestAndPreview/index.js +1 -0
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/SmsPreviewContent.test.js +32 -0
- package/v2Components/SmsFallback/constants.js +19 -0
- package/v2Components/SmsFallback/index.js +0 -3
- package/v2Containers/SmsTrai/Edit/constants.js +2 -0
- package/v2Containers/SmsTrai/Edit/dltVarTypes.js +88 -0
- package/v2Containers/SmsTrai/Edit/index.js +206 -96
- package/v2Containers/SmsTrai/Edit/index.scss +117 -1
- package/v2Containers/SmsTrai/Edit/messages.js +40 -0
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +21164 -4559
- package/v2Containers/SmsTrai/Edit/tests/dltVarTypes.test.js +100 -0
- package/v2Containers/Templates/_templates.scss +23 -0
- package/v2Containers/Templates/index.js +96 -32
- package/v2Containers/Templates/messages.js +12 -0
- package/v2Containers/Whatsapp/index.js +2 -0
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +612 -0
- package/v2Containers/Whatsapp/tests/index.test.js +8 -0
|
@@ -19,11 +19,14 @@ import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
|
|
|
19
19
|
import CapError from '@capillarytech/cap-ui-library/CapError';
|
|
20
20
|
import CapCheckbox from '@capillarytech/cap-ui-library/CapCheckbox';
|
|
21
21
|
import CapInfoNote from '@capillarytech/cap-ui-library/CapInfoNote';
|
|
22
|
+
import CapAlert from '@capillarytech/cap-ui-library/CapAlert';
|
|
23
|
+
import CapIcon from '@capillarytech/cap-ui-library/CapIcon';
|
|
22
24
|
import injectSaga from '../../../utils/injectSaga';
|
|
23
25
|
import injectReducer from '../../../utils/injectReducer';
|
|
24
26
|
import {
|
|
25
27
|
CAP_SPACE_16,
|
|
26
28
|
CAP_SPACE_12,
|
|
29
|
+
CAP_SPACE_08,
|
|
27
30
|
CAP_SPACE_24,
|
|
28
31
|
CAP_SPACE_32,
|
|
29
32
|
CAP_SPACE_04,
|
|
@@ -51,6 +54,7 @@ import {
|
|
|
51
54
|
FULL,
|
|
52
55
|
ALL,
|
|
53
56
|
LIBRARY,
|
|
57
|
+
HORIZONTAL_WHITESPACE_ONLY_REGEX,
|
|
54
58
|
} from './constants';
|
|
55
59
|
import v2EditSmsReducer from '../../Sms/Edit/reducer';
|
|
56
60
|
import { v2SmsEditSagas } from '../../Sms/Edit/sagas';
|
|
@@ -68,6 +72,15 @@ import {
|
|
|
68
72
|
} from '../../../utils/templateVarUtils';
|
|
69
73
|
import VarSegmentMessageEditor from '../../../v2Components/VarSegmentMessageEditor';
|
|
70
74
|
import rcsMessages from '../../Rcs/messages';
|
|
75
|
+
import {
|
|
76
|
+
ANY_DLT_HASH_TOKEN_GLOBAL_REGEX,
|
|
77
|
+
ANY_DLT_HASH_TOKEN_PROBE_REGEX,
|
|
78
|
+
DLT_LEGACY_VAR_REGEX,
|
|
79
|
+
DLT_LEGACY_VAR_TOKEN,
|
|
80
|
+
isAnyDltVarToken,
|
|
81
|
+
getDltVarTypeMeta,
|
|
82
|
+
getDltVarCharLimit,
|
|
83
|
+
} from './dltVarTypes';
|
|
71
84
|
|
|
72
85
|
import './index.scss';
|
|
73
86
|
|
|
@@ -257,8 +270,8 @@ export const SmsTraiEdit = (props) => {
|
|
|
257
270
|
<span className="sms-trai-rcs-fallback-var-hint" style={dltVarSlotHintStyle}>
|
|
258
271
|
{formatMessage(messages.textAreaCounts, {
|
|
259
272
|
varCounts,
|
|
260
|
-
var:
|
|
261
|
-
charCounts: varCounts * CHARLIMIT,
|
|
273
|
+
var: dltSegmentToken,
|
|
274
|
+
charCounts: varCounts * getDltVarCharLimit(dltSegmentToken, CHARLIMIT),
|
|
262
275
|
})}
|
|
263
276
|
</span>
|
|
264
277
|
);
|
|
@@ -288,9 +301,13 @@ export const SmsTraiEdit = (props) => {
|
|
|
288
301
|
}
|
|
289
302
|
`;
|
|
290
303
|
const TraiEditTemplateDetails = styled.div`
|
|
304
|
+
display: flex;
|
|
305
|
+
flex-wrap: wrap;
|
|
306
|
+
align-items: center;
|
|
307
|
+
gap: ${CAP_SPACE_08};
|
|
291
308
|
margin-bottom: ${CAP_SPACE_16};
|
|
292
309
|
.cap-label-span {
|
|
293
|
-
margin-right:
|
|
310
|
+
margin-right: 0;
|
|
294
311
|
}
|
|
295
312
|
`;
|
|
296
313
|
|
|
@@ -415,18 +432,21 @@ export const SmsTraiEdit = (props) => {
|
|
|
415
432
|
if (isRcsSmsFallback) return;
|
|
416
433
|
traiDataRef.current = isFullMode ? templateDetails : templateData;
|
|
417
434
|
if (traiDataRef.current && !isEmpty(traiDataRef.current)) {
|
|
418
|
-
|
|
435
|
+
const msg = get(traiDataRef.current, `versions.base.sms-editor`, '') || '';
|
|
419
436
|
const templateMessageArray = [];
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
msg
|
|
426
|
-
} else {
|
|
427
|
-
templateMessageArray.push(msg);
|
|
428
|
-
break;
|
|
437
|
+
let cursor = 0;
|
|
438
|
+
ANY_DLT_HASH_TOKEN_GLOBAL_REGEX.lastIndex = 0;
|
|
439
|
+
let match = ANY_DLT_HASH_TOKEN_GLOBAL_REGEX.exec(msg);
|
|
440
|
+
while (match) {
|
|
441
|
+
if (match.index > cursor) {
|
|
442
|
+
templateMessageArray.push(msg.substring(cursor, match.index));
|
|
429
443
|
}
|
|
444
|
+
templateMessageArray.push(match[0]);
|
|
445
|
+
cursor = match.index + match[0].length;
|
|
446
|
+
match = ANY_DLT_HASH_TOKEN_GLOBAL_REGEX.exec(msg);
|
|
447
|
+
}
|
|
448
|
+
if (cursor < msg.length) {
|
|
449
|
+
templateMessageArray.push(msg.substring(cursor));
|
|
430
450
|
}
|
|
431
451
|
const filteredTemplateMessageArray = templateMessageArray.filter((i) => i === 0 || i);
|
|
432
452
|
updateTempMsgArray(filteredTemplateMessageArray);
|
|
@@ -488,16 +508,18 @@ export const SmsTraiEdit = (props) => {
|
|
|
488
508
|
let varCount = 1;
|
|
489
509
|
let horizontalSpaceCount = 0;
|
|
490
510
|
for (let i = 0; i < tempMsgArray.length; i += 1) {
|
|
491
|
-
if (tempMsgArray[i]
|
|
511
|
+
if (isAnyDltVarToken(tempMsgArray[i])) {
|
|
492
512
|
const nextElem =
|
|
493
513
|
tempMsgArray[i === tempMsgArray.length - 1 ? -1 : i + 1];
|
|
494
|
-
if (nextElem?.replace(
|
|
514
|
+
if (nextElem?.replace(HORIZONTAL_WHITESPACE_ONLY_REGEX, '') === '') {
|
|
495
515
|
horizontalSpaceCount += 1;
|
|
496
516
|
}
|
|
497
|
-
if (tempMsgArray[i] !== nextElem && nextElem?.replace(
|
|
498
|
-
|
|
517
|
+
if (tempMsgArray[i] !== nextElem && nextElem?.replace(HORIZONTAL_WHITESPACE_ONLY_REGEX, '') !== '') {
|
|
518
|
+
const slotStartIndex = (i - varCount - horizontalSpaceCount) + 1;
|
|
519
|
+
varMapRef.current[`${SMS_TRAI_VAR}_${slotStartIndex}`] = {
|
|
499
520
|
data: '',
|
|
500
521
|
count: varCount,
|
|
522
|
+
token: tempMsgArray[slotStartIndex] || tempMsgArray[i],
|
|
501
523
|
};
|
|
502
524
|
varCount = 1;
|
|
503
525
|
horizontalSpaceCount = 0;
|
|
@@ -567,7 +589,7 @@ export const SmsTraiEdit = (props) => {
|
|
|
567
589
|
if (
|
|
568
590
|
!isFullMode &&
|
|
569
591
|
updatedSmsEditor?.length > 0 &&
|
|
570
|
-
!updatedSmsEditor.
|
|
592
|
+
!updatedSmsEditor.some(isAnyDltVarToken)
|
|
571
593
|
) {
|
|
572
594
|
tagValidationResponseRef.current = runValidateTags(updatedSmsEditor.join(''));
|
|
573
595
|
const missing = (tagValidationResponseRef.current.missingTags || []).length > 0;
|
|
@@ -600,7 +622,7 @@ export const SmsTraiEdit = (props) => {
|
|
|
600
622
|
for (let i = _id; i < loopIndex; i += 1) {
|
|
601
623
|
if (i === _id) {
|
|
602
624
|
arr[i] = varMapRef.current[key].data; //data for first #var# of the textbox
|
|
603
|
-
} else if (arr[i]
|
|
625
|
+
} else if (isAnyDltVarToken(arr[i])) {
|
|
604
626
|
arr[i] = ''; //'' for remaining #var# of a textbox
|
|
605
627
|
}
|
|
606
628
|
}
|
|
@@ -698,7 +720,7 @@ export const SmsTraiEdit = (props) => {
|
|
|
698
720
|
const editorJoined = Array.isArray(updatedSmsEditor)
|
|
699
721
|
? updatedSmsEditor.join('')
|
|
700
722
|
: String(updatedSmsEditor || '');
|
|
701
|
-
if (!isRcsSmsFallback &&
|
|
723
|
+
if (!isRcsSmsFallback && ANY_DLT_HASH_TOKEN_PROBE_REGEX.test(editorJoined) && !isFullMode) {
|
|
702
724
|
updateIsValidationError(true);
|
|
703
725
|
} else {
|
|
704
726
|
// Only show full-screen spinner when waiting on full-mode SMS edit API — not for RCS SMS fallback
|
|
@@ -807,7 +829,7 @@ export const SmsTraiEdit = (props) => {
|
|
|
807
829
|
const varMapKeys = Object.keys(varMapRef.current)?.map((key) => Number(key.slice(8)))?.sort((a, b) => a - b) || [];
|
|
808
830
|
const loopIndex = varMapKeys[varMapKeys?.indexOf(textAreaId) + 1] || arr.length;
|
|
809
831
|
for (let i = textAreaId; i < loopIndex; i += 1) {
|
|
810
|
-
if (arr[i]
|
|
832
|
+
if (isAnyDltVarToken(arr[i])) {
|
|
811
833
|
arr[i] = '';
|
|
812
834
|
}
|
|
813
835
|
}
|
|
@@ -830,17 +852,18 @@ export const SmsTraiEdit = (props) => {
|
|
|
830
852
|
const loopIndex = varMapKeys[varMapKeys?.indexOf(_id) + 1] || arr.length;
|
|
831
853
|
|
|
832
854
|
varMapRef.current[`${SMS_TRAI_VAR}_${_id}`].data = value;
|
|
855
|
+
const slotToken = varMapRef.current[`${SMS_TRAI_VAR}_${_id}`]?.token || SMS_TRAI_VAR;
|
|
833
856
|
if (value === '') {
|
|
834
857
|
for (let i = _id; i < loopIndex; i += 1) {
|
|
835
858
|
if (i === _id || arr[i] === '') {
|
|
836
|
-
arr[i] =
|
|
859
|
+
arr[i] = slotToken;
|
|
837
860
|
}
|
|
838
861
|
}
|
|
839
862
|
} else {
|
|
840
863
|
for (let i = _id; i < loopIndex; i += 1) {
|
|
841
864
|
if (i === _id) {
|
|
842
865
|
arr[i] = varMapRef.current[`${SMS_TRAI_VAR}_${_id}`].data;
|
|
843
|
-
} else if (arr[i]
|
|
866
|
+
} else if (isAnyDltVarToken(arr[i])) {
|
|
844
867
|
arr[i] = '';
|
|
845
868
|
}
|
|
846
869
|
}
|
|
@@ -853,7 +876,7 @@ export const SmsTraiEdit = (props) => {
|
|
|
853
876
|
if (idValue >= 0 && updatedSmsEditor) {
|
|
854
877
|
if (
|
|
855
878
|
updatedSmsEditor[idValue] &&
|
|
856
|
-
updatedSmsEditor[idValue]
|
|
879
|
+
!isAnyDltVarToken(updatedSmsEditor[idValue])
|
|
857
880
|
) {
|
|
858
881
|
return updatedSmsEditor[idValue];
|
|
859
882
|
}
|
|
@@ -862,62 +885,86 @@ export const SmsTraiEdit = (props) => {
|
|
|
862
885
|
return '';
|
|
863
886
|
};
|
|
864
887
|
|
|
865
|
-
const
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
>
|
|
873
|
-
{formatMessage(messages.textAreaCounts, {
|
|
874
|
-
varCounts: varCount,
|
|
875
|
-
var: SMS_TRAI_VAR,
|
|
876
|
-
charCounts: varCount * CHARLIMIT,
|
|
877
|
-
})}
|
|
878
|
-
</CapHeading>
|
|
879
|
-
);
|
|
888
|
+
const getSlotDisplayMeta = (token) => {
|
|
889
|
+
const meta = getDltVarTypeMeta(token);
|
|
890
|
+
if (!meta) {
|
|
891
|
+
return {
|
|
892
|
+
placeholder: props.intl.formatMessage(messages.inputplaceHolderText),
|
|
893
|
+
charLimit: CHARLIMIT,
|
|
894
|
+
};
|
|
880
895
|
}
|
|
881
|
-
return
|
|
896
|
+
return {
|
|
897
|
+
placeholder: formatMessage(messages[meta.placeholderKey]),
|
|
898
|
+
charLimit: meta.charLimit,
|
|
899
|
+
};
|
|
882
900
|
};
|
|
883
901
|
|
|
902
|
+
const renderSlotCounter = (currentValue, charLimit) => (
|
|
903
|
+
<CapLabelInline type="label4" className="sms-trai-slot-counter">
|
|
904
|
+
{formatMessage(messages.slotCharCounter, {
|
|
905
|
+
current: (currentValue || '').length,
|
|
906
|
+
max: charLimit,
|
|
907
|
+
})}
|
|
908
|
+
</CapLabelInline>
|
|
909
|
+
);
|
|
910
|
+
|
|
884
911
|
const renderedContent = () => {
|
|
885
912
|
const renderArray = [];
|
|
886
913
|
if (tempMsgArray?.length !== 0) {
|
|
887
914
|
let varCount = 0;
|
|
915
|
+
let slotStartIndex = -1;
|
|
916
|
+
let slotToken = SMS_TRAI_VAR;
|
|
888
917
|
tempMsgArray.forEach((elem, index) => {
|
|
889
918
|
let prevElem = '';
|
|
890
919
|
prevElem =
|
|
891
920
|
tempMsgArray[[index === 0 ? -1 : index - 1]];
|
|
892
|
-
if (elem
|
|
921
|
+
if (isAnyDltVarToken(elem)) {
|
|
922
|
+
if (varCount === 0) {
|
|
923
|
+
slotStartIndex = index;
|
|
924
|
+
slotToken = elem;
|
|
925
|
+
}
|
|
893
926
|
varCount += 1;
|
|
894
|
-
if (prevElem
|
|
927
|
+
if (!isAnyDltVarToken(prevElem) && prevElem?.replace(HORIZONTAL_WHITESPACE_ONLY_REGEX, '') !== '') {
|
|
928
|
+
const currentSlotToken = slotToken;
|
|
929
|
+
const currentSlotIndex = slotStartIndex;
|
|
930
|
+
const { placeholder, charLimit: baseLimit } = getSlotDisplayMeta(currentSlotToken);
|
|
931
|
+
const slotValue = textAreaValue(currentSlotIndex);
|
|
895
932
|
renderArray.push(
|
|
896
|
-
<
|
|
897
|
-
|
|
898
|
-
key={
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
933
|
+
<CapRow
|
|
934
|
+
type="flex-column"
|
|
935
|
+
key={`slot_${currentSlotToken}_${index}`}
|
|
936
|
+
className="sms-trai-slot"
|
|
937
|
+
>
|
|
938
|
+
<CapRow type="flex" noWrap align="middle" className="sms-trai-slot__field">
|
|
939
|
+
<CapColumn className="sms-trai-slot__chip">
|
|
940
|
+
<CapLabel type="label3">{currentSlotToken}</CapLabel>
|
|
941
|
+
</CapColumn>
|
|
942
|
+
<CapColumn flex="auto" className="sms-trai-slot__input-wrap">
|
|
943
|
+
<TextArea
|
|
944
|
+
id={currentSlotIndex}
|
|
945
|
+
placeholder={placeholder}
|
|
946
|
+
autosize={{ minRows: 1, maxRows: 1 }}
|
|
947
|
+
onChange={textAreaValueChange}
|
|
948
|
+
value={slotValue}
|
|
949
|
+
onFocus={setTextAreaId}
|
|
950
|
+
errorMessage={
|
|
951
|
+
isValidationError &&
|
|
952
|
+
isAnyDltVarToken(updatedSmsEditor[currentSlotIndex]) &&
|
|
953
|
+
formatMessage(messages.textAreaError)
|
|
954
|
+
}
|
|
955
|
+
/>
|
|
956
|
+
</CapColumn>
|
|
957
|
+
</CapRow>
|
|
958
|
+
{renderSlotCounter(slotValue, baseLimit * varCount)}
|
|
959
|
+
</CapRow>,
|
|
912
960
|
);
|
|
913
961
|
}
|
|
914
962
|
if (index === tempMsgArray.length - 1) {
|
|
915
|
-
renderArray.push(capHeading(index, varCount));
|
|
916
963
|
varCount = 0;
|
|
964
|
+
slotStartIndex = -1;
|
|
917
965
|
}
|
|
918
|
-
} else if (varCount > 0 && elem
|
|
966
|
+
} else if (varCount > 0 && elem?.replace(HORIZONTAL_WHITESPACE_ONLY_REGEX, '') !== '') {
|
|
919
967
|
renderArray.push(
|
|
920
|
-
capHeading(index, varCount),
|
|
921
968
|
<CapHeading
|
|
922
969
|
key={`${elem}${index}`}
|
|
923
970
|
style={{ margin: `${CAP_SPACE_16} 0`, clear: 'both' }}
|
|
@@ -926,7 +973,8 @@ export const SmsTraiEdit = (props) => {
|
|
|
926
973
|
</CapHeading>,
|
|
927
974
|
);
|
|
928
975
|
varCount = 0;
|
|
929
|
-
|
|
976
|
+
slotStartIndex = -1;
|
|
977
|
+
} else if (elem?.replace(HORIZONTAL_WHITESPACE_ONLY_REGEX, '') !== '') {
|
|
930
978
|
renderArray.push(
|
|
931
979
|
<CapHeading
|
|
932
980
|
key={`${elem}${index}`}
|
|
@@ -969,7 +1017,7 @@ export const SmsTraiEdit = (props) => {
|
|
|
969
1017
|
return;
|
|
970
1018
|
}
|
|
971
1019
|
const msgLenWithoutVar = tempMsgArray
|
|
972
|
-
?.filter((i) => i
|
|
1020
|
+
?.filter((i) => !isAnyDltVarToken(i))
|
|
973
1021
|
.join('');
|
|
974
1022
|
const varLen = calculateLenForTextBox();
|
|
975
1023
|
const totalMsgLen = msgLenWithoutVar?.length + varLen;
|
|
@@ -979,13 +1027,15 @@ export const SmsTraiEdit = (props) => {
|
|
|
979
1027
|
const calculateLenForTextBox = () => {
|
|
980
1028
|
let countVarChar = 0;
|
|
981
1029
|
Object.keys(varMapRef.current).forEach((i) => {
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
1030
|
+
const slot = varMapRef.current[i];
|
|
1031
|
+
const slotLimit = getDltVarCharLimit(slot.token, CHARLIMIT) * slot.count;
|
|
1032
|
+
if (slot.data) {
|
|
1033
|
+
countVarChar += slot.data?.length;
|
|
1034
|
+
if (!showMsgLengthNote && slot.data?.length > slotLimit) {
|
|
985
1035
|
updateshowMsgLengthNote(true);
|
|
986
1036
|
}
|
|
987
1037
|
} else {
|
|
988
|
-
countVarChar +=
|
|
1038
|
+
countVarChar += slotLimit;
|
|
989
1039
|
}
|
|
990
1040
|
});
|
|
991
1041
|
return countVarChar;
|
|
@@ -1014,12 +1064,8 @@ export const SmsTraiEdit = (props) => {
|
|
|
1014
1064
|
const disablehandler = () => {
|
|
1015
1065
|
if (isRcsSmsFallback) return false;
|
|
1016
1066
|
if (traiDataRef.current && !isEmpty(traiDataRef.current)) {
|
|
1017
|
-
const msg = get(traiDataRef.current, `versions.base.sms-editor`, '');
|
|
1018
|
-
|
|
1019
|
-
if (index === -1) {
|
|
1020
|
-
return true;
|
|
1021
|
-
}
|
|
1022
|
-
return false;
|
|
1067
|
+
const msg = get(traiDataRef.current, `versions.base.sms-editor`, '') || '';
|
|
1068
|
+
return !ANY_DLT_HASH_TOKEN_PROBE_REGEX.test(msg);
|
|
1023
1069
|
}
|
|
1024
1070
|
return true;
|
|
1025
1071
|
};
|
|
@@ -1069,7 +1115,7 @@ export const SmsTraiEdit = (props) => {
|
|
|
1069
1115
|
const shouldShowPreview =
|
|
1070
1116
|
!isRcsSmsFallback || (showPreviewInRcsFallback && !hidePreview);
|
|
1071
1117
|
const smsSidePreviewColumn = (
|
|
1072
|
-
<CapColumn span={
|
|
1118
|
+
<CapColumn span={6} offset={0}>
|
|
1073
1119
|
<UnifiedPreview
|
|
1074
1120
|
channel={SMS}
|
|
1075
1121
|
content={updatedSmsEditor.join('')}
|
|
@@ -1097,25 +1143,35 @@ export const SmsTraiEdit = (props) => {
|
|
|
1097
1143
|
<CapRow typeof='flex' align='top' noWrap fullWidth>
|
|
1098
1144
|
<CapRow type='flex' vertical fullWidth>
|
|
1099
1145
|
{traiDataRef.current && !isEmpty(traiDataRef.current) && !isRcsSmsFallback && (
|
|
1100
|
-
|
|
1101
|
-
<
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1146
|
+
<>
|
|
1147
|
+
<TraiEditTemplateDetails>
|
|
1148
|
+
<CapLabelInline type="label1">
|
|
1149
|
+
{formatMessage(messages.templateLabel)}
|
|
1150
|
+
</CapLabelInline>
|
|
1151
|
+
<CapLabelInline type="label2">
|
|
1152
|
+
{get(traiDataRef.current, 'versions.base.template_name', '')}
|
|
1153
|
+
</CapLabelInline>
|
|
1154
|
+
<CapLabelInline type="label1">
|
|
1155
|
+
{formatMessage(messages.traiEditSeperator)}
|
|
1156
|
+
</CapLabelInline>
|
|
1157
|
+
<CapLabelInline type="label1">
|
|
1158
|
+
{formatMessage(messages.senderIdlabel)}
|
|
1159
|
+
</CapLabelInline>
|
|
1160
|
+
<CapLabelInline className="sms-trai-sender-id-chip">
|
|
1161
|
+
<CapIcon
|
|
1162
|
+
type="closed-lock"
|
|
1163
|
+
size="s"
|
|
1164
|
+
className="sms-trai-sender-id-chip__lock"
|
|
1165
|
+
/>
|
|
1166
|
+
<CapLabelInline type="label2">
|
|
1167
|
+
{[...get(traiDataRef.current, 'versions.base.header', [])].join(', ')}
|
|
1168
|
+
</CapLabelInline>
|
|
1169
|
+
</CapLabelInline>
|
|
1170
|
+
<CapLabelInline type="label1" className="sms-trai-sender-id-locked-note">
|
|
1171
|
+
{formatMessage(messages.senderIdLockedNote)}
|
|
1172
|
+
</CapLabelInline>
|
|
1173
|
+
</TraiEditTemplateDetails>
|
|
1174
|
+
</>
|
|
1119
1175
|
)}
|
|
1120
1176
|
{isRcsSmsFallback &&
|
|
1121
1177
|
traiDataRef.current &&
|
|
@@ -1137,14 +1193,68 @@ export const SmsTraiEdit = (props) => {
|
|
|
1137
1193
|
<CapLabelInline type="label1">
|
|
1138
1194
|
{formatMessage(messages.senderIdlabel)}
|
|
1139
1195
|
</CapLabelInline>
|
|
1140
|
-
<CapLabelInline
|
|
1141
|
-
|
|
1196
|
+
<CapLabelInline className="sms-trai-sender-id-chip">
|
|
1197
|
+
<CapIcon type="closed-lock" size="s" className="sms-trai-sender-id-chip__lock" />
|
|
1198
|
+
<CapLabelInline type="label2">
|
|
1199
|
+
{[...get(traiDataRef.current, 'versions.base.header', [])].join(', ')}
|
|
1200
|
+
</CapLabelInline>
|
|
1201
|
+
</CapLabelInline>
|
|
1202
|
+
<CapLabelInline type="label1" className="sms-trai-sender-id-locked-note">
|
|
1203
|
+
{formatMessage(messages.senderIdLockedNote)}
|
|
1142
1204
|
</CapLabelInline>
|
|
1143
1205
|
</>
|
|
1144
1206
|
) : null}
|
|
1145
1207
|
</TraiEditTemplateDetails>
|
|
1146
1208
|
)}
|
|
1147
|
-
|
|
1209
|
+
{isRcsSmsFallback
|
|
1210
|
+
&& traiDltEnabled
|
|
1211
|
+
&& !isEmpty(traiDataRef.current)
|
|
1212
|
+
&& get(traiDataRef.current, 'versions.base.type', '')
|
|
1213
|
+
?.toLowerCase()
|
|
1214
|
+
?.includes('promo') && (
|
|
1215
|
+
<CapInfoNote
|
|
1216
|
+
type="clock-circle"
|
|
1217
|
+
className="sms-trai-promotional-window-banner"
|
|
1218
|
+
noteText={formatMessage(messages.promotionalWindowBanner)}
|
|
1219
|
+
/>
|
|
1220
|
+
)}
|
|
1221
|
+
{isRcsSmsFallback
|
|
1222
|
+
&& traiDltEnabled
|
|
1223
|
+
&& DLT_LEGACY_VAR_REGEX.test(
|
|
1224
|
+
get(traiDataRef.current, 'versions.base.sms-editor', '') || '',
|
|
1225
|
+
) && (
|
|
1226
|
+
<CapInfoNote
|
|
1227
|
+
type="warning"
|
|
1228
|
+
className="sms-trai-legacy-warning-banner"
|
|
1229
|
+
noteText={formatMessage(messages.smsLegacyFormatWarning, {
|
|
1230
|
+
legacyToken: DLT_LEGACY_VAR_TOKEN,
|
|
1231
|
+
})}
|
|
1232
|
+
/>
|
|
1233
|
+
)}
|
|
1234
|
+
<CapColumn span={shouldShowPreview ? 18 : 24}>
|
|
1235
|
+
{!isRcsSmsFallback
|
|
1236
|
+
&& !isEmpty(traiDataRef.current)
|
|
1237
|
+
&& get(traiDataRef.current, 'versions.base.type', '')
|
|
1238
|
+
?.toLowerCase()
|
|
1239
|
+
?.includes('promo') && (
|
|
1240
|
+
<CapInfoNote
|
|
1241
|
+
type="clock-circle"
|
|
1242
|
+
className="sms-trai-promotional-window-banner"
|
|
1243
|
+
noteText={formatMessage(messages.promotionalWindowBanner)}
|
|
1244
|
+
/>
|
|
1245
|
+
)}
|
|
1246
|
+
{!isRcsSmsFallback
|
|
1247
|
+
&& DLT_LEGACY_VAR_REGEX.test(
|
|
1248
|
+
get(traiDataRef.current, 'versions.base.sms-editor', '') || '',
|
|
1249
|
+
) && (
|
|
1250
|
+
<CapInfoNote
|
|
1251
|
+
type="warning"
|
|
1252
|
+
className="sms-trai-legacy-warning-banner"
|
|
1253
|
+
noteText={formatMessage(messages.smsLegacyFormatWarning, {
|
|
1254
|
+
legacyToken: DLT_LEGACY_VAR_TOKEN,
|
|
1255
|
+
})}
|
|
1256
|
+
/>
|
|
1257
|
+
)}
|
|
1148
1258
|
<CapRow useLegacy>
|
|
1149
1259
|
<CapHeader
|
|
1150
1260
|
title={formatMessage(messages.traiEditTitle)}
|
|
@@ -107,7 +107,9 @@
|
|
|
107
107
|
/* Non–RCS fallback: segmented editor shell + character count row (was inline styles on CapRow) */
|
|
108
108
|
.sms-trai-editor-segment-row {
|
|
109
109
|
background-color: $CAP_G10;
|
|
110
|
-
padding: $CAP_SPACE_16;
|
|
110
|
+
padding: $CAP_SPACE_24 $CAP_SPACE_24 $CAP_SPACE_16 $CAP_SPACE_24;
|
|
111
|
+
border-radius: 0.375rem;
|
|
112
|
+
margin-right: $CAP_SPACE_16;
|
|
111
113
|
}
|
|
112
114
|
|
|
113
115
|
.sms-trai-length-row {
|
|
@@ -124,3 +126,117 @@
|
|
|
124
126
|
.sms-trai-edit-bottom-spacer {
|
|
125
127
|
margin-bottom: 6.25rem;
|
|
126
128
|
}
|
|
129
|
+
|
|
130
|
+
.sms-trai-slot {
|
|
131
|
+
display: flex;
|
|
132
|
+
flex-direction: column;
|
|
133
|
+
margin: 0 0 $CAP_SPACE_16 0;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.sms-trai-slot__field {
|
|
137
|
+
display: flex;
|
|
138
|
+
align-items: stretch;
|
|
139
|
+
background-color: $CAP_WHITE;
|
|
140
|
+
border: 1px solid $CAP_G07;
|
|
141
|
+
border-radius: 0.375rem;
|
|
142
|
+
overflow: hidden;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.sms-trai-slot__chip {
|
|
146
|
+
flex-shrink: 0;
|
|
147
|
+
display: flex;
|
|
148
|
+
align-items: center;
|
|
149
|
+
justify-content: center;
|
|
150
|
+
min-width: 4.5rem;
|
|
151
|
+
padding: 0 $CAP_SPACE_08;
|
|
152
|
+
background-color: $CAP_G10;
|
|
153
|
+
border-right: 1px solid $CAP_G07;
|
|
154
|
+
color: $FONT_COLOR_02;
|
|
155
|
+
font-family: Menlo, Monaco, 'Courier New', monospace;
|
|
156
|
+
font-size: 0.75rem;
|
|
157
|
+
line-height: 1.125rem;
|
|
158
|
+
white-space: nowrap;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.sms-trai-slot__input-wrap {
|
|
162
|
+
flex: 1;
|
|
163
|
+
min-width: 0;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.sms-trai-slot__input-wrap .ant-input,
|
|
167
|
+
.sms-trai-slot__input-wrap textarea.ant-input {
|
|
168
|
+
background-color: transparent;
|
|
169
|
+
border: none;
|
|
170
|
+
border-radius: 0;
|
|
171
|
+
padding: $CAP_SPACE_08 $CAP_SPACE_12;
|
|
172
|
+
min-height: 2.5rem;
|
|
173
|
+
box-shadow: none;
|
|
174
|
+
overflow-x: auto;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.sms-trai-slot__input-wrap .ant-input::placeholder,
|
|
178
|
+
.sms-trai-slot__input-wrap textarea.ant-input::placeholder {
|
|
179
|
+
white-space: nowrap;
|
|
180
|
+
overflow: hidden;
|
|
181
|
+
text-overflow: ellipsis;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.sms-trai-slot__input-wrap .ant-input:focus,
|
|
185
|
+
.sms-trai-slot__input-wrap .ant-input:active,
|
|
186
|
+
.sms-trai-slot__input-wrap textarea.ant-input:focus,
|
|
187
|
+
.sms-trai-slot__input-wrap textarea.ant-input:active {
|
|
188
|
+
border: none;
|
|
189
|
+
box-shadow: none;
|
|
190
|
+
outline: none;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.sms-trai-slot-counter {
|
|
194
|
+
align-self: flex-end;
|
|
195
|
+
margin-top: $CAP_SPACE_04;
|
|
196
|
+
color: $FONT_COLOR_02;
|
|
197
|
+
font-size: 0.75rem;
|
|
198
|
+
line-height: 1rem;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.sms-trai-sender-id-chip {
|
|
202
|
+
display: inline-flex;
|
|
203
|
+
align-items: center;
|
|
204
|
+
gap: $CAP_SPACE_04;
|
|
205
|
+
padding: $CAP_SPACE_02 $CAP_SPACE_08;
|
|
206
|
+
border: 1px solid $CAP_G07;
|
|
207
|
+
border-radius: 0.25rem;
|
|
208
|
+
background-color: $CAP_G10;
|
|
209
|
+
line-height: 1.25rem;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.sms-trai-sender-id-chip__lock {
|
|
213
|
+
display: inline-flex;
|
|
214
|
+
align-items: center;
|
|
215
|
+
font-size: 0.75rem;
|
|
216
|
+
line-height: 1;
|
|
217
|
+
color: $FONT_COLOR_02;
|
|
218
|
+
}
|
|
219
|
+
.sms-trai-sender-id-chip__lock svg {
|
|
220
|
+
width: 0.75rem;
|
|
221
|
+
height: 0.75rem;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.sms-trai-sender-id-locked-note {
|
|
225
|
+
margin-left: $CAP_SPACE_08;
|
|
226
|
+
color: $FONT_COLOR_02;
|
|
227
|
+
font-style: italic;
|
|
228
|
+
font-size: 0.75rem;
|
|
229
|
+
line-height: 1rem;
|
|
230
|
+
font-weight: 400;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.sms-trai-promotional-window-banner.ant-alert,
|
|
234
|
+
.sms-trai-legacy-warning-banner.ant-alert {
|
|
235
|
+
margin: 0 $CAP_SPACE_16 $CAP_SPACE_16 0;
|
|
236
|
+
|
|
237
|
+
.ant-alert-title,
|
|
238
|
+
.ant-alert-title span {
|
|
239
|
+
font-weight: $FONT_WEIGHT_REGULAR;
|
|
240
|
+
white-space: normal;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
@@ -82,4 +82,44 @@ export default defineMessages({
|
|
|
82
82
|
id: `${prefix}.incompleteOrInvalidTagsError`,
|
|
83
83
|
defaultMessage: 'Incomplete or invalid tags. Please provide values for all variables (e.g. {{optout}}, {{fullname}}).',
|
|
84
84
|
},
|
|
85
|
+
slotCharCounter: {
|
|
86
|
+
id: `${prefix}.slotCharCounter`,
|
|
87
|
+
defaultMessage: '{current}/{max}',
|
|
88
|
+
},
|
|
89
|
+
senderIdLockedNote: {
|
|
90
|
+
id: `${prefix}.senderIdLockedNote`,
|
|
91
|
+
defaultMessage: "— locked to this template, can't be overridden",
|
|
92
|
+
},
|
|
93
|
+
promotionalWindowBanner: {
|
|
94
|
+
id: `${prefix}.promotionalWindowBanner`,
|
|
95
|
+
defaultMessage: 'Promotional template — can only be delivered between 10:00 AM and 9:00 PM IST.',
|
|
96
|
+
},
|
|
97
|
+
smsLegacyFormatWarning: {
|
|
98
|
+
id: `${prefix}.smsLegacyFormatWarning`,
|
|
99
|
+
defaultMessage: "Uses old {legacyToken} placeholders — can't be used until re-registered with typed variables on the DLT portal.",
|
|
100
|
+
},
|
|
101
|
+
dltVarPlaceholderNumeric: {
|
|
102
|
+
id: `${prefix}.dltVarPlaceholderNumeric`,
|
|
103
|
+
defaultMessage: 'Digits 0–9 only. No letters, spaces, symbols or links.',
|
|
104
|
+
},
|
|
105
|
+
dltVarPlaceholderAlphanumeric: {
|
|
106
|
+
id: `${prefix}.dltVarPlaceholderAlphanumeric`,
|
|
107
|
+
defaultMessage: 'Letters & digits, common punctuation and spaces. No links, numbers as CTA, or email.',
|
|
108
|
+
},
|
|
109
|
+
dltVarPlaceholderUrl: {
|
|
110
|
+
id: `${prefix}.dltVarPlaceholderUrl`,
|
|
111
|
+
defaultMessage: 'A valid web link that matches a Call-To-Action (CTA) registered for this template.',
|
|
112
|
+
},
|
|
113
|
+
dltVarPlaceholderUrlott: {
|
|
114
|
+
id: `${prefix}.dltVarPlaceholderUrlott`,
|
|
115
|
+
defaultMessage: 'A valid app / OTT deep link that matches a registered CTA for this template.',
|
|
116
|
+
},
|
|
117
|
+
dltVarPlaceholderCbn: {
|
|
118
|
+
id: `${prefix}.dltVarPlaceholderCbn`,
|
|
119
|
+
defaultMessage: 'A valid phone number — digits with an optional +/country code. No free text.',
|
|
120
|
+
},
|
|
121
|
+
dltVarPlaceholderEmail: {
|
|
122
|
+
id: `${prefix}.dltVarPlaceholderEmail`,
|
|
123
|
+
defaultMessage: 'A valid email address in the form name@domain.tld.',
|
|
124
|
+
},
|
|
85
125
|
});
|