/** * WooCommerce Business Central - Admin JavaScript */ (function($) { 'use strict'; var WBC_Admin = { /** * Initialize */ init: function() { this.bindEvents(); this.checkInitialSyncStatus(); }, /** * If a background sync is already running (e.g. triggered by cron, * or the admin reloaded the page mid-sync), resume polling for it. */ checkInitialSyncStatus: function() { var $btn = $('#wbc-manual-sync'); var $status = $('#wbc-sync-status'); if (!$btn.length) { return; } $.ajax({ url: wbc_admin.ajax_url, type: 'POST', data: { action: 'wbc_sync_status', nonce: wbc_admin.nonce }, success: function(response) { if (response.success && response.data.status === 'running') { $btn.prop('disabled', true); $status.removeClass('success error').addClass('loading'); WBC_Admin.pollSyncStatus($btn, $status); } } }); }, /** * Bind event handlers */ bindEvents: function() { // Test connection $('#wbc-test-connection').on('click', this.testConnection); // Manual sync $('#wbc-manual-sync').on('click', this.manualSync); // Clear logs $('#wbc-clear-logs').on('click', this.clearLogs); // Load companies $('#wbc-load-companies').on('click', this.loadCompanies); // Select company $('#wbc-company-select').on('change', this.selectCompany); // Toggle log data $(document).on('click', '.wbc-toggle-data', this.toggleLogData); }, /** * Test connection to Business Central */ testConnection: function(e) { e.preventDefault(); var $btn = $(this); var $status = $('#wbc-connection-status'); $btn.prop('disabled', true); $status.removeClass('success error').addClass('loading').text(wbc_admin.strings.testing); $.ajax({ url: wbc_admin.ajax_url, type: 'POST', data: { action: 'wbc_test_connection', nonce: wbc_admin.nonce }, success: function(response) { $btn.prop('disabled', false); $status.removeClass('loading'); if (response.success) { $status.addClass('success').text(response.data.message); } else { $status.addClass('error').text(response.data.message || 'Connection failed'); } }, error: function(xhr, status, error) { $btn.prop('disabled', false); $status.removeClass('loading').addClass('error').text('Request failed: ' + error); } }); }, /** * Run manual sync * * The sync itself runs in the background (Action Scheduler batches), * so this just kicks it off and then polls for progress instead of * waiting on one long-lived request. */ manualSync: function(e) { e.preventDefault(); var $btn = $(this); var $status = $('#wbc-sync-status'); $btn.prop('disabled', true); $status.removeClass('success error').addClass('loading').text(wbc_admin.strings.syncing); $.ajax({ url: wbc_admin.ajax_url, type: 'POST', data: { action: 'wbc_manual_sync', nonce: wbc_admin.nonce }, success: function(response) { if (response.success) { WBC_Admin.pollSyncStatus($btn, $status); } else { $btn.prop('disabled', false); $status.removeClass('loading').addClass('error').text((response.data && response.data.message) || 'Sync failed'); } }, error: function(xhr, status, error) { $btn.prop('disabled', false); $status.removeClass('loading').addClass('error').text('Request failed: ' + error); } }); }, /** * Poll background sync progress until it completes */ pollSyncStatus: function($btn, $status) { $.ajax({ url: wbc_admin.ajax_url, type: 'POST', data: { action: 'wbc_sync_status', nonce: wbc_admin.nonce }, success: function(response) { if (!response.success) { $btn.prop('disabled', false); $status.removeClass('loading').addClass('error').text((response.data && response.data.message) || 'Failed to get sync status'); return; } var run = response.data; if (run.status === 'running') { var progressText = (run.mode === 'category') ? (run.pages_done || 0) + ' page(s), ' + (run.total || 0) + ' item(s) checked' : (run.batches_done || 0) + ' / ' + (run.total_batches || 0) + ' batches'; $status.text('Syncing... ' + progressText + ' (success: ' + (run.success || 0) + ', failed: ' + (run.failed || 0) + ', skipped: ' + (run.skipped || 0) + ')'); setTimeout(function() { WBC_Admin.pollSyncStatus($btn, $status); }, 3000); } else if (run.status === 'completed') { $btn.prop('disabled', false); $status.removeClass('loading').addClass('success').text('Sync completed. Success: ' + (run.success || 0) + ', Failed: ' + (run.failed || 0) + ', Skipped: ' + (run.skipped || 0)); } else { $btn.prop('disabled', false); $status.removeClass('loading'); } }, error: function(xhr, status, error) { $btn.prop('disabled', false); $status.removeClass('loading').addClass('error').text('Request failed: ' + error); } }); }, /** * Clear all logs */ clearLogs: function(e) { e.preventDefault(); if (!confirm(wbc_admin.strings.confirm_clear)) { return; } var $btn = $(this); var originalText = $btn.text(); $btn.prop('disabled', true).text(wbc_admin.strings.clearing); $.ajax({ url: wbc_admin.ajax_url, type: 'POST', data: { action: 'wbc_clear_logs', nonce: wbc_admin.nonce }, success: function(response) { if (response.success) { // Reload the page to show empty logs location.reload(); } else { alert(response.data.message || 'Failed to clear logs'); $btn.prop('disabled', false).text(originalText); } }, error: function(xhr, status, error) { alert('Request failed: ' + error); $btn.prop('disabled', false).text(originalText); } }); }, /** * Load companies from Business Central */ loadCompanies: function(e) { e.preventDefault(); var $btn = $(this); var $select = $('#wbc-company-select'); var $list = $('#wbc-companies-list'); var originalText = $btn.text(); $btn.prop('disabled', true).text(wbc_admin.strings.loading); $.ajax({ url: wbc_admin.ajax_url, type: 'POST', data: { action: 'wbc_get_companies', nonce: wbc_admin.nonce }, success: function(response) { $btn.prop('disabled', false).text(originalText); if (response.success && response.data.companies) { // Clear existing options except the first one $select.find('option:not(:first)').remove(); // Add companies $.each(response.data.companies, function(i, company) { $select.append( $('