Ask with Unraid's own dialog, not the browser's
Every confirm() and prompt() in the plugin could be switched off from inside itself — one tick of "prevent this page from creating additional dialogs" and all 32 of them returned false while drawing nothing, across every tab, until a full reload. swal is already global on every webGUI page and core uses it 370 times without a single confirm(), so this costs no new dependency. vvConfirmRun() is the one that mattered: it returned a boolean to three callers testing !it, and an unawaited promise is always truthy, so leaving those alone would have run every job without asking. The wrapper's callback is a classic function expression on purpose — SweetAlert only calls back on cancel when the callback's own source declares a parameter, and an arrow would have hung the promise forever.
This commit is contained in:
@@ -1573,8 +1573,8 @@ function vvSelectLog(btn) {
|
||||
//
|
||||
// Dry Run is named in the prompt on purpose. For anything destructive it is the actual answer to
|
||||
// "are you sure", and it is the button immediately beside the one that raised the question.
|
||||
function vvConfirmRun(id) {
|
||||
return confirm('Run ' + id + ' now?\n\n'
|
||||
async function vvConfirmRun(id) {
|
||||
return vvConfirm('Run ' + id + ' now?\n\n'
|
||||
+ 'It starts immediately and as root, with the same effect as a scheduled run.\n'
|
||||
+ 'Use Dry Run first if you want to see what it would change.');
|
||||
}
|
||||
@@ -1596,16 +1596,16 @@ function vvRunStart(id, data) {
|
||||
}
|
||||
|
||||
// Run a script by ID directly — no DOM card needed.
|
||||
function vvRunById(id) {
|
||||
if (!vvConfirmRun(id)) return;
|
||||
async function vvRunById(id) {
|
||||
if (!await vvConfirmRun(id)) return;
|
||||
vvRunStart(id, {id, manual: '1'});
|
||||
}
|
||||
|
||||
function vvGitPull(btn) {
|
||||
async function vvGitPull(btn) {
|
||||
const id = 'git_pull_execute.sh';
|
||||
// Asked before the button is disabled, so cancelling does not leave it stuck reading "Pulling…"
|
||||
// for the next four seconds while nothing is pulling.
|
||||
if (!vvConfirmRun(id)) return;
|
||||
if (!await vvConfirmRun(id)) return;
|
||||
btn.disabled = true;
|
||||
btn.textContent = '⟳ Pulling…';
|
||||
vvRunStart(id, {id, manual: '1'});
|
||||
@@ -1613,10 +1613,10 @@ function vvGitPull(btn) {
|
||||
setTimeout(() => { btn.disabled = false; btn.textContent = '↻ Git Pull'; }, 4000);
|
||||
}
|
||||
|
||||
function vvRunJob(btn) {
|
||||
async function vvRunJob(btn) {
|
||||
const job = btn.closest('[data-id]');
|
||||
const id = job.dataset.id;
|
||||
if (!vvConfirmRun(id)) return;
|
||||
if (!await vvConfirmRun(id)) return;
|
||||
const location = job.querySelector('.vv-rsync-location')?.value.trim() || '';
|
||||
const extra_args = job.querySelector('.vv-script-args')?.value.trim() || '';
|
||||
const data = {id};
|
||||
@@ -1913,14 +1913,14 @@ function vvShowEditorMode(title) {
|
||||
requestAnimationFrame(vvFitRight);
|
||||
}
|
||||
|
||||
function vvSaveScript() {
|
||||
async function vvSaveScript() {
|
||||
const name = document.getElementById('vv-editor-name').value.trim();
|
||||
const content = document.getElementById('vv-editor-body').value;
|
||||
if (!name || !/^[a-zA-Z0-9_\-]+$/.test(name)) {
|
||||
alert('Name must be letters, numbers, _ or - only (no spaces, no .sh)');
|
||||
return;
|
||||
}
|
||||
if (!confirm('Save changes to "' + name + '.sh"?')) return;
|
||||
if (!await vvConfirm('Save changes to "' + name + '.sh"?')) return;
|
||||
const btn = document.getElementById('vv-save-script-btn');
|
||||
btn.disabled = true;
|
||||
btn.textContent = 'Saving…';
|
||||
@@ -1933,10 +1933,10 @@ function vvSaveScript() {
|
||||
.catch(() => { btn.disabled = false; btn.textContent = 'Save Script'; });
|
||||
}
|
||||
|
||||
function vvDeleteScript() {
|
||||
async function vvDeleteScript() {
|
||||
if (!vvEditorId) return;
|
||||
const name = vvEditorId.replace(/^Custom\//, '').replace(/\.sh$/, '');
|
||||
if (!confirm('Delete "' + name + '.sh"? This cannot be undone.')) return;
|
||||
if (!await vvConfirm('Delete "' + name + '.sh"? This cannot be undone.')) return;
|
||||
const btn = document.getElementById('vv-delete-script-btn');
|
||||
btn.disabled = true;
|
||||
btn.textContent = 'Deleting…';
|
||||
@@ -2107,10 +2107,10 @@ function _vvImpUpdateFooter() {
|
||||
btn.disabled = !_vvImpSelected;
|
||||
}
|
||||
|
||||
function _vvImpDoImport() {
|
||||
async function _vvImpDoImport() {
|
||||
if (!_vvImpSelected) return;
|
||||
const dest = (window.__vvCustomScriptsDir || 'Custom Scripts') + '/' + _vvImpSelected.replace(/^.*\//, '');
|
||||
if (!confirm('Move\n ' + _vvImpSelected + '\n→ ' + dest + '\n\nThe original will be deleted once the copy is verified. Continue?')) return;
|
||||
if (!await vvConfirm('Move\n ' + _vvImpSelected + '\n→ ' + dest + '\n\nThe original will be deleted once the copy is verified. Continue?')) return;
|
||||
|
||||
const btn = document.getElementById('vv-imp-do-btn');
|
||||
btn.disabled = true;
|
||||
@@ -2253,10 +2253,10 @@ function vvCfInitArrays(root) {
|
||||
(root || document).querySelectorAll('.vv-cf-array').forEach(vvCfLines);
|
||||
}
|
||||
|
||||
function vvSaveConf() {
|
||||
async function vvSaveConf() {
|
||||
if (!vvConfId) return;
|
||||
const _cfName = vvConfId.replace(/\.sh$/, '').split('/').pop();
|
||||
if (!confirm('Save configuration changes for "' + _cfName + '"?')) return;
|
||||
if (!await vvConfirm('Save configuration changes for "' + _cfName + '"?')) return;
|
||||
const inputs = document.querySelectorAll('#vv-confform .vv-cf-input, #vv-si-view .vv-cf-input');
|
||||
const changes = [];
|
||||
inputs.forEach(el => changes.push({key: el.dataset.key, file: el.dataset.file, type: el.dataset.type, value: el.value}));
|
||||
@@ -2895,8 +2895,8 @@ function vvUpdatePartner(partner) {
|
||||
+ '</div>';
|
||||
}
|
||||
|
||||
function vvClearLock(file, btn) {
|
||||
if (!confirm('Clear lock "' + file + '"?\nOnly do this if the script has crashed and the lock is stale.')) return;
|
||||
async function vvClearLock(file, btn) {
|
||||
if (!await vvConfirm('Clear lock "' + file + '"?\nOnly do this if the script has crashed and the lock is stale.')) return;
|
||||
btn.disabled = true; btn.textContent = '…';
|
||||
vvPost('/plugins/varaverk/api/clearlock.php', {file})
|
||||
.then(d => { if (d.ok) vvBoardPoll(); else { btn.disabled = false; btn.textContent = 'Clear'; }})
|
||||
@@ -3491,9 +3491,9 @@ function vvShowRawConfMode(title) {
|
||||
requestAnimationFrame(vvFitRight);
|
||||
}
|
||||
|
||||
function vvSaveRawConf() {
|
||||
async function vvSaveRawConf() {
|
||||
if (!vvRawConfFile) return;
|
||||
if (!vvSetupConf && !confirm('Save changes to "' + vvRawConfFile + '"?')) return;
|
||||
if (!vvSetupConf && !await vvConfirm('Save changes to "' + vvRawConfFile + '"?')) return;
|
||||
const content = document.getElementById('vv-editor-body').value;
|
||||
const btn = document.getElementById('vv-save-rawconf-btn');
|
||||
btn.disabled = true;
|
||||
|
||||
Reference in New Issue
Block a user