diff --git a/classes/plugin/SafeUpgradeManager.php b/classes/plugin/SafeUpgradeManager.php index a6123737..ef7e09a1 100644 --- a/classes/plugin/SafeUpgradeManager.php +++ b/classes/plugin/SafeUpgradeManager.php @@ -186,6 +186,78 @@ class SafeUpgradeManager $this->writeManifest($data); } + public function ensureJobResult(array $result): void + { + if (!$this->jobManifestPath) { + return; + } + + $status = $result['status'] ?? null; + $progress = $this->getProgress(); + + if ($status === 'success') { + $targetVersion = $result['version'] ?? ($result['manifest']['target_version'] ?? null); + $manifest = $result['manifest'] ?? null; + + if (($progress['stage'] ?? null) !== 'complete') { + $extras = []; + if ($targetVersion !== null) { + $extras['target_version'] = $targetVersion; + } + if ($manifest !== null) { + $extras['manifest'] = $manifest; + } + + $this->setProgress('complete', 'Upgrade complete.', 100, $extras); + $progress = $this->getProgress(); + } + + $this->updateJob([ + 'status' => 'success', + 'completed_at' => time(), + 'result' => $result, + 'progress' => $progress, + ]); + + return; + } + + if ($status === 'error') { + $message = $result['message'] ?? 'Safe upgrade failed.'; + if (($progress['stage'] ?? null) !== 'error') { + $this->setProgress('error', $message, null, ['message' => $message]); + $progress = $this->getProgress(); + } + + $this->updateJob([ + 'status' => 'error', + 'completed_at' => time(), + 'result' => $result, + 'progress' => $progress, + 'error' => $message, + ]); + + return; + } + + if ($status === 'noop' || $status === 'finalized') { + if (($progress['stage'] ?? null) !== 'complete') { + $this->setProgress('complete', $progress['message'] ?? 'Upgrade complete.', 100, [ + 'target_version' => $result['version'] ?? null, + 'manifest' => $result['manifest'] ?? null, + ]); + $progress = $this->getProgress(); + } + + $this->updateJob([ + 'status' => $status, + 'completed_at' => time(), + 'result' => $result, + 'progress' => $progress, + ]); + } + } + public function markJobError(string $message): void { $this->setProgress('error', $message, null, ['message' => $message]); diff --git a/themes/grav/app/updates/safe-upgrade.js b/themes/grav/app/updates/safe-upgrade.js index e79e41cb..1772cf57 100644 --- a/themes/grav/app/updates/safe-upgrade.js +++ b/themes/grav/app/updates/safe-upgrade.js @@ -445,8 +445,9 @@ export default class SafeUpgrade { this.pollTimer = null; let nextStage = null; - - let shouldContinue = true; + let jobComplete = false; + let jobFailed = false; + let shouldReload = false; console.debug('[SafeUpgrade] poll status'); @@ -464,6 +465,7 @@ export default class SafeUpgrade { }); } nextStage = 'error'; + jobFailed = true; return; } @@ -475,16 +477,32 @@ export default class SafeUpgrade { this.renderProgress(data, job); if (job.status === 'error') { - shouldContinue = false; nextStage = 'error'; const message = job.error || data.message || t('SAFE_UPGRADE_GENERIC_ERROR', 'Safe upgrade could not complete. See Grav logs for details.'); - this.renderResult({ status: 'error', message }); - } else if (job.status === 'success' && data.stage === 'complete') { - shouldContinue = false; - nextStage = 'complete'; - if (job.result) { - this.renderResult(job.result); + this.renderProgress({ + stage: 'error', + message, + percent: null + }, job); + jobFailed = true; + } else if (job.status === 'success') { + if (data.stage !== 'complete') { + const completePayload = { + stage: 'complete', + message: t('SAFE_UPGRADE_STAGE_COMPLETE', 'Upgrade complete'), + percent: 100, + target_version: (job.result && job.result.version) || data.target_version || null, + manifest: (job.result && job.result.manifest) || data.manifest || null + }; + + this.renderProgress(completePayload, job); + nextStage = 'complete'; } + jobComplete = true; + shouldReload = true; + } else if (!job.status && data.stage === 'complete') { + jobComplete = true; + shouldReload = true; } }); @@ -495,17 +513,17 @@ export default class SafeUpgrade { return; } - if (nextStage === 'complete' || nextStage === 'error') { + if (jobFailed) { this.stopPolling(); this.jobId = null; - if (nextStage === 'complete') { + } else if (jobComplete || nextStage === 'complete') { + this.stopPolling(); + this.jobId = null; + if (shouldReload) { setTimeout(() => window.location.reload(), 2500); } - } else if (shouldContinue) { - this.schedulePoll(); } else { - this.stopPolling(); - this.jobId = null; + this.schedulePoll(); } }; diff --git a/themes/grav/js/admin.min.js b/themes/grav/js/admin.min.js index ef15e0e2..561cc051 100644 --- a/themes/grav/js/admin.min.js +++ b/themes/grav/js/admin.min.js @@ -4923,7 +4923,9 @@ var SafeUpgrade = /*#__PURE__*/function () { } this.pollTimer = null; var nextStage = null; - var shouldContinue = true; + var jobComplete = false; + var jobFailed = false; + var shouldReload = false; console.debug('[SafeUpgrade] poll status'); var statusUrl = this.jobId ? "".concat(this.urls.status, "?job=").concat(encodeURIComponent(this.jobId)) : this.urls.status; this.statusRequest = utils_request(statusUrl, function (response) { @@ -4937,6 +4939,7 @@ var SafeUpgrade = /*#__PURE__*/function () { }); } nextStage = 'error'; + jobFailed = true; return; } var payload = response.data || {}; @@ -4945,19 +4948,31 @@ var SafeUpgrade = /*#__PURE__*/function () { nextStage = data.stage || null; _this6.renderProgress(data, job); if (job.status === 'error') { - shouldContinue = false; nextStage = 'error'; var message = job.error || data.message || t('SAFE_UPGRADE_GENERIC_ERROR', 'Safe upgrade could not complete. See Grav logs for details.'); - _this6.renderResult({ - status: 'error', - message: message - }); - } else if (job.status === 'success' && data.stage === 'complete') { - shouldContinue = false; - nextStage = 'complete'; - if (job.result) { - _this6.renderResult(job.result); + _this6.renderProgress({ + stage: 'error', + message: message, + percent: null + }, job); + jobFailed = true; + } else if (job.status === 'success') { + if (data.stage !== 'complete') { + var completePayload = { + stage: 'complete', + message: t('SAFE_UPGRADE_STAGE_COMPLETE', 'Upgrade complete'), + percent: 100, + target_version: job.result && job.result.version || data.target_version || null, + manifest: job.result && job.result.manifest || data.manifest || null + }; + _this6.renderProgress(completePayload, job); + nextStage = 'complete'; } + jobComplete = true; + shouldReload = true; + } else if (!job.status && data.stage === 'complete') { + jobComplete = true; + shouldReload = true; } }); var finalize = function finalize() { @@ -4965,19 +4980,19 @@ var SafeUpgrade = /*#__PURE__*/function () { if (!_this6.isPolling) { return; } - if (nextStage === 'complete' || nextStage === 'error') { + if (jobFailed) { _this6.stopPolling(); _this6.jobId = null; - if (nextStage === 'complete') { + } else if (jobComplete || nextStage === 'complete') { + _this6.stopPolling(); + _this6.jobId = null; + if (shouldReload) { setTimeout(function () { return window.location.reload(); }, 2500); } - } else if (shouldContinue) { - _this6.schedulePoll(); } else { - _this6.stopPolling(); - _this6.jobId = null; + _this6.schedulePoll(); } }; this.statusRequest.then(finalize, finalize); @@ -14246,4 +14261,4 @@ external_jQuery_default()(__webpack_require__.g).on('sidebar_state._grav', funct /******/ Grav = __webpack_exports__; /******/ /******/ })() -; \ No newline at end of file +;