PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 2.4.6
MxChat – AI Chatbot & Content Generation for WordPress v2.4.6
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
← All changes | js/content-selector.js +108 -340 3.2.152.4.6 View file →
@@ -8,14 +8,8 @@
8 8 const $pagination = $('.mxchat-kb-pagination');
9 9 const $processButton = $('#mxchat-kb-process-selected');
10 10 const $selectAll = $('#mxchat-kb-select-all');
11 11 const $selectionCount = $('.mxchat-kb-selection-count');
12 - const $acfPdfExtractCheckbox = $('#mxchat-kb-acf-pdf-extract');
13 -
14 - // Restore last-used ACF→PDF extract preference from the server-localized default.
15 - if (typeof mxchatSelector !== 'undefined' && mxchatSelector.acfPdfExtractDefault) {
16 - $acfPdfExtractCheckbox.prop('checked', true);
17 - }
18 12
19 13 // Filter elements
20 14 const $searchInput = $('#mxchat-kb-content-search');1
21 15 const $typeFilter = $('#mxchat-kb-content-type-filter');
@@ -43,103 +37,56 @@
43 37 // Handle import option box clicks (for non-WordPress options)
44 38 $('.mxchat-import-box').on('click', function() {
45 39 const $box = $(this);
46 40 const option = $box.data('option');
47 -
41 +
48 42 // Skip if this is the WordPress option (it has its own handler)
49 43 if (option === 'wordpress') {
50 44 return;
51 45 }
52 -
46 +
53 47 // Update active state
54 48 $('.mxchat-import-box').removeClass('active');
55 49 $box.addClass('active');
56 -
50 +
57 51 // Hide all input areas
58 - $('#mxchat-url-input-area, #mxchat-content-input-area, #mxchat-pdf-upload-area, #mxchat-youtube-input-area').hide();
59 -
60 - // Hide sitemap-specific sections (but NOT for sitemap option - let detection logic handle it)
61 - if (option !== 'sitemap') {
62 - $('#mxchat-detected-sitemaps, #mxchat-no-sitemaps, #mxchat-sitemaps-loading').hide();
63 - }
64 -
52 + $('#mxchat-url-input-area, #mxchat-content-input-area').hide();
53 +
65 54 // Handle different import options
66 55 switch (option) {
67 - case 'pdf-url':
56 + case 'pdf':
68 57 case 'sitemap':
69 58 case 'url':
70 59 // Show URL input area with appropriate placeholder
71 60 $('#mxchat-url-input-area').show();
72 61 $('#sitemap_url').attr('placeholder', $box.data('placeholder'));
73 - $('#import_type').val(option === 'pdf-url' ? 'pdf' : option);
74 -
62 + $('#import_type').val(option);
63 +
75 64 // UPDATED: Add or update bot_id hidden field for URL forms
76 65 updateBotIdInForm('#mxchat-url-form');
77 -
66 +
78 67 // Update the description text based on the import type
79 68 let descriptionText = '';
80 - if (option === 'pdf-url') {
69 + if (option === 'pdf') {
81 70 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.';
82 71 } else if (option === 'sitemap') {
83 72 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.';
84 - // Re-show sitemap sections if they were previously loaded
85 - const $sitemapsList = $('#mxchat-sitemaps-list');
86 - if ($sitemapsList.children().length > 0) {
87 - // Sitemaps were already loaded, just show the container
88 - $('#mxchat-detected-sitemaps').show();
89 - } else if ($('#mxchat-no-sitemaps').data('was-shown')) {
90 - // No sitemaps message was shown before
91 - $('#mxchat-no-sitemaps').show();
92 - }
93 - // Note: If neither condition is true, initSitemapDetection will show loading state
94 73 } else if (option === 'url') {
95 74 descriptionText = 'Import content from any webpage by entering its URL.';
96 75 }
97 76 $('#url-description-text').text(descriptionText);
98 77 break;
99 -
78 +
100 79 case 'content':
101 80 // Show content input area
102 81 $('#mxchat-content-input-area').show();
103 -
82 +
104 83 // UPDATED: Add or update bot_id hidden field for content forms
105 84 updateBotIdInForm('#mxchat-content-form');
106 85 break;
107 -
108 - case 'pdf-upload':
109 - // Show PDF file upload area
110 - $('#mxchat-pdf-upload-area').show();
111 -
112 - // Add or update bot_id hidden field for PDF upload form
113 - updateBotIdInForm('#mxchat-pdf-upload-form');
114 - break;
115 -
116 - case 'youtube':
117 - // Show YouTube import area
118 - $('#mxchat-youtube-input-area').show();
119 -
120 - // Add or update bot_id hidden field for YouTube form
121 - updateBotIdInForm('#mxchat-youtube-form');
122 - break;
123 86 }
124 87 });
125 88
126 -// YouTube import: toggle the manual-description box with the mode radios, and
127 -// only require the textarea when "Write my own" is selected.
128 -$(document).on('change', 'input[name="youtube_description_mode"]', function() {
129 - const manual = $('input[name="youtube_description_mode"]:checked').val() === 'manual';
130 - $('#mxchat-youtube-description-field').toggle(manual);
131 - $('#mxchat-youtube-description').prop('required', manual);
132 -});
133 -
134 -// If the server bounced back with prefill state (auto-import found no
135 -// transcript), reopen the YouTube form in manual mode ready to augment.
136 -if ($('#mxchat-youtube-form').data('yt-prefill')) {
137 - $('.mxchat-import-box[data-option="youtube"]').trigger('click');
138 - $('input[name="youtube_description_mode"]').trigger('change');
139 - $('#mxchat-youtube-description').trigger('focus');
140 -}
141 -
142 89 // Helper function to add/update bot_id hidden field in forms
143 90 function updateBotIdInForm(formSelector) {
144 91 const $form = $(formSelector);
145 92 if ($form.length === 0) return;
@@ -170,9 +117,9 @@
170 117 const data = {
171 118 action: 'mxchat_get_content_list',
172 119 nonce: mxchatSelector.nonce,
173 120 page: currentPage,
174 - per_page: 100,
121 + per_page: 50,
175 122 search: $searchInput.val(),
176 123 post_type: $typeFilter.val(),
177 124 post_status: $statusFilter.val(),
178 125 processed_filter: $processedFilter.val()
@@ -237,22 +184,18 @@
237 184
238 185 // Render content items
239 186 function renderContentItems(items) {
240 187 let html = '';
241 -
188 +
242 189 items.forEach(function(item) {
243 190 const isSelected = selectedItems.has(item.id);
244 191 const isProcessed = item.already_processed;
245 - const chunkCount = item.chunk_count || 0;
246 -
247 - // Updated badge text - include chunk count if > 1
248 - let badgeText = 'Not In Knowledge Base';
249 - if (isProcessed) {
250 - badgeText = chunkCount > 1 ? `In Knowledge Base (${chunkCount} chunks)` : 'In Knowledge Base';
251 - }
192 +
193 + // Updated badge text
194 + const badgeText = isProcessed ? 'In Knowledge Base' : 'Not In Knowledge Base';
252 195 const badgeClass = isProcessed ? 'mxchat-kb-processed-badge' : 'mxchat-kb-unprocessed-badge';
253 -
254 -
196 +
197 +
255 198 html += `
256 199 <div class="mxchat-kb-content-item ${isProcessed ? 'processed' : ''}" data-id="${item.id}">
257 200 <div class="mxchat-kb-content-checkbox">
258 201 <input type="checkbox" id="content-${item.id}" ${isSelected ? 'checked' : ''}>
@@ -272,9 +215,9 @@
272 215 </div>
273 216 </div>
274 217 `;
275 218 });
276 -
219 +
277 220 $contentList.html(html);
278 221
279 222 // Add event listeners for checkboxes using delegation for better performance
280 223 $contentList.off('change', 'input[type="checkbox"]').on('change', 'input[type="checkbox"]', function() {
@@ -347,36 +290,18 @@
347 290 function updateSelection() {
348 291 const selectedCount = selectedItems.size;
349 292 $selectionCount.text(selectedCount + ' ' + (selectedCount === 1 ? 'selected' : 'selected'));
350 293 $('.mxchat-kb-selected-count').text('(' + selectedCount + ')');
351 -
352 - // Show/hide clear all selections link
353 - let $clearAllLink = $('.mxchat-kb-clear-all-selections');
354 - if (selectedCount > 0) {
355 - if ($clearAllLink.length === 0) {
356 - $clearAllLink = $('<a href="#" class="mxchat-kb-clear-all-selections" style="margin-left: 10px; font-size: 12px; color: var(--mxch-error, #dc2626);">Clear all</a>');
357 - $selectionCount.after($clearAllLink);
358 - $clearAllLink.on('click', function(e) {
359 - e.preventDefault();
360 - selectedItems.clear();
361 - $('.mxchat-kb-content-item input[type="checkbox"]').prop('checked', false);
362 - updateSelection();
363 - });
364 - }
365 - $clearAllLink.show();
366 - } else {
367 - $clearAllLink.hide();
368 - }
369 -
294 +
370 295 // Determine if any selected items are already processed
371 296 const hasProcessedItems = Array.from(selectedItems).some(id => {
372 297 const item = allItems.find(item => item.id === id);
373 298 return item && item.already_processed;
374 299 });
375 -
300 +
376 301 if (selectedCount > 0) {
377 302 $processButton.prop('disabled', false);
378 -
303 +
379 304 // Update button text based on selection
380 305 if (hasProcessedItems && selectedCount === 1) {
381 306 $processButton.text('Update Selected Content (1)').addClass('update-mode');
382 307 } else if (hasProcessedItems && selectedCount > 1) {
@@ -388,9 +313,9 @@
388 313 $processButton.prop('disabled', true);
389 314 $processButton.text('Process Selected Content').removeClass('update-mode mixed-mode');
390 315 $('.mxchat-kb-selected-count').text('(0)');
391 316 }
392 -
317 +
393 318 updateSelectAllState();
394 319 }
395 320
396 321 // Update "Select All" checkbox state
@@ -478,13 +403,9 @@
478 403
479 404 // UPDATED: Get current bot_id for WordPress content processing
480 405 const currentBotId = $('#mxchat-bot-selector').val();
481 406
482 - // Flag to track if processing should be aborted
483 - let abortProcessing = false;
484 - let currentXHR = null;
485 -
486 - // Create a modal to show progress with stop button
407 + // Create a modal to show progress
487 408 const $progressModal = $('<div class="mxchat-kb-processing-overlay">' +
488 409 '<div class="mxchat-kb-processing-content">' +
489 410 '<h3>Processing Content</h3>' +
490 411 '<p class="mxchat-kb-processing-status">Processing 1 of ' + totalToProcess + '...</p>' +
@@ -489,65 +410,46 @@
489 410 '<h3>Processing Content</h3>' +
490 411 '<p class="mxchat-kb-processing-status">Processing 1 of ' + totalToProcess + '...</p>' +
491 412 '<div class="mxchat-kb-progress-bar"><div class="mxchat-kb-progress-fill" style="width: 0%"></div></div>' +
492 413 '<p class="mxchat-kb-current-item"></p>' +
493 - '<button type="button" class="mxchat-kb-stop-processing mxch-btn mxch-btn-secondary" style="margin-top: 15px;">' +
494 - '<span class="dashicons dashicons-controls-pause" style="margin-right: 5px;"></span>Stop Processing</button>' +
495 414 '</div>' +
496 415 '</div>');
497 -
416 +
498 417 $('body').append($progressModal);
499 -
500 - // Handle stop button click
501 - $progressModal.find('.mxchat-kb-stop-processing').on('click', function() {
502 - abortProcessing = true;
503 - $(this).prop('disabled', true).html('<span class="dashicons dashicons-update spin" style="margin-right: 5px;"></span>Stopping...');
504 - if (currentXHR) {
505 - currentXHR.abort();
506 - }
507 - });
508 418
509 419 // Process posts one by one
510 420 function processNext(index) {
511 - // Check if processing was aborted
512 - if (abortProcessing) {
513 - finishProcessing(true); // Pass true to indicate abort
514 - return;
515 - }
516 -
517 421 if (index >= selectedPostIds.length) {
518 422 // All done
519 423 finishProcessing();
520 424 return;
521 425 }
522 -
426 +
523 427 const postId = selectedPostIds[index];
524 428 const percent = Math.round((index / totalToProcess) * 100);
525 429 const item = allItems.find(item => item.id === postId);
526 430 const isUpdate = item && item.already_processed;
527 -
431 +
528 432 // Update progress UI
529 433 $progressModal.find('.mxchat-kb-processing-status')
530 434 .text((isUpdate ? 'Updating' : 'Processing') + ' ' + (index + 1) + ' of ' + totalToProcess + '...');
531 435 $progressModal.find('.mxchat-kb-progress-fill').css('width', percent + '%');
532 -
436 +
533 437 // UPDATED: Prepare AJAX data with bot_id
534 - const extractAcfPdfs = $acfPdfExtractCheckbox.prop('checked') ? 1 : 0;
535 438 const ajaxData = {
536 439 action: 'mxchat_process_selected_content',
537 440 nonce: mxchatSelector.nonce,
538 441 post_ids: [postId],
539 - is_update: isUpdate,
540 - extract_acf_pdfs: extractAcfPdfs
442 + is_update: isUpdate
541 443 };
542 -
444 +
543 445 // Add bot_id if multi-bot is active and not default
544 446 if (currentBotId && currentBotId !== 'default') {
545 447 ajaxData.bot_id = currentBotId;
546 448 }
547 -
548 - // Make AJAX request for this post (store reference for potential abort)
549 - currentXHR = $.ajax({
449 +
450 + // Make AJAX request for this post
451 + $.ajax({
550 452 url: mxchatSelector.ajaxurl,
551 453 method: 'POST',
552 454 data: ajaxData,
553 455 dataType: 'json',
@@ -566,15 +468,10 @@
566 468 title: response.data.title || ('ID: ' + postId)
567 469 });
568 470 }
569 471
570 - let successText = 'Successfully ' + (isUpdate ? 'updated' : 'processed') + ': ' + response.data.title;
571 - const pdfCount = parseInt(response.data.pdf_extracted_count, 10) || 0;
572 - if (pdfCount > 0) {
573 - const suffixTpl = (mxchatSelector.i18n && mxchatSelector.i18n.pdfExtractedSuffix) || ' (%d PDF(s) extracted)';
574 - successText += suffixTpl.replace('%d', pdfCount);
575 - }
576 - $progressModal.find('.mxchat-kb-current-item').text(successText);
472 + $progressModal.find('.mxchat-kb-current-item')
473 + .text('Successfully ' + (isUpdate ? 'updated' : 'processed') + ': ' + response.data.title);
577 474 } else {
578 475 failed++;
579 476 results.failed.push({
580 477 id: postId,
@@ -608,32 +505,23 @@
608 505 });
609 506 }
610 507
611 508 // Function to finish processing and show results
612 - function finishProcessing(wasAborted) {
509 + function finishProcessing() {
613 510 // Remove progress modal
614 511 $progressModal.remove();
615 -
512 +
616 513 // Determine notification type based on results
617 514 let notificationClass = 'success';
618 - if (wasAborted) {
619 - notificationClass = processed > 0 || updated > 0 ? 'warning' : 'info';
620 - } else if (failed > 0) {
515 + if (failed > 0) {
621 516 notificationClass = processed > 0 || updated > 0 ? 'warning' : 'error';
622 517 }
623 -
518 +
624 519 // Create summary message
625 - let resultHTML = '<div class="mxchat-kb-notification ' + notificationClass + '">' +
520 + let resultHTML = '<div class="mxchat-kb-notification ' + notificationClass + '">' +
626 521 '<h4>';
627 -
628 - if (wasAborted) {
629 - resultHTML += 'Processing stopped. ';
630 - if (processed > 0 || updated > 0) {
631 - resultHTML += 'Completed ' + (processed + updated) + ' of ' + totalToProcess + ' items before stopping';
632 - } else {
633 - resultHTML += 'No items were processed before stopping';
634 - }
635 - } else if (processed > 0 && updated > 0) {
522 +
523 + if (processed > 0 && updated > 0) {
636 524 resultHTML += 'Processed ' + processed + ' new items and updated ' + updated + ' existing items';
637 525 } else if (processed > 0) {
638 526 resultHTML += 'Processed ' + processed + ' items successfully';
639 527 } else if (updated > 0) {
@@ -640,10 +528,10 @@
640 528 resultHTML += 'Updated ' + updated + ' items successfully';
641 529 } else {
642 530 resultHTML += 'No items were processed successfully';
643 531 }
644 -
645 - if (failed > 0 && !wasAborted) {
532 +
533 + if (failed > 0) {
646 534 resultHTML += ' with ' + failed + ' failures';
647 535 }
648 536
649 537 resultHTML += '</h4>';
@@ -673,20 +561,21 @@
673 561 $button.prop('disabled', false)
674 562 .text('Process Selected Content')
675 563 .removeClass('update-mode mixed-mode');
676 564 $('.mxchat-kb-selected-count').text('(0)');
677 -
565 +
678 566 // Only reload if there were successful operations
679 567 if (processed > 0 || updated > 0) {
680 - // Refresh the knowledge base table with properly grouped entries
681 - if (typeof window.refreshKnowledgeBaseTable === 'function') {
682 - window.refreshKnowledgeBaseTable();
683 - }
684 -
685 - // Reload content list to update "already processed" status
568 + // Reload after delay
686 569 setTimeout(function() {
687 - loadContent();
688 - }, 1000);
570 + // Reload the knowledge base table - if this function exists
571 + if (typeof reloadKnowledgeBaseTable === 'function') {
572 + reloadKnowledgeBaseTable();
573 + } else {
574 + // Fallback: reload content list instead of full page reload
575 + loadContent();
576 + }
577 + }, 3000);
689 578 }
690 579 }
691 580
692 581 // Start processing the first post
@@ -696,150 +585,91 @@
696 585 // Initialize - Set WordPress as the active option by default
697 586 $('.mxchat-import-box[data-option="wordpress"]').addClass('active');
698 587 });
699 588
700 -// Navigation functionality for Knowledge Base page
589 +// Tab switching functionality - Keep this separate
701 590 jQuery(document).ready(function($) {
702 -
703 - // Hook into the new navigation system using .mxch-nav-link
704 - $(document).on('click', '.mxch-nav-link[data-target], .mxch-mobile-nav-link[data-target]', function() {
705 - var target = $(this).data('target');
706 -
707 - // Initialize Pinecone functionality when Pinecone section is activated
708 - if (target === 'pinecone') {
709 - setTimeout(function() {
710 - if (typeof initPineconeFeatures === 'function') {
711 - initPineconeFeatures();
712 - }
713 - }, 100);
591 +
592 +// Tab switching functionality
593 +// Modified tab switching to check for Pinecone changes
594 +$('.mxchat-kb-tab-button').on('click', function() {
595 + var tabId = $(this).data('tab');
596 + var $button = $(this);
597 +
598 + // Switch tabs immediately for all tabs
599 + $('.mxchat-kb-tab-button').removeClass('active');
600 + $('.mxchat-kb-tab-content').removeClass('active');
601 + $button.addClass('active');
602 + $('#mxchat-kb-tab-' + tabId).addClass('active');
603 +
604 + // Check if Pinecone was changed and we're going to import tab
605 + if (tabId === 'import' && sessionStorage.getItem('mxchat_pinecone_changed') === 'true') {
606 + sessionStorage.removeItem('mxchat_pinecone_changed');
607 +
608 + // Show refresh notice
609 + var $knowledgeCard = $('#mxchat-kb-tab-import .mxchat-card').eq(1);
610 + if ($knowledgeCard.length > 0 && $knowledgeCard.find('.notice-warning').length === 0) {
611 + var refreshNotice = $('<div class="notice notice-warning" style="margin: 15px 0; padding: 10px 15px;">' +
612 + '<p style="margin: 0;">' +
613 + '<span class="dashicons dashicons-info" style="color: #f0ad4e; margin-right: 5px;"></span>' +
614 + 'Database settings have changed. ' +
615 + '<a href="#" onclick="location.reload(); return false;" style="font-weight: bold;">Click here to refresh</a> to see the updated knowledge base.' +
616 + '</p></div>');
617 +
618 + $knowledgeCard.prepend(refreshNotice);
714 619 }
715 -
716 - // Initialize OpenAI Vector Store functionality when Vector Store section is activated
717 - if (target === 'openai-vectorstore') {
718 - setTimeout(function() {
719 - if (typeof initVectorStoreFeatures === 'function') {
720 - initVectorStoreFeatures();
721 - }
722 - }, 100);
723 - }
724 -
725 - // Check if Pinecone was changed and we're going to import section
726 - if (target === 'import' && sessionStorage.getItem('mxchat_pinecone_changed') === 'true') {
727 - sessionStorage.removeItem('mxchat_pinecone_changed');
728 -
729 - // Show refresh notice
730 - var $knowledgeCard = $('#import .mxch-card').eq(1);
731 - if ($knowledgeCard.length > 0 && $knowledgeCard.find('.notice-warning').length === 0) {
732 - var refreshNotice = $('<div class="notice notice-warning" style="margin: 15px 0; padding: 10px 15px;">' +
733 - '<p style="margin: 0;">' +
734 - '<span class="dashicons dashicons-info" style="color: #f0ad4e; margin-right: 5px;"></span>' +
735 - 'Database settings have changed. ' +
736 - '<a href="#" onclick="location.reload(); return false;" style="font-weight: bold;">Click here to refresh</a> to see the updated knowledge base.' +
737 - '</p></div>');
738 -
739 - $knowledgeCard.prepend(refreshNotice);
740 - }
741 - }
742 - });
743 -
744 - // Also check on page load if we're already on one of these sections
745 - setTimeout(function() {
746 - if ($('#pinecone').is(':visible') || $('#pinecone.active').length > 0) {
747 - if (typeof initPineconeFeatures === 'function') {
748 - initPineconeFeatures();
749 - }
750 - }
751 -
752 - if ($('#openai-vectorstore').is(':visible') || $('#openai-vectorstore.active').length > 0) {
753 - if (typeof initVectorStoreFeatures === 'function') {
754 - initVectorStoreFeatures();
755 - }
756 - }
757 - }, 200);
620 + }
621 +
622 + // Initialize Pinecone functionality when Pinecone tab is activated
623 + if (tabId === 'pinecone') {
624 + setTimeout(function() {
625 + initPineconeFeatures();
626 + }, 100);
627 + }
758 628 });
759 629
760 -// Pinecone and Vector Store functionality - global functions
761 -var initPineconeFeatures, initVectorStoreFeatures;
762 630
763 -(function($) {
764 -
765 - // Helper function to update sidebar badge when integration is toggled
766 - function updateSidebarBadge(section, isActive) {
767 - // Find the nav item for this section (both desktop and mobile)
768 - var $desktopNavItem = $('.mxch-nav-item[data-section="' + section + '"] .mxch-nav-link');
769 - var $mobileNavItem = $('.mxch-mobile-nav-link[data-target="' + section + '"]');
770 -
771 - // Remove existing badge if any
772 - $desktopNavItem.find('.mxch-active-badge').remove();
773 - $mobileNavItem.find('.mxch-active-badge').remove();
774 -
775 - // Add badge if active
776 - if (isActive) {
777 - var badgeHtml = '<span class="mxch-nav-link-badge mxch-active-badge">Active</span>';
778 - $desktopNavItem.append(badgeHtml);
779 - $mobileNavItem.append(badgeHtml);
780 - }
781 - }
782 -
783 631 // Pinecone functionality
784 - initPineconeFeatures = function() {
785 - // Check for either old or new section ID
786 - if ($('#pinecone').length === 0 && $('#mxchat-kb-tab-pinecone').length === 0) {
632 + function initPineconeFeatures() {
633 + //console.log('Initializing Pinecone features...');
634 +
635 + if ($('#mxchat-kb-tab-pinecone').length === 0) {
787 636 return;
788 637 }
789 -
638 +
790 639 initPineconeToggle();
791 640 initPineconeConnectionTest();
792 641 checkPineconeCompatibility();
793 - };
794 -
642 + }
643 +
795 644 function initPineconeToggle() {
796 645 // Remove any existing handlers to prevent duplicates
797 - var $toggleInput = $('input[name="mxchat_pinecone_addon_options[mxchat_use_pinecone]"]');
798 - $toggleInput.off('change.pineconeToggle');
799 -
800 - // Ensure the success notice exists in the settings div (add if not present)
801 - // Check for both the JS-added class and any existing PHP-rendered success notice
802 - var settingsDiv = $('.mxchat-pinecone-settings');
803 - if (settingsDiv.length > 0 && settingsDiv.find('.mxch-notice-success').length === 0) {
804 - var successNotice = $('<div class="mxch-notice mxch-notice-success mxchat-pinecone-enabled-notice" style="margin-bottom: 20px; display: none;">' +
805 - '<svg class="mxch-notice-icon" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>' +
806 - '<span>Pinecone is enabled. All new knowledge base content will be stored in Pinecone.</span>' +
807 - '</div>');
808 - settingsDiv.prepend(successNotice);
809 - }
810 -
646 + $('input[name="mxchat_pinecone_addon_options[mxchat_use_pinecone]"]').off('change.pineconeToggle');
647 +
811 648 // Add the toggle handler for UI only (auto-save will handle the actual saving)
812 - $toggleInput.on('change.pineconeToggle', function() {
649 + $('input[name="mxchat_pinecone_addon_options[mxchat_use_pinecone]"]').on('change.pineconeToggle', function() {
813 650 var $checkbox = $(this);
814 651 var isChecked = $checkbox.is(':checked');
815 652 var settingsDiv = $('.mxchat-pinecone-settings');
816 - var enabledNotice = settingsDiv.find('.mxchat-pinecone-enabled-notice, .mxch-notice-success');
817 -
653 +
654 + //console.log('Pinecone toggle changed to:', isChecked);
655 +
818 656 // Update the UI immediately
819 657 if (isChecked) {
820 658 settingsDiv.slideDown(300);
821 - enabledNotice.slideDown(300);
822 659 } else {
823 - enabledNotice.slideUp(300);
824 660 settingsDiv.slideUp(300);
825 661 }
826 -
827 - // Update sidebar badge for Pinecone
828 - updateSidebarBadge('pinecone', isChecked);
829 662 });
830 -
663 +
831 664 // Set initial state based on current checkbox value
832 665 var currentToggle = $('input[name="mxchat_pinecone_addon_options[mxchat_use_pinecone]"]');
833 666 if (currentToggle.length > 0) {
834 667 var settingsDiv = $('.mxchat-pinecone-settings');
835 - var enabledNotice = settingsDiv.find('.mxchat-pinecone-enabled-notice, .mxch-notice-success');
836 668 if (currentToggle.is(':checked')) {
837 669 settingsDiv.show();
838 - enabledNotice.show();
839 670 } else {
840 671 settingsDiv.hide();
841 - enabledNotice.hide();
842 672 }
843 673 }
844 674 }
845 675
@@ -936,68 +766,6 @@
936 766 }
937 767 });
938 768 }
939 769 }
940 -
941 - // ============================================
942 - // OpenAI Vector Store functionality
943 - // ============================================
944 - initVectorStoreFeatures = function() {
945 - if ($('#openai-vectorstore').length === 0) {
946 - return;
947 - }
948 -
949 - initVectorStoreToggle();
950 - };
951 -
952 - function initVectorStoreToggle() {
953 - // Remove any existing handlers to prevent duplicates
954 - var $toggleInput = $('input[name="mxchat_openai_vectorstore_options[mxchat_use_openai_vectorstore]"]');
955 - $toggleInput.off('change.vectorstoreToggle');
956 -
957 - // Ensure the success notice exists in the settings div (add if not present)
958 - // Check for both the JS-added class and any existing PHP-rendered success notice
959 - var settingsDiv = $('.mxchat-vectorstore-settings');
960 - if (settingsDiv.length > 0 && settingsDiv.find('.mxch-notice-success').length === 0) {
961 - var successNotice = $('<div class="mxch-notice mxch-notice-success mxchat-vectorstore-enabled-notice" style="margin-bottom: 20px; display: none;">' +
962 - '<svg class="mxch-notice-icon" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>' +
963 - '<span>OpenAI Vector Store is enabled. Queries will search your Vector Store for relevant content.</span>' +
964 - '</div>');
965 - settingsDiv.prepend(successNotice);
966 - }
967 -
968 - // Add the toggle handler for UI only (form submit will handle the actual saving)
969 - $toggleInput.on('change.vectorstoreToggle', function() {
970 - var $checkbox = $(this);
971 - var isChecked = $checkbox.is(':checked');
972 - var settingsDiv = $('.mxchat-vectorstore-settings');
973 - var enabledNotice = settingsDiv.find('.mxchat-vectorstore-enabled-notice, .mxch-notice-success');
974 -
975 - // Update the UI immediately
976 - if (isChecked) {
977 - settingsDiv.slideDown(300);
978 - enabledNotice.slideDown(300);
979 - } else {
980 - enabledNotice.slideUp(300);
981 - settingsDiv.slideUp(300);
982 - }
983 -
984 - // Update sidebar badge for OpenAI Vector Store
985 - updateSidebarBadge('openai-vectorstore', isChecked);
986 - });
987 -
988 - // Set initial state based on current checkbox value
989 - var currentToggle = $('input[name="mxchat_openai_vectorstore_options[mxchat_use_openai_vectorstore]"]');
990 - if (currentToggle.length > 0) {
991 - var settingsDiv = $('.mxchat-vectorstore-settings');
992 - var enabledNotice = settingsDiv.find('.mxchat-vectorstore-enabled-notice, .mxch-notice-success');
993 - if (currentToggle.is(':checked')) {
994 - settingsDiv.show();
995 - enabledNotice.show();
996 - } else {
997 - settingsDiv.hide();
998 - enabledNotice.hide();
999 - }
1000 - }
1001 - }
1002 -
1003 -})(jQuery);
770 +
771 +});