mirror of
https://github.com/getgrav/grav-plugin-admin.git
synced 2025-11-01 10:56:08 +01:00
175 lines
5.7 KiB
JavaScript
175 lines
5.7 KiB
JavaScript
import $ from 'jquery';
|
|
import { config, translations } from 'grav-config';
|
|
import request from '../utils/request';
|
|
import toastr from '../utils/toastr';
|
|
|
|
const paramSep = config.param_sep;
|
|
const task = `task${paramSep}`;
|
|
const nonce = `admin-nonce${paramSep}${config.admin_nonce}`;
|
|
const base = `${config.base_url_relative}/update.json`;
|
|
|
|
const urls = {
|
|
restore: `${base}/${task}safeUpgradeRestore/${nonce}`,
|
|
status: `${base}/${task}safeUpgradeStatus/${nonce}`,
|
|
};
|
|
|
|
class RestoreManager {
|
|
constructor() {
|
|
this.job = null;
|
|
this.pollTimer = null;
|
|
this.pollFailures = 0;
|
|
|
|
$(document).on('click', '[data-restore-snapshot]', (event) => {
|
|
event.preventDefault();
|
|
const button = $(event.currentTarget);
|
|
if (this.job) {
|
|
return;
|
|
}
|
|
this.startRestore(button);
|
|
});
|
|
}
|
|
|
|
startRestore(button) {
|
|
const snapshot = button.data('restore-snapshot');
|
|
if (!snapshot) {
|
|
return;
|
|
}
|
|
|
|
button.prop('disabled', true).addClass('is-loading');
|
|
|
|
const body = { snapshot };
|
|
request(urls.restore, { method: 'post', body }, (response) => {
|
|
button.prop('disabled', false).removeClass('is-loading');
|
|
|
|
if (!response) {
|
|
toastr.error(translations.PLUGIN_ADMIN?.RESTORE_GRAV_FAILED || 'Snapshot restore failed.');
|
|
return;
|
|
}
|
|
|
|
if (response.status === 'error') {
|
|
toastr.error(response.message || translations.PLUGIN_ADMIN?.RESTORE_GRAV_FAILED || 'Snapshot restore failed.');
|
|
return;
|
|
}
|
|
|
|
const data = response.data || {};
|
|
const jobId = data.job_id || (data.job && data.job.id);
|
|
if (!jobId) {
|
|
const message = response.message || translations.PLUGIN_ADMIN?.RESTORE_GRAV_FAILED || 'Snapshot restore failed.';
|
|
toastr.error(message);
|
|
return;
|
|
}
|
|
|
|
this.job = {
|
|
id: jobId,
|
|
snapshot,
|
|
};
|
|
this.pollFailures = 0;
|
|
|
|
const runningMessage = translations.PLUGIN_ADMIN?.RESTORE_GRAV_RUNNING
|
|
? translations.PLUGIN_ADMIN.RESTORE_GRAV_RUNNING.replace('%s', snapshot)
|
|
: `Restoring snapshot ${snapshot}...`;
|
|
toastr.info(runningMessage);
|
|
this.schedulePoll();
|
|
});
|
|
}
|
|
|
|
schedulePoll(delay = 1200) {
|
|
this.clearPoll();
|
|
this.pollTimer = setTimeout(() => this.pollStatus(), delay);
|
|
}
|
|
|
|
clearPoll() {
|
|
if (this.pollTimer) {
|
|
clearTimeout(this.pollTimer);
|
|
this.pollTimer = null;
|
|
}
|
|
}
|
|
|
|
pollStatus() {
|
|
if (!this.job) {
|
|
return;
|
|
}
|
|
|
|
const jobId = this.job.id;
|
|
let handled = false;
|
|
|
|
request(`${urls.status}?job=${encodeURIComponent(jobId)}`, { silentErrors: true }, (response) => {
|
|
handled = true;
|
|
this.pollFailures = 0;
|
|
|
|
if (!response || response.status !== 'success') {
|
|
this.schedulePoll();
|
|
return;
|
|
}
|
|
|
|
const data = response.data || {};
|
|
const job = data.job || {};
|
|
const progress = data.progress || {};
|
|
|
|
const stage = progress.stage || null;
|
|
const status = job.status || progress.status || null;
|
|
|
|
if (stage === 'error' || status === 'error') {
|
|
const message = job.error || progress.message || translations.PLUGIN_ADMIN?.RESTORE_GRAV_FAILED || 'Snapshot restore failed.';
|
|
toastr.error(message);
|
|
this.job = null;
|
|
this.clearPoll();
|
|
return;
|
|
}
|
|
|
|
if (stage === 'complete' || status === 'success') {
|
|
const snapshot = progress.snapshot || this.job.snapshot;
|
|
const version = (job.result && job.result.version) || progress.version || '';
|
|
let successMessage;
|
|
if (translations.PLUGIN_ADMIN?.RESTORE_GRAV_SUCCESS_MESSAGE && version) {
|
|
successMessage = translations.PLUGIN_ADMIN.RESTORE_GRAV_SUCCESS_MESSAGE.replace('%1$s', snapshot).replace('%2$s', version);
|
|
} else if (translations.PLUGIN_ADMIN?.RESTORE_GRAV_SUCCESS_SIMPLE) {
|
|
successMessage = translations.PLUGIN_ADMIN.RESTORE_GRAV_SUCCESS_SIMPLE.replace('%s', snapshot);
|
|
} else {
|
|
successMessage = version ? `Snapshot ${snapshot} restored (Grav ${version}).` : `Snapshot ${snapshot} restored.`;
|
|
}
|
|
toastr.success(successMessage);
|
|
this.job = null;
|
|
this.clearPoll();
|
|
setTimeout(() => window.location.reload(), 1500);
|
|
return;
|
|
}
|
|
|
|
this.schedulePoll();
|
|
}).then(() => {
|
|
if (!handled) {
|
|
this.handleSilentFailure();
|
|
}
|
|
});
|
|
}
|
|
|
|
handleSilentFailure() {
|
|
if (!this.job) {
|
|
return;
|
|
}
|
|
|
|
this.pollFailures += 1;
|
|
const snapshot = this.job.snapshot || '';
|
|
|
|
if (this.pollFailures >= 3) {
|
|
const message = snapshot
|
|
? `Snapshot ${snapshot} restore is completing. Reloading...`
|
|
: 'Snapshot restore is completing. Reloading...';
|
|
toastr.info(message);
|
|
this.job = null;
|
|
this.clearPoll();
|
|
setTimeout(() => window.location.reload(), 1500);
|
|
|
|
return;
|
|
}
|
|
|
|
const delay = Math.min(5000, 1200 * this.pollFailures);
|
|
this.schedulePoll(delay);
|
|
}
|
|
}
|
|
|
|
// Initialize restore manager when tools view loads.
|
|
$(document).ready(() => {
|
|
new RestoreManager();
|
|
});
|