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 +105 -300 3.2.12.4.6 View file →
@@ -37,76 +37,53 @@
37 37 // Handle import option box clicks (for non-WordPress options)
38 38 $('.mxchat-import-box').on('click', function() {
39 39 const $box = $(this);
40 40 const option = $box.data('option');
41 -
41 +
42 42 // Skip if this is the WordPress option (it has its own handler)
43 43 if (option === 'wordpress') {
44 44 return;
45 45 }
46 -
46 +
47 47 // Update active state
48 48 $('.mxchat-import-box').removeClass('active');
49 49 $box.addClass('active');
50 -
50 +
51 51 // Hide all input areas
52 - $('#mxchat-url-input-area, #mxchat-content-input-area, #mxchat-pdf-upload-area').hide();
53 -
54 - // Hide sitemap-specific sections (but NOT for sitemap option - let detection logic handle it)
55 - if (option !== 'sitemap') {
56 - $('#mxchat-detected-sitemaps, #mxchat-no-sitemaps, #mxchat-sitemaps-loading').hide();
57 - }
58 -
52 + $('#mxchat-url-input-area, #mxchat-content-input-area').hide();
53 +
59 54 // Handle different import options
60 55 switch (option) {
61 - case 'pdf-url':
56 + case 'pdf':
62 57 case 'sitemap':
63 58 case 'url':
64 59 // Show URL input area with appropriate placeholder
65 60 $('#mxchat-url-input-area').show();
66 61 $('#sitemap_url').attr('placeholder', $box.data('placeholder'));
67 - $('#import_type').val(option === 'pdf-url' ? 'pdf' : option);
68 -
62 + $('#import_type').val(option);
63 +
69 64 // UPDATED: Add or update bot_id hidden field for URL forms
70 65 updateBotIdInForm('#mxchat-url-form');
71 -
66 +
72 67 // Update the description text based on the import type
73 68 let descriptionText = '';
74 - if (option === 'pdf-url') {
69 + if (option === 'pdf') {
75 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.';
76 71 } else if (option === 'sitemap') {
77 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.';
78 - // Re-show sitemap sections if they were previously loaded
79 - const $sitemapsList = $('#mxchat-sitemaps-list');
80 - if ($sitemapsList.children().length > 0) {
81 - // Sitemaps were already loaded, just show the container
82 - $('#mxchat-detected-sitemaps').show();
83 - } else if ($('#mxchat-no-sitemaps').data('was-shown')) {
84 - // No sitemaps message was shown before
85 - $('#mxchat-no-sitemaps').show();
86 - }
87 - // Note: If neither condition is true, initSitemapDetection will show loading state
88 73 } else if (option === 'url') {
89 74 descriptionText = 'Import content from any webpage by entering its URL.';
90 75 }
91 76 $('#url-description-text').text(descriptionText);
92 77 break;
93 -
78 +
94 79 case 'content':
95 80 // Show content input area
96 81 $('#mxchat-content-input-area').show();
97 -
82 +
98 83 // UPDATED: Add or update bot_id hidden field for content forms
99 84 updateBotIdInForm('#mxchat-content-form');
100 85 break;
101 -
102 - case 'pdf-upload':
103 - // Show PDF file upload area
104 - $('#mxchat-pdf-upload-area').show();
105 -
106 - // Add or update bot_id hidden field for PDF upload form
107 - updateBotIdInForm('#mxchat-pdf-upload-form');
108 - break;
109 86 }
110 87 });
111 88
112 89 // Helper function to add/update bot_id hidden field in forms
@@ -140,9 +117,9 @@
140 117 const data = {
141 118 action: 'mxchat_get_content_list',
142 119 nonce: mxchatSelector.nonce,
143 120 page: currentPage,
144 - per_page: 100,
121 + per_page: 50,
145 122 search: $searchInput.val(),
146 123 post_type: $typeFilter.val(),
147 124 post_status: $statusFilter.val(),
148 125 processed_filter: $processedFilter.val()
@@ -207,22 +184,18 @@
207 184
208 185 // Render content items
209 186 function renderContentItems(items) {
210 187 let html = '';
211 -
188 +
212 189 items.forEach(function(item) {
213 190 const isSelected = selectedItems.has(item.id);
214 191 const isProcessed = item.already_processed;
215 - const chunkCount = item.chunk_count || 0;
216 -
217 - // Updated badge text - include chunk count if > 1
218 - let badgeText = 'Not In Knowledge Base';
219 - if (isProcessed) {
220 - badgeText = chunkCount > 1 ? `In Knowledge Base (${chunkCount} chunks)` : 'In Knowledge Base';
221 - }
192 +
193 + // Updated badge text
194 + const badgeText = isProcessed ? 'In Knowledge Base' : 'Not In Knowledge Base';
222 195 const badgeClass = isProcessed ? 'mxchat-kb-processed-badge' : 'mxchat-kb-unprocessed-badge';
223 -
224 -
196 +
197 +
225 198 html += `
226 199 <div class="mxchat-kb-content-item ${isProcessed ? 'processed' : ''}" data-id="${item.id}">
227 200 <div class="mxchat-kb-content-checkbox">
228 201 <input type="checkbox" id="content-${item.id}" ${isSelected ? 'checked' : ''}>
@@ -242,9 +215,9 @@
242 215 </div>
243 216 </div>
244 217 `;
245 218 });
246 -
219 +
247 220 $contentList.html(html);
248 221
249 222 // Add event listeners for checkboxes using delegation for better performance
250 223 $contentList.off('change', 'input[type="checkbox"]').on('change', 'input[type="checkbox"]', function() {
@@ -317,36 +290,18 @@
317 290 function updateSelection() {
318 291 const selectedCount = selectedItems.size;
319 292 $selectionCount.text(selectedCount + ' ' + (selectedCount === 1 ? 'selected' : 'selected'));
320 293 $('.mxchat-kb-selected-count').text('(' + selectedCount + ')');
321 -
322 - // Show/hide clear all selections link
323 - let $clearAllLink = $('.mxchat-kb-clear-all-selections');
324 - if (selectedCount > 0) {
325 - if ($clearAllLink.length === 0) {
326 - $clearAllLink = $('<a href="#" class="mxchat-kb-clear-all-selections" style="margin-left: 10px; font-size: 12px; color: var(--mxch-error, #dc2626);">Clear all</a>');
327 - $selectionCount.after($clearAllLink);
328 - $clearAllLink.on('click', function(e) {
329 - e.preventDefault();
330 - selectedItems.clear();
331 - $('.mxchat-kb-content-item input[type="checkbox"]').prop('checked', false);
332 - updateSelection();
333 - });
334 - }
335 - $clearAllLink.show();
336 - } else {
337 - $clearAllLink.hide();
338 - }
339 -
294 +
340 295 // Determine if any selected items are already processed
341 296 const hasProcessedItems = Array.from(selectedItems).some(id => {
342 297 const item = allItems.find(item => item.id === id);
343 298 return item && item.already_processed;
344 299 });
345 -
300 +
346 301 if (selectedCount > 0) {
347 302 $processButton.prop('disabled', false);
348 -
303 +
349 304 // Update button text based on selection
350 305 if (hasProcessedItems && selectedCount === 1) {
351 306 $processButton.text('Update Selected Content (1)').addClass('update-mode');
352 307 } else if (hasProcessedItems && selectedCount > 1) {
@@ -358,9 +313,9 @@
358 313 $processButton.prop('disabled', true);
359 314 $processButton.text('Process Selected Content').removeClass('update-mode mixed-mode');
360 315 $('.mxchat-kb-selected-count').text('(0)');
361 316 }
362 -
317 +
363 318 updateSelectAllState();
364 319 }
365 320
366 321 // Update "Select All" checkbox state
@@ -448,13 +403,9 @@
448 403
449 404 // UPDATED: Get current bot_id for WordPress content processing
450 405 const currentBotId = $('#mxchat-bot-selector').val();
451 406
452 - // Flag to track if processing should be aborted
453 - let abortProcessing = false;
454 - let currentXHR = null;
455 -
456 - // Create a modal to show progress with stop button
407 + // Create a modal to show progress
457 408 const $progressModal = $('<div class="mxchat-kb-processing-overlay">' +
458 409 '<div class="mxchat-kb-processing-content">' +
459 410 '<h3>Processing Content</h3>' +
460 411 '<p class="mxchat-kb-processing-status">Processing 1 of ' + totalToProcess + '...</p>' +
@@ -459,48 +410,31 @@
459 410 '<h3>Processing Content</h3>' +
460 411 '<p class="mxchat-kb-processing-status">Processing 1 of ' + totalToProcess + '...</p>' +
461 412 '<div class="mxchat-kb-progress-bar"><div class="mxchat-kb-progress-fill" style="width: 0%"></div></div>' +
462 413 '<p class="mxchat-kb-current-item"></p>' +
463 - '<button type="button" class="mxchat-kb-stop-processing mxch-btn mxch-btn-secondary" style="margin-top: 15px;">' +
464 - '<span class="dashicons dashicons-controls-pause" style="margin-right: 5px;"></span>Stop Processing</button>' +
465 414 '</div>' +
466 415 '</div>');
467 -
416 +
468 417 $('body').append($progressModal);
469 -
470 - // Handle stop button click
471 - $progressModal.find('.mxchat-kb-stop-processing').on('click', function() {
472 - abortProcessing = true;
473 - $(this).prop('disabled', true).html('<span class="dashicons dashicons-update spin" style="margin-right: 5px;"></span>Stopping...');
474 - if (currentXHR) {
475 - currentXHR.abort();
476 - }
477 - });
478 418
479 419 // Process posts one by one
480 420 function processNext(index) {
481 - // Check if processing was aborted
482 - if (abortProcessing) {
483 - finishProcessing(true); // Pass true to indicate abort
484 - return;
485 - }
486 -
487 421 if (index >= selectedPostIds.length) {
488 422 // All done
489 423 finishProcessing();
490 424 return;
491 425 }
492 -
426 +
493 427 const postId = selectedPostIds[index];
494 428 const percent = Math.round((index / totalToProcess) * 100);
495 429 const item = allItems.find(item => item.id === postId);
496 430 const isUpdate = item && item.already_processed;
497 -
431 +
498 432 // Update progress UI
499 433 $progressModal.find('.mxchat-kb-processing-status')
500 434 .text((isUpdate ? 'Updating' : 'Processing') + ' ' + (index + 1) + ' of ' + totalToProcess + '...');
501 435 $progressModal.find('.mxchat-kb-progress-fill').css('width', percent + '%');
502 -
436 +
503 437 // UPDATED: Prepare AJAX data with bot_id
504 438 const ajaxData = {
505 439 action: 'mxchat_process_selected_content',
506 440 nonce: mxchatSelector.nonce,
@@ -506,16 +440,16 @@
506 440 nonce: mxchatSelector.nonce,
507 441 post_ids: [postId],
508 442 is_update: isUpdate
509 443 };
510 -
444 +
511 445 // Add bot_id if multi-bot is active and not default
512 446 if (currentBotId && currentBotId !== 'default') {
513 447 ajaxData.bot_id = currentBotId;
514 448 }
515 -
516 - // Make AJAX request for this post (store reference for potential abort)
517 - currentXHR = $.ajax({
449 +
450 + // Make AJAX request for this post
451 + $.ajax({
518 452 url: mxchatSelector.ajaxurl,
519 453 method: 'POST',
520 454 data: ajaxData,
521 455 dataType: 'json',
@@ -571,32 +505,23 @@
571 505 });
572 506 }
573 507
574 508 // Function to finish processing and show results
575 - function finishProcessing(wasAborted) {
509 + function finishProcessing() {
576 510 // Remove progress modal
577 511 $progressModal.remove();
578 -
512 +
579 513 // Determine notification type based on results
580 514 let notificationClass = 'success';
581 - if (wasAborted) {
582 - notificationClass = processed > 0 || updated > 0 ? 'warning' : 'info';
583 - } else if (failed > 0) {
515 + if (failed > 0) {
584 516 notificationClass = processed > 0 || updated > 0 ? 'warning' : 'error';
585 517 }
586 -
518 +
587 519 // Create summary message
588 - let resultHTML = '<div class="mxchat-kb-notification ' + notificationClass + '">' +
520 + let resultHTML = '<div class="mxchat-kb-notification ' + notificationClass + '">' +
589 521 '<h4>';
590 -
591 - if (wasAborted) {
592 - resultHTML += 'Processing stopped. ';
593 - if (processed > 0 || updated > 0) {
594 - resultHTML += 'Completed ' + (processed + updated) + ' of ' + totalToProcess + ' items before stopping';
595 - } else {
596 - resultHTML += 'No items were processed before stopping';
597 - }
598 - } else if (processed > 0 && updated > 0) {
522 +
523 + if (processed > 0 && updated > 0) {
599 524 resultHTML += 'Processed ' + processed + ' new items and updated ' + updated + ' existing items';
600 525 } else if (processed > 0) {
601 526 resultHTML += 'Processed ' + processed + ' items successfully';
602 527 } else if (updated > 0) {
@@ -603,10 +528,10 @@
603 528 resultHTML += 'Updated ' + updated + ' items successfully';
604 529 } else {
605 530 resultHTML += 'No items were processed successfully';
606 531 }
607 -
608 - if (failed > 0 && !wasAborted) {
532 +
533 + if (failed > 0) {
609 534 resultHTML += ' with ' + failed + ' failures';
610 535 }
611 536
612 537 resultHTML += '</h4>';
@@ -636,20 +561,21 @@
636 561 $button.prop('disabled', false)
637 562 .text('Process Selected Content')
638 563 .removeClass('update-mode mixed-mode');
639 564 $('.mxchat-kb-selected-count').text('(0)');
640 -
565 +
641 566 // Only reload if there were successful operations
642 567 if (processed > 0 || updated > 0) {
643 - // Refresh the knowledge base table with properly grouped entries
644 - if (typeof window.refreshKnowledgeBaseTable === 'function') {
645 - window.refreshKnowledgeBaseTable();
646 - }
647 -
648 - // Reload content list to update "already processed" status
568 + // Reload after delay
649 569 setTimeout(function() {
650 - loadContent();
651 - }, 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);
652 578 }
653 579 }
654 580
655 581 // Start processing the first post
@@ -659,150 +585,91 @@
659 585 // Initialize - Set WordPress as the active option by default
660 586 $('.mxchat-import-box[data-option="wordpress"]').addClass('active');
661 587 });
662 588
663 -// Navigation functionality for Knowledge Base page
589 +// Tab switching functionality - Keep this separate
664 590 jQuery(document).ready(function($) {
665 -
666 - // Hook into the new navigation system using .mxch-nav-link
667 - $(document).on('click', '.mxch-nav-link[data-target], .mxch-mobile-nav-link[data-target]', function() {
668 - var target = $(this).data('target');
669 -
670 - // Initialize Pinecone functionality when Pinecone section is activated
671 - if (target === 'pinecone') {
672 - setTimeout(function() {
673 - if (typeof initPineconeFeatures === 'function') {
674 - initPineconeFeatures();
675 - }
676 - }, 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);
677 619 }
678 -
679 - // Initialize OpenAI Vector Store functionality when Vector Store section is activated
680 - if (target === 'openai-vectorstore') {
681 - setTimeout(function() {
682 - if (typeof initVectorStoreFeatures === 'function') {
683 - initVectorStoreFeatures();
684 - }
685 - }, 100);
686 - }
687 -
688 - // Check if Pinecone was changed and we're going to import section
689 - if (target === 'import' && sessionStorage.getItem('mxchat_pinecone_changed') === 'true') {
690 - sessionStorage.removeItem('mxchat_pinecone_changed');
691 -
692 - // Show refresh notice
693 - var $knowledgeCard = $('#import .mxch-card').eq(1);
694 - if ($knowledgeCard.length > 0 && $knowledgeCard.find('.notice-warning').length === 0) {
695 - var refreshNotice = $('<div class="notice notice-warning" style="margin: 15px 0; padding: 10px 15px;">' +
696 - '<p style="margin: 0;">' +
697 - '<span class="dashicons dashicons-info" style="color: #f0ad4e; margin-right: 5px;"></span>' +
698 - 'Database settings have changed. ' +
699 - '<a href="#" onclick="location.reload(); return false;" style="font-weight: bold;">Click here to refresh</a> to see the updated knowledge base.' +
700 - '</p></div>');
701 -
702 - $knowledgeCard.prepend(refreshNotice);
703 - }
704 - }
705 - });
706 -
707 - // Also check on page load if we're already on one of these sections
708 - setTimeout(function() {
709 - if ($('#pinecone').is(':visible') || $('#pinecone.active').length > 0) {
710 - if (typeof initPineconeFeatures === 'function') {
711 - initPineconeFeatures();
712 - }
713 - }
714 -
715 - if ($('#openai-vectorstore').is(':visible') || $('#openai-vectorstore.active').length > 0) {
716 - if (typeof initVectorStoreFeatures === 'function') {
717 - initVectorStoreFeatures();
718 - }
719 - }
720 - }, 200);
620 + }
621 +
622 + // Initialize Pinecone functionality when Pinecone tab is activated
623 + if (tabId === 'pinecone') {
624 + setTimeout(function() {
625 + initPineconeFeatures();
626 + }, 100);
627 + }
721 628 });
722 629
723 -// Pinecone and Vector Store functionality - global functions
724 -var initPineconeFeatures, initVectorStoreFeatures;
725 630
726 -(function($) {
727 -
728 - // Helper function to update sidebar badge when integration is toggled
729 - function updateSidebarBadge(section, isActive) {
730 - // Find the nav item for this section (both desktop and mobile)
731 - var $desktopNavItem = $('.mxch-nav-item[data-section="' + section + '"] .mxch-nav-link');
732 - var $mobileNavItem = $('.mxch-mobile-nav-link[data-target="' + section + '"]');
733 -
734 - // Remove existing badge if any
735 - $desktopNavItem.find('.mxch-active-badge').remove();
736 - $mobileNavItem.find('.mxch-active-badge').remove();
737 -
738 - // Add badge if active
739 - if (isActive) {
740 - var badgeHtml = '<span class="mxch-nav-link-badge mxch-active-badge">Active</span>';
741 - $desktopNavItem.append(badgeHtml);
742 - $mobileNavItem.append(badgeHtml);
743 - }
744 - }
745 -
746 631 // Pinecone functionality
747 - initPineconeFeatures = function() {
748 - // Check for either old or new section ID
749 - 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) {
750 636 return;
751 637 }
752 -
638 +
753 639 initPineconeToggle();
754 640 initPineconeConnectionTest();
755 641 checkPineconeCompatibility();
756 - };
757 -
642 + }
643 +
758 644 function initPineconeToggle() {
759 645 // Remove any existing handlers to prevent duplicates
760 - var $toggleInput = $('input[name="mxchat_pinecone_addon_options[mxchat_use_pinecone]"]');
761 - $toggleInput.off('change.pineconeToggle');
762 -
763 - // Ensure the success notice exists in the settings div (add if not present)
764 - // Check for both the JS-added class and any existing PHP-rendered success notice
765 - var settingsDiv = $('.mxchat-pinecone-settings');
766 - if (settingsDiv.length > 0 && settingsDiv.find('.mxch-notice-success').length === 0) {
767 - var successNotice = $('<div class="mxch-notice mxch-notice-success mxchat-pinecone-enabled-notice" style="margin-bottom: 20px; display: none;">' +
768 - '<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>' +
769 - '<span>Pinecone is enabled. All new knowledge base content will be stored in Pinecone.</span>' +
770 - '</div>');
771 - settingsDiv.prepend(successNotice);
772 - }
773 -
646 + $('input[name="mxchat_pinecone_addon_options[mxchat_use_pinecone]"]').off('change.pineconeToggle');
647 +
774 648 // Add the toggle handler for UI only (auto-save will handle the actual saving)
775 - $toggleInput.on('change.pineconeToggle', function() {
649 + $('input[name="mxchat_pinecone_addon_options[mxchat_use_pinecone]"]').on('change.pineconeToggle', function() {
776 650 var $checkbox = $(this);
777 651 var isChecked = $checkbox.is(':checked');
778 652 var settingsDiv = $('.mxchat-pinecone-settings');
779 - var enabledNotice = settingsDiv.find('.mxchat-pinecone-enabled-notice, .mxch-notice-success');
780 -
653 +
654 + //console.log('Pinecone toggle changed to:', isChecked);
655 +
781 656 // Update the UI immediately
782 657 if (isChecked) {
783 658 settingsDiv.slideDown(300);
784 - enabledNotice.slideDown(300);
785 659 } else {
786 - enabledNotice.slideUp(300);
787 660 settingsDiv.slideUp(300);
788 661 }
789 -
790 - // Update sidebar badge for Pinecone
791 - updateSidebarBadge('pinecone', isChecked);
792 662 });
793 -
663 +
794 664 // Set initial state based on current checkbox value
795 665 var currentToggle = $('input[name="mxchat_pinecone_addon_options[mxchat_use_pinecone]"]');
796 666 if (currentToggle.length > 0) {
797 667 var settingsDiv = $('.mxchat-pinecone-settings');
798 - var enabledNotice = settingsDiv.find('.mxchat-pinecone-enabled-notice, .mxch-notice-success');
799 668 if (currentToggle.is(':checked')) {
800 669 settingsDiv.show();
801 - enabledNotice.show();
802 670 } else {
803 671 settingsDiv.hide();
804 - enabledNotice.hide();
805 672 }
806 673 }
807 674 }
808 675
@@ -899,68 +766,6 @@
899 766 }
900 767 });
901 768 }
902 769 }
903 -
904 - // ============================================
905 - // OpenAI Vector Store functionality
906 - // ============================================
907 - initVectorStoreFeatures = function() {
908 - if ($('#openai-vectorstore').length === 0) {
909 - return;
910 - }
911 -
912 - initVectorStoreToggle();
913 - };
914 -
915 - function initVectorStoreToggle() {
916 - // Remove any existing handlers to prevent duplicates
917 - var $toggleInput = $('input[name="mxchat_openai_vectorstore_options[mxchat_use_openai_vectorstore]"]');
918 - $toggleInput.off('change.vectorstoreToggle');
919 -
920 - // Ensure the success notice exists in the settings div (add if not present)
921 - // Check for both the JS-added class and any existing PHP-rendered success notice
922 - var settingsDiv = $('.mxchat-vectorstore-settings');
923 - if (settingsDiv.length > 0 && settingsDiv.find('.mxch-notice-success').length === 0) {
924 - var successNotice = $('<div class="mxch-notice mxch-notice-success mxchat-vectorstore-enabled-notice" style="margin-bottom: 20px; display: none;">' +
925 - '<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>' +
926 - '<span>OpenAI Vector Store is enabled. Queries will search your Vector Store for relevant content.</span>' +
927 - '</div>');
928 - settingsDiv.prepend(successNotice);
929 - }
930 -
931 - // Add the toggle handler for UI only (form submit will handle the actual saving)
932 - $toggleInput.on('change.vectorstoreToggle', function() {
933 - var $checkbox = $(this);
934 - var isChecked = $checkbox.is(':checked');
935 - var settingsDiv = $('.mxchat-vectorstore-settings');
936 - var enabledNotice = settingsDiv.find('.mxchat-vectorstore-enabled-notice, .mxch-notice-success');
937 -
938 - // Update the UI immediately
939 - if (isChecked) {
940 - settingsDiv.slideDown(300);
941 - enabledNotice.slideDown(300);
942 - } else {
943 - enabledNotice.slideUp(300);
944 - settingsDiv.slideUp(300);
945 - }
946 -
947 - // Update sidebar badge for OpenAI Vector Store
948 - updateSidebarBadge('openai-vectorstore', isChecked);
949 - });
950 -
951 - // Set initial state based on current checkbox value
952 - var currentToggle = $('input[name="mxchat_openai_vectorstore_options[mxchat_use_openai_vectorstore]"]');
953 - if (currentToggle.length > 0) {
954 - var settingsDiv = $('.mxchat-vectorstore-settings');
955 - var enabledNotice = settingsDiv.find('.mxchat-vectorstore-enabled-notice, .mxch-notice-success');
956 - if (currentToggle.is(':checked')) {
957 - settingsDiv.show();
958 - enabledNotice.show();
959 - } else {
960 - settingsDiv.hide();
961 - enabledNotice.hide();
962 - }
963 - }
964 - }
965 -
966 -})(jQuery);
770 +
771 +});