* [PATCH proxmox v2 1/6] fix #7904: Add 'enable' to {sync,verify,tape,gc} job schema and datastore config
2026-10-07 13:43 [PATCH proxmox{,-backup} v2 0/6] fix #7904: Implement Enable checkboxes for all jobs Jonas Theisen
@ 2026-10-07 13:43 ` Jonas Theisen
2026-10-07 13:43 ` [PATCH proxmox-backup v2 2/6] ui: prune job: Align Prune Edit window to other "Enable" checkboxes Jonas Theisen
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Jonas Theisen @ 2026-10-07 13:43 UTC (permalink / raw)
To: pbs-devel
To be able to en-/disable the respective jobs this patch adds the
enable field to the job config and the needed schema.
This also adds the gc_enable parameter to the datastore config
to allow this type of job to be disabled.
Signed-off-by: Jonas Theisen <j.theisen@proxmox.com>
---
pbs-api-types/src/datastore.rs | 12 ++++++++++++
pbs-api-types/src/jobs.rs | 24 ++++++++++++++++++++++++
2 files changed, 36 insertions(+)
diff --git a/pbs-api-types/src/datastore.rs b/pbs-api-types/src/datastore.rs
index 93ccaf07..50658b58 100644
--- a/pbs-api-types/src/datastore.rs
+++ b/pbs-api-types/src/datastore.rs
@@ -460,6 +460,11 @@ pub const COUNTER_RESET_SCHEDULE_SCHEMA: Schema =
optional: true,
schema: SINGLE_LINE_COMMENT_SCHEMA,
},
+ "gc-enable": {
+ description: "Enable scheduled execution of garbage collection.",
+ optional: true,
+ type: bool,
+ },
"gc-schedule": {
optional: true,
schema: GC_SCHEDULE_SCHEMA,
@@ -524,6 +529,9 @@ pub struct DataStoreConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub gc_enable: Option<bool>,
+
#[serde(skip_serializing_if = "Option::is_none")]
pub gc_schedule: Option<String>,
@@ -605,6 +613,7 @@ impl DataStoreConfig {
name,
path,
comment: None,
+ gc_enable: None,
gc_schedule: None,
gc_on_unmount: None,
prune_schedule: None,
@@ -1704,6 +1713,9 @@ pub struct GarbageCollectionJobStatus {
pub store: String,
#[serde(flatten)]
pub status: GarbageCollectionStatus,
+ /// Scheduled execution of the gc job
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub enable: Option<bool>,
/// Schedule of the gc job
#[serde(skip_serializing_if = "Option::is_none")]
pub schedule: Option<String>,
diff --git a/pbs-api-types/src/jobs.rs b/pbs-api-types/src/jobs.rs
index 9a5d2b77..0ae93678 100644
--- a/pbs-api-types/src/jobs.rs
+++ b/pbs-api-types/src/jobs.rs
@@ -62,6 +62,12 @@ pub const VERIFICATION_SCHEDULE_SCHEMA: Schema =
.type_text("<calendar-event>")
.schema();
+pub const ENABLE_JOB_SCHEMA: Schema = BooleanSchema::new(
+ "Enables the scheduled execution of this task.",
+)
+.default(true)
+.schema();
+
pub const REMOVE_VANISHED_BACKUPS_SCHEMA: Schema = BooleanSchema::new(
"Delete vanished backups. This removes the local copy if the remote backup was deleted.",
)
@@ -228,6 +234,10 @@ pub const VERIFICATION_OUTDATED_AFTER_SCHEMA: Schema =
optional: true,
schema: VERIFICATION_SCHEDULE_SCHEMA,
},
+ enable: {
+ optional: true,
+ schema: ENABLE_JOB_SCHEMA,
+ },
ns: {
optional: true,
schema: BACKUP_NAMESPACE_SCHEMA,
@@ -268,6 +278,8 @@ pub struct VerificationJobConfig {
/// when to schedule this job in calendar event notation
pub schedule: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", default)]
+ pub enable: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
/// on which backup namespace to run the verification recursively
pub ns: Option<BackupNamespace>,
#[serde(skip_serializing_if = "Option::is_none", default)]
@@ -403,6 +415,10 @@ pub struct TapeBackupJobSetup {
optional: true,
schema: SYNC_SCHEDULE_SCHEMA,
},
+ enable: {
+ optional: true,
+ schema: ENABLE_JOB_SCHEMA,
+ },
}
)]
#[derive(Serialize, Deserialize, Clone, Updater, PartialEq)]
@@ -417,6 +433,8 @@ pub struct TapeBackupJobConfig {
pub comment: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub schedule: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub enable: Option<bool>,
}
#[api(
@@ -642,6 +660,10 @@ pub const UNMOUNT_ON_SYNC_DONE_SCHEMA: Schema =
optional: true,
schema: SYNC_SCHEDULE_SCHEMA,
},
+ enable: {
+ optional: true,
+ schema: ENABLE_JOB_SCHEMA,
+ },
"group-filter": {
schema: GROUP_FILTER_LIST_SCHEMA,
optional: true,
@@ -718,6 +740,8 @@ pub struct SyncJobConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub schedule: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
+ pub enable: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
pub group_filter: Option<Vec<GroupFilter>>,
#[serde(flatten)]
pub limit: RateLimitConfig,
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH proxmox-backup v2 2/6] ui: prune job: Align Prune Edit window to other "Enable" checkboxes
2026-10-07 13:43 [PATCH proxmox{,-backup} v2 0/6] fix #7904: Implement Enable checkboxes for all jobs Jonas Theisen
2026-10-07 13:43 ` [PATCH proxmox v2 1/6] fix #7904: Add 'enable' to {sync,verify,tape,gc} job schema and datastore config Jonas Theisen
@ 2026-10-07 13:43 ` Jonas Theisen
2026-10-07 13:43 ` [PATCH proxmox-backup v2 3/6] fix #7904: api: implement "enable" for {sync,verify,tape,GC} jobs Jonas Theisen
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Jonas Theisen @ 2026-10-07 13:43 UTC (permalink / raw)
To: pbs-devel
This commit aligns the already existing "Enabled" checkbox in
the Prune Job Edit window to the other checkboxes.
Meaning a reword from "Enabled" to "Enable" as it is more common
throghout the UI and the disabling of the schedule field if the
checkbox is off.
Signed-off-by: Jonas Theisen <j.theisen@proxmox.com>
---
www/window/PruneJobEdit.js | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/www/window/PruneJobEdit.js b/www/window/PruneJobEdit.js
index a3dafde21..9eea3de52 100644
--- a/www/window/PruneJobEdit.js
+++ b/www/window/PruneJobEdit.js
@@ -118,11 +118,19 @@ Ext.define('PBS.window.PruneJobEdit', {
},
{
xtype: 'proxmoxcheckbox',
- fieldLabel: gettext('Enabled'),
+ fieldLabel: gettext('Enable'),
name: 'enable',
uncheckedValue: 0,
defaultValue: 1,
checked: true,
+ listeners: {
+ change: function (field, enabled) {
+ let me = this;
+ let view = me.up('pbsPruneJobEdit');
+ let schedule = view.down('field[name=schedule]');
+ schedule.setDisabled(!enabled);
+ },
+ },
},
],
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH proxmox-backup v2 3/6] fix #7904: api: implement "enable" for {sync,verify,tape,GC} jobs
2026-10-07 13:43 [PATCH proxmox{,-backup} v2 0/6] fix #7904: Implement Enable checkboxes for all jobs Jonas Theisen
2026-10-07 13:43 ` [PATCH proxmox v2 1/6] fix #7904: Add 'enable' to {sync,verify,tape,gc} job schema and datastore config Jonas Theisen
2026-10-07 13:43 ` [PATCH proxmox-backup v2 2/6] ui: prune job: Align Prune Edit window to other "Enable" checkboxes Jonas Theisen
@ 2026-10-07 13:43 ` Jonas Theisen
2026-10-07 13:43 ` [PATCH proxmox-backup v2 4/6] fix #7904: ui: job edit: introduce "Enable" checkbox " Jonas Theisen
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Jonas Theisen @ 2026-10-07 13:43 UTC (permalink / raw)
To: pbs-devel
To allow users to disable jobs without having to remove the
schedule this patch introduces the "enable" parameter.
The value is inserted into the job config and honored by
the scheduler by skipping disabled jobs altogether.
For GC jobs the value is inserted into the datastore config.
If the value is not present in a job config it is assumed the job
is to be enabled for backwards compatibility.
Fixes: https://bugzilla.proxmox.com/show_bug.cgi?id=7904
Signed-off-by: Jonas Theisen <j.theisen@proxmox.com>
---
src/api2/admin/datastore.rs | 1 +
src/api2/admin/gc.rs | 13 ++++++++++++-
src/api2/admin/sync.rs | 8 +++++++-
src/api2/admin/verify.rs | 8 +++++++-
src/api2/config/datastore.rs | 4 ++++
src/api2/config/sync.rs | 4 ++++
src/api2/config/verify.rs | 3 +++
src/api2/tape/backup.rs | 7 ++++++-
src/bin/proxmox-backup-proxy.rs | 20 ++++++++++++++++++++
9 files changed, 64 insertions(+), 4 deletions(-)
diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs
index 3367fb2c1..c4169b9c0 100644
--- a/src/api2/admin/datastore.rs
+++ b/src/api2/admin/datastore.rs
@@ -1264,6 +1264,7 @@ pub(crate) fn garbage_collection_status_unchecked(
let mut info = GarbageCollectionJobStatus {
store: store.clone(),
schedule: store_config.gc_schedule,
+ enable: store_config.gc_enable,
..Default::default()
};
diff --git a/src/api2/admin/gc.rs b/src/api2/admin/gc.rs
index 3c8bc2946..21a03ea86 100644
--- a/src/api2/admin/gc.rs
+++ b/src/api2/admin/gc.rs
@@ -58,7 +58,18 @@ pub fn list_all_gc_jobs(
.collect::<Vec<_>>(),
};
- Ok(gc_info)
+ let mut list = Vec::new();
+
+ for mut job in gc_info {
+ // default set to `true` to be backwards compatible
+ if !job.enable.unwrap_or(true) {
+ job.next_run = Some(0);
+ }
+
+ list.push(job);
+ }
+
+ Ok(list)
}
const GC_ROUTER: Router = Router::new().get(&API_METHOD_LIST_ALL_GC_JOBS);
diff --git a/src/api2/admin/sync.rs b/src/api2/admin/sync.rs
index 1799f51c0..2ecc2ab24 100644
--- a/src/api2/admin/sync.rs
+++ b/src/api2/admin/sync.rs
@@ -112,7 +112,13 @@ pub fn list_config_sync_jobs(
continue;
}
- let status = compute_schedule_status("syncjob", &job.id, job.schedule.as_deref())?;
+ let mut status =
+ compute_schedule_status("syncjob", &job.id, job.schedule.as_deref())?;
+
+ // default set to `true` to be backwards compatible
+ if !job.enable.unwrap_or(true) {
+ status.next_run = Some(0);
+ }
list.push(SyncJobStatus {
config: job,
diff --git a/src/api2/admin/verify.rs b/src/api2/admin/verify.rs
index 80659ebe2..eab3347e2 100644
--- a/src/api2/admin/verify.rs
+++ b/src/api2/admin/verify.rs
@@ -73,7 +73,13 @@ pub fn list_verification_jobs(
let mut list = Vec::new();
for job in job_config_iter {
- let status = compute_schedule_status("verificationjob", &job.id, job.schedule.as_deref())?;
+ let mut status =
+ compute_schedule_status("verificationjob", &job.id, job.schedule.as_deref())?;
+
+ // default set to `true` to be backwards compatible
+ if !job.enable.unwrap_or(true) {
+ status.next_run = Some(0);
+ }
list.push(VerificationJobStatus {
config: job,
diff --git a/src/api2/config/datastore.rs b/src/api2/config/datastore.rs
index e7028480c..3c372b7f6 100644
--- a/src/api2/config/datastore.rs
+++ b/src/api2/config/datastore.rs
@@ -571,6 +571,10 @@ pub fn update_datastore(
data.gc_on_unmount = update.gc_on_unmount;
}
+ if update.gc_enable.is_some() {
+ data.gc_enable = update.gc_enable;
+ }
+
macro_rules! prune_disabled {
($(($param:literal, $($member:tt)+)),+) => {
$(
diff --git a/src/api2/config/sync.rs b/src/api2/config/sync.rs
index beed6e7e3..dabd4a3ef 100644
--- a/src/api2/config/sync.rs
+++ b/src/api2/config/sync.rs
@@ -702,6 +702,9 @@ pub fn update_sync_job(
if update.schedule.is_some() {
data.schedule = update.schedule;
}
+ if let Some(enable) = update.enable {
+ data.enable = Some(enable);
+ }
if update.remove_vanished.is_some() {
data.remove_vanished = update.remove_vanished;
}
@@ -847,6 +850,7 @@ acl:1:/remote/remote1/remotestore1:write@pbs:RemoteSyncOperator
max_depth: None,
group_filter: None,
schedule: None,
+ enable: None,
limit: pbs_api_types::RateLimitConfig::default(), // no limit
transfer_last: None,
encrypted_only: None,
diff --git a/src/api2/config/verify.rs b/src/api2/config/verify.rs
index 35be9b175..a0c23841e 100644
--- a/src/api2/config/verify.rs
+++ b/src/api2/config/verify.rs
@@ -262,6 +262,9 @@ pub fn update_verification_job(
if update.schedule.is_some() {
data.schedule = update.schedule;
}
+ if let Some(enable) = update.enable {
+ data.enable = Some(enable);
+ }
if let Some(ns) = update.ns {
if !ns.is_root() {
data.ns = Some(ns);
diff --git a/src/api2/tape/backup.rs b/src/api2/tape/backup.rs
index c0a4ca65b..2be8c3fe3 100644
--- a/src/api2/tape/backup.rs
+++ b/src/api2/tape/backup.rs
@@ -83,7 +83,12 @@ pub fn list_tape_backup_jobs(
let status = compute_schedule_status("tape-backup-job", &job.id, job.schedule.as_deref())?;
- let next_run = status.next_run.unwrap_or(current_time);
+ // default set to `true` to be backwards compatible
+ let next_run = if job.enable.unwrap_or(true) {
+ status.next_run.unwrap_or(current_time)
+ } else {
+ 0
+ };
let mut next_media_label = None;
diff --git a/src/bin/proxmox-backup-proxy.rs b/src/bin/proxmox-backup-proxy.rs
index 22abfdbdb..a6426ccbe 100644
--- a/src/bin/proxmox-backup-proxy.rs
+++ b/src/bin/proxmox-backup-proxy.rs
@@ -537,6 +537,11 @@ async fn schedule_datastore_garbage_collection() {
}
};
+ let gc_enabled = store_config.gc_enable.unwrap_or(true);
+ if !gc_enabled {
+ continue;
+ }
+
let event_str = match store_config.gc_schedule {
Some(event_str) => event_str,
None => continue,
@@ -684,6 +689,11 @@ async fn schedule_datastore_sync_jobs() {
None => continue,
};
+ let job_enabled = job_config.enable.unwrap_or(true);
+ if !job_enabled {
+ continue;
+ }
+
let worker_type = "syncjob";
if check_schedule(worker_type, &event_str, &job_id) {
let job = match Job::new(worker_type, &job_id) {
@@ -720,6 +730,11 @@ async fn schedule_datastore_verify_jobs() {
None => continue,
};
+ let job_enabled = job_config.enable.unwrap_or(true);
+ if !job_enabled {
+ continue;
+ }
+
let worker_type = "verificationjob";
let auth_id = Authid::root_auth_id().clone();
if check_schedule(worker_type, &event_str, &job_id) {
@@ -756,6 +771,11 @@ async fn schedule_tape_backup_jobs() {
None => continue,
};
+ let job_enabled = job_config.enable.unwrap_or(true);
+ if !job_enabled {
+ continue;
+ }
+
let worker_type = "tape-backup-job";
let auth_id = Authid::root_auth_id().clone();
if check_schedule(worker_type, &event_str, &job_id) {
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH proxmox-backup v2 4/6] fix #7904: ui: job edit: introduce "Enable" checkbox for {sync,verify,tape,GC} jobs
2026-10-07 13:43 [PATCH proxmox{,-backup} v2 0/6] fix #7904: Implement Enable checkboxes for all jobs Jonas Theisen
` (2 preceding siblings ...)
2026-10-07 13:43 ` [PATCH proxmox-backup v2 3/6] fix #7904: api: implement "enable" for {sync,verify,tape,GC} jobs Jonas Theisen
@ 2026-10-07 13:43 ` Jonas Theisen
2026-10-07 13:43 ` [PATCH proxmox-backup v2 5/6] ui: Improve visibility of disabled {sync,verify,tape,GC,prune} jobs on the overview page Jonas Theisen
2026-10-07 13:43 ` [PATCH proxmox-backup v2 6/6] ui: calendar-event: Remove clear button from calendar selector Jonas Theisen
5 siblings, 0 replies; 7+ messages in thread
From: Jonas Theisen @ 2026-10-07 13:43 UTC (permalink / raw)
To: pbs-devel
This allow users to disable jobs from the UI using the "enable"
API paramter.
This also disallows the schedule from being empty since disabling jobs
can now be done with the "enable" parameter.
To avoid user confusion and remain backwards compatible, the setValues
function automatically sets the "enable" parameter to false if
the schedule is currently empty i.e. the job is disabled.
Fixes: https://bugzilla.proxmox.com/show_bug.cgi?id=7904
Signed-off-by: Jonas Theisen <j.theisen@proxmox.com>
---
www/config/GCView.js | 2 ++
www/tape/window/TapeBackupJob.js | 30 ++++++++++++++++++++++--
www/window/GCJobEdit.js | 39 ++++++++++++++++++++++++++++----
www/window/SyncJobEdit.js | 26 +++++++++++++++++++--
www/window/VerifyJobEdit.js | 30 ++++++++++++++++++++++--
5 files changed, 116 insertions(+), 11 deletions(-)
diff --git a/www/config/GCView.js b/www/config/GCView.js
index 9fcc22344..5077f0566 100644
--- a/www/config/GCView.js
+++ b/www/config/GCView.js
@@ -5,6 +5,7 @@ Ext.define('pbs-gc-jobs-status', {
'upid',
'removed-bytes',
'pending-bytes',
+ 'enable',
'schedule',
'next-run',
'last-run-endtime',
@@ -73,6 +74,7 @@ Ext.define('PBS.config.GCJobView', {
datastore: data.store,
id: data.store,
schedule: data.schedule,
+ enable: data.enable,
listeners: {
destroy: () => this.reload(),
},
diff --git a/www/tape/window/TapeBackupJob.js b/www/tape/window/TapeBackupJob.js
index ad03b6076..2c50470e5 100644
--- a/www/tape/window/TapeBackupJob.js
+++ b/www/tape/window/TapeBackupJob.js
@@ -46,6 +46,14 @@ Ext.define('PBS.TapeManagement.BackupJobEdit', {
},
},
+ setValues: function (values) {
+ let me = this;
+ if (!values.schedule || values.schedule === '') {
+ values.enable = false;
+ }
+ me.callParent([values]);
+ },
+
items: {
xtype: 'tabpanel',
bodyPadding: 10,
@@ -112,13 +120,31 @@ Ext.define('PBS.TapeManagement.BackupJobEdit', {
],
column2: [
+ {
+ xtype: 'proxmoxcheckbox',
+ fieldLabel: gettext('Enable'),
+ name: 'enable',
+ autoEl: {
+ tag: 'div',
+ 'data-qtip': gettext('Enable scheduled execution of this task.'),
+ },
+ listeners: {
+ change: function (field, enabled) {
+ let me = this;
+ let view = me.up('pbsTapeBackupJobEdit');
+ let schedule = view.down('field[name=schedule]');
+ schedule.setDisabled(!enabled);
+ },
+ },
+ uncheckedValue: false,
+ value: true,
+ },
{
fieldLabel: gettext('Schedule'),
xtype: 'pbsCalendarEvent',
name: 'schedule',
- emptyText: gettext('none (disabled)'),
+ allowBlank: false,
cbind: {
- deleteEmpty: '{!isCreate}',
value: '{scheduleValue}',
},
},
diff --git a/www/window/GCJobEdit.js b/www/window/GCJobEdit.js
index 6afcf7de1..e1a94754d 100644
--- a/www/window/GCJobEdit.js
+++ b/www/window/GCJobEdit.js
@@ -19,10 +19,39 @@ Ext.define('PBS.window.GCJobEdit', {
return {};
},
- items: {
- xtype: 'pbsCalendarEvent',
- name: 'gc-schedule',
- fieldLabel: gettext('GC Schedule'),
- emptyText: gettext('none (disabled)'),
+ setValues: function (values) {
+ let me = this;
+ if (!values['gc-schedule'] || values['gc-schedule'] === '') {
+ values['gc-enable'] = false;
+ }
+ me.callParent([values]);
},
+
+ items: [
+ {
+ xtype: 'proxmoxcheckbox',
+ fieldLabel: gettext('Enable'),
+ name: 'gc-enable',
+ autoEl: {
+ tag: 'div',
+ 'data-qtip': gettext('Enable scheduled execution of this task.'),
+ },
+ listeners: {
+ change: function (field, enabled) {
+ let me = this;
+ let view = me.up('pbsGCJobEdit');
+ let schedule = view.down('field[name=gc-schedule]');
+ schedule.setDisabled(!enabled);
+ },
+ },
+ uncheckedValue: false,
+ value: true,
+ },
+ {
+ xtype: 'pbsCalendarEvent',
+ name: 'gc-schedule',
+ fieldLabel: gettext('GC Schedule'),
+ allowBlank: false,
+ },
+ ],
});
diff --git a/www/window/SyncJobEdit.js b/www/window/SyncJobEdit.js
index 961ce2951..9ff949b22 100644
--- a/www/window/SyncJobEdit.js
+++ b/www/window/SyncJobEdit.js
@@ -97,6 +97,10 @@ Ext.define('PBS.window.SyncJobEdit', {
} else {
values.location = 'remote';
}
+
+ if (!values.schedule || values.schedule === '') {
+ values.enable = false;
+ }
me.callParent([values]);
},
@@ -203,13 +207,31 @@ Ext.define('PBS.window.SyncJobEdit', {
deleteEmpty: '{!isCreate}',
},
},
+ {
+ xtype: 'proxmoxcheckbox',
+ fieldLabel: gettext('Enable'),
+ name: 'enable',
+ autoEl: {
+ tag: 'div',
+ 'data-qtip': gettext('Enable scheduled execution of this task.'),
+ },
+ listeners: {
+ change: function (field, enabled) {
+ let me = this;
+ let view = me.up('pbsSyncJobEdit');
+ let schedule = view.down('field[name=schedule]');
+ schedule.setDisabled(!enabled);
+ },
+ },
+ uncheckedValue: false,
+ value: true,
+ },
{
xtype: 'pbsCalendarEvent',
name: 'schedule',
fieldLabel: gettext('Sync Schedule'),
- emptyText: gettext('none'),
+ allowBlank: false,
cbind: {
- deleteEmpty: '{!isCreate}',
value: '{scheduleValue}',
},
},
diff --git a/www/window/VerifyJobEdit.js b/www/window/VerifyJobEdit.js
index b8d8b5810..c8e54e0f2 100644
--- a/www/window/VerifyJobEdit.js
+++ b/www/window/VerifyJobEdit.js
@@ -80,6 +80,14 @@ Ext.define('PBS.window.VerifyJobEdit', {
},
},
+ setValues: function (values) {
+ let me = this;
+ if (!values.schedule || values.schedule === '') {
+ values.enable = false;
+ }
+ me.callParent([values]);
+ },
+
items: {
xtype: 'inputpanel',
onGetValues: function (values) {
@@ -124,14 +132,32 @@ Ext.define('PBS.window.VerifyJobEdit', {
],
column2: [
+ {
+ xtype: 'proxmoxcheckbox',
+ fieldLabel: gettext('Enable'),
+ name: 'enable',
+ autoEl: {
+ tag: 'div',
+ 'data-qtip': gettext('Enable scheduled execution of this task.'),
+ },
+ listeners: {
+ change: function (field, enabled) {
+ let me = this;
+ let view = me.up('pbsVerifyJobEdit');
+ let schedule = view.down('field[name=schedule]');
+ schedule.setDisabled(!enabled);
+ },
+ },
+ uncheckedValue: false,
+ value: true,
+ },
{
xtype: 'pbsCalendarEvent',
name: 'schedule',
fieldLabel: gettext('Schedule'),
- emptyText: gettext('none (disabled)'),
+ allowBlank: false,
cbind: {
value: '{scheduleValue}',
- deleteEmpty: '{!isCreate}',
},
},
{
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH proxmox-backup v2 5/6] ui: Improve visibility of disabled {sync,verify,tape,GC,prune} jobs on the overview page
2026-10-07 13:43 [PATCH proxmox{,-backup} v2 0/6] fix #7904: Implement Enable checkboxes for all jobs Jonas Theisen
` (3 preceding siblings ...)
2026-10-07 13:43 ` [PATCH proxmox-backup v2 4/6] fix #7904: ui: job edit: introduce "Enable" checkbox " Jonas Theisen
@ 2026-10-07 13:43 ` Jonas Theisen
2026-10-07 13:43 ` [PATCH proxmox-backup v2 6/6] ui: calendar-event: Remove clear button from calendar selector Jonas Theisen
5 siblings, 0 replies; 7+ messages in thread
From: Jonas Theisen @ 2026-10-07 13:43 UTC (permalink / raw)
To: pbs-devel
This commit adds additional logic to prominently display if
a job was disabled on the respective overview page by introducing
a new renderer.
If the job is disabled the text "Disabled" is shown instead of
the schedule which is still present in the config file.
For backwords compatibility if no schedule is defined the fallback
is still None.
Signed-off-by: Jonas Theisen <j.theisen@proxmox.com>
---
www/Utils.js | 10 ++++++++++
www/config/GCView.js | 2 +-
www/config/PruneView.js | 1 +
www/config/SyncView.js | 2 ++
www/config/VerifyView.js | 2 ++
www/tape/BackupJobs.js | 2 ++
6 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/www/Utils.js b/www/Utils.js
index d6bfd459e..aa2f19832 100644
--- a/www/Utils.js
+++ b/www/Utils.js
@@ -335,6 +335,16 @@ Ext.define('PBS.Utils', {
);
},
+ render_schedule: function (val, metadat, record) {
+ if(record.data.enable === false || record.data.disable === true) {
+ return gettext('Disabled');
+ }
+ if(val) {
+ return val;
+ }
+ return Proxmox.Utils.NoneText;
+ },
+
get_help_tool: function (blockid) {
let info = Proxmox.Utils.get_help_info(blockid);
if (info === undefined) {
diff --git a/www/config/GCView.js b/www/config/GCView.js
index 5077f0566..2ac931cd8 100644
--- a/www/config/GCView.js
+++ b/www/config/GCView.js
@@ -183,7 +183,7 @@ Ext.define('PBS.config.GCJobView', {
header: gettext('Schedule'),
dataIndex: 'schedule',
hideable: false,
- renderer: (value) => (value ? value : Proxmox.Utils.NoneText),
+ renderer: PBS.Utils.render_schedule,
minWidth: 85,
flex: 1,
},
diff --git a/www/config/PruneView.js b/www/config/PruneView.js
index f38724687..c6fb750c7 100644
--- a/www/config/PruneView.js
+++ b/www/config/PruneView.js
@@ -234,6 +234,7 @@ Ext.define('PBS.config.PruneJobView', {
minWidth: 80,
flex: 1,
sortable: true,
+ renderer: PBS.Utils.render_schedule,
},
{
text: gettext('Keep'),
diff --git a/www/config/SyncView.js b/www/config/SyncView.js
index 386489120..494cad65a 100644
--- a/www/config/SyncView.js
+++ b/www/config/SyncView.js
@@ -8,6 +8,7 @@ Ext.define('pbs-sync-jobs-status', {
'remote-ns',
'store',
'ns',
+ 'enable',
'schedule',
'group-filter',
'next-run',
@@ -395,6 +396,7 @@ Ext.define('PBS.config.SyncJobView', {
minWidth: 80,
flex: 1,
sortable: true,
+ renderer: PBS.Utils.render_schedule,
},
{
header: gettext('Last Sync'),
diff --git a/www/config/VerifyView.js b/www/config/VerifyView.js
index 2c63f0d79..29da0773c 100644
--- a/www/config/VerifyView.js
+++ b/www/config/VerifyView.js
@@ -5,6 +5,7 @@ Ext.define('pbs-verify-jobs-status', {
'store',
'outdated-after',
'ignore-verified',
+ 'enable',
'schedule',
'next-run',
'last-run-upid',
@@ -253,6 +254,7 @@ Ext.define('PBS.config.VerifyJobView', {
maxWidth: 220,
minWidth: 80,
flex: 1,
+ renderer: PBS.Utils.render_schedule,
},
{
header: gettext('Last Verification'),
diff --git a/www/tape/BackupJobs.js b/www/tape/BackupJobs.js
index 68d808af5..8cefb2dae 100644
--- a/www/tape/BackupJobs.js
+++ b/www/tape/BackupJobs.js
@@ -7,6 +7,7 @@ Ext.define('pbs-tape-backup-job-status', {
'drive',
'store',
'schedule',
+ 'enable',
'comment',
'group-filter',
{ name: 'eject-media', type: 'boolean' },
@@ -259,6 +260,7 @@ Ext.define('PBS.config.TapeBackupJobView', {
minWidth: 80,
flex: 1,
sortable: true,
+ renderer: PBS.Utils.render_schedule,
},
{
header: gettext('Last Backup'),
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH proxmox-backup v2 6/6] ui: calendar-event: Remove clear button from calendar selector
2026-10-07 13:43 [PATCH proxmox{,-backup} v2 0/6] fix #7904: Implement Enable checkboxes for all jobs Jonas Theisen
` (4 preceding siblings ...)
2026-10-07 13:43 ` [PATCH proxmox-backup v2 5/6] ui: Improve visibility of disabled {sync,verify,tape,GC,prune} jobs on the overview page Jonas Theisen
@ 2026-10-07 13:43 ` Jonas Theisen
5 siblings, 0 replies; 7+ messages in thread
From: Jonas Theisen @ 2026-10-07 13:43 UTC (permalink / raw)
To: pbs-devel
Since the schedule fields in all the forms do not allow
empty inputs anymore it would be unintuitive to have a clear button.
This patch removes the trigger and listener logic for that.
Signed-off-by: Jonas Theisen <j.theisen@proxmox.com>
---
www/form/CalendarEvent.js | 19 -------------------
1 file changed, 19 deletions(-)
diff --git a/www/form/CalendarEvent.js b/www/form/CalendarEvent.js
index b050da694..d6cc6e0e9 100644
--- a/www/form/CalendarEvent.js
+++ b/www/form/CalendarEvent.js
@@ -53,25 +53,6 @@ Ext.define('PBS.form.CalendarEvent', {
return data;
},
- triggers: {
- clear: {
- cls: 'pmx-clear-trigger',
- weight: -1,
- hidden: true,
- handler: function () {
- this.triggers.clear.setVisible(false);
- this.setValue('');
- },
- },
- },
-
- listeners: {
- change: function (field, value) {
- let canClear = (value ?? '') !== '';
- field.triggers.clear.setVisible(canClear);
- },
- },
-
store: {
type: 'calendarEventExamples',
},
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread