@capillarytech/creatives-library 8.0.159-alpha.1 → 8.0.160

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "8.0.159-alpha.1",
4
+ "version": "8.0.160",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -43,7 +43,7 @@ const SendTestMessage = ({
43
43
  multiple
44
44
  placeholder={formatMessage(messages.testCustomersPlaceholder)}
45
45
  />
46
- <CapButton onClick={handleSendTestMessage} disabled={isEmpty(selectedTestEntities) || isEmpty(formData['template-subject']) || isSendingTestMessage}>
46
+ <CapButton onClick={handleSendTestMessage} disabled={isEmpty(selectedTestEntities) || (isEmpty(formData['template-subject']) && isEmpty(formData[0]?.['template-subject'])) || isSendingTestMessage}>
47
47
  <FormattedMessage {...messages.sendTestButton} />
48
48
  </CapButton>
49
49
  </CapRow>),
@@ -86,7 +86,20 @@ const TestAndPreviewSlidebox = (props) => {
86
86
  const [showJSON, setShowJSON] = useState(false);
87
87
  const [tagsExtracted, setTagsExtracted] = useState(false);
88
88
  const [previewDevice, setPreviewDevice] = useState('desktop');
89
- const [previewDataHtml, setPreviewDataHtml] = useState(previewData || '');
89
+ const [previewDataHtml, setPreviewDataHtml] = useState(() => {
90
+ // Initialize with current content if available
91
+ const currentTabData = formData[currentTab - 1];
92
+ const activeTab = currentTabData?.activeTab;
93
+ const templateContent = currentTabData?.[activeTab]?.['template-content'];
94
+
95
+ if (templateContent) {
96
+ return {
97
+ resolvedBody: templateContent,
98
+ resolvedTitle: formData['template-subject'] || ''
99
+ };
100
+ }
101
+ return previewData || '';
102
+ });
90
103
  const [selectedTestEntities, setSelectedTestEntities] = useState([]);
91
104
  const [beeContent, setBeeContent] = useState(''); // Track BEE editor content separately
92
105
  const previousBeeContentRef = useRef(''); // Track previous BEE content to prevent unnecessary updates
@@ -101,18 +114,15 @@ const TestAndPreviewSlidebox = (props) => {
101
114
  const activeTab = currentTabData?.activeTab;
102
115
  const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
103
116
 
104
- console.log('🔍 getCurrentContent computed:', {
105
- beeInstance: !!beeInstance,
106
- isDragDrop,
107
- beeContent: beeContent || 'EMPTY',
108
- content: content || 'EMPTY',
109
- templateContent: currentTabData?.[activeTab]?.[`template-content`] || 'EMPTY',
110
- result: isDragDrop && beeContent ? beeContent : content
111
- });
112
-
113
117
  if (isDragDrop && beeContent) {
114
118
  return beeContent; // Use BEE content if available
115
119
  }
120
+
121
+ // For CKEditor in edit mode, get content from formData
122
+ if (!isDragDrop && currentTabData?.[activeTab]?.['template-content']) {
123
+ return currentTabData[activeTab]['template-content'];
124
+ }
125
+
116
126
  return content; // Fall back to content prop
117
127
  }, [formData, currentTab, beeContent, content, beeInstance]);
118
128
 
@@ -149,73 +159,60 @@ const TestAndPreviewSlidebox = (props) => {
149
159
  const activeTab = currentTabData?.activeTab;
150
160
  const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
151
161
 
152
- console.log('🔍 Tag extraction debug:', {
153
- show,
154
- beeInstance: !!beeInstance,
155
- isDragDrop,
156
- currentTab,
157
- activeTab,
158
- currentTabData: !!currentTabData,
159
- templateContent: currentTabData?.[activeTab]?.[`template-content`] || 'EMPTY',
160
- contentProp: content || 'EMPTY',
161
- getCurrentContent: getCurrentContent || 'EMPTY',
162
- beeContentState: beeContent || 'EMPTY'
163
- });
164
-
165
162
  if (beeInstance && isDragDrop) {
166
- console.log('🔍 Using BEE editor path for tag extraction');
167
-
168
- // For BEE editor, trigger save first to ensure latest content is captured
169
- console.log('🔍 Triggering BEE save to capture latest content...');
163
+ // Store original save handler
164
+ const originalOnSave = beeInstance.onSave;
165
+
166
+ // Create temporary save handler
167
+ const tempSaveHandler = (jsonFile, htmlFile) => {
168
+ // Call original handler first to ensure editor state is saved
169
+ if (originalOnSave) {
170
+ originalOnSave(jsonFile, htmlFile);
171
+ }
172
+
173
+ if (htmlFile) {
174
+ // Update our states
175
+ previousBeeContentRef.current = htmlFile;
176
+ setBeeContent(htmlFile);
177
+ setPreviewDataHtml({
178
+ resolvedBody: htmlFile,
179
+ resolvedTitle: formData['template-subject'] || ''
180
+ });
181
+
182
+ // Extract tags with latest content
183
+ const payloadContent = convert(htmlFile, GLOBAL_CONVERT_OPTIONS);
184
+ actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
185
+ }
186
+
187
+ // Restore original handler
188
+ beeInstance.onSave = originalOnSave;
189
+ };
190
+
191
+ // Set temporary handler and trigger save
192
+ beeInstance.onSave = tempSaveHandler;
170
193
  beeInstance.save();
171
-
172
- // Get content from formData (which should have the latest BEE content)
173
- const currentTabData = formData[currentTab - 1];
174
- const activeTab = currentTabData?.activeTab;
175
- const templateContent = currentTabData?.[activeTab]?.[`template-content`];
176
-
177
- console.log('🔍 BEE content sources:', {
178
- templateContent: templateContent || 'EMPTY',
179
- beeContent: beeContent || 'EMPTY',
180
- content: content || 'EMPTY'
181
- });
182
-
183
- // Use template content from formData if available, otherwise fall back to other sources
184
- const beeContentToUse = templateContent || beeContent || content;
185
-
186
- if (beeContentToUse && beeContentToUse.trim() !== '') {
187
- console.log('🔍 Using BEE content for tag extraction:', beeContentToUse.substring(0, 100) + '...');
188
- const payloadContent = convert(beeContentToUse, GLOBAL_CONVERT_OPTIONS);
189
- console.log('🔍 Converted BEE content for tag extraction:', payloadContent || 'EMPTY');
194
+ } else {
195
+ // For CKEditor, get content from formData
196
+ const templateContent = currentTabData?.[activeTab]?.['template-content'];
197
+
198
+ if (templateContent) {
199
+ // Update preview with initial content
200
+ setPreviewDataHtml({
201
+ resolvedBody: templateContent,
202
+ resolvedTitle: formData['template-subject'] || ''
203
+ });
204
+
205
+ // Extract tags with initial content
206
+ const payloadContent = convert(templateContent, GLOBAL_CONVERT_OPTIONS);
190
207
  actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
191
208
  } else {
192
- console.log('🔍 No BEE content available in any source');
193
- // If no content available, wait a bit for the save to complete and try again
194
- setTimeout(() => {
195
- const updatedTemplateContent = formData[currentTab - 1]?.[activeTab]?.[`template-content`];
196
- if (updatedTemplateContent && updatedTemplateContent.trim() !== '') {
197
- console.log('🔍 BEE content now available after save:', updatedTemplateContent.substring(0, 100) + '...');
198
- const payloadContent = convert(updatedTemplateContent, GLOBAL_CONVERT_OPTIONS);
199
- actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
200
- } else {
201
- console.log('🔍 Still no BEE content, using empty content for tag extraction');
202
- actions.extractTagsRequested(formData['template-subject'] || '', '');
203
- }
204
- }, 1000); // Wait 1 second for save to complete
209
+ // Fallback to content prop if no template content
210
+ const payloadContent = convert(
211
+ getCurrentContent,
212
+ GLOBAL_CONVERT_OPTIONS
213
+ );
214
+ actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
205
215
  }
206
- } else {
207
- console.log('🔍 Using non-BEE editor path for tag extraction');
208
- console.log('🔍 Non-BEE content sources:', {
209
- getCurrentContent: getCurrentContent || 'EMPTY',
210
- contentProp: content || 'EMPTY'
211
- });
212
- // For non-BEE editor, use content prop directly
213
- const payloadContent = convert(
214
- getCurrentContent,
215
- GLOBAL_CONVERT_OPTIONS
216
- );
217
- console.log('🔍 Converted content for tag extraction:', payloadContent || 'EMPTY');
218
- actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
219
216
  }
220
217
 
221
218
  actions.fetchTestCustomersRequested();
@@ -223,22 +220,39 @@ const TestAndPreviewSlidebox = (props) => {
223
220
  }
224
221
  }, [show, beeInstance, currentTab]);
225
222
 
226
- // Single useEffect to handle BEE content updates without causing loops
223
+ // Effect to handle content updates for both editors
227
224
  useEffect(() => {
228
225
  const currentTabData = formData[currentTab - 1];
229
226
  const activeTab = currentTabData?.activeTab;
230
227
  const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
228
+ const templateContent = currentTabData?.[activeTab]?.['template-content'];
231
229
 
232
- if (isDragDrop && currentTabData?.[activeTab]?.[`template-content`]) {
233
- const newBeeContent = currentTabData[activeTab][`template-content`];
234
- if (newBeeContent && newBeeContent.trim() !== '' && newBeeContent !== previousBeeContentRef.current) {
235
- // Only update if content actually changed to prevent loops
236
- previousBeeContentRef.current = newBeeContent;
237
- setBeeContent(newBeeContent);
230
+ if (templateContent && templateContent.trim() !== '') {
231
+ if (isDragDrop) {
232
+ // For Bee editor, update both preview and extract tags
233
+ if (templateContent !== previousBeeContentRef.current) {
234
+
235
+ previousBeeContentRef.current = templateContent;
236
+ setBeeContent(templateContent);
237
+ setPreviewDataHtml({
238
+ resolvedBody: templateContent,
239
+ resolvedTitle: formData['template-subject'] || ''
240
+ });
241
+
242
+ // Extract tags with latest content
243
+ const payloadContent = convert(templateContent, GLOBAL_CONVERT_OPTIONS);
244
+ actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
245
+ }
246
+ } else {
247
+ // For CKEditor, always update preview and extract tags with latest content
238
248
  setPreviewDataHtml({
239
- resolvedBody: newBeeContent,
249
+ resolvedBody: templateContent,
240
250
  resolvedTitle: formData['template-subject'] || ''
241
251
  });
252
+
253
+ // Extract tags with latest content
254
+ const payloadContent = convert(templateContent, GLOBAL_CONVERT_OPTIONS);
255
+ actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
242
256
  }
243
257
  }
244
258
  }, [formData, currentTab]);
@@ -424,43 +438,65 @@ const TestAndPreviewSlidebox = (props) => {
424
438
 
425
439
  // Handle update preview
426
440
  const handleUpdatePreview = async () => {
427
- // For BEE editor, ensure content is saved first
428
441
  const currentTabData = formData[currentTab - 1];
429
442
  const activeTab = currentTabData?.activeTab;
443
+ const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
430
444
 
431
- // Get latest content from BEE editor if needed
432
- if (beeInstance && currentTabData?.[activeTab]?.is_drag_drop) {
445
+ // For BEE editor, ensure content is saved first
446
+ if (isDragDrop && beeInstance) {
433
447
  // Trigger save to ensure latest content
434
448
  beeInstance.save();
435
449
 
436
- // Wait a bit for save to complete
450
+ // Wait a bit for save to complete and formData to update
437
451
  await new Promise((resolve) => setTimeout(resolve, 500));
438
452
 
439
- // Get latest content from BEE editor
440
- beeInstance.getContent((jsonFile, htmlFile) => {
441
- const payload = {
442
- channel: EMAIL,
443
- messageTitle: formData['template-subject'],
444
- messageBody: htmlFile || getCurrentContent,
445
- resolvedTags: customValues,
446
- userId: selectedCustomer?.customerId,
447
- };
453
+ // Get latest content from formData
454
+ const updatedContent = formData[currentTab - 1]?.[activeTab]?.['template-content'];
455
+ const payload = {
456
+ channel: EMAIL,
457
+ messageTitle: formData['template-subject'],
458
+ messageBody: updatedContent || getCurrentContent,
459
+ resolvedTags: customValues,
460
+ userId: selectedCustomer?.customerId,
461
+ };
448
462
 
449
- actions.updatePreviewRequested(payload);
450
- });
463
+ actions.updatePreviewRequested(payload);
451
464
  return;
452
465
  }
453
466
 
454
- // Use current content for non-BEE editor
455
- const payload = {
456
- channel: EMAIL,
457
- messageTitle: formData['template-subject'],
458
- messageBody: getCurrentContent,
459
- resolvedTags: customValues,
460
- userId: selectedCustomer?.customerId,
461
- };
467
+ // For CKEditor, get latest content directly from formData
468
+ const templateContent = currentTabData?.[activeTab]?.['template-content'];
469
+ if (templateContent) {
470
+ // Update preview with latest content
471
+ setPreviewDataHtml({
472
+ resolvedBody: templateContent,
473
+ resolvedTitle: formData['template-subject'] || ''
474
+ });
475
+
476
+ // Extract tags with latest content
477
+ const payloadContent = convert(templateContent, GLOBAL_CONVERT_OPTIONS);
478
+ actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
462
479
 
463
- actions.updatePreviewRequested(payload);
480
+ // Update preview with latest content
481
+ const payload = {
482
+ channel: EMAIL,
483
+ messageTitle: formData['template-subject'],
484
+ messageBody: templateContent,
485
+ resolvedTags: customValues,
486
+ userId: selectedCustomer?.customerId,
487
+ };
488
+ actions.updatePreviewRequested(payload);
489
+ } else {
490
+ // Fallback to getCurrentContent if no template content
491
+ const payload = {
492
+ channel: EMAIL,
493
+ messageTitle: formData['template-subject'],
494
+ messageBody: getCurrentContent,
495
+ resolvedTags: customValues,
496
+ userId: selectedCustomer?.customerId,
497
+ };
498
+ actions.updatePreviewRequested(payload);
499
+ }
464
500
  };
465
501
 
466
502
  // Handle extract tags button click
@@ -165,7 +165,6 @@ export function SlideBoxContent(props) {
165
165
  handleCloseTestAndPreview,
166
166
  isTestAndPreviewMode,
167
167
  } = props;
168
- console.log('📥 SlideBoxContent received isTestAndPreviewMode:', isTestAndPreviewMode);
169
168
  const type = (messageDetails.type || '').toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
170
169
  const query = { type: !isFullMode && 'embedded', module: isFullMode ? 'default' : 'library', isEditFromCampaigns: (templateData || {}).isEditFromCampaigns};
171
170
  const creativesLocationProps = {
@@ -664,7 +663,6 @@ export function SlideBoxContent(props) {
664
663
  handleTestAndPreview={handleTestAndPreview}
665
664
  handleCloseTestAndPreview={handleCloseTestAndPreview}
666
665
  isTestAndPreviewMode={(() => {
667
- console.log('📤 SlideBoxContent passing isTestAndPreviewMode:', isTestAndPreviewMode);
668
666
  return isTestAndPreviewMode;
669
667
  })()}
670
668
  />
@@ -1256,11 +1256,8 @@ export class Creatives extends React.Component {
1256
1256
  }
1257
1257
 
1258
1258
 
1259
-
1260
1259
  // NEW: Handler for Test and Preview button
1261
1260
  handleTestAndPreview = () => {
1262
- console.log('🔓 CreativesContainer handleTestAndPreview called');
1263
- console.log('🔓 Setting isTestAndPreviewMode to true');
1264
1261
  this.setState({
1265
1262
  showTestAndPreviewSlidebox: true,
1266
1263
  isTestAndPreviewMode: true, // Set flag to prevent validation
@@ -1269,8 +1266,6 @@ export class Creatives extends React.Component {
1269
1266
 
1270
1267
  // NEW: Handler to close Test and Preview slidebox
1271
1268
  handleCloseTestAndPreview = () => {
1272
- console.log('🔒 CreativesContainer handleCloseTestAndPreview called');
1273
- console.log('🔒 Setting isTestAndPreviewMode to false');
1274
1269
  this.setState({
1275
1270
  showTestAndPreviewSlidebox: false,
1276
1271
  isTestAndPreviewMode: false, // Reset flag when closing
@@ -1617,10 +1612,7 @@ export class Creatives extends React.Component {
1617
1612
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
1618
1613
  handleTestAndPreview={this.handleTestAndPreview}
1619
1614
  handleCloseTestAndPreview={this.handleCloseTestAndPreview}
1620
- isTestAndPreviewMode={(() => {
1621
- console.log('📤 CreativesContainer passing isTestAndPreviewMode:', this.state.isTestAndPreviewMode);
1622
- return this.state.isTestAndPreviewMode;
1623
- })()}
1615
+ isTestAndPreviewMode={(() => this.state.isTestAndPreviewMode)()}
1624
1616
  />
1625
1617
  )}
1626
1618
  footer={this.shouldShowFooter() ? (