@capillarytech/creatives-library 8.0.330-alpha.0 → 8.0.330

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.
Files changed (122) hide show
  1. package/constants/unified.js +0 -18
  2. package/package.json +1 -1
  3. package/services/api.js +0 -17
  4. package/services/tests/api.test.js +0 -85
  5. package/utils/commonUtils.js +0 -28
  6. package/utils/tests/commonUtil.test.js +0 -169
  7. package/v2Components/CapTagList/index.js +0 -10
  8. package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +49 -70
  9. package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
  10. package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -207
  11. package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +0 -16
  12. package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +10 -85
  13. package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +0 -30
  14. package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +11 -79
  15. package/v2Components/CommonTestAndPreview/SendTestMessage.js +53 -87
  16. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +1 -20
  17. package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +4 -133
  18. package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +34 -145
  19. package/v2Components/CommonTestAndPreview/actions.js +0 -10
  20. package/v2Components/CommonTestAndPreview/constants.js +1 -53
  21. package/v2Components/CommonTestAndPreview/index.js +168 -998
  22. package/v2Components/CommonTestAndPreview/messages.js +3 -147
  23. package/v2Components/CommonTestAndPreview/reducer.js +0 -10
  24. package/v2Components/CommonTestAndPreview/sagas.js +6 -15
  25. package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +286 -328
  26. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +65 -231
  27. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +5 -118
  28. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +0 -341
  29. package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +24 -65
  30. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +1 -199
  31. package/v2Components/CommonTestAndPreview/tests/constants.test.js +1 -31
  32. package/v2Components/CommonTestAndPreview/tests/index.test.js +4 -168
  33. package/v2Components/CommonTestAndPreview/tests/reducer.test.js +0 -71
  34. package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
  35. package/v2Components/CommonTestAndPreview/tests/selectors.test.js +0 -17
  36. package/v2Components/FormBuilder/index.js +1 -7
  37. package/v2Components/TestAndPreviewSlidebox/index.js +1 -13
  38. package/v2Components/TestAndPreviewSlidebox/sagas.js +4 -11
  39. package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +1 -3
  40. package/v2Containers/CreativesContainer/SlideBoxContent.js +4 -36
  41. package/v2Containers/CreativesContainer/SlideBoxFooter.js +1 -10
  42. package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -29
  43. package/v2Containers/CreativesContainer/constants.js +0 -9
  44. package/v2Containers/CreativesContainer/index.js +93 -292
  45. package/v2Containers/CreativesContainer/index.scss +1 -51
  46. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +34 -78
  47. package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +16 -79
  48. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -8
  49. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +98 -357
  50. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +10 -20
  51. package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
  52. package/v2Containers/Rcs/constants.js +3 -40
  53. package/v2Containers/Rcs/index.js +895 -1145
  54. package/v2Containers/Rcs/index.scss +6 -85
  55. package/v2Containers/Rcs/messages.js +2 -12
  56. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +2236 -41719
  57. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +5 -0
  58. package/v2Containers/Rcs/tests/index.test.js +38 -41
  59. package/v2Containers/Rcs/tests/mockData.js +0 -38
  60. package/v2Containers/Rcs/tests/utils.test.js +1 -435
  61. package/v2Containers/Rcs/utils.js +10 -405
  62. package/v2Containers/Sms/Create/index.js +38 -100
  63. package/v2Containers/SmsTrai/Create/index.js +4 -9
  64. package/v2Containers/SmsTrai/Edit/constants.js +0 -2
  65. package/v2Containers/SmsTrai/Edit/index.js +128 -636
  66. package/v2Containers/SmsTrai/Edit/messages.js +4 -14
  67. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2604 -4590
  68. package/v2Containers/SmsWrapper/index.js +8 -37
  69. package/v2Containers/TagList/index.js +0 -6
  70. package/v2Containers/Templates/_templates.scss +2 -63
  71. package/v2Containers/Templates/actions.js +0 -11
  72. package/v2Containers/Templates/constants.js +0 -2
  73. package/v2Containers/Templates/index.js +40 -90
  74. package/v2Containers/Templates/sagas.js +12 -57
  75. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1079 -1043
  76. package/v2Containers/Templates/tests/sagas.test.js +123 -193
  77. package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -72
  78. package/v2Containers/TemplatesV2/index.js +23 -86
  79. package/v2Containers/Whatsapp/index.js +20 -3
  80. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +4872 -5790
  81. package/utils/templateVarUtils.js +0 -201
  82. package/utils/tests/templateVarUtils.test.js +0 -204
  83. package/v2Components/CommonTestAndPreview/AddTestCustomer.js +0 -42
  84. package/v2Components/CommonTestAndPreview/CustomerCreationModal.js +0 -155
  85. package/v2Components/CommonTestAndPreview/ExistingCustomerModal.js +0 -93
  86. package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
  87. package/v2Components/CommonTestAndPreview/tests/AddTestCustomer.test.js +0 -66
  88. package/v2Components/CommonTestAndPreview/tests/CommonTestAndPreview.addTestCustomer.test.js +0 -648
  89. package/v2Components/CommonTestAndPreview/tests/CustomerCreationModal.test.js +0 -174
  90. package/v2Components/CommonTestAndPreview/tests/ExistingCustomerModal.test.js +0 -114
  91. package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +0 -67
  92. package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +0 -87
  93. package/v2Components/SmsFallback/constants.js +0 -73
  94. package/v2Components/SmsFallback/index.js +0 -955
  95. package/v2Components/SmsFallback/index.scss +0 -265
  96. package/v2Components/SmsFallback/messages.js +0 -78
  97. package/v2Components/SmsFallback/smsFallbackUtils.js +0 -118
  98. package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +0 -50
  99. package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +0 -147
  100. package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +0 -304
  101. package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +0 -197
  102. package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -277
  103. package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +0 -422
  104. package/v2Components/SmsFallback/useLocalTemplateList.js +0 -92
  105. package/v2Components/VarSegmentMessageEditor/constants.js +0 -2
  106. package/v2Components/VarSegmentMessageEditor/index.js +0 -125
  107. package/v2Components/VarSegmentMessageEditor/index.scss +0 -46
  108. package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +0 -43
  109. package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +0 -67
  110. package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +0 -90
  111. package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +0 -258
  112. package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +0 -125
  113. package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +0 -225
  114. package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +0 -318
  115. package/v2Containers/Sms/smsFormDataHelpers.js +0 -67
  116. package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +0 -253
  117. package/v2Containers/SmsTrai/Edit/index.scss +0 -121
  118. package/v2Containers/Templates/TemplatesActionBar.js +0 -101
  119. package/v2Containers/Templates/tests/TemplatesActionBar.test.js +0 -120
  120. package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +0 -180
  121. package/v2Containers/Templates/utils/smsTemplatesListApi.js +0 -79
  122. package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +0 -131
@@ -1,11 +1,10 @@
1
1
  /* eslint-disable no-restricted-syntax */
2
2
  /* eslint-disable no-undef */
3
- import React, { useState, useEffect, useMemo, useRef } from 'react';
4
- import PropTypes from 'prop-types';
3
+ import React, { useState, useEffect } from 'react';
5
4
  import { createStructuredSelector } from 'reselect';
6
5
  import { bindActionCreators } from 'redux';
7
6
  import { FormattedMessage } from 'react-intl';
8
- import { get, cloneDeep, isEmpty } from 'lodash';
7
+ import { get, cloneDeep, isEmpty, isObject } from 'lodash';
9
8
  import styled from 'styled-components';
10
9
  import CapRow from '@capillarytech/cap-ui-library/CapRow';
11
10
  import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
@@ -28,13 +27,13 @@ import {
28
27
  CAP_SPACE_32,
29
28
  CAP_SPACE_04,
30
29
  CAP_WHITE,
30
+ CAP_G10,
31
31
  } from '@capillarytech/cap-ui-library/styled/variables';
32
32
  import { makeSelectTemplateDetailsResponse } from '../../Sms/Edit/selectors';
33
33
  import { makeSelectMetaEntities, selectLiquidStateDetails, setInjectedTags } from '../../Cap/selectors';
34
34
  import * as smsEditActions from '../../Sms/Edit/actions';
35
35
  import * as globalActions from '../../Cap/actions';
36
36
  import messages from './messages';
37
- import globalMessages from '../../Cap/messages';
38
37
  import TagList from '../../TagList';
39
38
  import formBuilderMessages from '../../../v2Components/FormBuilder/messages';
40
39
  import UnifiedPreview from '../../../v2Components/CommonTestAndPreview/UnifiedPreview';
@@ -42,8 +41,6 @@ import TestAndPreviewSlidebox from '../../../v2Components/TestAndPreviewSlidebox
42
41
  import withCreatives from '../../../hoc/withCreatives';
43
42
  import {
44
43
  CHARLIMIT,
45
- SMS,
46
- SMS_TRAI_CONTENT_MAX_LENGTH,
47
44
  SMS_TRAI_VAR,
48
45
  TAG,
49
46
  EMBEDDED,
@@ -52,39 +49,24 @@ import {
52
49
  ALL,
53
50
  LIBRARY,
54
51
  } from './constants';
52
+ import { SMS } from '../../CreativesContainer/constants';
55
53
  import v2EditSmsReducer from '../../Sms/Edit/reducer';
56
54
  import { v2SmsEditSagas } from '../../Sms/Edit/sagas';
57
55
  import ErrorInfoNote from '../../../v2Components/ErrorInfoNote';
58
- import { isTraiDLTEnable, hasTraiDltFeature } from '../../../utils/common';
59
56
  import { validateLiquidTemplateContent } from '../../../utils/commonUtils';
60
57
  import { validateTags } from '../../../utils/tagValidations';
58
+ import globalMessages from '../../Cap/messages';
61
59
  import { ANDROID } from '../../../v2Components/CommonTestAndPreview/constants';
62
- import {
63
- getFallbackResolvedContent,
64
- splitTemplateVarString,
65
- COMBINED_SMS_TEMPLATE_VAR_REGEX,
66
- isAnyTemplateVarToken,
67
- isDltHashVarToken,
68
- } from '../../../utils/templateVarUtils';
69
- import VarSegmentMessageEditor from '../../../v2Components/VarSegmentMessageEditor';
70
- import rcsMessages from '../../Rcs/messages';
71
-
72
- import './index.scss';
73
60
 
61
+ let varMap = {};
62
+ let traiData = {};
74
63
  const { TextArea } = CapInput;
75
64
  const { CapLabelInline } = CapLabel;
76
65
 
77
- /** Redux `metaEntities` may be an Immutable.Map; TagList needs plain `tags.standard`. */
78
- const getStandardTagsFromMeta = (metaEntities) => {
79
- if (!metaEntities) return [];
80
- const plain = typeof metaEntities.toJS === 'function' ? metaEntities.toJS() : metaEntities;
81
- const standard = get(plain, 'tags.standard');
82
- return Array.isArray(standard) ? standard : [];
83
- };
84
-
85
66
  export const SmsTraiEdit = (props) => {
86
67
  const {
87
68
  intl,
69
+ handleClose,
88
70
  params,
89
71
  actions,
90
72
  templateDetails,
@@ -103,17 +85,6 @@ export const SmsTraiEdit = (props) => {
103
85
  fetchingLiquidTags,
104
86
  getLiquidTags,
105
87
  showLiquidErrorInFooter,
106
- smsRegister,
107
- // RCS -> SMS fallback edit mode
108
- isRcsSmsFallback = false,
109
- /** When editing an existing RCS template, lock Unicode (matches product: no mid-edit toggle). */
110
- isRcsEditFlow = false,
111
- showPreviewInRcsFallback = false,
112
- hidePreview = false,
113
- isOverview = false,
114
- forceFullTagContext = false,
115
- /** RCS parent: merge `rcsSmsFallbackVarMapped` into `smsFallbackData` (same idea as `cardVarMapped`). */
116
- onRcsFallbackEditorStateChange,
117
88
  } = props || {};
118
89
 
119
90
  const { formatMessage } = intl;
@@ -123,149 +94,14 @@ export const SmsTraiEdit = (props) => {
123
94
  const [tags, updateTags] = useState([]);
124
95
  const [textAreaId, updateTextAreaId] = useState();
125
96
  const [isValidationError, updateIsValidationError] = useState(false);
126
- const [isTagValidationError, updateIsTagValidationError] = useState(false);
127
97
  const [totalMessageLength, setTotalMessageLength] = useState(0);
128
98
  const [isUnicodeAllowed, updateIsUnicodeAllowed] = useState(true);
129
- const [fallbackText, setFallbackText] = useState('');
130
- const [fallbackVarMappedData, setFallbackVarMappedData] = useState({});
131
- const [fallbackFocusedId, setFallbackFocusedId] = useState('');
132
99
  const [showMsgLengthNote, updateshowMsgLengthNote] = useState(false);
133
100
  const [liquidErrorMessages, setLiquidErrorMessages] = useState({});
134
101
  const [isLiquidValidationError, setIsLiquidValidationError] = useState(false);
135
102
  /** After user closes the validation panel, keep it hidden until Save is clicked again (even if ErrorInfoNote remounts). */
136
103
  const [liquidErrorPanelDismissed, setLiquidErrorPanelDismissed] = useState(false);
137
104
  const [showTestAndPreviewSlidebox, setShowTestAndPreviewSlidebox] = useState(false);
138
-
139
- /** Per-instance only — was module-level (leaked across mounts / multiple editors). */
140
- const varMapRef = useRef({});
141
- const traiDataRef = useRef({});
142
- const tagValidationResponseRef = useRef({});
143
- /** De-dupe repeated /meta/TAG fetches from popover/context callbacks. */
144
- const lastTagSchemaQueryKeyRef = useRef(null);
145
- /** Latest template props for RCS fallback init — avoids effect deps on unstable `templateData` references. */
146
- const rcsFallbackTemplateSourceRef = useRef({ isFullMode, templateDetails, templateData });
147
- rcsFallbackTemplateSourceRef.current = { isFullMode, templateDetails, templateData };
148
-
149
- const fetchTagSchemaIfNewQuery = (query) => {
150
- const key = JSON.stringify(query);
151
- if (lastTagSchemaQueryKeyRef.current === key) return;
152
- lastTagSchemaQueryKeyRef.current = key;
153
- globalActions.fetchSchemaForEntity(query);
154
- };
155
-
156
- const traiDltEnabled = useMemo(
157
- () => isTraiDLTEnable(isFullMode, smsRegister),
158
- [isFullMode, smsRegister],
159
- );
160
- /**
161
- * VarSegment for RCS SMS fallback when:
162
- * - `isTraiDLTEnable` passes (library + `smsRegister === 'DLT'`, or full-mode library), or
163
- * - org has TRAI DLT (`hasTraiDltFeature`) — needed when slidebox used to force `isFullMode={false}`
164
- * or `smsRegister` is missing so `isTraiDLTEnable` alone is false, or
165
- * - RCS template inline edit (`isRcsEditFlow`).
166
- */
167
- const useRcsFallbackVarSegment = useMemo(() => {
168
- if (!isRcsSmsFallback) return false;
169
- return traiDltEnabled || hasTraiDltFeature() || isRcsEditFlow;
170
- }, [isRcsSmsFallback, traiDltEnabled, isRcsEditFlow]);
171
-
172
- /**
173
- * RCS SMS fallback: always show character count vs TRAI max (`SMS_TRAI_CONTENT_MAX_LENGTH`).
174
- * Do not use `totalCharacters` ({smsCount} SMS via length/160) here: resolved template + variable
175
- * values can exceed one GSM segment while DLT still shows a single registered template — length/160
176
- * is only a rough segment hint and reads as “wrong SMS count” in campaigns.
177
- */
178
- const renderDescriptionCharacterCount = (className = "rcs-character-count") => (
179
- <CapLabel type="label1" className={className}>
180
- {formatMessage(messages.charactersCountLabel, {
181
- current: totalMessageLength,
182
- max: SMS_TRAI_CONTENT_MAX_LENGTH,
183
- })}
184
- </CapLabel>
185
- );
186
-
187
- const dltConsecutiveRunLength = (segments, index) => {
188
- if (!Array.isArray(segments) || typeof segments[index] !== 'string' || !isDltHashVarToken(segments[index])) {
189
- return 0;
190
- }
191
- let lo = index;
192
- while (lo > 0 && isDltHashVarToken(segments[lo - 1])) lo -= 1;
193
- let hi = index;
194
- while (hi < segments.length - 1 && isDltHashVarToken(segments[hi + 1])) hi += 1;
195
- return hi - lo + 1;
196
- };
197
-
198
- const renderRcsFallbackMessage = (str = '') => {
199
- if (!useRcsFallbackVarSegment) {
200
- return (
201
- <CapRow className="rcs-create-template-message-input">
202
- <div className="rcs_text_area_wrapper">
203
- <TextArea
204
- id="rcs_fallback_message_textarea"
205
- autosize={{ minRows: 4, maxRows: 12 }}
206
- value={fallbackText}
207
- onChange={(e) => setFallbackText(e.target.value)}
208
- placeholder={formatMessage(rcsMessages.fallbackMsgPlaceholder)}
209
- data-testid="rcs_fallback_plain_text_area"
210
- />
211
- {renderDescriptionCharacterCount()}
212
- </div>
213
- </CapRow>
214
- );
215
- }
216
- return (
217
- <CapRow className="rcs-create-template-message-input">
218
- <div className="rcs_text_area_wrapper">
219
- <VarSegmentMessageEditor
220
- templateString={str}
221
- valueMap={fallbackVarMappedData || {}}
222
- onChange={(varSegmentFieldId, nextSlotValue) => {
223
- setFallbackVarMappedData((previousSlotMap) => ({
224
- ...(previousSlotMap || {}),
225
- [varSegmentFieldId]: nextSlotValue,
226
- }));
227
- }}
228
- onFocus={setFallbackFocusedId}
229
- varRegex={COMBINED_SMS_TEMPLATE_VAR_REGEX}
230
- placeholderPrefix=""
231
- getPlaceholder={() => formatMessage(rcsMessages.fallbackMsgPlaceholder)}
232
- renderVarFooter={(dltSegmentToken, dltSegmentIndex) => {
233
- if (!isDltHashVarToken(dltSegmentToken)) return null;
234
- const segments = splitTemplateVarString(str, COMBINED_SMS_TEMPLATE_VAR_REGEX);
235
- const varCounts = dltConsecutiveRunLength(segments, dltSegmentIndex);
236
- if (varCounts < 1) return null;
237
- /* Inline layout/color so hint is visible even if CapSpin / load order blocks SCSS */
238
- const dltVarSlotHintStyle = {
239
- display: 'block',
240
- marginTop: CAP_SPACE_04,
241
- marginLeft: 'auto',
242
- marginRight: 0,
243
- width: 'fit-content',
244
- maxWidth: '100%',
245
- textAlign: 'right',
246
- color: 'rgba(0, 0, 0, 0.45)',
247
- fontSize: 12,
248
- fontWeight: 400,
249
- lineHeight: '16px',
250
- };
251
- return (
252
- <span className="sms-trai-rcs-fallback-var-hint" style={dltVarSlotHintStyle}>
253
- {formatMessage(messages.textAreaCounts, {
254
- varCounts,
255
- var: SMS_TRAI_VAR,
256
- charCounts: varCounts * CHARLIMIT,
257
- })}
258
- </span>
259
- );
260
- }}
261
- />
262
- {(!isFullMode)
263
- ? renderDescriptionCharacterCount('rcs-character-count rcs-character-count--compact')
264
- : (isFullMode && renderDescriptionCharacterCount())}
265
- </div>
266
- </CapRow>
267
- );
268
- };
269
105
  const SMSTraiFooter = styled.div`
270
106
  background-color: ${CAP_WHITE};
271
107
  padding: ${CAP_SPACE_32} ${CAP_SPACE_24};
@@ -281,6 +117,7 @@ export const SmsTraiEdit = (props) => {
281
117
  .ant-btn {
282
118
  margin-right: ${CAP_SPACE_16};
283
119
  }
120
+ }
284
121
  `;
285
122
  const TraiEditTemplateDetails = styled.div`
286
123
  margin-bottom: ${CAP_SPACE_16};
@@ -289,127 +126,41 @@ export const SmsTraiEdit = (props) => {
289
126
  }
290
127
  `;
291
128
 
292
- /**
293
- * RCS embedded SMS fallback receives a new `templateData` object from `mapFallbackValueToEditTemplateData`
294
- * on every parent render. Depending on `[templateDetails || templateData]` re-ran init and wiped
295
- * VarSegmentMessageEditor state whenever Test & Preview (or any) re-rendered Rcs. Key only changes
296
- * when template id / sms-editor / header actually change.
297
- *
298
- * Do NOT include `unicode-validity` in the key: parent merges `onRcsFallbackEditorStateChange`
299
- * unicode patches into `templateData`, which would change the key every toggle and re-run init —
300
- * resetting local checkbox state (visible as the unicode control flipping).
301
- *
302
- * Do NOT include `rcs-sms-fallback-var-mapped` in the key: the parent merges slot edits into
303
- * `templateData` on every change, so the key would change each keystroke and this effect would
304
- * re-run and reset slots — visible as toggling between old and new values.
305
- */
306
- const rcsFallbackTemplateInitKey = useMemo(() => {
307
- if (!isRcsSmsFallback) return null;
308
- // RCS fallback slidebox always passes `templateData` from `mapFallbackValueToEditTemplateData`.
309
- // `templateDetails` stays empty there (no route id fetch) — do not branch on `isFullMode` or init
310
- // key is null, the effect never runs, and `loading` stays true forever.
311
- const activeSmsTemplateSource = templateData;
312
- if (!activeSmsTemplateSource || isEmpty(activeSmsTemplateSource)) return null;
313
- const templateBase = get(activeSmsTemplateSource, 'versions.base', {}) || {};
314
- const smsEditorTemplateString = templateBase?.['sms-editor'] ?? '';
315
- const registeredSenderHeaderList = templateBase?.header;
316
- const headerListFingerprint = Array.isArray(registeredSenderHeaderList)
317
- ? registeredSenderHeaderList.join('\u001f')
318
- : '';
319
- const templateRecordId = activeSmsTemplateSource?._id ?? '';
320
- return [
321
- templateRecordId,
322
- smsEditorTemplateString,
323
- headerListFingerprint,
324
- ].join('\u0000');
325
- }, [isRcsSmsFallback, templateData]);
326
-
327
129
  useEffect(() => {
130
+ //fetching tags
328
131
  const { type, module } = location.query || {};
329
132
  const isEmbedded = type === EMBEDDED;
330
133
  const query = {
331
134
  layout: SMS,
332
135
  type: TAG,
333
136
  context: isEmbedded ? module : DEFAULT,
334
- embedded: forceFullTagContext ? FULL : (isEmbedded ? type : FULL),
137
+ embedded: isEmbedded ? type : FULL,
335
138
  };
336
139
  if (getDefaultTags) {
337
140
  query.context = getDefaultTags;
338
141
  }
339
- fetchTagSchemaIfNewQuery(query);
142
+ globalActions.fetchSchemaForEntity(query);
143
+ //fetching template data in fullmode
340
144
  const { id } = params || {};
341
145
  if (id) {
342
146
  actions.getTemplateDetails(id);
343
147
  }
148
+ //cleanup code
344
149
  return () => {
345
150
  actions.resetEditTemplate();
346
- varMapRef.current = {};
151
+ varMap = {};
347
152
  };
348
153
  }, []);
349
154
 
155
+ //computing placeholder array for mapping values and rendering dynamic form
350
156
  useEffect(() => {
351
- if (!isRcsSmsFallback || rcsFallbackTemplateInitKey == null) return;
352
- const {
353
- isFullMode: isFullModeFromRef,
354
- templateDetails: templateDetailsFromRef,
355
- templateData: templateDataFromRef,
356
- } = rcsFallbackTemplateSourceRef.current;
357
- const activeTemplateSourceForInit = isRcsSmsFallback
358
- ? templateDataFromRef
359
- : (isFullModeFromRef ? templateDetailsFromRef : templateDataFromRef);
360
- if (!activeTemplateSourceForInit || isEmpty(activeTemplateSourceForInit)) return;
361
- traiDataRef.current = activeTemplateSourceForInit;
362
- const templateBase = get(activeTemplateSourceForInit, 'versions.base', {});
363
- const unicodeValidity = get(templateBase, 'unicode-validity', true);
364
- const templateMsg = get(activeTemplateSourceForInit, 'versions.base.sms-editor', '') || '';
365
- if (!useRcsFallbackVarSegment) {
366
- setFallbackText(templateMsg);
367
- setFallbackVarMappedData({});
368
- setUpdatedSmsEditor(String(templateMsg).split(''));
369
- setTotalMessageLength(String(templateMsg).length);
370
- updateIsUnicodeAllowed(unicodeValidity);
371
- updateLoading(false);
372
- return;
373
- }
374
- const savedVarMap = get(templateBase, 'rcs-sms-fallback-var-mapped', {}) || {};
375
- const initialVarMap = {};
376
- const templateSegments = splitTemplateVarString(templateMsg, COMBINED_SMS_TEMPLATE_VAR_REGEX);
377
- let varOrdinal = 0;
378
- templateSegments.forEach((segmentToken, segmentIndexInTemplate) => {
379
- const isVar =
380
- typeof segmentToken === 'string' && isAnyTemplateVarToken(segmentToken);
381
- if (!isVar) return;
382
- varOrdinal += 1;
383
- const varSegmentSlotId = `${segmentToken}_${segmentIndexInTemplate}`;
384
- const persistedSlotValue =
385
- savedVarMap?.[varSegmentSlotId]
386
- ?? savedVarMap?.[`${segmentToken}_${varOrdinal}`];
387
- // Persisted '' means the user cleared the slot — must not fall back to `segmentToken` for mustache
388
- // (that would resurrect {{…}} in the input and look like the tag "came back").
389
- if (typeof persistedSlotValue === 'string') {
390
- initialVarMap[varSegmentSlotId] = persistedSlotValue;
391
- } else if (isDltHashVarToken(segmentToken)) {
392
- initialVarMap[varSegmentSlotId] = '';
393
- } else {
394
- initialVarMap[varSegmentSlotId] = segmentToken;
395
- }
396
- });
397
- setFallbackText(templateMsg);
398
- setFallbackVarMappedData(initialVarMap);
399
- const initialResolvedFallbackDisplay = getFallbackResolvedContent(templateMsg, initialVarMap);
400
- setUpdatedSmsEditor(initialResolvedFallbackDisplay.split(''));
401
- setTotalMessageLength(initialResolvedFallbackDisplay.length);
402
- updateIsUnicodeAllowed(unicodeValidity);
403
- updateLoading(false);
404
- // eslint-disable-next-line react-hooks/exhaustive-deps -- init only when semantic key changes; template props are read from ref
405
- }, [isRcsSmsFallback, rcsFallbackTemplateInitKey, useRcsFallbackVarSegment]);
406
-
407
- useEffect(() => {
408
- if (isRcsSmsFallback) return;
409
- traiDataRef.current = isFullMode ? templateDetails : templateData;
410
- if (traiDataRef.current && !isEmpty(traiDataRef.current)) {
411
- let msg = get(traiDataRef.current, `versions.base.sms-editor`, '');
157
+ traiData = isFullMode ? templateDetails : templateData;
158
+ if (traiData && !isEmpty(traiData)) {
159
+ let msg = get(traiData, `versions.base.sms-editor`, '');
412
160
  const templateMessageArray = [];
161
+ //converting sms-editor string to an array split at '{#var#}'
162
+ //split and push string before '{#var#}[0 to index]', push '{#var#}',
163
+ //split and repeat for remaining string[index+7 to length]
413
164
  while (msg.length !== 0) {
414
165
  const index = msg.search(SMS_TRAI_VAR);
415
166
  if (index !== -1) {
@@ -423,59 +174,30 @@ export const SmsTraiEdit = (props) => {
423
174
  }
424
175
  const filteredTemplateMessageArray = templateMessageArray.filter((i) => i === 0 || i);
425
176
  updateTempMsgArray(filteredTemplateMessageArray);
177
+ //stop spinner
426
178
  updateLoading(false);
427
179
  }
428
- }, [templateDetails || templateData, isRcsSmsFallback, isFullMode]);
180
+ }, [templateDetails || templateData]);
429
181
 
182
+ //compute/get varMapped and updated-sms-editor
430
183
  useEffect(() => {
431
- if (!isRcsSmsFallback) return;
432
- if (!useRcsFallbackVarSegment) {
433
- const plainFallbackSmsText = fallbackText || '';
434
- setUpdatedSmsEditor(plainFallbackSmsText.split(''));
435
- setTotalMessageLength(plainFallbackSmsText.length);
436
- return;
437
- }
438
- const resolvedFallbackDisplay = getFallbackResolvedContent(
439
- fallbackText || '',
440
- fallbackVarMappedData || {},
441
- );
442
- setUpdatedSmsEditor(resolvedFallbackDisplay.split(''));
443
- setTotalMessageLength(resolvedFallbackDisplay.length);
444
- }, [isRcsSmsFallback, useRcsFallbackVarSegment, fallbackText, fallbackVarMappedData]);
445
-
446
- useEffect(() => {
447
- if (!isRcsSmsFallback) return;
448
- if (typeof onRcsFallbackEditorStateChange !== 'function') return;
449
- onRcsFallbackEditorStateChange({
450
- rcsSmsFallbackVarMapped: fallbackVarMappedData || {},
451
- });
452
- }, [isRcsSmsFallback, fallbackVarMappedData, onRcsFallbackEditorStateChange]);
453
-
454
- useEffect(() => {
455
- if (!isRcsSmsFallback) return;
456
- if (typeof onRcsFallbackEditorStateChange !== 'function') return;
457
- onRcsFallbackEditorStateChange({
458
- unicodeValidity: isUnicodeAllowed,
459
- });
460
- }, [isRcsSmsFallback, isUnicodeAllowed, onRcsFallbackEditorStateChange]);
461
-
462
- useEffect(() => {
463
- if (isRcsSmsFallback) return;
464
184
  if (tempMsgArray.length !== 0) {
465
- const traiBase = traiDataRef.current?.versions?.base || {};
185
+ const traiBase = traiData?.versions?.base || {};
466
186
  const {
467
187
  'var-mapped': varMapped = {},
468
188
  'updated-sms-editor': traiSmsEditor = '',
469
189
  'unicode-validity': unicodeValidity = true,
470
190
  } = traiBase;
191
+ //if varMap and updated-sms-editor is already present on non first edits,use those values
471
192
  if (!isEmpty(varMapped)) {
472
- varMapRef.current = cloneDeep(varMapped);
193
+ varMap = cloneDeep(varMapped);
473
194
  if (isFullMode) {
474
195
  setUpdatedSmsEditor(traiSmsEditor);
475
196
  } else {
476
197
  computeUpdatedSmsEditor();
477
198
  }
478
199
  } else {
200
+ //computing and setting varMap for first edit
479
201
  let varCount = 1;
480
202
  let horizontalSpaceCount = 0;
481
203
  for (let i = 0; i < tempMsgArray.length; i += 1) {
@@ -486,7 +208,7 @@ export const SmsTraiEdit = (props) => {
486
208
  horizontalSpaceCount += 1;
487
209
  }
488
210
  if (tempMsgArray[i] !== nextElem && nextElem?.replace(/[^\S\r\n]/gm, '') !== '') {
489
- varMapRef.current[`${tempMsgArray[i]}_${(i - varCount - horizontalSpaceCount) + 1}`] = {
211
+ varMap[`${tempMsgArray[i]}_${(i - varCount - horizontalSpaceCount) + 1}`] = {
490
212
  data: '',
491
213
  count: varCount,
492
214
  };
@@ -500,6 +222,7 @@ export const SmsTraiEdit = (props) => {
500
222
  setUpdatedSmsEditor(tempMsgArray);
501
223
  }
502
224
  updateIsUnicodeAllowed(unicodeValidity);
225
+ // calcaulate message length here
503
226
  calculateTotalMessageLength();
504
227
  }
505
228
  }, [tempMsgArray]);
@@ -513,84 +236,17 @@ export const SmsTraiEdit = (props) => {
513
236
  }
514
237
  }, []);
515
238
 
516
- useEffect(() => {
517
- const runValidateTags = (content) =>
518
- validateTags({
519
- content,
520
- tagsParam: tags,
521
- location,
522
- tagModule: getDefaultTags,
523
- isFullMode,
524
- }) || {};
525
-
526
- if (isRcsSmsFallback) {
527
- if (isFullMode) {
528
- tagValidationResponseRef.current = {};
529
- updateIsTagValidationError(false);
530
- return;
531
- }
532
- // TRAI/DLT VarSegment: `validateIfTagClosed` only understands paired `{{…}}` and breaks on
533
- // legitimate `{#…#}` / mixed TRAI shapes (extra `{`/`}` counts). Do not tie Done to it;
534
- // slot completeness is enforced by `areAllRcsSmsFallbackVarSlotsFilled` on the RCS screen.
535
- if (useRcsFallbackVarSegment) {
536
- tagValidationResponseRef.current = {};
537
- updateIsTagValidationError(false);
538
- return;
539
- }
540
- const validationContent = fallbackText || '';
541
- if (!validationContent.trim()) {
542
- tagValidationResponseRef.current = {};
543
- updateIsTagValidationError(false);
544
- return;
545
- }
546
- tagValidationResponseRef.current = validateTags({
547
- content: validationContent,
548
- tagsParam: tags,
549
- location,
550
- tagModule: getDefaultTags,
551
- isFullMode: true,
552
- }) || {};
553
- const braceErr = !!tagValidationResponseRef.current.isBraceError;
554
- // Plain (non-VarSegment) fallback textarea: only unbalanced `{{…}}` disables Done.
555
- updateIsTagValidationError(braceErr);
556
- return;
557
- }
558
- if (
559
- !isFullMode &&
560
- updatedSmsEditor?.length > 0 &&
561
- !updatedSmsEditor.includes(SMS_TRAI_VAR)
562
- ) {
563
- tagValidationResponseRef.current = runValidateTags(updatedSmsEditor.join(''));
564
- const missing = (tagValidationResponseRef.current.missingTags || []).length > 0;
565
- const braceErr = !!tagValidationResponseRef.current.isBraceError;
566
- updateIsTagValidationError(missing || braceErr);
567
- } else if (!isRcsSmsFallback) {
568
- tagValidationResponseRef.current = {};
569
- updateIsTagValidationError(false);
570
- }
571
- }, [
572
- updatedSmsEditor,
573
- tags,
574
- isRcsSmsFallback,
575
- isFullMode,
576
- useRcsFallbackVarSegment,
577
- fallbackText,
578
- fallbackVarMappedData,
579
- getDefaultTags,
580
- location,
581
- ]);
582
-
583
239
  const computeUpdatedSmsEditor = () => {
584
240
  const arr = [...tempMsgArray];
585
- const varMapKeys = Object.keys(varMapRef.current)?.map((key) => Number(key.slice(8)))?.sort((a, b) => a - b) || [];
586
- for (const key in varMapRef.current) {
587
- if (varMapRef.current[key].data !== '') {
241
+ const varMapKeys = Object.keys(varMap)?.map((key) => Number(key.slice(8)))?.sort((a, b) => a - b) || [];
242
+ for (const key in varMap) {
243
+ if (varMap[key].data !== '') {
588
244
  const _id = Number(key.slice(8)); //Eg: -> extracting index 1 from keys like {#var# } _1
589
245
  const loopIndex =
590
246
  varMapKeys[varMapKeys?.indexOf(_id) + 1] || arr.length;
591
247
  for (let i = _id; i < loopIndex; i += 1) {
592
248
  if (i === _id) {
593
- arr[i] = varMapRef.current[key].data; //data for first #var# of the textbox
249
+ arr[i] = varMap[key].data; //data for first #var# of the textbox
594
250
  } else if (arr[i] === SMS_TRAI_VAR) {
595
251
  arr[i] = ''; //'' for remaining #var# of a textbox
596
252
  }
@@ -600,8 +256,8 @@ export const SmsTraiEdit = (props) => {
600
256
  setUpdatedSmsEditor(arr);
601
257
  };
602
258
 
259
+ //Saving on done start
603
260
  const onUpdateTemplateComplete = (editResponse, errorMsg) => {
604
- updateLoading(false);
605
261
  if (editResponse?.templateId) {
606
262
  CapNotification.success({
607
263
  message: formatMessage(messages.smsEditNotification),
@@ -680,121 +336,66 @@ export const SmsTraiEdit = (props) => {
680
336
  };
681
337
 
682
338
  const onDoneCallback = () => {
683
- // RCS fallback: allow Save when only "missing tags" ({{name}} may not be in TagList); still block unbalanced braces.
684
- if (isTagValidationError) {
685
- if (!isRcsSmsFallback) return;
686
- const tagValidationSnapshot = tagValidationResponseRef.current ?? {};
687
- if (tagValidationSnapshot.isBraceError) return;
688
- }
689
- const editorJoined = Array.isArray(updatedSmsEditor)
690
- ? updatedSmsEditor.join('')
691
- : String(updatedSmsEditor || '');
692
- if (!isRcsSmsFallback && editorJoined.includes(SMS_TRAI_VAR) && !isFullMode) {
339
+ if (updatedSmsEditor.includes(SMS_TRAI_VAR) && !isFullMode) {
340
+ //during save textbox should not be empty
693
341
  updateIsValidationError(true);
694
342
  } else {
695
- // Only show full-screen spinner when waiting on full-mode SMS edit API — not for RCS SMS fallback
696
- // handoff (getFormSubscriptionData → SmsFallback closeSlidebox) and not for embedded sync handoff.
697
- if (isFullMode && !isRcsSmsFallback) {
698
- updateLoading(true);
699
- }
700
- if (!traiDataRef.current.versions) {
701
- traiDataRef.current.versions = { base: {}, history: [] };
702
- }
703
- const traiVersions = traiDataRef.current.versions;
704
- if (isRcsSmsFallback) {
705
- const {
706
- 'var-mapped': _ignoredVarMapped,
707
- 'updated-sms-editor': _ignoredUpdatedSmsEditor,
708
- 'rcs-sms-fallback-var-mapped': _ignoredFallbackVarMapped,
709
- ...baseWithoutDerivedFields
710
- } = traiVersions.base || {};
711
- traiVersions.base = {
712
- ...baseWithoutDerivedFields,
713
- 'sms-editor': fallbackText || '',
714
- 'unicode-validity': isUnicodeAllowed,
715
- ...(useRcsFallbackVarSegment && {
716
- 'rcs-sms-fallback-var-mapped': fallbackVarMappedData || {},
717
- }),
718
- };
719
- } else {
720
- traiVersions.base = {
721
- ...traiVersions.base,
722
- 'var-mapped': varMapRef.current,
723
- 'updated-sms-editor': updatedSmsEditor,
724
- 'unicode-validity': isUnicodeAllowed,
725
- };
726
- }
343
+ //start spinner
344
+ updateLoading(true);
345
+ const traiVersions = traiData.versions || {};
346
+ traiVersions.base = {
347
+ ...traiVersions.base,
348
+ 'var-mapped': varMap,
349
+ 'updated-sms-editor': updatedSmsEditor,
350
+ 'unicode-validity': isUnicodeAllowed,
351
+ };
727
352
  traiVersions.history = [traiVersions.base];
728
- // RCS → SMS fallback (slidebox / inline): always hand off via getFormSubscriptionData so parent
729
- // can persist fallback state and close the slide — never the standalone TRAI editTemplate API here.
730
- if (isFullMode && !isRcsSmsFallback) {
731
- actions.editTemplate(traiDataRef.current, onUpdateTemplateComplete);
353
+ if (isFullMode) {
354
+ actions.editTemplate(traiData, onUpdateTemplateComplete);
732
355
  } else {
733
356
  getFormSubscriptionData({
734
- value: traiVersions,
735
- // Consumers/tests read `versions.base` first (see getBaseFromSmsTraiFormData, rcsDltEditCompletionHandler).
736
- versions: traiVersions,
357
+ value: traiData.versions,
737
358
  _id: params && params.id,
738
359
  validity: true,
739
360
  type: SMS,
740
361
  });
741
- updateLoading(false);
742
362
  }
743
363
  }
744
364
  };
365
+ //Saving on done end
745
366
 
746
- const locationQueryType = location?.query?.type;
747
- const locationQueryModule = location?.query?.module;
748
-
367
+ // tag code start
749
368
  useEffect(() => {
750
- let tag = getStandardTagsFromMeta(metaEntities);
751
- if ((!Array.isArray(tag) || tag.length === 0) && Array.isArray(supportedTags) && supportedTags.length > 0) {
369
+ let tag =
370
+ metaEntities && metaEntities.tags ? metaEntities.tags.standard : [];
371
+ const { type, module } = location.query || {};
372
+ if (type === EMBEDDED && module === LIBRARY && !getDefaultTags) {
752
373
  tag = supportedTags;
753
374
  }
754
- if (
755
- locationQueryType === EMBEDDED &&
756
- locationQueryModule === LIBRARY &&
757
- !getDefaultTags
758
- ) {
759
- tag = supportedTags || [];
760
- }
761
- updateTags(Array.isArray(tag) ? tag : []);
762
- }, [metaEntities, getDefaultTags, supportedTags, locationQueryType, locationQueryModule]);
375
+ updateTags(tag);
376
+ }, [metaEntities]);
763
377
 
764
378
  const handleOnTagsContextChange = (data) => {
765
- // CapTagList passes "Outbound" | "Loyalty" from the module filter; TagList may pass "Outbound" on init.
766
- if (data == null || data === '') return;
767
- const normalizedContext = String(data).toLowerCase();
768
379
  const { type } = location.query || {};
769
380
  const isEmbedded = type === EMBEDDED;
770
381
  const query = {
771
382
  layout: SMS,
772
383
  type: TAG,
773
- context: normalizedContext === ALL ? DEFAULT : normalizedContext,
774
- embedded: forceFullTagContext ? FULL : (isEmbedded ? type : FULL),
384
+ context:
385
+ (data || '').toLowerCase() === ALL
386
+ ? DEFAULT
387
+ : (data || '').toLowerCase(),
388
+ embedded: isEmbedded ? type : FULL,
775
389
  };
776
- fetchTagSchemaIfNewQuery(query);
390
+ globalActions.fetchSchemaForEntity(query);
777
391
  };
778
392
 
779
393
  const onTagSelect = (data) => {
780
- if (isRcsSmsFallback) {
781
- if (!useRcsFallbackVarSegment) {
782
- setFallbackText((prev) => `${prev || ''}{{${data}}}`);
783
- return;
784
- }
785
- if (!fallbackFocusedId) return;
786
- const prevVal = fallbackVarMappedData?.[fallbackFocusedId] ?? '';
787
- const nextVal = `${prevVal}{{${data}}}`;
788
- setFallbackVarMappedData((prev) => ({
789
- ...(prev || {}),
790
- [fallbackFocusedId]: nextVal,
791
- }));
792
- return;
793
- }
794
- if (textAreaId >= 0 && varMapRef.current && updatedSmsEditor) {
394
+ if (textAreaId >= 0 && varMap && updatedSmsEditor) {
795
395
  const arr = [...updatedSmsEditor];
796
- const varMapKeys = Object.keys(varMapRef.current)?.map((key) => Number(key.slice(8)))?.sort((a, b) => a - b) || [];
396
+ const varMapKeys = Object.keys(varMap)?.map((key) => Number(key.slice(8)))?.sort((a, b) => a - b) || [];
797
397
  const loopIndex = varMapKeys[varMapKeys?.indexOf(textAreaId) + 1] || arr.length;
398
+ //when trying to insert tag in empty textarea,{#var#} is replaced with "" and then tag is added
798
399
  for (let i = textAreaId; i < loopIndex; i += 1) {
799
400
  if (arr[i] === SMS_TRAI_VAR) {
800
401
  arr[i] = '';
@@ -802,23 +403,26 @@ export const SmsTraiEdit = (props) => {
802
403
  }
803
404
  const messageData = `${arr[textAreaId]}{{${data}}}`;
804
405
  arr[textAreaId] = messageData;
805
- varMapRef.current[`${SMS_TRAI_VAR}_${textAreaId}`].data = messageData;
406
+ varMap[`${SMS_TRAI_VAR}_${textAreaId}`].data = messageData;
806
407
  setUpdatedSmsEditor(arr);
807
408
  }
808
409
  };
809
-
410
+ //setting the id of currently selected text area, is used onTagSelect
810
411
  const setTextAreaId = (event) => {
811
412
  updateTextAreaId(Number(event.target.id));
812
413
  };
414
+ // tag code end
813
415
 
416
+ // on change event of Text Area
814
417
  const textAreaValueChange = ({ target: { value, id } }) => {
815
- if (isRcsSmsFallback) return;
816
418
  const _id = Number(id);
817
419
  const arr = [...updatedSmsEditor];
818
- const varMapKeys = Object.keys(varMapRef.current)?.map((key) => Number(key.slice(8)))?.sort((a, b) => a - b) || [];
420
+ const varMapKeys = Object.keys(varMap)?.map((key) => Number(key.slice(8)))?.sort((a, b) => a - b) || [];
819
421
  const loopIndex = varMapKeys[varMapKeys?.indexOf(_id) + 1] || arr.length;
820
422
 
821
- varMapRef.current[`${SMS_TRAI_VAR}_${_id}`].data = value;
423
+ //assign entered value to varMap
424
+ varMap[`${SMS_TRAI_VAR}_${_id}`].data = value;
425
+ //based on entered value update updatedSmsEditor
822
426
  if (value === '') {
823
427
  for (let i = _id; i < loopIndex; i += 1) {
824
428
  if (i === _id || arr[i] === '') {
@@ -828,7 +432,7 @@ export const SmsTraiEdit = (props) => {
828
432
  } else {
829
433
  for (let i = _id; i < loopIndex; i += 1) {
830
434
  if (i === _id) {
831
- arr[i] = varMapRef.current[`${SMS_TRAI_VAR}_${_id}`].data;
435
+ arr[i] = varMap[`${SMS_TRAI_VAR}_${_id}`].data;
832
436
  } else if (arr[i] === SMS_TRAI_VAR) {
833
437
  arr[i] = '';
834
438
  }
@@ -931,33 +535,18 @@ export const SmsTraiEdit = (props) => {
931
535
  };
932
536
 
933
537
  const smsLengthForVar = () => (
934
- <CapHeading
935
- type="h5"
936
- className={isRcsSmsFallback ? 'rcs-character-count rcs-character-count--compact' : ''}
937
- style={isRcsSmsFallback ? {} : { marginTop: CAP_SPACE_04, marginBottom: 0 }}
938
- >
939
- {isRcsSmsFallback
940
- ? formatMessage(messages.charactersCountLabel, {
941
- current: totalMessageLength,
942
- max: SMS_TRAI_CONTENT_MAX_LENGTH,
943
- })
944
- : formatMessage(messages.totalCharacters, {
945
- smsCount: Math.ceil(totalMessageLength / 160),
946
- number: totalMessageLength,
947
- })}
538
+ <CapHeading type="h5" style={{ marginTop: CAP_SPACE_04, float: 'right' }}>
539
+ {formatMessage(messages.totalCharacters, {
540
+ smsCount: Math.ceil(totalMessageLength / 160),
541
+ number: totalMessageLength,
542
+ })}
948
543
  </CapHeading>
949
544
  );
950
545
 
546
+ // to compute the length of the message
547
+ //40 characters is blocked per'{#var#}' if textbox is empty otherwise it will be textbox length
548
+ // and the remaining string length is added to it
951
549
  const calculateTotalMessageLength = () => {
952
- if (isRcsSmsFallback) {
953
- if (useRcsFallbackVarSegment) {
954
- const resolved = getFallbackResolvedContent(fallbackText || '', fallbackVarMappedData || {});
955
- setTotalMessageLength(resolved.length);
956
- } else {
957
- setTotalMessageLength((fallbackText || '').length);
958
- }
959
- return;
960
- }
961
550
  const msgLenWithoutVar = tempMsgArray
962
551
  ?.filter((i) => i !== SMS_TRAI_VAR)
963
552
  .join('');
@@ -968,43 +557,22 @@ export const SmsTraiEdit = (props) => {
968
557
 
969
558
  const calculateLenForTextBox = () => {
970
559
  let countVarChar = 0;
971
- Object.keys(varMapRef.current).forEach((i) => {
972
- if (varMapRef.current[i].data) {
973
- countVarChar += varMapRef.current[i].data?.length;
974
- if (!showMsgLengthNote && varMapRef.current[i].data?.length > varMapRef.current[i].count * CHARLIMIT) {
560
+ Object.keys(varMap).forEach((i) => {
561
+ if (varMap[i].data) {
562
+ countVarChar += varMap[i].data?.length;
563
+ if (!showMsgLengthNote && varMap[i].data?.length > varMap[i].count * CHARLIMIT) {
975
564
  updateshowMsgLengthNote(true);
976
565
  }
977
566
  } else {
978
- countVarChar += varMapRef.current[i].count * CHARLIMIT;
567
+ countVarChar += varMap[i].count * CHARLIMIT;
979
568
  }
980
569
  });
981
570
  return countVarChar;
982
571
  };
983
572
 
984
- const tagValidationErrorMessage = () => {
985
- const { missingTags = [], unsupportedTags = [], isBraceError } = tagValidationResponseRef.current || {};
986
- const listForMessage = (unsupportedTags && unsupportedTags.length > 0)
987
- ? unsupportedTags
988
- : missingTags;
989
- if (isBraceError) {
990
- return <CapError>{formatMessage(globalMessages.unbalanacedCurlyBraces)}</CapError>;
991
- }
992
- if (listForMessage.length > 0) {
993
- return (
994
- <CapError>
995
- {formatMessage(messages.unsupportedTagsValidationError, {
996
- unsupportedTags: listForMessage,
997
- })}
998
- </CapError>
999
- );
1000
- }
1001
- return null;
1002
- };
1003
-
1004
573
  const disablehandler = () => {
1005
- if (isRcsSmsFallback) return false;
1006
- if (traiDataRef.current && !isEmpty(traiDataRef.current)) {
1007
- const msg = get(traiDataRef.current, `versions.base.sms-editor`, '');
574
+ if (traiData && !isEmpty(traiData)) {
575
+ const msg = get(traiData, `versions.base.sms-editor`, '');
1008
576
  const index = msg.search(SMS_TRAI_VAR);
1009
577
  if (index === -1) {
1010
578
  return true;
@@ -1018,6 +586,7 @@ export const SmsTraiEdit = (props) => {
1018
586
  updateIsUnicodeAllowed(checked);
1019
587
  };
1020
588
 
589
+ // Get template content for test and preview
1021
590
  const getTemplateContent = () => {
1022
591
  if (!updatedSmsEditor || updatedSmsEditor.length === 0) {
1023
592
  return '';
@@ -1025,69 +594,42 @@ export const SmsTraiEdit = (props) => {
1025
594
  return updatedSmsEditor.join('');
1026
595
  };
1027
596
 
597
+ // Build formData for TestAndPreviewSlidebox - templateConfigs with templateId and template for DLT test
1028
598
  const getFormDataForTestAndPreview = () => {
1029
- const smsBase = get(traiDataRef.current, 'versions.base') || get(templateDetails, 'versions.base') || get(templateData, 'versions.base');
599
+ const smsBase = get(traiData, 'versions.base') || get(templateDetails, 'versions.base') || get(templateData, 'versions.base');
1030
600
  if (!smsBase || !smsBase.template_id) {
1031
601
  return {};
1032
602
  }
1033
603
  const templateRaw = smsBase['updated-sms-editor'] || smsBase['sms-editor'] || '';
1034
604
  const template = Array.isArray(templateRaw) ? templateRaw.join('') : templateRaw;
1035
- const traiDlt = isTraiDLTEnable(isFullMode, smsRegister);
1036
- const headerIds = get(traiDataRef.current, 'versions.base.header', []) || [];
1037
605
  return {
1038
606
  templateConfigs: {
1039
- templateId: smsBase.template_id,
1040
- template,
1041
- traiDltEnabled: traiDlt,
1042
- registeredSenderIds: traiDlt ? headerIds : [],
607
+ templateId: smsBase.template_id, template, traiDltEnabled: true, registeredSenderIds: get(traiData, `versions.base.header`, []),
1043
608
  },
1044
609
  };
1045
610
  };
1046
611
 
612
+ // Handle test and preview button click
1047
613
  const handleTestAndPreview = () => {
1048
614
  setShowTestAndPreviewSlidebox(true);
1049
615
  };
1050
616
 
617
+ // Handle close test and preview slidebox
1051
618
  const handleCloseTestAndPreview = () => {
1052
619
  setShowTestAndPreviewSlidebox(false);
1053
620
  };
1054
621
 
1055
- const shouldShowPreview =
1056
- !isRcsSmsFallback || (showPreviewInRcsFallback && !hidePreview);
1057
- const smsSidePreviewColumn = (
1058
- <CapColumn span={8} offset={1}>
1059
- <UnifiedPreview
1060
- channel={SMS}
1061
- content={updatedSmsEditor.join('')}
1062
- device={ANDROID}
1063
- showDeviceToggle={false}
1064
- showHeader={false}
1065
- formatMessage={formatMessage}
1066
- senderId={isUnicodeAllowed ? 'Unicode' : 'ASCII'}
1067
- />
1068
- </CapColumn>
1069
- );
1070
-
1071
622
  return (
1072
623
  <>
1073
- <CapSpin
1074
- spinning={loading || fetchingLiquidTags}
1075
- tip={fetchingLiquidTags && formatMessage(formBuilderMessages.liquidSpinText)}
1076
- className={[
1077
- isRcsSmsFallback && 'sms-trai-edit-rcs-fallback',
1078
- isOverview && 'sms-trai-edit--overview',
1079
- ]
1080
- .filter(Boolean)
1081
- .join(' ') || undefined}
1082
- >
624
+ <CapSpin spinning={loading || fetchingLiquidTags} tip={fetchingLiquidTags && formatMessage(formBuilderMessages.liquidSpinText)}>
1083
625
  <CapRow>
1084
- {traiDataRef.current && !isEmpty(traiDataRef.current) && !isRcsSmsFallback && (
626
+ {traiData && !isEmpty(traiData) && (
1085
627
  <TraiEditTemplateDetails>
1086
628
  <CapLabelInline type="label1">
1087
629
  {formatMessage(messages.templateLabel)}
1088
630
  </CapLabelInline>
1089
631
  <CapLabelInline type="label2">
1090
- {get(traiDataRef.current, `versions.base.template_name`, '')}
632
+ {get(traiData, `versions.base.template_name`, '')}
1091
633
  </CapLabelInline>
1092
634
 
1093
635
  <CapLabelInline type="label1">
@@ -1098,42 +640,15 @@ export const SmsTraiEdit = (props) => {
1098
640
  {formatMessage(messages.senderIdlabel)}
1099
641
  </CapLabelInline>
1100
642
  <CapLabelInline type="label2">
1101
- {[...get(traiDataRef.current, `versions.base.header`, [])].join(', ')}
1102
- </CapLabelInline>
1103
- </TraiEditTemplateDetails>
1104
- )}
1105
- {isRcsSmsFallback &&
1106
- traiDataRef.current &&
1107
- !isEmpty(traiDataRef.current) &&
1108
- !loading && (
1109
- <TraiEditTemplateDetails className="sms-trai-edit-rcs-fallback__template-meta">
1110
- <CapLabelInline type="label1">
1111
- {formatMessage(messages.templateNameLabel)}
1112
- </CapLabelInline>
1113
- <CapLabelInline type="label2">
1114
- {get(traiDataRef.current, 'versions.base.template_name', '')
1115
- || get(traiDataRef.current, 'name', '')}
643
+ {[...get(traiData, `versions.base.header`, [])].join(', ')}
1116
644
  </CapLabelInline>
1117
- {traiDltEnabled ? (
1118
- <>
1119
- <CapLabelInline type="label1">
1120
- {formatMessage(messages.traiEditSeperator)}
1121
- </CapLabelInline>
1122
- <CapLabelInline type="label1">
1123
- {formatMessage(messages.senderIdlabel)}
1124
- </CapLabelInline>
1125
- <CapLabelInline type="label2">
1126
- {[...get(traiDataRef.current, 'versions.base.header', [])].join(', ')}
1127
- </CapLabelInline>
1128
- </>
1129
- ) : null}
1130
645
  </TraiEditTemplateDetails>
1131
646
  )}
1132
- <CapColumn span={shouldShowPreview ? 14 : 24}>
647
+ <CapColumn span={14}>
1133
648
  <CapRow>
1134
649
  <CapHeader
1135
650
  title={formatMessage(messages.traiEditTitle)}
1136
- size={isRcsSmsFallback ? 'label1' : 'regular'}
651
+ size="regular"
1137
652
  suffix={(
1138
653
  <TagList
1139
654
  label={formatMessage(messages.addLabels)}
@@ -1142,55 +657,42 @@ export const SmsTraiEdit = (props) => {
1142
657
  tags={tags || []}
1143
658
  onContextChange={handleOnTagsContextChange}
1144
659
  injectedTags={injectedTags || {}}
1145
- channel={SMS}
1146
- hidePopover={false}
1147
- disabled={!isRcsSmsFallback && disablehandler()}
660
+ hidePopover={disablehandler()}
1148
661
  selectedOfferDetails={selectedOfferDetails}
1149
662
  eventContextTags={eventContextTags}
1150
- popoverOverlayStyle={isRcsSmsFallback ? { zIndex: 10020 } : undefined}
1151
- popoverOverlayClassName={isRcsSmsFallback ? 'sms-fallback-taglist-popover rcs-sms-fallback-taglist-popover' : undefined}
1152
663
  />
1153
664
  )}
1154
665
  />
1155
666
  </CapRow>
1156
667
 
1157
- {isRcsSmsFallback ? (
1158
- <>
1159
- {renderRcsFallbackMessage(fallbackText)}
1160
- </>
1161
- ) : (
1162
- <>
1163
- <CapRow className="sms-trai-editor-segment-row">
1164
- <div className="sms-trai-segmented-editor">
1165
- {renderedContent()}
1166
- </div>
1167
- </CapRow>
1168
- <CapRow className="sms-trai-length-row">
1169
- {smsLengthForVar()}
1170
- </CapRow>
1171
- </>
1172
- )}
1173
- {isRcsSmsFallback && isTagValidationError && (
1174
- <CapRow>
1175
- {tagValidationErrorMessage()}
1176
- </CapRow>
1177
- )}
1178
- {!isRcsSmsFallback && isTagValidationError && tagValidationErrorMessage()}
1179
- <CapCheckbox
1180
- onChange={unicodeHandler}
1181
- checked={isUnicodeAllowed}
1182
- disabled={
1183
- isRcsSmsFallback
1184
- ? isRcsEditFlow
1185
- : disablehandler()
1186
- }
668
+ <CapRow
669
+ style={{
670
+ backgroundColor: CAP_G10,
671
+ padding: CAP_SPACE_16,
672
+ }}
1187
673
  >
674
+ {renderedContent()}
675
+ </CapRow>
676
+ <CapRow>
677
+ {smsLengthForVar()}
678
+ </CapRow>
679
+ <CapCheckbox onChange={unicodeHandler} checked={isUnicodeAllowed} disabled={disablehandler()}>
1188
680
  {formatMessage(messages.unicodeLabel)}
1189
681
  </CapCheckbox>
1190
682
  {showMsgLengthNote && <CapInfoNote message={<FormattedMessage {...messages.msgLengthNote} values={{ var: '{#var#}' }} />} />}
1191
- <div className="sms-trai-edit-bottom-spacer" />
683
+ <div style={{ marginBottom: '100px' }} />
684
+ </CapColumn>
685
+ <CapColumn span={8} offset={1}>
686
+ <UnifiedPreview
687
+ channel={SMS}
688
+ content={updatedSmsEditor.join('')}
689
+ device={ANDROID}
690
+ showDeviceToggle={false}
691
+ showHeader={false}
692
+ formatMessage={formatMessage}
693
+ senderId={isUnicodeAllowed ? 'Unicode' : 'ASCII'}
694
+ />
1192
695
  </CapColumn>
1193
- {shouldShowPreview && smsSidePreviewColumn}
1194
696
  </CapRow>
1195
697
  <SMSTraiFooter>
1196
698
  {isLiquidValidationError && !liquidErrorPanelDismissed && (
@@ -1216,9 +718,8 @@ export const SmsTraiEdit = (props) => {
1216
718
  <FormattedMessage {...messages.testAndPreviewButtonLabel} />
1217
719
  </CapButton>
1218
720
  <CapButton
1219
- onClick={onDoneCallback}
721
+ onClick={onSubmitWrapper}
1220
722
  className="create-msg"
1221
- disabled={isTagValidationError}
1222
723
  >
1223
724
  <FormattedMessage {...messages.saveButtonLabel} />
1224
725
  </CapButton>
@@ -1235,15 +736,6 @@ export const SmsTraiEdit = (props) => {
1235
736
  );
1236
737
  };
1237
738
 
1238
- SmsTraiEdit.propTypes = {
1239
- isRcsSmsFallback: PropTypes.bool,
1240
- isRcsEditFlow: PropTypes.bool,
1241
- showPreviewInRcsFallback: PropTypes.bool,
1242
- hidePreview: PropTypes.bool,
1243
- isOverview: PropTypes.bool,
1244
- onRcsFallbackEditorStateChange: PropTypes.func,
1245
- };
1246
-
1247
739
  const mapStateToProps = createStructuredSelector({
1248
740
  templateDetails: makeSelectTemplateDetailsResponse(),
1249
741
  metaEntities: makeSelectMetaEntities(),