PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 2.3.0
MxChat – AI Chatbot & Content Generation for WordPress v2.3.0
3.2.21 3.2.20 3.2.19 3.2.18 3.2.17 3.2.16 3.2.15 3.2.14 3.2.12 3.2.13 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 3.2.6 3.2.5 3.2.4 3.2.3 3.2.2 3.2.1 2.0.3 2.0.4 2.0.5 2.0.6 All 152 releases
mxchat-basic / js / content-selector.js

content-selector.js in MxChat – AI Chatbot & Content Generation for WordPress 2.3.0, at js/content-selector.js

732 lines 29.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 jQuery(document).ready(function($) {
2 // Modal elements
3 const $modal = $('#mxchat-kb-content-selector-modal');
4 const $openButton = $('#mxchat-open-content-selector');
5 const $closeButtons = $('.mxchat-kb-modal-close');
6 const $contentList = $('.mxchat-kb-content-list');
7 const $loading = $('.mxchat-kb-loading');
8 const $pagination = $('.mxchat-kb-pagination');
9 const $processButton = $('#mxchat-kb-process-selected');
10 const $selectAll = $('#mxchat-kb-select-all');
11 const $selectionCount = $('.mxchat-kb-selection-count');
12
13 // Filter elements
14 const $searchInput = $('#mxchat-kb-content-search');1
15 const $typeFilter = $('#mxchat-kb-content-type-filter');
16 const $statusFilter = $('#mxchat-kb-content-status-filter');
17 const $processedFilter = $('#mxchat-kb-processed-filter');
18
19 // Current state - using let for variables that change
20 let currentPage = 1;
21 let totalPages = 1;
22 let selectedItems = new Set();
23 let allItems = [];
24
25 // Open modal when WordPress import button is clicked
26 $openButton.on('click', function() {
27 $modal.show();
28 // Reset to first page when opening the modal
29 currentPage = 1;
30 loadContent();
31 });
32
33 // Close modal
34 $closeButtons.on('click', function() {
35 $modal.hide();
36 });
37 // Handle import option box clicks (for non-WordPress options)
38 $('.mxchat-import-box').on('click', function() {
39 const $box = $(this);
40 const option = $box.data('option');
41
42 // Skip if this is the WordPress option (it has its own handler)
43 if (option === 'wordpress') {
44 return;
45 }
46
47 // Update active state
48 $('.mxchat-import-box').removeClass('active');
49 $box.addClass('active');
50
51 // Hide all input areas
52 $('#mxchat-url-input-area, #mxchat-content-input-area').hide();
53
54 // Handle different import options
55 switch (option) {
56 case 'pdf':
57 case 'sitemap':
58 case 'url':
59 // Show URL input area with appropriate placeholder
60 $('#mxchat-url-input-area').show();
61 $('#sitemap_url').attr('placeholder', $box.data('placeholder'));
62 $('#import_type').val(option);
63
64 // Update the description text based on the import type
65 let descriptionText = '';
66 if (option === 'pdf') {
67 descriptionText = 'Import a PDF document by entering its URL above. PDFs are processed via cron job. If processing does not start, you can manually process batch 5 pages at a time.';
68 } else if (option === 'sitemap') {
69 descriptionText = 'Enter a content-specific sub-sitemap URL, not the sitemap index. Sitemaps are processed via cron job. If processing does not start, you can manually process batch 5 pages at a time.';
70 } else if (option === 'url') {
71 descriptionText = 'Import content from any webpage by entering its URL.';
72 }
73 $('#url-description-text').text(descriptionText);
74 break;
75
76 case 'content':
77 // Show content input area
78 $('#mxchat-content-input-area').show();
79 break;
80 }
81 });
82
83
84 // Load content via AJAX
85 function loadContent() {
86 $loading.show();
87 $contentList.find('.mxchat-kb-content-item').remove();
88
89 const data = {
90 action: 'mxchat_get_content_list',
91 nonce: mxchatSelector.nonce,
92 page: currentPage,
93 per_page: 50,
94 search: $searchInput.val(),
95 post_type: $typeFilter.val(),
96 post_status: $statusFilter.val(),
97 processed_filter: $processedFilter.val()
98 };
99
100 //console.log('Loading content for page', currentPage, 'with filters:', data);
101
102 $.ajax({
103 url: mxchatSelector.ajaxurl,
104 data: data,
105 method: 'GET',
106 dataType: 'json',
107 success: function(response) {
108 $loading.hide();
109
110 if (response.success && response.data.items && response.data.items.length > 0) {
111 // Store the items directly
112 let items = response.data.items;
113
114 if (items.length > 0) {
115 renderContentItems(items);
116 renderPagination(parseInt(response.data.current_page), parseInt(response.data.total_pages));
117
118 // Update state
119 allItems = items;
120 totalPages = parseInt(response.data.total_pages);
121 currentPage = parseInt(response.data.current_page);
122
123 // Update select all checkbox based on current selection
124 updateSelectAllState();
125 } else {
126 displayNoResults($processedFilter.val());
127 }
128 } else {
129 displayNoResults($processedFilter.val());
130 }
131 },
132 error: function(xhr, status, error) {
133 $loading.hide();
134 console.error('AJAX Error:', status, error);
135 $contentList.html('<div class="mxchat-kb-error">Error loading content. Please try again.</div>');
136 // Clear pagination on error
137 $pagination.empty();
138 }
139 });
140 }
141
142 // Helper function to display appropriate "no results" message
143 function displayNoResults(processedStatus) {
144 let message = 'No content found matching your criteria.';
145
146 if (processedStatus === 'processed') {
147 message = 'No content found in knowledge base.';
148 } else if (processedStatus === 'unprocessed') {
149 message = 'All content is already in knowledge base.';
150 }
151
152 $contentList.html('<div class="mxchat-kb-no-results">' + message + '</div>');
153 // Clear pagination when no results
154 $pagination.empty();
155 }
156
157 // Render content items
158 function renderContentItems(items) {
159 let html = '';
160
161 items.forEach(function(item) {
162 const isSelected = selectedItems.has(item.id);
163 const isProcessed = item.already_processed;
164
165 // Updated badge text
166 const badgeText = isProcessed ? 'In Knowledge Base' : 'Not In Knowledge Base';
167 const badgeClass = isProcessed ? 'mxchat-kb-processed-badge' : 'mxchat-kb-unprocessed-badge';
168
169
170 html += `
171 <div class="mxchat-kb-content-item ${isProcessed ? 'processed' : ''}" data-id="${item.id}">
172 <div class="mxchat-kb-content-checkbox">
173 <input type="checkbox" id="content-${item.id}" ${isSelected ? 'checked' : ''}>
174 </div>
175 <div class="mxchat-kb-content-details">
176 <div class="mxchat-kb-content-title">
177 <a href="${item.permalink}" target="_blank">${item.title}</a>
178 <span class="${badgeClass}">${badgeText}</span>
179 ${isProcessed ? '<span class="mxchat-kb-last-updated">Last updated: ' + item.processed_date + '</span>' : ''}
180 </div>
181 <div class="mxchat-kb-content-meta">
182 <span class="mxchat-kb-content-type">${item.type}</span>
183 <span class="mxchat-kb-content-date">${item.date}</span>
184 <span class="mxchat-kb-content-words">${item.word_count} words</span>
185 </div>
186 <div class="mxchat-kb-content-excerpt">${item.excerpt}</div>
187 </div>
188 </div>
189 `;
190 });
191
192 $contentList.html(html);
193
194 // Add event listeners for checkboxes using delegation for better performance
195 $contentList.off('change', 'input[type="checkbox"]').on('change', 'input[type="checkbox"]', function() {
196 const $checkbox = $(this);
197 const itemId = parseInt($checkbox.closest('.mxchat-kb-content-item').data('id'));
198
199 if ($checkbox.is(':checked')) {
200 selectedItems.add(itemId);
201 } else {
202 selectedItems.delete(itemId);
203 }
204
205 updateSelection();
206 });
207 }
208
209 // Render pagination - FIXED VERSION
210 function renderPagination(currentPage, totalPages) {
211 // Clear existing pagination first
212 $pagination.empty();
213
214 // Don't render pagination if only one page
215 if (totalPages <= 1) {
216 return;
217 }
218
219 let html = '<div class="mxchat-kb-pagination-links">';
220
221 // Previous button
222 if (currentPage > 1) {
223 html += '<a href="#" class="mxchat-kb-page-link prev" data-page="' + (currentPage - 1) + '">&laquo; Previous</a>';
224 }
225
226 // Page numbers
227 const startPage = Math.max(1, currentPage - 2);
228 const endPage = Math.min(totalPages, startPage + 4);
229
230 for (let i = startPage; i <= endPage; i++) {
231 if (i === currentPage) {
232 html += '<span class="mxchat-kb-page-current">' + i + '</span>';
233 } else {
234 html += '<a href="#" class="mxchat-kb-page-link" data-page="' + i + '">' + i + '</a>';
235 }
236 }
237
238 // Next button
239 if (currentPage < totalPages) {
240 html += '<a href="#" class="mxchat-kb-page-link next" data-page="' + (currentPage + 1) + '">Next &raquo;</a>';
241 }
242
243 html += '</div>';
244
245 $pagination.html(html);
246 }
247
248 // Handle pagination clicks directly on the document
249 $(document).on('click', '.mxchat-kb-page-link', function(e) {
250 e.preventDefault();
251 const newPage = parseInt($(this).data('page'));
252 //console.log('Pagination clicked: changing from page', currentPage, 'to', newPage);
253
254 // Only reload if the page actually changed
255 if (currentPage !== newPage) {
256 currentPage = newPage;
257 loadContent();
258 }
259 });
260
261 // Update selection counts and button state
262 function updateSelection() {
263 const selectedCount = selectedItems.size;
264 $selectionCount.text(selectedCount + ' ' + (selectedCount === 1 ? 'selected' : 'selected'));
265 $('.mxchat-kb-selected-count').text('(' + selectedCount + ')');
266
267 // Determine if any selected items are already processed
268 const hasProcessedItems = Array.from(selectedItems).some(id => {
269 const item = allItems.find(item => item.id === id);
270 return item && item.already_processed;
271 });
272
273 if (selectedCount > 0) {
274 $processButton.prop('disabled', false);
275
276 // Update button text based on selection
277 if (hasProcessedItems && selectedCount === 1) {
278 $processButton.text('Update Selected Content (1)').addClass('update-mode');
279 } else if (hasProcessedItems && selectedCount > 1) {
280 $processButton.text('Process/Update Selected (' + selectedCount + ')').addClass('mixed-mode');
281 } else {
282 $processButton.text('Process Selected Content (' + selectedCount + ')').removeClass('update-mode mixed-mode');
283 }
284 } else {
285 $processButton.prop('disabled', true);
286 $processButton.text('Process Selected Content').removeClass('update-mode mixed-mode');
287 $('.mxchat-kb-selected-count').text('(0)');
288 }
289
290 updateSelectAllState();
291 }
292
293 // Update "Select All" checkbox state
294 function updateSelectAllState() {
295 const availableItems = allItems.length;
296 const selectedAvailableItems = allItems.filter(item => selectedItems.has(item.id)).length;
297
298 if (availableItems === 0) {
299 $selectAll.prop('checked', false);
300 $selectAll.prop('disabled', true);
301 } else if (selectedAvailableItems === availableItems) {
302 $selectAll.prop('checked', true);
303 } else {
304 $selectAll.prop('checked', false);
305 }
306 }
307
308 // Handle Select All checkbox
309 $selectAll.on('change', function() {
310 const isChecked = $(this).is(':checked');
311
312 $contentList.find('.mxchat-kb-content-item input[type="checkbox"]').each(function() {
313 const $checkbox = $(this);
314 const $item = $checkbox.closest('.mxchat-kb-content-item');
315 const itemId = parseInt($item.data('id'));
316
317 $checkbox.prop('checked', isChecked);
318
319 if (isChecked) {
320 selectedItems.add(itemId);
321 } else {
322 selectedItems.delete(itemId);
323 }
324 });
325
326 updateSelection();
327 });
328
329 // Handle search input
330 let searchTimer;
331 $searchInput.on('keyup', function() {
332 clearTimeout(searchTimer);
333 searchTimer = setTimeout(function() {
334 currentPage = 1; // Reset to first page on new search
335 loadContent();
336 }, 500);
337 });
338
339 // Handle filter changes
340 $typeFilter.add($statusFilter).add($processedFilter).on('change', function() {
341 currentPage = 1; // Reset to first page on filter change
342 selectedItems.clear(); // Clear selection when filter changes
343 loadContent();
344 });
345
346 // Process selected content
347 $processButton.on('click', function() {
348 if (selectedItems.size === 0) {
349 return;
350 }
351
352 const $button = $(this);
353 $button.prop('disabled', true);
354
355 // Update button text based on mode
356 if ($button.hasClass('update-mode')) {
357 $button.text('Updating...');
358 } else if ($button.hasClass('mixed-mode')) {
359 $button.text('Processing/Updating...');
360 } else {
361 $button.text('Processing...');
362 }
363
364 // Convert selected items to array
365 const selectedPostIds = Array.from(selectedItems);
366 const totalToProcess = selectedPostIds.length;
367 let processed = 0;
368 let updated = 0;
369 let failed = 0;
370 const results = {
371 success: [],
372 updated: [],
373 failed: []
374 };
375
376 // Create a modal to show progress
377 const $progressModal = $('<div class="mxchat-kb-processing-overlay">' +
378 '<div class="mxchat-kb-processing-content">' +
379 '<h3>Processing Content</h3>' +
380 '<p class="mxchat-kb-processing-status">Processing 1 of ' + totalToProcess + '...</p>' +
381 '<div class="mxchat-kb-progress-bar"><div class="mxchat-kb-progress-fill" style="width: 0%"></div></div>' +
382 '<p class="mxchat-kb-current-item"></p>' +
383 '</div>' +
384 '</div>');
385
386 $('body').append($progressModal);
387
388 // Process posts one by one
389 function processNext(index) {
390 if (index >= selectedPostIds.length) {
391 // All done
392 finishProcessing();
393 return;
394 }
395
396 const postId = selectedPostIds[index];
397 const percent = Math.round((index / totalToProcess) * 100);
398 const item = allItems.find(item => item.id === postId);
399 const isUpdate = item && item.already_processed;
400
401 // Update progress UI
402 $progressModal.find('.mxchat-kb-processing-status')
403 .text((isUpdate ? 'Updating' : 'Processing') + ' ' + (index + 1) + ' of ' + totalToProcess + '...');
404 $progressModal.find('.mxchat-kb-progress-fill').css('width', percent + '%');
405
406 // Make AJAX request for this post
407 $.ajax({
408 url: mxchatSelector.ajaxurl,
409 method: 'POST',
410 data: {
411 action: 'mxchat_process_selected_content',
412 nonce: mxchatSelector.nonce,
413 post_ids: [postId],
414 is_update: isUpdate
415 },
416 dataType: 'json',
417 success: function(response) {
418 if (response.success) {
419 if (isUpdate) {
420 updated++;
421 results.updated.push({
422 id: postId,
423 title: response.data.title || ('ID: ' + postId)
424 });
425 } else {
426 processed++;
427 results.success.push({
428 id: postId,
429 title: response.data.title || ('ID: ' + postId)
430 });
431 }
432
433 $progressModal.find('.mxchat-kb-current-item')
434 .text('Successfully ' + (isUpdate ? 'updated' : 'processed') + ': ' + response.data.title);
435 } else {
436 failed++;
437 results.failed.push({
438 id: postId,
439 error: response.data || 'Unknown error'
440 });
441
442 $progressModal.find('.mxchat-kb-current-item')
443 .text('Failed to ' + (isUpdate ? 'update' : 'process') + ' ID: ' + postId);
444 }
445
446 // Process next post
447 setTimeout(function() {
448 processNext(index + 1);
449 }, 500); // Small delay between requests
450 },
451 error: function(xhr, status, error) {
452 failed++;
453 results.failed.push({
454 id: postId,
455 error: error || 'Server error'
456 });
457
458 $progressModal.find('.mxchat-kb-current-item')
459 .text('Error ' + (isUpdate ? 'updating' : 'processing') + ' ID: ' + postId);
460
461 // Process next post
462 setTimeout(function() {
463 processNext(index + 1);
464 }, 500);
465 }
466 });
467 }
468
469 // Function to finish processing and show results
470 function finishProcessing() {
471 // Remove progress modal
472 $progressModal.remove();
473
474 // Determine notification type based on results
475 let notificationClass = 'success';
476 if (failed > 0) {
477 notificationClass = processed > 0 || updated > 0 ? 'warning' : 'error';
478 }
479
480 // Create summary message
481 let resultHTML = '<div class="mxchat-kb-notification ' + notificationClass + '">' +
482 '<h4>';
483
484 if (processed > 0 && updated > 0) {
485 resultHTML += 'Processed ' + processed + ' new items and updated ' + updated + ' existing items';
486 } else if (processed > 0) {
487 resultHTML += 'Processed ' + processed + ' items successfully';
488 } else if (updated > 0) {
489 resultHTML += 'Updated ' + updated + ' items successfully';
490 } else {
491 resultHTML += 'No items were processed successfully';
492 }
493
494 if (failed > 0) {
495 resultHTML += ' with ' + failed + ' failures';
496 }
497
498 resultHTML += '</h4>';
499
500 // Add details if there were failures
501 if (failed > 0) {
502 resultHTML += '<div class="mxchat-kb-results-details">';
503 resultHTML += '<h5>Failed Items:</h5><ul>';
504
505 results.failed.forEach(function(item) {
506 resultHTML += '<li><strong>ID: ' + item.id + '</strong>: ' + item.error + '</li>';
507 });
508
509 resultHTML += '</ul></div>';
510 }
511
512 resultHTML += '</div>';
513
514 // Show results in modal
515 $modal.find('.mxchat-kb-modal-content').prepend($(resultHTML));
516
517 // Clear selection
518 selectedItems.clear();
519 updateSelection();
520
521 // Enable button
522 $button.prop('disabled', false)
523 .text('Process Selected Content')
524 .removeClass('update-mode mixed-mode');
525 $('.mxchat-kb-selected-count').text('(0)');
526
527 // Only reload if there were successful operations
528 if (processed > 0 || updated > 0) {
529 // Reload after delay
530 setTimeout(function() {
531 // Reload the knowledge base table - if this function exists
532 if (typeof reloadKnowledgeBaseTable === 'function') {
533 reloadKnowledgeBaseTable();
534 } else {
535 // Fallback: reload content list instead of full page reload
536 loadContent();
537 }
538 }, 3000);
539 }
540 }
541
542 // Start processing the first post
543 processNext(0);
544 });
545
546 // Initialize - Set WordPress as the active option by default
547 $('.mxchat-import-box[data-option="wordpress"]').addClass('active');
548 });
549
550 // Tab switching functionality - Keep this separate
551 jQuery(document).ready(function($) {
552
553 // Tab switching functionality
554 // Modified tab switching to check for Pinecone changes
555 $('.mxchat-kb-tab-button').on('click', function() {
556 var tabId = $(this).data('tab');
557 var $button = $(this);
558
559 // Switch tabs immediately for all tabs
560 $('.mxchat-kb-tab-button').removeClass('active');
561 $('.mxchat-kb-tab-content').removeClass('active');
562 $button.addClass('active');
563 $('#mxchat-kb-tab-' + tabId).addClass('active');
564
565 // Check if Pinecone was changed and we're going to import tab
566 if (tabId === 'import' && sessionStorage.getItem('mxchat_pinecone_changed') === 'true') {
567 sessionStorage.removeItem('mxchat_pinecone_changed');
568
569 // Show refresh notice
570 var $knowledgeCard = $('#mxchat-kb-tab-import .mxchat-card').eq(1);
571 if ($knowledgeCard.length > 0 && $knowledgeCard.find('.notice-warning').length === 0) {
572 var refreshNotice = $('<div class="notice notice-warning" style="margin: 15px 0; padding: 10px 15px;">' +
573 '<p style="margin: 0;">' +
574 '<span class="dashicons dashicons-info" style="color: #f0ad4e; margin-right: 5px;"></span>' +
575 'Database settings have changed. ' +
576 '<a href="#" onclick="location.reload(); return false;" style="font-weight: bold;">Click here to refresh</a> to see the updated knowledge base.' +
577 '</p></div>');
578
579 $knowledgeCard.prepend(refreshNotice);
580 }
581 }
582
583 // Initialize Pinecone functionality when Pinecone tab is activated
584 if (tabId === 'pinecone') {
585 setTimeout(function() {
586 initPineconeFeatures();
587 }, 100);
588 }
589 });
590
591
592 // Pinecone functionality
593 function initPineconeFeatures() {
594 //console.log('Initializing Pinecone features...');
595
596 if ($('#mxchat-kb-tab-pinecone').length === 0) {
597 return;
598 }
599
600 initPineconeToggle();
601 initPineconeConnectionTest();
602 checkPineconeCompatibility();
603 }
604
605 function initPineconeToggle() {
606 // Remove any existing handlers to prevent duplicates
607 $('input[name="mxchat_pinecone_addon_options[mxchat_use_pinecone]"]').off('change.pineconeToggle');
608
609 // Add the toggle handler for UI only (auto-save will handle the actual saving)
610 $('input[name="mxchat_pinecone_addon_options[mxchat_use_pinecone]"]').on('change.pineconeToggle', function() {
611 var $checkbox = $(this);
612 var isChecked = $checkbox.is(':checked');
613 var settingsDiv = $('.mxchat-pinecone-settings');
614
615 //console.log('Pinecone toggle changed to:', isChecked);
616
617 // Update the UI immediately
618 if (isChecked) {
619 settingsDiv.slideDown(300);
620 } else {
621 settingsDiv.slideUp(300);
622 }
623 });
624
625 // Set initial state based on current checkbox value
626 var currentToggle = $('input[name="mxchat_pinecone_addon_options[mxchat_use_pinecone]"]');
627 if (currentToggle.length > 0) {
628 var settingsDiv = $('.mxchat-pinecone-settings');
629 if (currentToggle.is(':checked')) {
630 settingsDiv.show();
631 } else {
632 settingsDiv.hide();
633 }
634 }
635 }
636
637 function initPineconeConnectionTest() {
638 $('#test-pinecone-connection').off('click.pinecone');
639
640 $('#test-pinecone-connection').on('click.pinecone', function() {
641 var button = $(this);
642 var resultDiv = $('#connection-test-result');
643
644 var apiKey = $('#mxchat_pinecone_api_key').val();
645 var host = $('#mxchat_pinecone_host').val();
646 var index = $('#mxchat_pinecone_index').val();
647
648 if (!apiKey || !host || !index) {
649 resultDiv.html('<div class="notice notice-error"><p>Please fill in all required fields first.</p></div>').show();
650 return;
651 }
652
653 button.prop('disabled', true).text('Testing...');
654 resultDiv.hide();
655
656 var ajaxUrl = (typeof mxchatPromptsAdmin !== 'undefined') ? mxchatPromptsAdmin.ajax_url : ajaxurl;
657 var nonce = (typeof mxchatPromptsAdmin !== 'undefined') ? mxchatPromptsAdmin.prompts_setting_nonce :
658 (typeof mxchatAdmin !== 'undefined') ? mxchatAdmin.setting_nonce : '';
659
660 $.ajax({
661 url: ajaxUrl,
662 type: 'POST',
663 data: {
664 action: 'mxchat_test_pinecone_connection',
665 _ajax_nonce: nonce,
666 api_key: apiKey,
667 host: host,
668 index_name: index
669 },
670 success: function(response) {
671 if (response.success) {
672 resultDiv.html('<div class="notice notice-success"><p><span class="dashicons dashicons-yes-alt"></span> ' + response.data.message + '</p></div>');
673 } else {
674 resultDiv.html('<div class="notice notice-error"><p><span class="dashicons dashicons-warning"></span> ' + response.data.message + '</p></div>');
675 }
676 resultDiv.show();
677 },
678 error: function() {
679 resultDiv.html('<div class="notice notice-error"><p>Connection test failed. Please check your settings.</p></div>').show();
680 },
681 complete: function() {
682 button.prop('disabled', false).text('Test Connection');
683 }
684 });
685 });
686 }
687
688 function checkPineconeCompatibility() {
689 if ($('.mxchat-pinecone-compatibility-notice').length > 0) {
690 return;
691 }
692
693 var hasOldAddon = $('body').hasClass('mxchat-pinecone-addon-active') ||
694 $('.pcm-card').length > 0;
695
696 if (hasOldAddon) {
697 var compatibilityNotice = $(`
698 <div class="notice notice-info mxchat-pinecone-compatibility-notice">
699 <p><strong>Pinecone Integration Notice:</strong> We've detected you have the Pinecone add-on installed.
700 Pinecone functionality is now built into the core plugin. You can safely deactivate the separate
701 Pinecone add-on after confirming your settings are migrated below.</p>
702 </div>
703 `);
704
705 $('#mxchat-kb-tab-pinecone .mxchat-card').prepend(compatibilityNotice);
706
707 migratePineconeSettings();
708 }
709 }
710
711 function migratePineconeSettings() {
712 if (typeof ajaxurl !== 'undefined') {
713 $.ajax({
714 url: ajaxurl,
715 type: 'POST',
716 data: {
717 action: 'mxchat_migrate_pinecone_settings',
718 _ajax_nonce: (typeof mxchatAdmin !== 'undefined') ? mxchatAdmin.setting_nonce : ''
719 },
720 success: function(response) {
721 if (response.success && response.data.migrated) {
722 location.reload();
723 }
724 },
725 error: function() {
726 //console.log('Pinecone settings migration not available');
727 }
728 });
729 }
730 }
731
732 });