@capillarytech/creatives-library 8.0.236-alpha.7 → 8.0.236

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 (86) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/constants/unified.js +1 -1
  4. package/initialReducer.js +0 -2
  5. package/package.json +1 -1
  6. package/services/api.js +0 -5
  7. package/services/tests/api.test.js +0 -18
  8. package/utils/common.js +2 -1
  9. package/utils/commonUtils.js +1 -14
  10. package/utils/tests/commonUtil.test.js +0 -224
  11. package/utils/transformTemplateConfig.js +10 -0
  12. package/v2Components/CapDeviceContent/index.js +56 -61
  13. package/v2Components/CapTagList/index.js +0 -4
  14. package/v2Components/CapWhatsappCTA/tests/index.test.js +0 -5
  15. package/v2Components/HtmlEditor/HTMLEditor.js +83 -235
  16. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +19 -932
  17. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +12 -17
  18. package/v2Components/HtmlEditor/_htmlEditor.scss +4 -2
  19. package/v2Components/HtmlEditor/_index.lazy.scss +1 -0
  20. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +101 -2
  21. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +131 -105
  22. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +1 -2
  23. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  24. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +0 -1
  25. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +7 -4
  26. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +45 -35
  27. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +3 -1
  28. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  29. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +6 -7
  30. package/v2Components/HtmlEditor/constants.js +20 -29
  31. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +16 -373
  32. package/v2Components/HtmlEditor/hooks/useInAppContent.js +148 -130
  33. package/v2Components/HtmlEditor/index.js +1 -1
  34. package/v2Components/HtmlEditor/messages.js +85 -85
  35. package/v2Components/MobilePushPreviewV2/index.js +7 -32
  36. package/v2Components/TemplatePreview/_templatePreview.scss +24 -44
  37. package/v2Components/TemplatePreview/index.js +32 -47
  38. package/v2Components/TemplatePreview/messages.js +0 -4
  39. package/v2Containers/BeeEditor/index.js +80 -82
  40. package/v2Containers/CreativesContainer/SlideBoxContent.js +34 -69
  41. package/v2Containers/CreativesContainer/SlideBoxHeader.js +1 -2
  42. package/v2Containers/CreativesContainer/constants.js +0 -1
  43. package/v2Containers/CreativesContainer/index.js +32 -92
  44. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +12 -4
  45. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +0 -15
  46. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +74 -40
  47. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +67 -2
  48. package/v2Containers/InApp/actions.js +0 -7
  49. package/v2Containers/InApp/constants.js +4 -20
  50. package/v2Containers/InApp/index.js +386 -984
  51. package/v2Containers/InApp/index.scss +3 -4
  52. package/v2Containers/InApp/messages.js +3 -7
  53. package/v2Containers/InApp/reducer.js +3 -21
  54. package/v2Containers/InApp/sagas.js +9 -29
  55. package/v2Containers/InApp/selectors.js +5 -25
  56. package/v2Containers/InApp/tests/index.test.js +50 -154
  57. package/v2Containers/InApp/tests/reducer.test.js +0 -34
  58. package/v2Containers/InApp/tests/sagas.test.js +9 -61
  59. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +0 -3
  60. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +0 -2
  61. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +0 -2
  62. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +0 -9
  63. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +0 -12
  64. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +0 -4
  65. package/v2Containers/TagList/index.js +1 -65
  66. package/v2Containers/Templates/_templates.scss +1 -60
  67. package/v2Containers/Templates/index.js +5 -99
  68. package/v2Containers/Templates/messages.js +0 -4
  69. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +0 -35
  70. package/v2Containers/BeePopupEditor/constants.js +0 -10
  71. package/v2Containers/BeePopupEditor/index.js +0 -193
  72. package/v2Containers/BeePopupEditor/tests/index.test.js +0 -627
  73. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +0 -376
  74. package/v2Containers/InApp/__tests__/sagas.test.js +0 -363
  75. package/v2Containers/InApp/tests/selectors.test.js +0 -612
  76. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +0 -162
  77. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +0 -267
  78. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +0 -9
  79. package/v2Containers/InAppWrapper/constants.js +0 -16
  80. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +0 -473
  81. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +0 -198
  82. package/v2Containers/InAppWrapper/index.js +0 -148
  83. package/v2Containers/InAppWrapper/messages.js +0 -49
  84. package/v2Containers/InappAdvance/index.js +0 -1115
  85. package/v2Containers/InappAdvance/index.scss +0 -10
  86. package/v2Containers/InappAdvance/tests/index.test.js +0 -448
@@ -9,23 +9,19 @@ import { render, screen, waitFor } from '@testing-library/react';
9
9
  import '@testing-library/jest-dom';
10
10
 
11
11
  // Mock CapSpin before importing the component
12
- jest.mock('@capillarytech/cap-ui-library/CapSpin', () => function MockCapSpin({ size }) {
13
- return <div data-testid="cap-spin" data-size={size}>Loading...</div>;
12
+ jest.mock('@capillarytech/cap-ui-library/CapSpin', () => {
13
+ return function MockCapSpin({ size }) {
14
+ return <div data-testid="cap-spin" data-size={size}>Loading...</div>;
15
+ };
14
16
  });
15
17
 
16
18
  // Mock the HTMLEditor component
17
19
  jest.mock('../HTMLEditor', () => {
18
- const MockHTMLEditor = function MockHTMLEditor(props) {
19
- return (
20
- <div data-testid="html-editor">
21
- Mock HTML Editor -
22
- {props.variant}
23
- </div>
24
- );
25
- };
26
20
  return {
27
21
  __esModule: true,
28
- default: MockHTMLEditor,
22
+ default: function MockHTMLEditor(props) {
23
+ return <div data-testid="html-editor">Mock HTML Editor - {props.variant}</div>;
24
+ }
29
25
  };
30
26
  });
31
27
 
@@ -117,8 +113,7 @@ describe('index.lazy.js', () => {
117
113
  expect(screen.getByTestId('html-editor')).toBeInTheDocument();
118
114
  });
119
115
 
120
- const editor = screen.getByTestId('html-editor');
121
- expect(editor.textContent).toBe('Mock HTML Editor -email');
116
+ expect(screen.getByText(/Mock HTML Editor - email/)).toBeInTheDocument();
122
117
  });
123
118
 
124
119
  it('shows fallback while loading', async () => {
@@ -139,7 +134,7 @@ describe('index.lazy.js', () => {
139
134
  <HTMLEditorLazy
140
135
  variant="inapp"
141
136
  onSave={mockOnSave}
142
- readOnly
137
+ readOnly={true}
143
138
  className="custom-class"
144
139
  />
145
140
  );
@@ -148,8 +143,7 @@ describe('index.lazy.js', () => {
148
143
  expect(screen.getByTestId('html-editor')).toBeInTheDocument();
149
144
  });
150
145
 
151
- const editor = screen.getByTestId('html-editor');
152
- expect(editor.textContent).toBe('Mock HTML Editor -inapp');
146
+ expect(screen.getByText(/Mock HTML Editor - inapp/)).toBeInTheDocument();
153
147
  });
154
148
 
155
149
  it('has correct display name', async () => {
@@ -221,7 +215,7 @@ describe('index.lazy.js', () => {
221
215
  render(
222
216
  <HTMLEditorLazy
223
217
  className="custom-editor"
224
- readOnly
218
+ readOnly={true}
225
219
  showFullscreenButton={false}
226
220
  autoSave={false}
227
221
  autoSaveInterval={60000}
@@ -535,3 +529,4 @@ describe('index.lazy.js', () => {
535
529
  });
536
530
  });
537
531
  });
532
+
@@ -28,7 +28,6 @@
28
28
  padding: 0;
29
29
  min-height: 3.25rem;
30
30
  height: 3.25rem;
31
- position: relative;
32
31
 
33
32
  // Right-align toolbar actions
34
33
  &__right {
@@ -129,7 +128,6 @@
129
128
  padding: 0;
130
129
  min-height: 3.25rem; // 52px = 3.25rem
131
130
  height: 3.25rem;
132
- position: relative;
133
131
 
134
132
  // Right-align toolbar actions
135
133
  &__right {
@@ -269,6 +267,10 @@
269
267
 
270
268
  // Focus states and accessibility
271
269
  .html-editor {
270
+ &:focus-within {
271
+ outline: 0.125rem solid map-get($CAP_PRIMARY, base); // 2px = 0.125rem
272
+ outline-offset: -0.125rem; // -2px = -0.125rem
273
+ }
272
274
 
273
275
  // High contrast mode support
274
276
  @media (prefers-contrast: high) {
@@ -13,6 +13,7 @@
13
13
  align-items: center;
14
14
  min-height: 25rem; // 400px = 25rem
15
15
  background: $CAP_G11; // Light background similar to #fafbfc
16
+ border: 0.0625rem solid $CAP_G07; // 1px border similar to #dfe2e7
16
17
  border-radius: 0.5rem; // 8px = 0.5rem
17
18
  flex-direction: column;
18
19
  gap: 1rem; // 16px = 1rem
@@ -31,6 +31,79 @@
31
31
  display: flex;
32
32
  align-items: center;
33
33
  gap: 0.5rem;
34
+
35
+ .cap-button,
36
+ .ant-btn,
37
+ button {
38
+ color: map-get($CAP_PRIMARY, base);
39
+ border: none;
40
+ background: $CAP_WHITE;
41
+ border-radius: 0.25rem;
42
+ padding: 0.375rem 0.5rem;
43
+ font-size: 0.875rem;
44
+ font-family: $FONT_FAMILY;
45
+ font-weight: 500;
46
+ height: auto;
47
+ min-width: 5.9375rem;
48
+ display: flex;
49
+ align-items: center;
50
+ gap: 0.25rem;
51
+ box-shadow: 0 0 0.0625rem 0 rgba(9, 30, 66, 0.31), 0 0.25rem 0.5rem -0.125rem rgba(9, 30, 66, 0.25);
52
+ line-height: 1.25rem;
53
+ text-align: left;
54
+
55
+ &:hover {
56
+ background: $CAP_G09;
57
+ box-shadow: 0 0 0.0625rem 0 rgba(9, 30, 66, 0.31), 0 0.375rem 0.75rem -0.125rem rgba(9, 30, 66, 0.25);
58
+ color: map-get($CAP_PRIMARY, base);
59
+ border: none;
60
+ }
61
+
62
+ &:active,
63
+ &:focus {
64
+ background: $CAP_G08;
65
+ box-shadow: 0 0 0.0625rem 0 rgba(9, 30, 66, 0.31), 0 0.125rem 0.25rem -0.125rem rgba(9, 30, 66, 0.25);
66
+ color: map-get($CAP_PRIMARY, base);
67
+ border: none;
68
+ }
69
+
70
+ .anticon,
71
+ .cap-icon {
72
+ font-size: 1rem;
73
+ color: map-get($CAP_PRIMARY, base);
74
+ }
75
+
76
+ span {
77
+ font-size: 0.875rem;
78
+ font-weight: 500;
79
+ line-height: 1.25rem;
80
+ color: map-get($CAP_PRIMARY, base);
81
+ white-space: nowrap;
82
+ }
83
+
84
+ &:before,
85
+ &:after {
86
+ display: none;
87
+ }
88
+ }
89
+
90
+ .tooltip-add-label-container {
91
+
92
+ .cap-button,
93
+ .ant-btn {
94
+ color: map-get($CAP_PRIMARY, base);
95
+ background: $CAP_WHITE;
96
+ border: none;
97
+ box-shadow: 0 0 0.0625rem 0 rgba(9, 30, 66, 0.31), 0 0.25rem 0.5rem -0.125rem rgba(9, 30, 66, 0.25);
98
+ }
99
+ }
100
+
101
+ .cap-button-flat,
102
+ .cap-button-add {
103
+ background: $CAP_WHITE;
104
+ color: map-get($CAP_PRIMARY, base);
105
+ border: none;
106
+ }
34
107
  }
35
108
 
36
109
  &__content {
@@ -40,7 +113,7 @@
40
113
  overflow: auto;
41
114
  position: relative;
42
115
  height: 100%;
43
- max-height: 34.25rem;
116
+ max-height: 31.25rem;
44
117
  background-color: $CAP_G01;
45
118
  }
46
119
 
@@ -150,7 +223,7 @@
150
223
  .codemirror-wrapper {
151
224
  position: relative;
152
225
  height: 100%;
153
- max-height: 34.25rem;
226
+ max-height: 31.25rem;
154
227
  background-color: $CAP_G01;
155
228
  border-radius: 0;
156
229
  overflow: hidden;
@@ -161,6 +234,31 @@
161
234
  top: 0.5rem;
162
235
  right: 0.5rem;
163
236
  z-index: 20;
237
+
238
+ .cap-button,
239
+ .ant-btn,
240
+ button {
241
+ background: $CAP_WHITE;
242
+ color: map-get($CAP_PRIMARY, base);
243
+ border: none;
244
+ border-radius: 0.25rem;
245
+ padding: 0.375rem 0.5rem;
246
+ font-size: 0.875rem;
247
+ font-family: $FONT_FAMILY;
248
+ font-weight: 500;
249
+ min-width: 5.9375rem;
250
+ box-shadow: 0 0 0.0625rem 0 rgba(9, 30, 66, 0.31), 0 0.25rem 0.5rem -0.125rem rgba(9, 30, 66, 0.25);
251
+
252
+ &:hover {
253
+ background: $CAP_G09;
254
+ color: map-get($CAP_PRIMARY, base);
255
+ }
256
+
257
+ &:active {
258
+ background: $CAP_G08;
259
+ color: map-get($CAP_PRIMARY, base);
260
+ }
261
+ }
164
262
  }
165
263
 
166
264
  .codemirror-editor {
@@ -198,6 +296,7 @@
198
296
  }
199
297
 
200
298
  .cm-gutters {
299
+ background-color: var(--editor-gutter-bg, $CAP_G02);
201
300
  border-right: 0.0625rem solid var(--editor-border, $CAP_G04);
202
301
  color: var(--editor-gutter-foreground, $FONT_COLOR_02);
203
302
  }
@@ -8,57 +8,45 @@
8
8
  * - Theme support with proper styling
9
9
  */
10
10
 
11
- import React, {
12
- forwardRef, useImperativeHandle, useRef, useEffect, useCallback,
13
- } from 'react';
11
+ import React, { forwardRef, useImperativeHandle, useRef, useEffect, useState } from 'react';
14
12
  import PropTypes from 'prop-types';
15
13
 
16
14
  // CodeMirror 6 imports
17
15
  import { EditorState } from '@codemirror/state';
18
16
  import { EditorView, lineNumbers, highlightActiveLine } from '@codemirror/view';
19
17
 
18
+ // Import our comprehensive syntax highlighting solution
19
+ import { createRobustExtensions } from '../../utils/properSyntaxHighlighting';
20
+
20
21
 
21
22
  import { injectIntl, intlShape } from 'react-intl';
22
23
 
23
24
  // Messages
24
- import CapRow from '@capillarytech/cap-ui-library/CapRow';
25
25
  import messages from '../../messages';
26
26
 
27
27
  // Cap UI Components
28
+ import CapRow from '@capillarytech/cap-ui-library/CapRow';
28
29
 
29
30
  // Components
30
31
  import TagList from '../../../../v2Containers/TagList';
31
32
 
32
- // Constants - removed unused imports since tag fetching is handled by parent
33
-
34
33
  // Context
35
34
  import { useEditorContext } from '../common/EditorContext';
36
35
 
37
36
  // Styles
38
37
  import './_codeEditorPane.scss';
39
38
 
40
- // Define Theme and Highlighting inline to avoid "multiple instances of @codemirror/state" error
41
-
42
-
43
39
  // Legacy CodeMirrorEditor removed - using enhanced implementation only
44
40
 
45
41
  const CodeEditorPaneComponent = ({
46
42
  intl,
47
43
  readOnly = false,
48
44
  className = '',
49
- forwardedRef,
50
- // Tag-related props - tags are fetched and managed by parent component
51
- tags = [],
52
- injectedTags = {},
53
- location,
54
- eventContextTags = [],
55
- selectedOfferDetails = [],
56
- channel,
57
- userLocale = 'en',
58
- moduleFilterEnabled = true,
59
- onTagContextChange,
45
+ isFullscreenMode = false,
46
+ onLabelInsert,
47
+ forwardedRef
60
48
  }) => {
61
- const { content } = useEditorContext();
49
+ const { content, validation } = useEditorContext();
62
50
  const { content: contentValue, updateContent } = content;
63
51
  const editorRef = useRef(null);
64
52
  const viewRef = useRef(null);
@@ -73,7 +61,7 @@ const CodeEditorPaneComponent = ({
73
61
  get view() {
74
62
  return viewRef.current;
75
63
  },
76
- viewRef, // For compatibility with existing code
64
+ viewRef: viewRef, // For compatibility with existing code
77
65
 
78
66
  focus: () => {
79
67
  if (viewRef.current) {
@@ -87,7 +75,7 @@ const CodeEditorPaneComponent = ({
87
75
  const pos = position !== undefined ? position : head;
88
76
  view.dispatch({
89
77
  changes: { from: pos, insert: text },
90
- selection: { anchor: pos + text.length },
78
+ selection: { anchor: pos + text.length }
91
79
  });
92
80
  } else {
93
81
  throw new Error('CodeMirror view not initialized');
@@ -100,7 +88,9 @@ const CodeEditorPaneComponent = ({
100
88
  }
101
89
  return 0;
102
90
  },
103
- getValue: () => contentValue || '',
91
+ getValue: () => {
92
+ return contentValue || '';
93
+ },
104
94
  setValue: (value) => {
105
95
  updateContent(value);
106
96
  },
@@ -117,7 +107,7 @@ const CodeEditorPaneComponent = ({
117
107
 
118
108
  view.dispatch({
119
109
  selection: { anchor: pos },
120
- effects: EditorView.scrollIntoView(pos, { y: 'center' }),
110
+ effects: EditorView.scrollIntoView(pos, { y: 'center' })
121
111
  });
122
112
  view.focus();
123
113
  } catch (error) {
@@ -127,7 +117,7 @@ const CodeEditorPaneComponent = ({
127
117
  }
128
118
  }
129
119
  }
130
- },
120
+ }
131
121
  }), [contentValue]);
132
122
 
133
123
  // Note: handleContentChange removed - using updateContentRef directly in CodeMirror
@@ -143,9 +133,7 @@ const CodeEditorPaneComponent = ({
143
133
  if (typeof tagData === 'string') {
144
134
  tagText = tagData;
145
135
  } else if (tagData) {
146
- const {
147
- text, name, label, value,
148
- } = tagData;
136
+ const { text, name, label, value } = tagData;
149
137
  tagText = text || name || label || value;
150
138
  if (!tagText) {
151
139
  console.warn('Invalid tag data:', tagData);
@@ -159,59 +147,49 @@ const CodeEditorPaneComponent = ({
159
147
  // For unified HTML editor, insert as template variable
160
148
  const formattedTag = `{{${tagText}}}`;
161
149
 
162
- // Insert the tag at cursor position directly
150
+ // Insert the tag at cursor position
163
151
  view.dispatch({
164
152
  changes: { from: pos, insert: formattedTag },
165
- selection: { anchor: pos + formattedTag.length },
153
+ selection: { anchor: pos + formattedTag.length }
166
154
  });
167
155
 
168
156
  // Focus back to editor
169
157
  view.focus();
170
158
 
171
- // Note: We don't call onLabelInsert here because:
172
- // 1. The tag is already inserted directly into the editor
173
- // 2. onLabelInsert (handleLabelInsert from HTMLEditor) would try to insert again
174
- // 3. This causes "Editor method not available" error
175
- // The direct insertion via view.dispatch is sufficient
159
+ // Call the parent's handleLabelInsert if available
160
+ if (onLabelInsert) {
161
+ onLabelInsert(formattedTag, pos);
162
+ }
176
163
  }
177
164
  };
178
165
 
179
- // Handle tag context change - delegate to parent component
180
- // Tags are fetched in parent components (EmailHTMLEditor, INAPP, etc.)
181
- // This component just passes the context change event up
182
- const handleTagContextChange = useCallback((data) => {
183
- if (onTagContextChange) {
184
- // Parent component handles tag fetching and updates
185
- onTagContextChange(data);
186
- }
187
- // No fallback - tags must be managed by parent component
188
- }, [onTagContextChange]);
189
-
190
166
  // Initialize CodeMirror effect
191
167
  useEffect(() => {
192
168
  if (editorRef.current && !viewRef.current) {
193
- // Add additional extensions for line numbers, active line, and update listener
194
- const extensions = [
195
- lineNumbers(),
196
- highlightActiveLine(),
197
- // html(), // 1. HTML language support - TEMPORARILY DISABLED due to version conflict
198
- // syntaxHighlighting(comprehensiveVSCodeTheme), // 2. Syntax highlighting - TEMPORARILY DISABLED
199
- // cleanEditorTheme, // 3. Theme - TEMPORARILY DISABLED
200
- EditorView.updateListener.of((update) => {
201
- if (update.docChanged) {
202
- updateContentRef.current(update.state.doc.toString());
203
- }
204
- }),
205
- ];
169
+ // Use the comprehensive extensions from properSyntaxHighlighting.js
170
+ // This includes: html(), syntaxHighlighting(comprehensiveVSCodeTheme), cleanEditorTheme
171
+ const robustExtensions = createRobustExtensions();
172
+
173
+ // Add additional extensions for line numbers, active line, and update listener
174
+ const extensions = [
175
+ lineNumbers(),
176
+ highlightActiveLine(),
177
+ ...robustExtensions, // Spread the robust extensions (html, syntax highlighting, theme)
178
+ EditorView.updateListener.of((update) => {
179
+ if (update.docChanged) {
180
+ updateContentRef.current(update.state.doc.toString());
181
+ }
182
+ })
183
+ ];
206
184
 
207
185
  const state = EditorState.create({
208
186
  doc: contentValue || '',
209
- extensions,
187
+ extensions
210
188
  });
211
189
 
212
190
  viewRef.current = new EditorView({
213
191
  state,
214
- parent: editorRef.current,
192
+ parent: editorRef.current
215
193
  });
216
194
  }
217
195
 
@@ -237,43 +215,100 @@ const CodeEditorPaneComponent = ({
237
215
  changes: {
238
216
  from: 0,
239
217
  to: length,
240
- insert: contentValue || '',
241
- },
218
+ insert: contentValue || ''
219
+ }
242
220
  });
243
221
  }
244
222
  }, [contentValue]);
245
223
 
246
- return (
247
- <CapRow className={`code-editor-pane ${className}`}>
248
- {/* Unified Code Editor with Floating Add Label Button */}
249
- <CapRow className="code-editor-pane__content">
250
- <div className="codemirror-wrapper">
251
- <div ref={editorRef} className="codemirror-editor" />
252
- {/* Floating Add Label Button */}
253
- <CapRow className="code-editor-pane__actions">
254
- <TagList
255
- key="html-editor-taglist"
256
- label={intl.formatMessage(messages.addLabel)}
257
- onTagSelect={handleTagSelect}
258
- onContextChange={handleTagContextChange}
259
- className="tag-list-trigger"
260
- tags={tags}
261
- injectedTags={injectedTags}
262
- moduleFilterEnabled={moduleFilterEnabled}
263
- userLocale={userLocale}
264
- channel={channel}
265
- disabled={readOnly}
266
- location={location}
267
- selectedOfferDetails={selectedOfferDetails}
268
- eventContextTags={eventContextTags}
269
- popoverPlacement="rightTop"
270
- />
271
- </CapRow>
272
- </div>
273
- </CapRow>
224
+ return (
225
+ <CapRow className={`code-editor-pane ${className}`}>
226
+ {/* Unified Code Editor with Floating Add Label Button */}
227
+ <CapRow className="code-editor-pane__content">
228
+ <div className="codemirror-wrapper">
229
+ <div ref={editorRef} className="codemirror-editor" />
230
+ {/* Floating Add Label Button */}
231
+ <CapRow className="code-editor-pane__actions">
232
+ <TagList
233
+ key="html-editor-taglist"
234
+ label={intl.formatMessage(messages.addLabel)}
235
+ onTagSelect={handleTagSelect}
236
+ onContextChange={(context) => {
237
+ }}
238
+ className="tag-list-trigger"
239
+ tags={[]} // Empty initially - TagList will fetch from API
240
+ injectedTags={{
241
+ // Add common HTML/Email specific tags as fallback
242
+ 'Customer Info': {
243
+ name: 'Customer Info',
244
+ desc: 'Customer information tags',
245
+ resolved: true,
246
+ 'tag-header': true,
247
+ subtags: {
248
+ 'customer.firstName': {
249
+ name: 'First Name',
250
+ desc: 'Customer first name',
251
+ resolved: true
252
+ },
253
+ 'customer.lastName': {
254
+ name: 'Last Name',
255
+ desc: 'Customer last name',
256
+ resolved: true
257
+ },
258
+ 'customer.email': {
259
+ name: 'Email',
260
+ desc: 'Customer email address',
261
+ resolved: true
262
+ },
263
+ 'customer.phone': {
264
+ name: 'Phone',
265
+ desc: 'Customer phone number',
266
+ resolved: true
267
+ }
268
+ }
269
+ },
270
+ 'Common Tags': {
271
+ name: 'Common Tags',
272
+ desc: 'Commonly used template tags',
273
+ resolved: true,
274
+ 'tag-header': true,
275
+ subtags: {
276
+ 'organization.name': {
277
+ name: 'Organization Name',
278
+ desc: 'Organization name',
279
+ resolved: true
280
+ },
281
+ 'currentDate': {
282
+ name: 'Current Date',
283
+ desc: 'Current date',
284
+ resolved: true
285
+ },
286
+ 'unsubscribeLink': {
287
+ name: 'Unsubscribe Link',
288
+ desc: 'Unsubscribe link',
289
+ resolved: true
290
+ }
291
+ }
292
+ }
293
+ }}
294
+ moduleFilterEnabled={true}
295
+ userLocale="en"
296
+ channel="email"
297
+ disabled={readOnly}
298
+ location={{
299
+ query: {
300
+ type: 'html-editor' // Identify the context
301
+ }
302
+ }}
303
+ selectedOfferDetails={[]}
304
+ eventContextTags={[]}
305
+ />
306
+ </CapRow>
307
+ </div>
308
+ </CapRow>
274
309
 
275
- </CapRow>
276
- );
310
+ </CapRow>
311
+ );
277
312
  };
278
313
 
279
314
  // Create the forwardRef wrapper
@@ -288,18 +323,9 @@ CodeEditorPane.propTypes = {
288
323
  readOnly: PropTypes.bool,
289
324
  className: PropTypes.string,
290
325
  isFullscreenMode: PropTypes.bool,
291
- onLabelInsert: PropTypes.func,
292
- // Tag-related props - tags are fetched and managed by parent component
293
- tags: PropTypes.array,
294
- injectedTags: PropTypes.object,
295
- location: PropTypes.object,
296
- eventContextTags: PropTypes.array,
297
- selectedOfferDetails: PropTypes.array,
298
- channel: PropTypes.string,
299
- userLocale: PropTypes.string,
300
- moduleFilterEnabled: PropTypes.bool,
301
- onTagContextChange: PropTypes.func, // Required - parent must handle tag fetching
326
+ onLabelInsert: PropTypes.func
302
327
  };
303
328
 
304
329
  // Export with injectIntl - ref forwarding is handled by forwardRef wrapper
305
330
  export default injectIntl(CodeEditorPane);
331
+
@@ -9,7 +9,7 @@
9
9
  .html-editor .device-toggle {
10
10
  display: flex;
11
11
  align-items: center;
12
- margin-left: 2.5rem;
12
+ gap: 1rem;
13
13
  padding: 0;
14
14
  background-color: $CAP_G10;
15
15
  border-radius: 0.25rem 0.25rem 0 0;
@@ -220,7 +220,6 @@
220
220
 
221
221
  // Integration with editor toolbar
222
222
  .html-editor.html-editor--inapp {
223
- margin-top: 4%;
224
223
  .editor-toolbar {
225
224
  padding: 0 1rem 0 0; // Remove left padding to align with device toggle
226
225
  background-color: $CAP_G10;
@@ -32,7 +32,7 @@ const DeviceToggle = ({
32
32
  onDeviceChange,
33
33
  keepContentSame = false,
34
34
  onKeepContentSameChange,
35
- className = '',
35
+ className = ''
36
36
  }) => {
37
37
  const handleDeviceClick = (device) => {
38
38
  if (onDeviceChange && device !== activeDevice) {
@@ -97,7 +97,7 @@ DeviceToggle.propTypes = {
97
97
  onDeviceChange: PropTypes.func,
98
98
  keepContentSame: PropTypes.bool,
99
99
  onKeepContentSameChange: PropTypes.func,
100
- className: PropTypes.string,
100
+ className: PropTypes.string
101
101
  };
102
102
 
103
103
  DeviceToggle.defaultProps = {
@@ -105,7 +105,7 @@ DeviceToggle.defaultProps = {
105
105
  onDeviceChange: null,
106
106
  keepContentSame: false,
107
107
  onKeepContentSameChange: null,
108
- className: '',
108
+ className: ''
109
109
  };
110
110
 
111
111
  export default injectIntl(DeviceToggle);
@@ -49,7 +49,6 @@ body .ant-modal-mask+.ant-modal-wrap .ant-modal.html-editor-fullscreen-modal .an
49
49
  padding: 0;
50
50
  min-height: 3.25rem;
51
51
  height: 3.25rem;
52
- position: relative;
53
52
 
54
53
  &__right {
55
54
  margin-left: auto;