/** * Admin JavaScript * * Handles AJAX functionality for documentation mappings. * * @package RobotsTxt\DocumentationMarkdown */ (function($) { 'use strict'; /** * Sync a single mapping via AJAX */ function syncMapping(mappingId, button) { const $button = $(button); const originalText = $button.text(); // Disable button and show loading state $button.prop('disabled', true).text(robotstxtDocMd.strings.syncing); $.ajax({ url: robotstxtDocMd.ajaxUrl, type: 'POST', data: { action: 'robotstxt_docmd_sync_mapping', nonce: robotstxtDocMd.nonce, mapping_id: mappingId }, success: function(response) { if (response.success) { // Update sync status badge const $row = $button.closest('tr'); const $statusCell = $row.find('td').eq(4); // Sync Status column $statusCell.html(response.data.sync_status); // Update last sync time const $lastSyncCell = $row.find('td').eq(5); // Last Sync column if (response.data.mapping.last_sync) { $lastSyncCell.text(response.data.mapping.last_sync); } // Show success message showNotice(response.data.message, 'success'); } else { showNotice(robotstxtDocMd.strings.syncError + ' ' + response.data.message, 'error'); } }, error: function(xhr, status, error) { showNotice(robotstxtDocMd.strings.syncError + ' ' + error, 'error'); }, complete: function() { // Re-enable button $button.prop('disabled', false).text(originalText); } }); } /** * Sync all active mappings via AJAX */ function syncAllMappings() { const $button = $('#sync-all-mappings'); const originalText = $button.text(); // Disable button and show loading state $button.prop('disabled', true).text(robotstxtDocMd.strings.syncingAll); $.ajax({ url: robotstxtDocMd.ajaxUrl, type: 'POST', data: { action: 'robotstxt_docmd_sync_all', nonce: robotstxtDocMd.nonce }, success: function(response) { if (response.success) { showNotice(response.data.message, 'success'); // Reload page to show updated statuses setTimeout(function() { location.reload(); }, 1500); } else { showNotice(robotstxtDocMd.strings.syncError + ' ' + response.data.message, 'error'); } }, error: function(xhr, status, error) { showNotice(robotstxtDocMd.strings.syncError + ' ' + error, 'error'); }, complete: function() { // Re-enable button $button.prop('disabled', false).text(originalText); } }); } /** * Show admin notice */ function showNotice(message, type) { const $notice = $('

' + message + '

'); // Insert after the h1 $('.wrap h1').after($notice); // Make it dismissible $(document).trigger('wp-updates-notice-added'); // Auto-dismiss after 5 seconds setTimeout(function() { $notice.fadeOut(400, function() { $(this).remove(); }); }, 5000); } // Document ready $(document).ready(function() { // Sync single mapping button click $('.sync-mapping-btn').on('click', function(e) { e.preventDefault(); const mappingId = $(this).data('mapping-id'); syncMapping(mappingId, this); }); // Sync all mappings button click $('#sync-all-mappings').on('click', function(e) { e.preventDefault(); syncAllMappings(); }); // Form validation $('form[action*="robotstxt_docmd_save_mapping"]').on('submit', function(e) { const title = $('#title').val().trim(); const repoOwner = $('#repo_owner').val().trim(); const repoName = $('#repo_name').val().trim(); const filePath = $('#file_path').val().trim(); if (!title || !repoOwner || !repoName || !filePath) { e.preventDefault(); showNotice('Please fill in all required fields.', 'error'); return false; } // Validate file path ends with .md or .markdown if (!/\.(md|markdown)$/i.test(filePath)) { e.preventDefault(); showNotice('File path must end with .md or .markdown', 'error'); return false; } }); }); })(jQuery);