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