@capillarytech/creatives-library 8.0.236-alpha.3 → 8.0.236-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/utils/tests/commonUtil.test.js +224 -0
- package/v2Components/HtmlEditor/_htmlEditor.scss +2 -0
- package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +0 -1
- package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +82 -84
- package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +1 -1
- package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +1 -0
- package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +203 -0
- package/v2Components/HtmlEditor/hooks/useInAppContent.js +5 -4
- package/v2Components/TemplatePreview/_templatePreview.scss +2 -1
- package/v2Containers/BeePopupEditor/index.js +5 -4
- package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +2 -67
- package/v2Containers/InApp/constants.js +1 -0
- package/v2Containers/InApp/index.js +174 -64
- package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +4 -4
- package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +1 -1
- package/v2Containers/InappAdvance/index.js +36 -10
- package/v2Containers/InappAdvance/tests/index.test.js +32 -32
- package/v2Containers/Templates/_templates.scss +11 -0
package/package.json
CHANGED
|
@@ -1376,4 +1376,228 @@ describe("validateCarouselCards", () => {
|
|
|
1376
1376
|
expect(result.isValid).toBe(true);
|
|
1377
1377
|
});
|
|
1378
1378
|
});
|
|
1379
|
+
|
|
1380
|
+
describe('extractContent BEE Editor Logic (L404-L412)', () => {
|
|
1381
|
+
it('extracts content from beeHtml as string', () => {
|
|
1382
|
+
const platformData = {
|
|
1383
|
+
title: 'Test Title',
|
|
1384
|
+
isBEEeditor: true,
|
|
1385
|
+
beeHtml: '<p>BEE HTML Content</p>',
|
|
1386
|
+
ctas: [
|
|
1387
|
+
{ text: 'Click Here', actionLink: 'https://example.com' },
|
|
1388
|
+
],
|
|
1389
|
+
};
|
|
1390
|
+
|
|
1391
|
+
const result = extractContent(platformData);
|
|
1392
|
+
|
|
1393
|
+
expect(result).toContain('Test Title');
|
|
1394
|
+
expect(result).toContain('<p>BEE HTML Content</p>');
|
|
1395
|
+
expect(result).toContain('Click Here');
|
|
1396
|
+
});
|
|
1397
|
+
|
|
1398
|
+
it('extracts content from beeHtml as object with value property', () => {
|
|
1399
|
+
const platformData = {
|
|
1400
|
+
title: 'Test Title',
|
|
1401
|
+
isBEEeditor: true,
|
|
1402
|
+
beeHtml: { value: '<p>BEE HTML from Object</p>' },
|
|
1403
|
+
ctas: [
|
|
1404
|
+
{ text: 'Button Text' },
|
|
1405
|
+
],
|
|
1406
|
+
};
|
|
1407
|
+
|
|
1408
|
+
const result = extractContent(platformData);
|
|
1409
|
+
|
|
1410
|
+
expect(result).toContain('Test Title');
|
|
1411
|
+
expect(result).toContain('<p>BEE HTML from Object</p>');
|
|
1412
|
+
expect(result).toContain('Button Text');
|
|
1413
|
+
});
|
|
1414
|
+
|
|
1415
|
+
it('handles beeHtml as object without value property', () => {
|
|
1416
|
+
const platformData = {
|
|
1417
|
+
title: 'Test Title',
|
|
1418
|
+
isBEEeditor: true,
|
|
1419
|
+
beeHtml: { someOtherProperty: 'data' },
|
|
1420
|
+
ctas: [],
|
|
1421
|
+
};
|
|
1422
|
+
|
|
1423
|
+
const result = extractContent(platformData);
|
|
1424
|
+
|
|
1425
|
+
// Should extract title and empty beeHtml (since value is undefined)
|
|
1426
|
+
expect(result).toContain('Test Title');
|
|
1427
|
+
expect(result).not.toContain('someOtherProperty');
|
|
1428
|
+
});
|
|
1429
|
+
|
|
1430
|
+
it('extracts ctas with text property', () => {
|
|
1431
|
+
const platformData = {
|
|
1432
|
+
title: 'Title',
|
|
1433
|
+
isBEEeditor: true,
|
|
1434
|
+
beeHtml: '<p>Content</p>',
|
|
1435
|
+
ctas: [
|
|
1436
|
+
{ text: 'CTA Text 1' },
|
|
1437
|
+
{ text: 'CTA Text 2' },
|
|
1438
|
+
],
|
|
1439
|
+
};
|
|
1440
|
+
|
|
1441
|
+
const result = extractContent(platformData);
|
|
1442
|
+
|
|
1443
|
+
expect(result).toContain('CTA Text 1');
|
|
1444
|
+
expect(result).toContain('CTA Text 2');
|
|
1445
|
+
});
|
|
1446
|
+
|
|
1447
|
+
it('extracts ctas with actionLink when text is missing', () => {
|
|
1448
|
+
const platformData = {
|
|
1449
|
+
title: 'Title',
|
|
1450
|
+
isBEEeditor: true,
|
|
1451
|
+
beeHtml: '<p>Content</p>',
|
|
1452
|
+
ctas: [
|
|
1453
|
+
{ actionLink: 'https://link1.com' },
|
|
1454
|
+
{ actionLink: 'https://link2.com' },
|
|
1455
|
+
],
|
|
1456
|
+
};
|
|
1457
|
+
|
|
1458
|
+
const result = extractContent(platformData);
|
|
1459
|
+
|
|
1460
|
+
expect(result).toContain('https://link1.com');
|
|
1461
|
+
expect(result).toContain('https://link2.com');
|
|
1462
|
+
});
|
|
1463
|
+
|
|
1464
|
+
it('filters out falsy values with filter(Boolean)', () => {
|
|
1465
|
+
const platformData = {
|
|
1466
|
+
title: '',
|
|
1467
|
+
isBEEeditor: true,
|
|
1468
|
+
beeHtml: null,
|
|
1469
|
+
ctas: [
|
|
1470
|
+
{ text: null, actionLink: null },
|
|
1471
|
+
{ text: 'Valid Text' },
|
|
1472
|
+
],
|
|
1473
|
+
};
|
|
1474
|
+
|
|
1475
|
+
const result = extractContent(platformData);
|
|
1476
|
+
|
|
1477
|
+
// Should only contain 'Valid Text' after filtering
|
|
1478
|
+
expect(result).toBe('Valid Text');
|
|
1479
|
+
});
|
|
1480
|
+
|
|
1481
|
+
it('handles empty ctas array', () => {
|
|
1482
|
+
const platformData = {
|
|
1483
|
+
title: 'Title Only',
|
|
1484
|
+
isBEEeditor: true,
|
|
1485
|
+
beeHtml: '<p>BEE Content</p>',
|
|
1486
|
+
ctas: [],
|
|
1487
|
+
};
|
|
1488
|
+
|
|
1489
|
+
const result = extractContent(platformData);
|
|
1490
|
+
|
|
1491
|
+
expect(result).toContain('Title Only');
|
|
1492
|
+
expect(result).toContain('<p>BEE Content</p>');
|
|
1493
|
+
});
|
|
1494
|
+
|
|
1495
|
+
it('handles undefined ctas', () => {
|
|
1496
|
+
const platformData = {
|
|
1497
|
+
title: 'Title',
|
|
1498
|
+
isBEEeditor: true,
|
|
1499
|
+
beeHtml: '<p>Content</p>',
|
|
1500
|
+
ctas: undefined,
|
|
1501
|
+
};
|
|
1502
|
+
|
|
1503
|
+
const result = extractContent(platformData);
|
|
1504
|
+
|
|
1505
|
+
expect(result).toContain('Title');
|
|
1506
|
+
expect(result).toContain('<p>Content</p>');
|
|
1507
|
+
});
|
|
1508
|
+
|
|
1509
|
+
it('joins all content with spaces', () => {
|
|
1510
|
+
const platformData = {
|
|
1511
|
+
title: 'Title',
|
|
1512
|
+
isBEEeditor: true,
|
|
1513
|
+
beeHtml: 'HTML',
|
|
1514
|
+
ctas: [
|
|
1515
|
+
{ text: 'CTA1' },
|
|
1516
|
+
{ text: 'CTA2' },
|
|
1517
|
+
],
|
|
1518
|
+
};
|
|
1519
|
+
|
|
1520
|
+
const result = extractContent(platformData);
|
|
1521
|
+
|
|
1522
|
+
expect(result).toBe('Title HTML CTA1 CTA2');
|
|
1523
|
+
});
|
|
1524
|
+
|
|
1525
|
+
it('falls back to regular content when not BEE editor', () => {
|
|
1526
|
+
const platformData = {
|
|
1527
|
+
title: 'Title',
|
|
1528
|
+
message: 'Message',
|
|
1529
|
+
isBEEeditor: false,
|
|
1530
|
+
beeHtml: '<p>Should be ignored</p>',
|
|
1531
|
+
ctas: [
|
|
1532
|
+
{ text: 'CTA' },
|
|
1533
|
+
],
|
|
1534
|
+
};
|
|
1535
|
+
|
|
1536
|
+
const result = extractContent(platformData);
|
|
1537
|
+
|
|
1538
|
+
expect(result).toContain('Title');
|
|
1539
|
+
expect(result).toContain('Message');
|
|
1540
|
+
expect(result).toContain('CTA');
|
|
1541
|
+
expect(result).not.toContain('<p>Should be ignored</p>');
|
|
1542
|
+
});
|
|
1543
|
+
|
|
1544
|
+
it('handles null beeHtml', () => {
|
|
1545
|
+
const platformData = {
|
|
1546
|
+
title: 'Title',
|
|
1547
|
+
isBEEeditor: true,
|
|
1548
|
+
beeHtml: null,
|
|
1549
|
+
ctas: [{ text: 'CTA' }],
|
|
1550
|
+
};
|
|
1551
|
+
|
|
1552
|
+
const result = extractContent(platformData);
|
|
1553
|
+
|
|
1554
|
+
expect(result).toContain('Title');
|
|
1555
|
+
expect(result).toContain('CTA');
|
|
1556
|
+
});
|
|
1557
|
+
|
|
1558
|
+
it('handles undefined beeHtml', () => {
|
|
1559
|
+
const platformData = {
|
|
1560
|
+
title: 'Title',
|
|
1561
|
+
isBEEeditor: true,
|
|
1562
|
+
beeHtml: undefined,
|
|
1563
|
+
ctas: [],
|
|
1564
|
+
};
|
|
1565
|
+
|
|
1566
|
+
const result = extractContent(platformData);
|
|
1567
|
+
|
|
1568
|
+
expect(result).toBe('Title');
|
|
1569
|
+
});
|
|
1570
|
+
|
|
1571
|
+
it('handles complex ctas with both text and actionLink', () => {
|
|
1572
|
+
const platformData = {
|
|
1573
|
+
title: 'Title',
|
|
1574
|
+
isBEEeditor: true,
|
|
1575
|
+
beeHtml: 'Content',
|
|
1576
|
+
ctas: [
|
|
1577
|
+
{ text: 'CTA Text', actionLink: 'https://example.com' },
|
|
1578
|
+
],
|
|
1579
|
+
};
|
|
1580
|
+
|
|
1581
|
+
const result = extractContent(platformData);
|
|
1582
|
+
|
|
1583
|
+
// Should prefer text over actionLink
|
|
1584
|
+
expect(result).toContain('CTA Text');
|
|
1585
|
+
expect(result).toContain('Title');
|
|
1586
|
+
expect(result).toContain('Content');
|
|
1587
|
+
});
|
|
1588
|
+
|
|
1589
|
+
it('handles empty string beeHtml', () => {
|
|
1590
|
+
const platformData = {
|
|
1591
|
+
title: 'Title',
|
|
1592
|
+
isBEEeditor: true,
|
|
1593
|
+
beeHtml: '',
|
|
1594
|
+
ctas: [{ text: 'CTA' }],
|
|
1595
|
+
};
|
|
1596
|
+
|
|
1597
|
+
const result = extractContent(platformData);
|
|
1598
|
+
|
|
1599
|
+
expect(result).toBe('Title CTA');
|
|
1600
|
+
});
|
|
1601
|
+
});
|
|
1379
1602
|
});
|
|
1603
|
+
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
padding: 0;
|
|
29
29
|
min-height: 3.25rem;
|
|
30
30
|
height: 3.25rem;
|
|
31
|
+
position: relative;
|
|
31
32
|
|
|
32
33
|
// Right-align toolbar actions
|
|
33
34
|
&__right {
|
|
@@ -128,6 +129,7 @@
|
|
|
128
129
|
padding: 0;
|
|
129
130
|
min-height: 3.25rem; // 52px = 3.25rem
|
|
130
131
|
height: 3.25rem;
|
|
132
|
+
position: relative;
|
|
131
133
|
|
|
132
134
|
// Right-align toolbar actions
|
|
133
135
|
&__right {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import React, {
|
|
12
|
-
forwardRef, useImperativeHandle, useRef, useEffect,
|
|
12
|
+
forwardRef, useImperativeHandle, useRef, useEffect, useCallback,
|
|
13
13
|
} from 'react';
|
|
14
14
|
import PropTypes from 'prop-types';
|
|
15
15
|
|
|
@@ -17,13 +17,11 @@ import PropTypes from 'prop-types';
|
|
|
17
17
|
import { EditorState } from '@codemirror/state';
|
|
18
18
|
import { EditorView, lineNumbers, highlightActiveLine } from '@codemirror/view';
|
|
19
19
|
|
|
20
|
-
// Import our comprehensive syntax highlighting solution
|
|
21
|
-
import { injectIntl, intlShape } from 'react-intl';
|
|
22
|
-
import CapRow from '@capillarytech/cap-ui-library/CapRow';
|
|
23
|
-
import { createRobustExtensions } from '../../utils/properSyntaxHighlighting';
|
|
24
20
|
|
|
21
|
+
import { injectIntl, intlShape } from 'react-intl';
|
|
25
22
|
|
|
26
23
|
// Messages
|
|
24
|
+
import CapRow from '@capillarytech/cap-ui-library/CapRow';
|
|
27
25
|
import messages from '../../messages';
|
|
28
26
|
|
|
29
27
|
// Cap UI Components
|
|
@@ -31,27 +29,34 @@ import messages from '../../messages';
|
|
|
31
29
|
// Components
|
|
32
30
|
import TagList from '../../../../v2Containers/TagList';
|
|
33
31
|
|
|
32
|
+
// Constants - removed unused imports since tag fetching is handled by parent
|
|
33
|
+
|
|
34
34
|
// Context
|
|
35
35
|
import { useEditorContext } from '../common/EditorContext';
|
|
36
36
|
|
|
37
37
|
// Styles
|
|
38
38
|
import './_codeEditorPane.scss';
|
|
39
39
|
|
|
40
|
+
// Define Theme and Highlighting inline to avoid "multiple instances of @codemirror/state" error
|
|
41
|
+
|
|
42
|
+
|
|
40
43
|
// Legacy CodeMirrorEditor removed - using enhanced implementation only
|
|
41
44
|
|
|
42
45
|
const CodeEditorPaneComponent = ({
|
|
43
46
|
intl,
|
|
44
47
|
readOnly = false,
|
|
45
48
|
className = '',
|
|
46
|
-
onLabelInsert,
|
|
47
49
|
forwardedRef,
|
|
48
|
-
//
|
|
50
|
+
// Tag-related props - tags are fetched and managed by parent component
|
|
49
51
|
tags = [],
|
|
50
52
|
injectedTags = {},
|
|
51
|
-
location
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
location,
|
|
54
|
+
eventContextTags = [],
|
|
55
|
+
selectedOfferDetails = [],
|
|
56
|
+
channel,
|
|
57
|
+
userLocale = 'en',
|
|
58
|
+
moduleFilterEnabled = true,
|
|
59
|
+
onTagContextChange,
|
|
55
60
|
}) => {
|
|
56
61
|
const { content } = useEditorContext();
|
|
57
62
|
const { content: contentValue, updateContent } = content;
|
|
@@ -129,77 +134,69 @@ const CodeEditorPaneComponent = ({
|
|
|
129
134
|
|
|
130
135
|
const handleTagSelect = (tagData) => {
|
|
131
136
|
// Get the unified editor
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
137
|
+
if (viewRef.current) {
|
|
138
|
+
const view = viewRef.current;
|
|
139
|
+
const { state: { selection: { main: { head: pos } } } } = view;
|
|
140
|
+
|
|
141
|
+
// Extract tag text from the tagData object using destructuring
|
|
142
|
+
let tagText = '';
|
|
143
|
+
if (typeof tagData === 'string') {
|
|
144
|
+
tagText = tagData;
|
|
145
|
+
} else if (tagData) {
|
|
146
|
+
const {
|
|
147
|
+
text, name, label, value,
|
|
148
|
+
} = tagData;
|
|
149
|
+
tagText = text || name || label || value;
|
|
150
|
+
if (!tagText) {
|
|
151
|
+
console.warn('Invalid tag data:', tagData);
|
|
152
|
+
return;
|
|
143
153
|
}
|
|
144
|
-
|
|
145
|
-
// Call onLabelInsert with null position to indicate editor not ready
|
|
146
|
-
onLabelInsert(formattedTag, null);
|
|
147
|
-
}
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const view = viewRef.current;
|
|
152
|
-
const { state: { selection: { main: { head: pos } } } } = view;
|
|
153
|
-
|
|
154
|
-
// Extract tag text from the tagData object using destructuring
|
|
155
|
-
let tagText = '';
|
|
156
|
-
if (typeof tagData === 'string') {
|
|
157
|
-
tagText = tagData;
|
|
158
|
-
} else if (tagData) {
|
|
159
|
-
const {
|
|
160
|
-
text, name, label, value,
|
|
161
|
-
} = tagData;
|
|
162
|
-
tagText = text || name || label || value;
|
|
163
|
-
if (!tagText) {
|
|
154
|
+
} else {
|
|
164
155
|
console.warn('Invalid tag data:', tagData);
|
|
165
156
|
return;
|
|
166
157
|
}
|
|
167
|
-
} else {
|
|
168
|
-
console.warn('Invalid tag data:', tagData);
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
158
|
|
|
172
|
-
|
|
173
|
-
|
|
159
|
+
// For unified HTML editor, insert as template variable
|
|
160
|
+
const formattedTag = `{{${tagText}}}`;
|
|
174
161
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
162
|
+
// Insert the tag at cursor position directly
|
|
163
|
+
view.dispatch({
|
|
164
|
+
changes: { from: pos, insert: formattedTag },
|
|
165
|
+
selection: { anchor: pos + formattedTag.length },
|
|
166
|
+
});
|
|
180
167
|
|
|
181
|
-
|
|
182
|
-
|
|
168
|
+
// Focus back to editor
|
|
169
|
+
view.focus();
|
|
183
170
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
|
188
176
|
}
|
|
189
177
|
};
|
|
190
178
|
|
|
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
|
+
|
|
191
190
|
// Initialize CodeMirror effect
|
|
192
191
|
useEffect(() => {
|
|
193
192
|
if (editorRef.current && !viewRef.current) {
|
|
194
|
-
// Use the comprehensive extensions from properSyntaxHighlighting.js
|
|
195
|
-
// This includes: html(), syntaxHighlighting(comprehensiveVSCodeTheme), cleanEditorTheme
|
|
196
|
-
const robustExtensions = createRobustExtensions();
|
|
197
|
-
|
|
198
193
|
// Add additional extensions for line numbers, active line, and update listener
|
|
199
194
|
const extensions = [
|
|
200
195
|
lineNumbers(),
|
|
201
196
|
highlightActiveLine(),
|
|
202
|
-
|
|
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
|
|
203
200
|
EditorView.updateListener.of((update) => {
|
|
204
201
|
if (update.docChanged) {
|
|
205
202
|
updateContentRef.current(update.state.doc.toString());
|
|
@@ -257,28 +254,19 @@ const CodeEditorPaneComponent = ({
|
|
|
257
254
|
<TagList
|
|
258
255
|
key="html-editor-taglist"
|
|
259
256
|
label={intl.formatMessage(messages.addLabel)}
|
|
260
|
-
onTagSelect={
|
|
261
|
-
|
|
262
|
-
handleTagSelect(tag);
|
|
263
|
-
// Also call parent's onTagSelect callback if provided
|
|
264
|
-
if (onTagSelect) {
|
|
265
|
-
onTagSelect(tag);
|
|
266
|
-
}
|
|
267
|
-
}}
|
|
268
|
-
onContextChange={(context) => {
|
|
269
|
-
if (onContextChange) {
|
|
270
|
-
onContextChange(context);
|
|
271
|
-
}
|
|
272
|
-
}}
|
|
257
|
+
onTagSelect={handleTagSelect}
|
|
258
|
+
onContextChange={handleTagContextChange}
|
|
273
259
|
className="tag-list-trigger"
|
|
274
|
-
tags={tags}
|
|
275
|
-
injectedTags={injectedTags}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
location && location?.query && location?.query?.type !== "embedded"
|
|
280
|
-
}
|
|
260
|
+
tags={tags}
|
|
261
|
+
injectedTags={injectedTags}
|
|
262
|
+
moduleFilterEnabled={moduleFilterEnabled}
|
|
263
|
+
userLocale={userLocale}
|
|
264
|
+
channel={channel}
|
|
281
265
|
disabled={readOnly}
|
|
266
|
+
location={location}
|
|
267
|
+
selectedOfferDetails={selectedOfferDetails}
|
|
268
|
+
eventContextTags={eventContextTags}
|
|
269
|
+
popoverPlacement="rightTop"
|
|
282
270
|
/>
|
|
283
271
|
</CapRow>
|
|
284
272
|
</div>
|
|
@@ -301,6 +289,16 @@ CodeEditorPane.propTypes = {
|
|
|
301
289
|
className: PropTypes.string,
|
|
302
290
|
isFullscreenMode: PropTypes.bool,
|
|
303
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
|
|
304
302
|
};
|
|
305
303
|
|
|
306
304
|
// Export with injectIntl - ref forwarding is handled by forwardRef wrapper
|