/home/altere25/.trash/wp-to-sanity-companion
Edit: /home/altere25/.trash/wp-to-sanity-companion/assets\js\admin.js (8534B)
/**
* Altered Digital Migration — admin JS
*
* - ADProgress class: real-time polling of Worker /v2/migrations.
* - updateSlug gated to plugin settings pages only (no global post-editor
* side effect — the classic editor already has its own slug UI).
* - wpToSanitySyncPost kept for the meta-box "Sync to Sanity" button.
* - wpToSanityRegenerateSecret kept.
*
* Dead v1 code removed: pollMigrationStatus, updateMigrationMetaBox,
* wpToSanityTrackProgress, showNotification, export/status polling (the
* vestigial migration_queue table no longer exists).
*/
(function($) {
'use strict';
var W = window.wpToSanity = window.wpToSanity || {};
// -----------------------------------------------------------------
// Regenerate webhook secret (settings page)
// -----------------------------------------------------------------
W.wpToSanityRegenerateSecret = function() {
if (!confirm('Regenerate the webhook secret? You will need to update your Worker configuration.')) {
return;
}
var newSecret = '';
var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
for (var i = 0; i < 32; i++) {
newSecret += chars.charAt(Math.floor(Math.random() * chars.length));
}
// Both v1 + v2 option names accept the value; the active input has
// name="ad_settings[webhook_secret]" on v2.
$('input[name="ad_settings[webhook_secret]"], input[name="wp_to_sanity_settings[webhook_secret]"]').val(newSecret);
};
// -----------------------------------------------------------------
// Sync-now button (meta box on post-edit screen)
// -----------------------------------------------------------------
W.wpToSanitySyncPost = function(postId) {
$.ajax({
url: W.restUrl + 'export',
method: 'POST',
headers: { 'X-WP-Nonce': W.restNonce },
data: { post_id: postId },
success: function(resp) {
if (resp && resp.success) {
alert('Sync triggered. Status will update shortly.');
} else {
alert('Sync failed: ' + (resp && resp.error ? resp.error : 'unknown error'));
}
},
error: function() { alert('Sync request failed.'); }
});
};
// -----------------------------------------------------------------
// Slug helper — gated to plugin settings pages only.
// The classic editor already manages its own slug; running this on
// every post_title input was a v1 side-effect that overwrote user
// slugs. Now it only runs when an AD settings field with
// name="post_name" exists (rare; left for back-compat).
// -----------------------------------------------------------------
function maybeUpdateSlug() {
if (!W || !W.restUrl) { return; }
// Only on a plugin settings page that exposes a post_name input.
if (!$('input[name="post_name"]').length) { return; }
if (!$('body').hasClass('wp-to-sanity_page_wp-to-sanity-settings') &&
!$('body').hasClass('toplevel_page_wp-to-sanity')) {
return;
}
var title = $('input[name="post_title"]').val();
if (!title) { return; }
var slug = title.toLowerCase()
.replace(/[^a-z0-9\s-]/g, '')
.replace(/\s+/g, '-')
.replace(/-+/g, '-')
.trim();
$('input[name="post_name"]').val(slug);
}
$(document).on('input', 'input[name="post_title"]', maybeUpdateSlug);
// -----------------------------------------------------------------
// ADProgress — real-time migration progress
// -----------------------------------------------------------------
function ADProgress() {
this.pollMs = 5000;
this.timer = null;
}
ADProgress.prototype.start = function() {
var self = this;
this.tick();
this.timer = setInterval(function() { self.tick(); }, this.pollMs);
};
ADProgress.prototype.stop = function() {
if (this.timer) { clearInterval(this.timer); this.timer = null; }
};
ADProgress.prototype.tick = function() {
if (!W || !W.restUrl) { return; }
var self = this;
$.ajax({
url: W.restUrl + 'progress',
method: 'GET',
headers: { 'X-WP-Nonce': W.restNonce },
success: function(resp) {
if (resp && resp.success && resp.data) {
self.render(resp.data);
}
},
error: function() {
// Worker unreachable — leave last-known state in place.
}
});
};
ADProgress.prototype.render = function(data) {
var stats = data.stats || {};
var total = parseInt(stats.total || 0, 10);
var success = parseInt(stats.success || 0, 10);
var pending = parseInt(stats.pending || 0, 10);
var failed = parseInt(stats.failed || 0, 10);
$('#ad-stat-total').text(total);
$('#ad-stat-success').text(success);
$('#ad-stat-pending').text(pending);
$('#ad-stat-failed').text(failed);
var pct = total > 0 ? Math.round((success / total) * 100) : 0;
$('#ad-progress-fill').css('width', pct + '%');
$('#ad-progress-pct').text(pct + '%');
var recent = data.recent || [];
var $tbody = $('#ad-progress-table tbody');
if (!$tbody.length) { return; }
if (!recent.length) {
$tbody.html('
| No migrations yet. |
');
return;
}
var rows = '';
for (var i = 0; i < recent.length; i++) {
var r = recent[i];
rows += '
' +
'| ' + (r.post_id || '') + ' | ' +
'' + (r.action || '') + ' | ' +
'' + (r.status || '') + ' | ' +
'' + (r.sanity_id || '') + ' | ' +
'' + (r.updated_at || r.created_at || '') + ' | ' +
'
';
}
$tbody.html(rows);
};
$(function() {
if ($('#ad-progress-table').length) {
new ADProgress().start();
}
});
// Expose for any future dashboard widget.
W.ADProgress = ADProgress;
// -----------------------------------------------------------------
// Wizard (onboarding-v2) — Phase B shell only.
// Phase C wires the real flows; here we just advance panels.
// -----------------------------------------------------------------
$(function() {
if (!$('.ad-wizard-steps').length) { return; }
function showPanel(n) {
$('.ad-wizard-panel').attr('hidden', true);
$('.ad-wizard-panel[data-panel="' + n + '"]').removeAttr('hidden');
$('.ad-wizard-steps li').removeClass('active');
$('.ad-wizard-steps li[data-step="' + n + '"]').addClass('active');
}
// Login submit → advance to step 2 (stub).
$('#ad-login-form').on('submit', function(e) {
e.preventDefault();
var $form = $(this);
$.ajax({
url: W.restUrl + 'auth/login',
method: 'POST',
headers: { 'X-WP-Nonce': W.restNonce },
data: {
email: $form.find('input[name="email"]').val(),
password: $form.find('input[name="password"]').val()
},
success: function(resp) {
if (resp && resp.success) {
showPanel(2);
} else {
$('#ad-login-status').removeAttr('hidden')
.text((resp && resp.error) ? resp.error : 'Login failed.');
}
},
error: function() {
$('#ad-login-status').removeAttr('hidden').text('Login request failed.');
}
});
});
$('#ad-analyze-trigger').on('click', function() {
// Phase C: trigger /analyze, poll, advance. For now just bump
// the panel so the wizard demo flow is walkable.
showPanel(3);
});
});
})(jQuery);