@capillarytech/creatives-library 8.0.319 → 8.0.321

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 (139) hide show
  1. package/constants/unified.js +14 -0
  2. package/package.json +1 -1
  3. package/utils/templateVarUtils.js +172 -0
  4. package/utils/tests/tagValidations.test.js +34 -0
  5. package/utils/tests/templateVarUtils.test.js +160 -0
  6. package/v2Components/CapTagList/index.js +25 -22
  7. package/v2Components/CapTagList/style.scss +48 -0
  8. package/v2Components/CapTagListWithInput/__tests__/CapTagListWithInput.test.js +63 -0
  9. package/v2Components/CapTagListWithInput/index.js +4 -0
  10. package/v2Components/CapWhatsappCTA/index.js +2 -0
  11. package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +70 -49
  12. package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +8 -2
  13. package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +207 -21
  14. package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +16 -0
  15. package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +85 -10
  16. package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +30 -0
  17. package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +79 -11
  18. package/v2Components/CommonTestAndPreview/SendTestMessage.js +11 -5
  19. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +20 -1
  20. package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +133 -4
  21. package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +12 -0
  22. package/v2Components/CommonTestAndPreview/constants.js +38 -0
  23. package/v2Components/CommonTestAndPreview/index.js +693 -155
  24. package/v2Components/CommonTestAndPreview/messages.js +41 -3
  25. package/v2Components/CommonTestAndPreview/previewApiUtils.js +59 -0
  26. package/v2Components/CommonTestAndPreview/sagas.js +15 -6
  27. package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +352 -0
  28. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +269 -1
  29. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +118 -5
  30. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +341 -0
  31. package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +25 -4
  32. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +199 -1
  33. package/v2Components/CommonTestAndPreview/tests/index.test.js +132 -4
  34. package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +67 -0
  35. package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
  36. package/v2Components/FormBuilder/index.js +14 -1
  37. package/v2Components/HtmlEditor/HTMLEditor.js +6 -1
  38. package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +1 -0
  39. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +927 -2
  40. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +3 -0
  41. package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +87 -0
  42. package/v2Components/SmsFallback/constants.js +73 -0
  43. package/v2Components/SmsFallback/index.js +956 -0
  44. package/v2Components/SmsFallback/index.scss +265 -0
  45. package/v2Components/SmsFallback/messages.js +78 -0
  46. package/v2Components/SmsFallback/smsFallbackUtils.js +107 -0
  47. package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +50 -0
  48. package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +147 -0
  49. package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +304 -0
  50. package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +197 -0
  51. package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +261 -0
  52. package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +422 -0
  53. package/v2Components/SmsFallback/useLocalTemplateList.js +92 -0
  54. package/v2Components/TestAndPreviewSlidebox/index.js +8 -1
  55. package/v2Components/TestAndPreviewSlidebox/sagas.js +11 -4
  56. package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +3 -1
  57. package/v2Components/VarSegmentMessageEditor/constants.js +2 -0
  58. package/v2Components/VarSegmentMessageEditor/index.js +125 -0
  59. package/v2Components/VarSegmentMessageEditor/index.scss +46 -0
  60. package/v2Containers/BeeEditor/index.js +3 -0
  61. package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +43 -0
  62. package/v2Containers/CreativesContainer/SlideBoxContent.js +64 -5
  63. package/v2Containers/CreativesContainer/SlideBoxFooter.js +10 -1
  64. package/v2Containers/CreativesContainer/SlideBoxHeader.js +29 -4
  65. package/v2Containers/CreativesContainer/constants.js +9 -0
  66. package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +67 -0
  67. package/v2Containers/CreativesContainer/index.js +292 -99
  68. package/v2Containers/CreativesContainer/index.scss +51 -1
  69. package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +90 -0
  70. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +104 -0
  71. package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +110 -0
  72. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +8 -0
  73. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +363 -0
  74. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +20 -10
  75. package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +258 -0
  76. package/v2Containers/CreativesContainer/tests/index.test.js +71 -9
  77. package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +125 -0
  78. package/v2Containers/Email/index.js +1 -0
  79. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +7 -1
  80. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +3 -0
  81. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +20 -2
  82. package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +16 -1
  83. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +3 -0
  84. package/v2Containers/EmailWrapper/index.js +4 -0
  85. package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +1 -0
  86. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +9 -0
  87. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +19 -0
  88. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +3 -0
  89. package/v2Containers/InAppWrapper/index.js +3 -0
  90. package/v2Containers/MobilePush/Create/index.js +2 -0
  91. package/v2Containers/MobilePush/Edit/index.js +2 -0
  92. package/v2Containers/MobilepushWrapper/index.js +3 -1
  93. package/v2Containers/Rcs/constants.js +32 -1
  94. package/v2Containers/Rcs/index.js +951 -873
  95. package/v2Containers/Rcs/index.scss +85 -6
  96. package/v2Containers/Rcs/messages.js +10 -1
  97. package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +205 -0
  98. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +40834 -1963
  99. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +0 -5
  100. package/v2Containers/Rcs/tests/index.test.js +41 -38
  101. package/v2Containers/Rcs/tests/mockData.js +38 -0
  102. package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +251 -0
  103. package/v2Containers/Rcs/tests/utils.test.js +379 -1
  104. package/v2Containers/Rcs/utils.js +358 -10
  105. package/v2Containers/Sms/Create/index.js +83 -36
  106. package/v2Containers/Sms/Edit/index.js +2 -0
  107. package/v2Containers/Sms/smsFormDataHelpers.js +67 -0
  108. package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +253 -0
  109. package/v2Containers/SmsTrai/Create/index.js +9 -4
  110. package/v2Containers/SmsTrai/Edit/constants.js +2 -0
  111. package/v2Containers/SmsTrai/Edit/index.js +611 -128
  112. package/v2Containers/SmsTrai/Edit/index.scss +121 -0
  113. package/v2Containers/SmsTrai/Edit/messages.js +9 -4
  114. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4327 -2374
  115. package/v2Containers/SmsWrapper/index.js +39 -8
  116. package/v2Containers/TagList/index.js +47 -2
  117. package/v2Containers/TagList/messages.js +4 -0
  118. package/v2Containers/TagList/tests/TagList.test.js +122 -20
  119. package/v2Containers/TagList/tests/mockdata.js +17 -0
  120. package/v2Containers/Templates/TemplatesActionBar.js +101 -0
  121. package/v2Containers/Templates/_templates.scss +61 -2
  122. package/v2Containers/Templates/actions.js +11 -0
  123. package/v2Containers/Templates/constants.js +2 -0
  124. package/v2Containers/Templates/index.js +90 -40
  125. package/v2Containers/Templates/sagas.js +57 -12
  126. package/v2Containers/Templates/tests/TemplatesActionBar.test.js +120 -0
  127. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1043 -1079
  128. package/v2Containers/Templates/tests/sagas.test.js +193 -12
  129. package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +180 -0
  130. package/v2Containers/Templates/utils/smsTemplatesListApi.js +79 -0
  131. package/v2Containers/TemplatesV2/TemplatesV2.style.js +72 -1
  132. package/v2Containers/TemplatesV2/index.js +86 -23
  133. package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +131 -0
  134. package/v2Containers/Viber/index.js +5 -0
  135. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +0 -2
  136. package/v2Containers/WebPush/Create/index.js +9 -1
  137. package/v2Containers/Whatsapp/index.js +8 -20
  138. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +598 -34
  139. package/v2Containers/Zalo/index.js +2 -0
@@ -0,0 +1,92 @@
1
+ import { useState, useCallback, useRef } from 'react';
2
+
3
+ /**
4
+ * @param {Object} options
5
+ * @param {(params: { page: number, search: string, reset: boolean }) => Promise<{ templates: Array, totalCount: number }>} options.fetchTemplates
6
+ * @param {number} [options.perPage=25]
7
+ */
8
+ export function useLocalTemplateList({ fetchTemplates, perPage = 25 }) {
9
+ const [listData, setListData] = useState({ templates: [], totalCount: 0 });
10
+ const [loading, setLoading] = useState(false);
11
+ const [page, setPage] = useState(1);
12
+ const [search, setSearchState] = useState('');
13
+ const searchRef = useRef('');
14
+ /** Drops stale responses when a newer fetch starts (search / reset while a request is in flight). */
15
+ const fetchGenerationRef = useRef(0);
16
+ const setSearch = useCallback((value) => {
17
+ const term = typeof value === 'string' ? value : '';
18
+ searchRef.current = term;
19
+ setSearchState(term);
20
+ }, []);
21
+ const lastFetchFullPageRef = useRef(false);
22
+
23
+ const { templates = [], totalCount = 0 } = listData ?? {};
24
+ const hasKnownTotal = (totalCount ?? 0) > 0;
25
+ const hasMoreByTotal = (totalCount ?? 0) > (templates?.length ?? 0);
26
+ const hasMoreByFullPage =
27
+ !hasKnownTotal && lastFetchFullPageRef.current && (templates?.length ?? 0) > 0;
28
+ const canLoadMore = (hasMoreByTotal || hasMoreByFullPage) && !loading;
29
+
30
+ const runFetch = useCallback(
31
+ async ({ page: p = 1, reset = true, search: searchTerm } = {}) => {
32
+ const term = searchTerm !== undefined ? searchTerm : searchRef.current;
33
+ const gen = ++fetchGenerationRef.current;
34
+ setLoading(true);
35
+ try {
36
+ const result = await fetchTemplates({ page: p, search: term, reset });
37
+ if (gen !== fetchGenerationRef.current) {
38
+ return;
39
+ }
40
+ const nextTemplates = result?.templates ?? [];
41
+ const nextTotalCount = result?.totalCount ?? 0;
42
+ lastFetchFullPageRef.current = nextTemplates.length >= perPage;
43
+ setListData((prev) => ({
44
+ templates: reset ? nextTemplates : [...(prev.templates || []), ...nextTemplates],
45
+ totalCount: nextTotalCount > 0 ? nextTotalCount : (reset ? 0 : prev.totalCount),
46
+ }));
47
+ setPage(p);
48
+ } catch (e) {
49
+ if (gen !== fetchGenerationRef.current) {
50
+ return;
51
+ }
52
+ lastFetchFullPageRef.current = false;
53
+ if (reset) {
54
+ setListData({ templates: [], totalCount: 0 });
55
+ setPage(1);
56
+ }
57
+ } finally {
58
+ if (gen === fetchGenerationRef.current) {
59
+ setLoading(false);
60
+ }
61
+ }
62
+ },
63
+ [fetchTemplates, perPage]
64
+ );
65
+
66
+ const loadMore = useCallback(() => {
67
+ if (!canLoadMore) return;
68
+ runFetch({ page: page + 1, reset: false, search: searchRef.current });
69
+ }, [canLoadMore, page, runFetch]);
70
+
71
+ const reset = useCallback(
72
+ (searchTerm) => {
73
+ const term = searchTerm !== undefined ? searchTerm : searchRef.current;
74
+ setSearch(term);
75
+ lastFetchFullPageRef.current = false;
76
+ runFetch({ page: 1, reset: true, search: term });
77
+ },
78
+ [runFetch, setSearch]
79
+ );
80
+
81
+ return {
82
+ templates,
83
+ totalCount,
84
+ loading,
85
+ page,
86
+ search,
87
+ setSearch,
88
+ loadMore,
89
+ reset,
90
+ canLoadMore,
91
+ };
92
+ }
@@ -18,7 +18,7 @@ import injectReducer from '../../utils/injectReducer';
18
18
  import injectSaga from '../../utils/injectSaga';
19
19
 
20
20
  import CommonTestAndPreview from '../CommonTestAndPreview';
21
- import { CHANNELS } from '../CommonTestAndPreview/constants';
21
+ import { CHANNELS, RCS_SMS_FALLBACK_VAR_MAPPED_PROP } from '../CommonTestAndPreview/constants';
22
22
  import * as commonTestAndPreviewActions from '../CommonTestAndPreview/actions';
23
23
  import { commonTestAndPreviewSaga } from '../CommonTestAndPreview/sagas';
24
24
  import commonTestAndPreviewReducer from '../CommonTestAndPreview/reducer';
@@ -78,6 +78,12 @@ TestAndPreviewSlidebox.propTypes = {
78
78
  content: PropTypes.string,
79
79
  beeInstance: PropTypes.object,
80
80
  currentTab: PropTypes.number,
81
+ smsFallbackContent: PropTypes.shape({
82
+ templateContent: PropTypes.string,
83
+ senderId: PropTypes.string,
84
+ templateName: PropTypes.string,
85
+ [RCS_SMS_FALLBACK_VAR_MAPPED_PROP]: PropTypes.object,
86
+ }),
81
87
  // Redux props are passed through
82
88
  actions: PropTypes.object.isRequired,
83
89
  extractedTags: PropTypes.array.isRequired,
@@ -113,6 +119,7 @@ TestAndPreviewSlidebox.defaultProps = {
113
119
  wecrmAccounts: [],
114
120
  isLoadingSenderDetails: false,
115
121
  orgUnitId: -1,
122
+ smsFallbackContent: null,
116
123
  };
117
124
 
118
125
  const mapStateToProps = createStructuredSelector({
@@ -34,6 +34,7 @@ import {
34
34
  GET_PREFILLED_VALUES_SUCCESS,
35
35
  GET_PREFILLED_VALUES_FAILURE,
36
36
  } from './constants';
37
+ import { extractPreviewFromLiquidResponse } from '../CommonTestAndPreview/previewApiUtils';
37
38
 
38
39
  // Search Customers Saga
39
40
  export function* searchCustomersSaga(action) {
@@ -80,11 +81,12 @@ export function* updatePreviewSaga(action) {
80
81
  const customValues = action.payload.resolvedTags;
81
82
 
82
83
  const response = yield call(Api.updateEmailPreview, action.payload);
83
- if (response?.data) {
84
+ const previewPayload = extractPreviewFromLiquidResponse(response);
85
+ if (previewPayload) {
84
86
  yield put({
85
87
  type: UPDATE_PREVIEW_SUCCESS,
86
88
  payload: {
87
- previewData: response.data,
89
+ previewData: previewPayload,
88
90
  customValues, // Pass custom values to be preserved
89
91
  },
90
92
  });
@@ -221,8 +223,13 @@ export function* createMessageMetaSaga(action) {
221
223
  export function* getPrefilledValuesSaga(action) {
222
224
  try {
223
225
  const response = yield call(Api.updateEmailPreview, action.payload);
224
- if (response?.data) {
225
- yield put({ type: GET_PREFILLED_VALUES_SUCCESS, payload: { values: response?.data?.resolvedTagValues } });
226
+ const body =
227
+ response?.data !== undefined && response?.data !== null
228
+ ? response.data
229
+ : response;
230
+ const resolvedTagValues = body?.resolvedTagValues;
231
+ if (resolvedTagValues != null) {
232
+ yield put({ type: GET_PREFILLED_VALUES_SUCCESS, payload: { values: resolvedTagValues } });
226
233
  } else {
227
234
  yield put({ type: GET_PREFILLED_VALUES_FAILURE, payload: { error: response.error || 'Failed to fetch prefilled values' } });
228
235
  }
@@ -136,7 +136,9 @@ describe('TestAndPreviewSlidebox Sagas', () => {
136
136
  describe('updatePreviewSaga', () => {
137
137
  it('should handle successful preview update', () => {
138
138
  const mockResponse = {
139
- data: 'Test Preview Data',
139
+ data: {
140
+ resolvedBody: 'Test Preview Data',
141
+ },
140
142
  };
141
143
  const customValues = { test: 'value' };
142
144
  return expectSaga(sagas.updatePreviewSaga, {
@@ -0,0 +1,2 @@
1
+ /** Default prefix before variable name in variable-slot placeholders. */
2
+ export const VAR_SEGMENT_PLACEHOLDER_PREFIX = 'enter the value for ';
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Shared message editor that renders template text with {{var}} and/or DLT `{#var#}` segments as
3
+ * variable inputs and static text as headings.
4
+ * Reused by RCS (title/description), SmsTrai Edit (SMS fallback), and WhatsApp (edit message/header).
5
+ */
6
+ import React from 'react';
7
+ import PropTypes from 'prop-types';
8
+ import CapRow from '@capillarytech/cap-ui-library/CapRow';
9
+ import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
10
+ import CapInput from '@capillarytech/cap-ui-library/CapInput';
11
+ import {
12
+ splitTemplateVarString,
13
+ DEFAULT_MUSTACHE_VAR_REGEX,
14
+ isAnyTemplateVarToken,
15
+ } from '../../utils/templateVarUtils';
16
+
17
+ import './index.scss';
18
+ import { VAR_SEGMENT_PLACEHOLDER_PREFIX } from './constants';
19
+
20
+ const { TextArea } = CapInput;
21
+
22
+ export function VarSegmentMessageEditor({
23
+ templateString = '',
24
+ valueMap = {},
25
+ onChange,
26
+ onFocus,
27
+ placeholderPrefix = VAR_SEGMENT_PLACEHOLDER_PREFIX,
28
+ getPlaceholder,
29
+ wrapperClassName = 'rcs_text_area_wrapper',
30
+ rowClassName = 'rcs-edit-template-message-input',
31
+ headingClassName = 'rcs-edit-template-message-split',
32
+ varRegex,
33
+ readOnly = false,
34
+ disabled = false,
35
+ footerContent,
36
+ renderVarFooter,
37
+ }) {
38
+ const segments = splitTemplateVarString(templateString, varRegex || DEFAULT_MUSTACHE_VAR_REGEX);
39
+ if (!segments?.length) return null;
40
+
41
+ return (
42
+ <div className={wrapperClassName}>
43
+ <CapRow className={rowClassName}>
44
+ {segments.map((segmentToken, segmentIndex) => {
45
+ const isVar =
46
+ typeof segmentToken === 'string' && isAnyTemplateVarToken(segmentToken);
47
+ if (isVar) {
48
+ const varSegmentFieldId = `${segmentToken}_${segmentIndex}`;
49
+ const slotValueFromMap = valueMap?.[varSegmentFieldId];
50
+ // Missing key: show empty (not the raw {{…}} token) so cleared slots and incomplete maps
51
+ // cannot resurrect the token; placeholder still guides the user.
52
+ const value =
53
+ slotValueFromMap !== undefined && slotValueFromMap !== null ? slotValueFromMap : '';
54
+ if (readOnly) {
55
+ return (
56
+ <CapHeading
57
+ key={varSegmentFieldId}
58
+ type="h4"
59
+ className={`${headingClassName} var-segment-message-editor__read-only-value`.trim()}
60
+ >
61
+ {value}
62
+ </CapHeading>
63
+ );
64
+ }
65
+ const fromGet = getPlaceholder && getPlaceholder(segmentToken, segmentIndex);
66
+ const placeholder =
67
+ fromGet !== undefined && fromGet !== null && fromGet !== ''
68
+ ? fromGet
69
+ : `${placeholderPrefix}${segmentToken}`;
70
+ return (
71
+ <div key={varSegmentFieldId} className="var-segment-message-editor__var-slot">
72
+ <TextArea
73
+ id={varSegmentFieldId}
74
+ placeholder={placeholder}
75
+ autosize={{ minRows: 1, maxRows: 3 }}
76
+ value={value}
77
+ onFocus={() => onFocus && onFocus(varSegmentFieldId)}
78
+ onChange={(e) =>
79
+ onChange && onChange(varSegmentFieldId, e?.target?.value ?? '')}
80
+ disabled={disabled}
81
+ />
82
+ {renderVarFooter
83
+ ? renderVarFooter(segmentToken, segmentIndex, varSegmentFieldId)
84
+ : null}
85
+ </div>
86
+ );
87
+ }
88
+ if (segmentToken) {
89
+ return (
90
+ <CapHeading
91
+ key={`static_${segmentIndex}_${segmentToken}`}
92
+ type="h4"
93
+ className={headingClassName}
94
+ >
95
+ {segmentToken}
96
+ </CapHeading>
97
+ );
98
+ }
99
+ return null;
100
+ })}
101
+ </CapRow>
102
+ {footerContent}
103
+ </div>
104
+ );
105
+ }
106
+
107
+ VarSegmentMessageEditor.propTypes = {
108
+ templateString: PropTypes.string,
109
+ valueMap: PropTypes.object,
110
+ onChange: PropTypes.func,
111
+ onFocus: PropTypes.func,
112
+ placeholderPrefix: PropTypes.string,
113
+ getPlaceholder: PropTypes.func,
114
+ wrapperClassName: PropTypes.string,
115
+ rowClassName: PropTypes.string,
116
+ headingClassName: PropTypes.string,
117
+ varRegex: PropTypes.object,
118
+ readOnly: PropTypes.bool,
119
+ disabled: PropTypes.bool,
120
+ footerContent: PropTypes.node,
121
+ /** Optional hint below a variable field (e.g. DLT `{#var#}` max length). */
122
+ renderVarFooter: PropTypes.func,
123
+ };
124
+
125
+ export default VarSegmentMessageEditor;
@@ -0,0 +1,46 @@
1
+ @import '~@capillarytech/cap-ui-library/styles/_variables';
2
+
3
+ /* Same look as RCS edit message block: background, spacing, text color */
4
+ .rcs_text_area_wrapper {
5
+ .rcs-edit-template-message-input {
6
+ background-color: $CAP_G10;
7
+ padding: $CAP_SPACE_12 $CAP_SPACE_16 $CAP_SPACE_16;
8
+ }
9
+
10
+ .rcs-edit-template-message-split {
11
+ margin: 0 0 $CAP_SPACE_04 0;
12
+ overflow: hidden;
13
+ text-overflow: ellipsis;
14
+ color: $FONT_COLOR_04;
15
+ font-weight: 500;
16
+ }
17
+
18
+ /* Variable chips: match RCS edit (white field, light border, 4px radius) */
19
+ .rcs-edit-template-message-input .ant-input,
20
+ .rcs-edit-template-message-input textarea.ant-input {
21
+ margin: 0 0 0.125rem 0;
22
+ border-radius: 0.25rem;
23
+ border: 0.0625rem solid $CAP_G07;
24
+ background-color: $CAP_WHITE;
25
+ overflow: hidden;
26
+ }
27
+
28
+ /* Small gap between tag border and the next line (static text) */
29
+ .rcs-edit-template-message-input :not(:first-child) {
30
+ margin-top: $CAP_SPACE_08;
31
+ }
32
+
33
+ .rcs-edit-template-message-input > *:last-child {
34
+ margin-bottom: 0;
35
+ }
36
+
37
+ .var-segment-message-editor__var-slot {
38
+ display: flex;
39
+ flex-direction: column;
40
+ width: 100%;
41
+ }
42
+ }
43
+
44
+ .var-segment-message-editor__read-only-value {
45
+ margin: 0;
46
+ }
@@ -53,6 +53,7 @@ function BeeEditor(props) {
53
53
  BEESelect,
54
54
  currentOrgDetails,
55
55
  eventContextTags,
56
+ waitEventContextTags,
56
57
  } = props;
57
58
  const { saveRowRequest } = BEESelect;
58
59
  const {formatMessage} = intl;
@@ -368,6 +369,7 @@ function BeeEditor(props) {
368
369
  }}
369
370
  onContextChange={onContextChange}
370
371
  eventContextTags={eventContextTags}
372
+ waitEventContextTags={waitEventContextTags}
371
373
  />
372
374
  <CapModal
373
375
  className="custom-row-modal"
@@ -414,6 +416,7 @@ BeeEditor.propTypes = {
414
416
  onContextChange: PropTypes.func,
415
417
  userLocale: PropTypes.string,
416
418
  eventContextTags: PropTypes.array,
419
+ waitEventContextTags: PropTypes.object,
417
420
  };
418
421
 
419
422
  const mapStateToProps = () => createStructuredSelector({
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Styled wrapper for CapSlideBox used by CreativesContainer and RCS SMS fallback
3
+ * so header/content/footer margins match.
4
+ */
5
+ import styled from 'styled-components';
6
+ import { CAP_SPACE_16 } from '@capillarytech/cap-ui-library/styled/variables';
7
+
8
+ const CreativesSlideBoxWrapper = styled.div`
9
+ .cap-slide-box-v2-container {
10
+ /*
11
+ * Liquid-error spacing must stay *inside* the content column. margin-bottom on
12
+ * .slidebox-content-container added to the in-flow height past 100vh, so the outer
13
+ * .cap-slide-box-v2-container (overflow-y: auto in cap-ui) gained a second scrollbar.
14
+ */
15
+ .slidebox-header {
16
+ margin-bottom: ${({ slideBoxWrapperMargin }) => `${slideBoxWrapperMargin}`};
17
+ padding: 0 rem;
18
+ &.has-footer {
19
+ overflow-x: hidden;
20
+ }
21
+ }
22
+ .slidebox-content-container {
23
+ margin-bottom: 0;
24
+ padding: 0 rem;
25
+ padding-bottom: ${({ slideBoxWrapperMargin }) => `${slideBoxWrapperMargin}`};
26
+ box-sizing: border-box;
27
+ &.has-footer {
28
+ overflow-x: hidden;
29
+ }
30
+ }
31
+ .slidebox-footer {
32
+ /* Only apply margin-bottom to footer when ErrorInfoNote is shown in footer (BEE editor) */
33
+ /* For HTML Editor, errors are shown in ValidationErrorDisplay (inside content area), so no footer margin needed */
34
+ margin-bottom: ${({ shouldApplyFooterMargin }) => (shouldApplyFooterMargin ? `${CAP_SPACE_16}` : '0')};
35
+ padding: 0 rem;
36
+ &.has-footer {
37
+ overflow-x: hidden;
38
+ }
39
+ }
40
+ }
41
+ `;
42
+
43
+ export default CreativesSlideBoxWrapper;