PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 2.3.5
MxChat – AI Chatbot & Content Generation for WordPress v2.3.5
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 +250 -484 3.2.52.3.5 View file →
@@ -37,101 +37,50 @@
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 -
69 - // UPDATED: Add or update bot_id hidden field for URL forms
70 - updateBotIdInForm('#mxchat-url-form');
71 -
62 + $('#import_type').val(option);
63 +
72 64 // Update the description text based on the import type
73 65 let descriptionText = '';
74 - if (option === 'pdf-url') {
66 + if (option === 'pdf') {
75 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.';
76 68 } else if (option === 'sitemap') {
77 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.';
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 70 } else if (option === 'url') {
89 71 descriptionText = 'Import content from any webpage by entering its URL.';
90 72 }
91 73 $('#url-description-text').text(descriptionText);
92 74 break;
93 -
75 +
94 76 case 'content':
95 77 // Show content input area
96 78 $('#mxchat-content-input-area').show();
97 -
98 - // UPDATED: Add or update bot_id hidden field for content forms
99 - updateBotIdInForm('#mxchat-content-form');
100 79 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 80 }
110 81 });
111 82
112 -// Helper function to add/update bot_id hidden field in forms
113 -function updateBotIdInForm(formSelector) {
114 - const $form = $(formSelector);
115 - if ($form.length === 0) return;
116 -
117 - // Get current bot_id from the bot selector dropdown
118 - const currentBotId = $('#mxchat-bot-selector').val();
119 -
120 - // Only add bot_id field if multi-bot is active and bot is not 'default'
121 - if (currentBotId && currentBotId !== 'default') {
122 - // Remove existing bot_id field if it exists
123 - $form.find('input[name="bot_id"]').remove();
124 -
125 - // Add new bot_id field
126 - $form.append('<input type="hidden" name="bot_id" value="' + currentBotId + '">');
127 -
128 - console.log('Updated bot_id in form ' + formSelector + ' to: ' + currentBotId);
129 - } else {
130 - // Remove bot_id field if bot is default
131 - $form.find('input[name="bot_id"]').remove();
132 - }
133 -}
134 83
135 84 // Load content via AJAX
136 85 function loadContent() {
137 86 $loading.show();
@@ -140,9 +89,9 @@
140 89 const data = {
141 90 action: 'mxchat_get_content_list',
142 91 nonce: mxchatSelector.nonce,
143 92 page: currentPage,
144 - per_page: 100,
93 + per_page: 50,
145 94 search: $searchInput.val(),
146 95 post_type: $typeFilter.val(),
147 96 post_status: $statusFilter.val(),
148 97 processed_filter: $processedFilter.val()
@@ -207,22 +156,18 @@
207 156
208 157 // Render content items
209 158 function renderContentItems(items) {
210 159 let html = '';
211 -
160 +
212 161 items.forEach(function(item) {
213 162 const isSelected = selectedItems.has(item.id);
214 163 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 - }
164 +
165 + // Updated badge text
166 + const badgeText = isProcessed ? 'In Knowledge Base' : 'Not In Knowledge Base';
222 167 const badgeClass = isProcessed ? 'mxchat-kb-processed-badge' : 'mxchat-kb-unprocessed-badge';
223 -
224 -
168 +
169 +
225 170 html += `
226 171 <div class="mxchat-kb-content-item ${isProcessed ? 'processed' : ''}" data-id="${item.id}">
227 172 <div class="mxchat-kb-content-checkbox">
228 173 <input type="checkbox" id="content-${item.id}" ${isSelected ? 'checked' : ''}>
@@ -242,9 +187,9 @@
242 187 </div>
243 188 </div>
244 189 `;
245 190 });
246 -
191 +
247 192 $contentList.html(html);
248 193
249 194 // Add event listeners for checkboxes using delegation for better performance
250 195 $contentList.off('change', 'input[type="checkbox"]').on('change', 'input[type="checkbox"]', function() {
@@ -317,36 +262,18 @@
317 262 function updateSelection() {
318 263 const selectedCount = selectedItems.size;
319 264 $selectionCount.text(selectedCount + ' ' + (selectedCount === 1 ? 'selected' : 'selected'));
320 265 $('.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 -
266 +
340 267 // Determine if any selected items are already processed
341 268 const hasProcessedItems = Array.from(selectedItems).some(id => {
342 269 const item = allItems.find(item => item.id === id);
343 270 return item && item.already_processed;
344 271 });
345 -
272 +
346 273 if (selectedCount > 0) {
347 274 $processButton.prop('disabled', false);
348 -
275 +
349 276 // Update button text based on selection
350 277 if (hasProcessedItems && selectedCount === 1) {
351 278 $processButton.text('Update Selected Content (1)').addClass('update-mode');
352 279 } else if (hasProcessedItems && selectedCount > 1) {
@@ -358,9 +285,9 @@
358 285 $processButton.prop('disabled', true);
359 286 $processButton.text('Process Selected Content').removeClass('update-mode mixed-mode');
360 287 $('.mxchat-kb-selected-count').text('(0)');
361 288 }
362 -
289 +
363 290 updateSelectAllState();
364 291 }
365 292
366 293 // Update "Select All" checkbox state
@@ -415,394 +342,295 @@
415 342 selectedItems.clear(); // Clear selection when filter changes
416 343 loadContent();
417 344 });
418 345
419 -// Process selected content
420 -$processButton.on('click', function() {
421 - if (selectedItems.size === 0) {
422 - return;
423 - }
424 -
425 - const $button = $(this);
426 - $button.prop('disabled', true);
427 -
428 - // Update button text based on mode
429 - if ($button.hasClass('update-mode')) {
430 - $button.text('Updating...');
431 - } else if ($button.hasClass('mixed-mode')) {
432 - $button.text('Processing/Updating...');
433 - } else {
434 - $button.text('Processing...');
435 - }
436 -
437 - // Convert selected items to array
438 - const selectedPostIds = Array.from(selectedItems);
439 - const totalToProcess = selectedPostIds.length;
440 - let processed = 0;
441 - let updated = 0;
442 - let failed = 0;
443 - const results = {
444 - success: [],
445 - updated: [],
446 - failed: []
447 - };
448 -
449 - // UPDATED: Get current bot_id for WordPress content processing
450 - const currentBotId = $('#mxchat-bot-selector').val();
451 -
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
457 - const $progressModal = $('<div class="mxchat-kb-processing-overlay">' +
458 - '<div class="mxchat-kb-processing-content">' +
459 - '<h3>Processing Content</h3>' +
460 - '<p class="mxchat-kb-processing-status">Processing 1 of ' + totalToProcess + '...</p>' +
461 - '<div class="mxchat-kb-progress-bar"><div class="mxchat-kb-progress-fill" style="width: 0%"></div></div>' +
462 - '<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 - '</div>' +
466 - '</div>');
467 -
468 - $('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 -
479 - // Process posts one by one
480 - function processNext(index) {
481 - // Check if processing was aborted
482 - if (abortProcessing) {
483 - finishProcessing(true); // Pass true to indicate abort
346 + // Process selected content
347 + $processButton.on('click', function() {
348 + if (selectedItems.size === 0) {
484 349 return;
485 350 }
486 -
487 - if (index >= selectedPostIds.length) {
488 - // All done
489 - finishProcessing();
490 - return;
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...');
491 362 }
492 -
493 - const postId = selectedPostIds[index];
494 - const percent = Math.round((index / totalToProcess) * 100);
495 - const item = allItems.find(item => item.id === postId);
496 - const isUpdate = item && item.already_processed;
497 -
498 - // Update progress UI
499 - $progressModal.find('.mxchat-kb-processing-status')
500 - .text((isUpdate ? 'Updating' : 'Processing') + ' ' + (index + 1) + ' of ' + totalToProcess + '...');
501 - $progressModal.find('.mxchat-kb-progress-fill').css('width', percent + '%');
502 -
503 - // UPDATED: Prepare AJAX data with bot_id
504 - const ajaxData = {
505 - action: 'mxchat_process_selected_content',
506 - nonce: mxchatSelector.nonce,
507 - post_ids: [postId],
508 - is_update: isUpdate
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: []
509 374 };
510 -
511 - // Add bot_id if multi-bot is active and not default
512 - if (currentBotId && currentBotId !== 'default') {
513 - ajaxData.bot_id = currentBotId;
514 - }
515 -
516 - // Make AJAX request for this post (store reference for potential abort)
517 - currentXHR = $.ajax({
518 - url: mxchatSelector.ajaxurl,
519 - method: 'POST',
520 - data: ajaxData,
521 - dataType: 'json',
522 - success: function(response) {
523 - if (response.success) {
524 - if (isUpdate) {
525 - updated++;
526 - results.updated.push({
527 - id: postId,
528 - title: response.data.title || ('ID: ' + postId)
529 - });
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);
530 435 } else {
531 - processed++;
532 - results.success.push({
436 + failed++;
437 + results.failed.push({
533 438 id: postId,
534 - title: response.data.title || ('ID: ' + postId)
439 + error: response.data || 'Unknown error'
535 440 });
441 +
442 + $progressModal.find('.mxchat-kb-current-item')
443 + .text('Failed to ' + (isUpdate ? 'update' : 'process') + ' ID: ' + postId);
536 444 }
537 445
538 - $progressModal.find('.mxchat-kb-current-item')
539 - .text('Successfully ' + (isUpdate ? 'updated' : 'processed') + ': ' + response.data.title);
540 - } else {
446 + // Process next post
447 + setTimeout(function() {
448 + processNext(index + 1);
449 + }, 500); // Small delay between requests
450 + },
451 + error: function(xhr, status, error) {
541 452 failed++;
542 453 results.failed.push({
543 454 id: postId,
544 - error: response.data || 'Unknown error'
455 + error: error || 'Server error'
545 456 });
546 457
547 458 $progressModal.find('.mxchat-kb-current-item')
548 - .text('Failed to ' + (isUpdate ? 'update' : 'process') + ' ID: ' + postId);
459 + .text('Error ' + (isUpdate ? 'updating' : 'processing') + ' ID: ' + postId);
460 +
461 + // Process next post
462 + setTimeout(function() {
463 + processNext(index + 1);
464 + }, 500);
549 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>';
550 504
551 - // Process next post
552 - setTimeout(function() {
553 - processNext(index + 1);
554 - }, 500); // Small delay between requests
555 - },
556 - error: function(xhr, status, error) {
557 - failed++;
558 - results.failed.push({
559 - id: postId,
560 - error: error || 'Server error'
505 + results.failed.forEach(function(item) {
506 + resultHTML += '<li><strong>ID: ' + item.id + '</strong>: ' + item.error + '</li>';
561 507 });
562 508
563 - $progressModal.find('.mxchat-kb-current-item')
564 - .text('Error ' + (isUpdate ? 'updating' : 'processing') + ' ID: ' + postId);
565 -
566 - // Process next post
567 - setTimeout(function() {
568 - processNext(index + 1);
569 - }, 500);
509 + resultHTML += '</ul></div>';
570 510 }
571 - });
572 - }
573 -
574 - // Function to finish processing and show results
575 - function finishProcessing(wasAborted) {
576 - // Remove progress modal
577 - $progressModal.remove();
578 -
579 - // Determine notification type based on results
580 - let notificationClass = 'success';
581 - if (wasAborted) {
582 - notificationClass = processed > 0 || updated > 0 ? 'warning' : 'info';
583 - } else if (failed > 0) {
584 - notificationClass = processed > 0 || updated > 0 ? 'warning' : 'error';
585 - }
586 -
587 - // Create summary message
588 - let resultHTML = '<div class="mxchat-kb-notification ' + notificationClass + '">' +
589 - '<h4>';
590 -
591 - if (wasAborted) {
592 - resultHTML += 'Processing stopped. ';
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
593 528 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';
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);
597 539 }
598 - } else if (processed > 0 && updated > 0) {
599 - resultHTML += 'Processed ' + processed + ' new items and updated ' + updated + ' existing items';
600 - } else if (processed > 0) {
601 - resultHTML += 'Processed ' + processed + ' items successfully';
602 - } else if (updated > 0) {
603 - resultHTML += 'Updated ' + updated + ' items successfully';
604 - } else {
605 - resultHTML += 'No items were processed successfully';
606 540 }
607 -
608 - if (failed > 0 && !wasAborted) {
609 - resultHTML += ' with ' + failed + ' failures';
610 - }
611 541
612 - resultHTML += '</h4>';
613 -
614 - // Add details if there were failures
615 - if (failed > 0) {
616 - resultHTML += '<div class="mxchat-kb-results-details">';
617 - resultHTML += '<h5>Failed Items:</h5><ul>';
618 -
619 - results.failed.forEach(function(item) {
620 - resultHTML += '<li><strong>ID: ' + item.id + '</strong>: ' + item.error + '</li>';
621 - });
622 -
623 - resultHTML += '</ul></div>';
624 - }
625 -
626 - resultHTML += '</div>';
627 -
628 - // Show results in modal
629 - $modal.find('.mxchat-kb-modal-content').prepend($(resultHTML));
630 -
631 - // Clear selection
632 - selectedItems.clear();
633 - updateSelection();
634 -
635 - // Enable button
636 - $button.prop('disabled', false)
637 - .text('Process Selected Content')
638 - .removeClass('update-mode mixed-mode');
639 - $('.mxchat-kb-selected-count').text('(0)');
542 + // Start processing the first post
543 + processNext(0);
544 + });
640 545
641 - // Only reload if there were successful operations
642 - 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
649 - setTimeout(function() {
650 - loadContent();
651 - }, 1000);
652 - }
653 - }
654 -
655 - // Start processing the first post
656 - processNext(0);
657 -});
658 -
659 546 // Initialize - Set WordPress as the active option by default
660 547 $('.mxchat-import-box[data-option="wordpress"]').addClass('active');
661 548 });
662 549
663 -// Navigation functionality for Knowledge Base page
550 +// Tab switching functionality - Keep this separate
664 551 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);
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);
677 580 }
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);
581 + }
582 +
583 + // Initialize Pinecone functionality when Pinecone tab is activated
584 + if (tabId === 'pinecone') {
585 + setTimeout(function() {
586 + initPineconeFeatures();
587 + }, 100);
588 + }
721 589 });
722 590
723 -// Pinecone and Vector Store functionality - global functions
724 -var initPineconeFeatures, initVectorStoreFeatures;
725 591
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 592 // 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) {
593 + function initPineconeFeatures() {
594 + //console.log('Initializing Pinecone features...');
595 +
596 + if ($('#mxchat-kb-tab-pinecone').length === 0) {
750 597 return;
751 598 }
752 -
599 +
753 600 initPineconeToggle();
754 601 initPineconeConnectionTest();
755 602 checkPineconeCompatibility();
756 - };
757 -
603 + }
604 +
758 605 function initPineconeToggle() {
759 606 // 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 -
607 + $('input[name="mxchat_pinecone_addon_options[mxchat_use_pinecone]"]').off('change.pineconeToggle');
608 +
774 609 // Add the toggle handler for UI only (auto-save will handle the actual saving)
775 - $toggleInput.on('change.pineconeToggle', function() {
610 + $('input[name="mxchat_pinecone_addon_options[mxchat_use_pinecone]"]').on('change.pineconeToggle', function() {
776 611 var $checkbox = $(this);
777 612 var isChecked = $checkbox.is(':checked');
778 613 var settingsDiv = $('.mxchat-pinecone-settings');
779 - var enabledNotice = settingsDiv.find('.mxchat-pinecone-enabled-notice, .mxch-notice-success');
780 -
614 +
615 + //console.log('Pinecone toggle changed to:', isChecked);
616 +
781 617 // Update the UI immediately
782 618 if (isChecked) {
783 619 settingsDiv.slideDown(300);
784 - enabledNotice.slideDown(300);
785 620 } else {
786 - enabledNotice.slideUp(300);
787 621 settingsDiv.slideUp(300);
788 622 }
789 -
790 - // Update sidebar badge for Pinecone
791 - updateSidebarBadge('pinecone', isChecked);
792 623 });
793 -
624 +
794 625 // Set initial state based on current checkbox value
795 626 var currentToggle = $('input[name="mxchat_pinecone_addon_options[mxchat_use_pinecone]"]');
796 627 if (currentToggle.length > 0) {
797 628 var settingsDiv = $('.mxchat-pinecone-settings');
798 - var enabledNotice = settingsDiv.find('.mxchat-pinecone-enabled-notice, .mxch-notice-success');
799 629 if (currentToggle.is(':checked')) {
800 630 settingsDiv.show();
801 - enabledNotice.show();
802 631 } else {
803 632 settingsDiv.hide();
804 - enabledNotice.hide();
805 633 }
806 634 }
807 635 }
808 636
@@ -899,68 +727,6 @@
899 727 }
900 728 });
901 729 }
902 730 }
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);
731 +
732 +});