Add Sys Backup toggle column to schedules list

Adds a "Sys Backup" column with an AJAX toggle in the schedules
table. Toggling it updates SYSBACKUP in the schedule config and
reinstalls the cron entry to include/remove --sysbackup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
shuki
2026-03-04 17:49:48 +02:00
parent 543b38bd53
commit 6511715b2b

View File

@@ -22,8 +22,9 @@ my $action = $form->{'action'} // 'list';
if ($action eq 'add') { handle_add() }
elsif ($action eq 'edit') { handle_edit() }
elsif ($action eq 'delete') { handle_delete() }
elsif ($action eq 'toggle_cron') { handle_toggle_cron() }
elsif ($action eq 'run_now') { handle_run_now() }
elsif ($action eq 'toggle_cron') { handle_toggle_cron() }
elsif ($action eq 'toggle_sysbackup') { handle_toggle_sysbackup() }
elsif ($action eq 'run_now') { handle_run_now() }
else { handle_list() }
exit;
@@ -47,7 +48,7 @@ sub handle_list {
if (@schedules) {
print qq{<div class="overflow-x-auto rounded-box border border-base-content/5 bg-base-100"><table class="table">\n};
print qq{<thead><tr><th>Name</th><th>Type</th><th>Time</th><th>Day</th><th>Remotes</th><th>Active</th><th>Actions</th></tr></thead>\n};
print qq{<thead><tr><th>Name</th><th>Type</th><th>Time</th><th>Day</th><th>Remotes</th><th>Sys Backup</th><th>Active</th><th>Actions</th></tr></thead>\n};
print qq{<tbody>\n};
for my $name (@schedules) {
my $conf = GnizaWHM::Config::parse(GnizaWHM::UI::schedule_conf_path($name), 'schedule');
@@ -61,10 +62,16 @@ sub handle_list {
my $in_cron = exists $cron_schedules->{$name};
my $checked = $in_cron ? ' checked' : '';
my $sysbackup_on = (($conf->{SYSBACKUP} // '') eq 'yes');
my $sysbackup_checked = $sysbackup_on ? ' checked' : '';
print qq{<tr class="hover">};
print qq{<td><strong>$esc_name</strong></td>};
print qq{<td>$esc_sched</td><td>$esc_time</td><td>$esc_day</td><td>$esc_remotes</td>};
print qq{<td>};
print qq{<input type="checkbox" class="toggle toggle-sm toggle-success" data-schedule="$esc_name" onchange="gnizaToggleSysbackup(this)"$sysbackup_checked>};
print qq{</td>};
print qq{<td>};
print qq{<input type="checkbox" class="toggle toggle-sm toggle-success" data-schedule="$esc_name" onchange="gnizaToggleCron(this)"$checked>};
print qq{</td>};
print qq{<td>};
@@ -115,6 +122,25 @@ function gnizaToggleCron(el) {
el.disabled = false;
});
}
function gnizaToggleSysbackup(el) {
var name = el.getAttribute('data-schedule');
el.disabled = true;
var fd = new FormData();
fd.append('action', 'toggle_sysbackup');
fd.append('name', name);
fd.append('gniza_csrf', gnizaCsrf);
fetch('schedules.cgi', { method: 'POST', body: fd })
.then(function(r) { return r.json(); })
.then(function(d) {
gnizaCsrf = d.csrf;
el.checked = d.active;
el.disabled = false;
})
.catch(function() {
el.checked = !el.checked;
el.disabled = false;
});
}
</script>\n};
# Action buttons
@@ -453,6 +479,51 @@ sub handle_toggle_cron {
}
}
# ── Toggle Sysbackup ────────────────────────────────────────────
sub handle_toggle_sysbackup {
if ($method ne 'POST') {
print "Status: 302 Found\r\n";
print "Location: schedules.cgi\r\n\r\n";
exit;
}
unless (GnizaWHM::UI::verify_csrf_token($form->{'gniza_csrf'})) {
my $new_csrf = GnizaWHM::UI::generate_csrf_token();
_json_response(0, 0, 'Invalid or expired form token.', $new_csrf);
}
my $new_csrf = GnizaWHM::UI::generate_csrf_token();
my $name = $form->{'name'} // '';
my $name_err = GnizaWHM::Validator::validate_schedule_name($name);
if ($name_err) {
_json_response(0, 0, 'Invalid schedule name.', $new_csrf);
}
my $conf_path = GnizaWHM::UI::schedule_conf_path($name);
unless (-f $conf_path) {
_json_response(0, 0, "Schedule '$name' not found.", $new_csrf);
}
my $conf = GnizaWHM::Config::parse($conf_path, 'schedule');
my $is_on = (($conf->{SYSBACKUP} // '') eq 'yes');
# Toggle the value
$conf->{SYSBACKUP} = $is_on ? '' : 'yes';
my ($ok, $err) = GnizaWHM::Config::write($conf_path, $conf, \@GnizaWHM::Config::SCHEDULE_KEYS);
if ($ok) {
# Reinstall cron so --sysbackup flag is updated
GnizaWHM::Cron::install_schedule($name);
my $new_state = $is_on ? 0 : 1;
my $label = $new_state ? 'enabled' : 'disabled';
_json_response(1, $new_state, "System backup $label for '$name'.", $new_csrf);
} else {
_json_response(0, $is_on ? 1 : 0, "Failed to update config: $err", $new_csrf);
}
}
sub _json_response {
my ($ok, $active, $message, $csrf) = @_;
# Escape for JSON