| 1 |
wpStatelessBatch = { |
| 2 |
token: window.wp_stateless_batch.REST_API_TOKEN, |
| 3 |
apiRoot: window.wp_stateless_batch.api_root + 'batch/', |
| 4 |
interval: null, |
| 5 |
|
| 6 |
startPolling: function () { |
| 7 |
var that = this |
| 8 |
this.stopPolling() |
| 9 |
this.interval = setInterval(function () { |
| 10 |
that.getState() |
| 11 |
}, 1000) |
| 12 |
}, |
| 13 |
|
| 14 |
stopPolling: function () { |
| 15 |
clearInterval(this.interval) |
| 16 |
}, |
| 17 |
|
| 18 |
updateState: function(state, action = false) { |
| 19 |
var detail = { |
| 20 |
state, |
| 21 |
action, |
| 22 |
} |
| 23 |
|
| 24 |
var event = new CustomEvent('wp-stateless-batch-state-updated', { detail }) |
| 25 |
|
| 26 |
document.dispatchEvent(event) |
| 27 |
|
| 28 |
if (state.is_running) { |
| 29 |
this.startPolling() |
| 30 |
} else { |
| 31 |
this.stopPolling() |
| 32 |
} |
| 33 |
}, |
| 34 |
|
| 35 |
processFail: function(error) { |
| 36 |
console.log(error) |
| 37 |
|
| 38 |
var event = new CustomEvent('wp-stateless-batch-error', { detail: error }) |
| 39 |
|
| 40 |
document.dispatchEvent(event) |
| 41 |
}, |
| 42 |
|
| 43 |
processAction: function(action, payload, callback = null) { |
| 44 |
var that = this |
| 45 |
|
| 46 |
var data = { |
| 47 |
action, |
| 48 |
...payload, |
| 49 |
} |
| 50 |
|
| 51 |
jQuery.ajax({ |
| 52 |
method: 'POST', |
| 53 |
url: that.apiRoot + 'action', |
| 54 |
headers: { |
| 55 |
'x-wps-auth': that.token, |
| 56 |
'Content-Type': 'application/json', |
| 57 |
}, |
| 58 |
dataType: 'json', |
| 59 |
data: JSON.stringify(data), |
| 60 |
}) |
| 61 |
.then(function (response) { |
| 62 |
that.updateState(response.data, true) |
| 63 |
}) |
| 64 |
.fail(function (error) { |
| 65 |
that.processFail(error) |
| 66 |
}) |
| 67 |
.always(function () { |
| 68 |
if (callback) { |
| 69 |
callback() |
| 70 |
} |
| 71 |
}) |
| 72 |
}, |
| 73 |
|
| 74 |
getState: function(data = {}) { |
| 75 |
var that = this |
| 76 |
|
| 77 |
jQuery.ajax({ |
| 78 |
method: 'GET', |
| 79 |
url: that.apiRoot + 'state', |
| 80 |
data, |
| 81 |
headers: { |
| 82 |
'x-wps-auth': that.token, |
| 83 |
'Content-Type': 'application/json', |
| 84 |
}, |
| 85 |
}) |
| 86 |
.then(function (response) { |
| 87 |
that.updateState(response.data) |
| 88 |
}) |
| 89 |
.fail(function (error) { |
| 90 |
that.processFail(error) |
| 91 |
}) |
| 92 |
}, |
| 93 |
|
| 94 |
init: function() { |
| 95 |
if ( window.wp_stateless_batch.is_running ) { |
| 96 |
this.startPolling() |
| 97 |
} |
| 98 |
|
| 99 |
// Check if we have a batch running on the backend |
| 100 |
jQuery(document).on('heartbeat-tick', function (e, data) { |
| 101 |
if ( data.hasOwnProperty('stateless-batch-running') && data['stateless-batch-running'] ) { |
| 102 |
this.startPolling() |
| 103 |
} |
| 104 |
}.bind(this)) |
| 105 |
} |
| 106 |
} |
| 107 |
|
| 108 |
wpStatelessBatch.init() |
| 109 |
|
| 110 |
/** |
| 111 |
* Manage data updates |
| 112 |
*/ |
| 113 |
function wpMigrations($) { |
| 114 |
function blockUI() { |
| 115 |
$('#migration-action .button').addClass('disabled') |
| 116 |
} |
| 117 |
|
| 118 |
function unblockUI() { |
| 119 |
$('#migration-action .button').removeClass('disabled') |
| 120 |
} |
| 121 |
|
| 122 |
// Process state |
| 123 |
document.addEventListener('wp-stateless-batch-state-updated', function (e) { |
| 124 |
var state = e.detail.state |
| 125 |
// 'action' indicates that the action was just started. |
| 126 |
// If the migration was quick - the state is empty and we need to update the state |
| 127 |
// Otherwise the state will contain the current running migration ID |
| 128 |
var forceRefresh = e.detail.action && !state.hasOwnProperty('id') |
| 129 |
|
| 130 |
if ( (!state.is_migration && !state.hasOwnProperty('migrations')) || forceRefresh ) { |
| 131 |
// If have migrations running on the frontend - we should finalize it |
| 132 |
if ( $('#migration-action.can-pause').length || $('#migration-action.can-resume').length || forceRefresh ) { |
| 133 |
wpStatelessBatch.getState({ |
| 134 |
force_migrations: true, |
| 135 |
}) |
| 136 |
} |
| 137 |
|
| 138 |
return |
| 139 |
} |
| 140 |
|
| 141 |
if ( !state.hasOwnProperty('migrations') ) { |
| 142 |
return |
| 143 |
} |
| 144 |
|
| 145 |
// Check if we need to wait for other migrations to start |
| 146 |
// If there are more migrations - wait 5 seconds and check again |
| 147 |
if ( !state.is_running && !state.is_paused ) { |
| 148 |
var migrationsCanStart = Object.values(state.migrations).some(function(migration) { return migration.can_start }) |
| 149 |
if ( migrationsCanStart ) { |
| 150 |
setTimeout(function() { |
| 151 |
wpStatelessBatch.getState() |
| 152 |
}, 5000) |
| 153 |
|
| 154 |
return |
| 155 |
} else { |
| 156 |
$('.metabox-holder.migrations-wrap').remove() |
| 157 |
} |
| 158 |
} |
| 159 |
|
| 160 |
var migrationElement = $('#migration-action') |
| 161 |
|
| 162 |
if ( state.migrations && state.hasOwnProperty('is_migration') && state.hasOwnProperty('id') ) { |
| 163 |
var migration = state.migrations[ state.id ]; |
| 164 |
migrationElement.attr('data-id', state.id) |
| 165 |
|
| 166 |
if ( migration.can_start ) { |
| 167 |
migrationElement.addClass('can-start') |
| 168 |
} else { |
| 169 |
migrationElement.removeClass('can-start') |
| 170 |
} |
| 171 |
|
| 172 |
if ( migration.can_pause ) { |
| 173 |
migrationElement.addClass('can-pause') |
| 174 |
} else { |
| 175 |
migrationElement.removeClass('can-pause') |
| 176 |
} |
| 177 |
|
| 178 |
if ( migration.can_resume ) { |
| 179 |
migrationElement.addClass('can-resume') |
| 180 |
} else { |
| 181 |
migrationElement.removeClass('can-resume') |
| 182 |
} |
| 183 |
|
| 184 |
if ( migration.hasOwnProperty('ui_message') && migration.ui_message ) { |
| 185 |
migrationElement.find('.description').html(migration.ui_message) |
| 186 |
} else { |
| 187 |
migrationElement.find('.description').text('') |
| 188 |
} |
| 189 |
} |
| 190 |
|
| 191 |
// Display progress |
| 192 |
if ( state.is_running || state.is_paused ) { |
| 193 |
if ( state.hasOwnProperty('total') && state.hasOwnProperty('completed') ) { |
| 194 |
var migrationElement = $('#migration-action') |
| 195 |
|
| 196 |
var percent = state.total > 0 ? Math.floor( (state.completed / state.total) * 100 ) + '%' : '' |
| 197 |
migrationElement.find('.progress .percent').html(percent) |
| 198 |
migrationElement.find('.progress .bar').css('width', percent) |
| 199 |
} |
| 200 |
} |
| 201 |
}) |
| 202 |
|
| 203 |
// Process notifications |
| 204 |
document.addEventListener('wp-stateless-batch-state-updated', function (e) { |
| 205 |
var state = e.detail.state |
| 206 |
|
| 207 |
var notify = state.hasOwnProperty('migrations_notify') ? state.migrations_notify : false |
| 208 |
|
| 209 |
if ( state.is_running ) { |
| 210 |
$('#stateless-notice-migrations-required').addClass('hidden') |
| 211 |
$('#stateless-notice-migrations-finished').addClass('hidden') |
| 212 |
$('#stateless-notice-migrations-running').removeClass('hidden') |
| 213 |
} else { |
| 214 |
$('#stateless-notice-migrations-running').addClass('hidden') |
| 215 |
$('#stateless-notice-migrations-required').addClass('hidden') |
| 216 |
$('#stateless-notice-migrations-finished').addClass('hidden') |
| 217 |
|
| 218 |
if ( notify === 'require' ) { |
| 219 |
$('#stateless-notice-migrations-required').removeClass('hidden') |
| 220 |
} else if ( notify === 'finished' ) { |
| 221 |
$('#stateless-notice-migrations-finished').removeClass('hidden') |
| 222 |
} |
| 223 |
} |
| 224 |
}) |
| 225 |
|
| 226 |
// Migration confirmation dialog |
| 227 |
$( "#stateless-migration-confirm" ).dialog({ |
| 228 |
resizable: false, |
| 229 |
height: "auto", |
| 230 |
width: 500, |
| 231 |
modal: true, |
| 232 |
draggable: false, |
| 233 |
autoOpen: false, |
| 234 |
position: { my: "center", at: "center", of: window }, |
| 235 |
open: function(event, ui) { |
| 236 |
$('body').css('overflow', 'hidden') |
| 237 |
|
| 238 |
$('.ui-dialog-buttonset').find('.ui-button').attr('class', 'button') |
| 239 |
$('.ui-dialog-buttonset').find('.button').last().addClass('button-primary') |
| 240 |
|
| 241 |
$('.ui-dialog').removeClass('ui-corner-all').addClass('stateless-migration-confirm'); |
| 242 |
$('.ui-dialog-titlebar').removeClass('ui-corner-all'); |
| 243 |
|
| 244 |
// backdrop |
| 245 |
$('.ui-widget-overlay').attr('class', 'media-modal-backdrop'); |
| 246 |
}, |
| 247 |
close: function(event, ui) { |
| 248 |
unblockUI() |
| 249 |
$('body').css('overflow', 'auto') |
| 250 |
$('#migration-action').removeClass('processing-action'); |
| 251 |
$('#migration-action').find('.button.start').removeClass('disabled'); |
| 252 |
$('#migration-action').find('.description').text( '' ); |
| 253 |
}, |
| 254 |
buttons: [ |
| 255 |
{ |
| 256 |
text: stateless_l10n.start_optimization, |
| 257 |
click: function() {}, |
| 258 |
}, |
| 259 |
{ |
| 260 |
text: stateless_l10n.cancel, |
| 261 |
click: function() { |
| 262 |
$( this ).dialog( 'close' ) |
| 263 |
}, |
| 264 |
}, |
| 265 |
], |
| 266 |
}) |
| 267 |
|
| 268 |
// Migration actions |
| 269 |
$('#migration-action .button').click(function (e) { |
| 270 |
e.preventDefault() |
| 271 |
|
| 272 |
if ( $(e.target).hasClass('disabled') ) { |
| 273 |
return; |
| 274 |
} |
| 275 |
|
| 276 |
blockUI() |
| 277 |
|
| 278 |
var id = $('#migration-action').data('id') |
| 279 |
var action = $(e.target).data('action') |
| 280 |
|
| 281 |
if ( !id || !action ) { |
| 282 |
return |
| 283 |
} |
| 284 |
|
| 285 |
if ( action === 'start' ) { |
| 286 |
$( '#stateless-migration-confirm' ).attr('data-id', id) |
| 287 |
|
| 288 |
$('#stateless-migration-confirm').closest('.ui-dialog').find('.ui-dialog-buttonset .ui-button').first().click(function(e) { |
| 289 |
e.preventDefault() |
| 290 |
|
| 291 |
$( '#stateless-migration-confirm' ).dialog('close') |
| 292 |
var id = $( '#stateless-migration-confirm' ).attr('data-id') |
| 293 |
var migrationElement = $('#migration-action') |
| 294 |
|
| 295 |
migrationElement.addClass('processing-action'); |
| 296 |
migrationElement.find('.button.start').addClass('disabled'); |
| 297 |
migrationElement.find('.description').text( stateless_l10n.starting ); |
| 298 |
|
| 299 |
wpStatelessBatch.processAction(action, { |
| 300 |
id, |
| 301 |
is_migration: true, |
| 302 |
email: $('input[name="email-notification"]:checked').val(), |
| 303 |
queue: migrationElement.data('queue'), |
| 304 |
}, function() { |
| 305 |
unblockUI(); |
| 306 |
migrationElement.removeClass('processing-action'); |
| 307 |
migrationElement.find('.button.start').removeClass('disabled'); |
| 308 |
migrationElement.find('.description').text( '' ); |
| 309 |
}) |
| 310 |
}) |
| 311 |
|
| 312 |
$( "#stateless-migration-confirm" ).dialog('open') |
| 313 |
return |
| 314 |
} else { |
| 315 |
wpStatelessBatch.processAction(action, { |
| 316 |
id, |
| 317 |
is_migration: true, |
| 318 |
}, unblockUI) |
| 319 |
} |
| 320 |
}.bind(this)) |
| 321 |
} |
| 322 |
|
| 323 |
wpMigrations(jQuery) |
| 324 |
|