From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id DEDC51FF0C2 for ; Thu, 15 Oct 2026 13:14:36 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 74EC1213A6; Thu, 15 Oct 2026 13:14:36 +0200 (CEST) Message-ID: <36ef1c50-cd0c-4cd4-8b9f-91b0c5919634@proxmox.com> Date: Thu, 15 Oct 2026 13:14:32 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird From: Christian Ebner Subject: Re: [PATCH proxmox-backup v3 06/10] fix #7904: ui: job edit: introduce "Enable" checkbox for {sync,verify,tape,GC} jobs To: Jonas Theisen , pbs-devel@lists.proxmox.com References: <20261009145445.282494-1-j.theisen@proxmox.com> <20261009145445.282494-4-j.theisen@proxmox.com> Content-Language: en-US, de-DE In-Reply-To: <20261009145445.282494-4-j.theisen@proxmox.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1792062872705 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.512 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: NIIS6KNIG36D7A2BLYZRX7KPGLHEANCM X-Message-ID-Hash: NIIS6KNIG36D7A2BLYZRX7KPGLHEANCM X-MailFrom: c.ebner@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Backup Server development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Same as for patch 3, ExtJS variable bindings should be used where possible in this patch as well, which will help with improving readability and code style. Also, please make sure to format all UI patches using proxmox-biome. On 10/9/26 4:55 PM, Jonas Theisen wrote: > This allow users to disable jobs from the UI using the "disable" > API paramter. > > This also disallows the schedule from being empty since disabling jobs > can now be done with the "disable" parameter. > > To avoid user confusion and remain backwards compatible, the setValues > function automatically sets the "disable" parameter to true 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 > --- > www/tape/window/TapeBackupJob.js | 40 ++++++++++++++++++++++-- > www/window/GCJobEdit.js | 52 +++++++++++++++++++++++++++++--- > www/window/SyncJobEdit.js | 36 ++++++++++++++++++++-- > www/window/VerifyJobEdit.js | 40 ++++++++++++++++++++++-- > 4 files changed, 157 insertions(+), 11 deletions(-) > > diff --git a/www/tape/window/TapeBackupJob.js b/www/tape/window/TapeBackupJob.js > index ad03b6076..833672076 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.disable = true; > + } > + me.callParent([values]); > + }, > + > items: { > xtype: 'tabpanel', > bodyPadding: 10, > @@ -66,6 +74,16 @@ Ext.define('PBS.TapeManagement.BackupJobEdit', { > delete values.delete; > } > > + values.disable = !values.enable; > + delete values.enable; > + > + return values; > + }, > + onSetValues: function (values) { > + let _me = this; > + values.enable = !values.disable; > + delete values.disable; > + > return values; > }, > cbind: { > @@ -112,13 +130,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..094bed874 100644 > --- a/www/window/GCJobEdit.js > +++ b/www/window/GCJobEdit.js > @@ -19,10 +19,52 @@ 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-disable'] = true; > + } > + > + values['gc-enable'] = !values['gc-disable']; > + delete values['gc-disable']; > + me.callParent([values]); > + }, > + > + getValues: function (dirtyOnly) { > + let me = this; > + let values = me.callParent([dirtyOnly]); > + > + values['gc-disable'] = !values['gc-enable']; > + delete values['gc-enable']; > + > + return 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..42f6070f1 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.disable = true; > + } > me.callParent([values]); > }, > > @@ -130,6 +134,16 @@ Ext.define('PBS.window.SyncJobEdit', { > PBS.Utils.delete_if_default(values, 'rate-out'); > PBS.Utils.delete_if_default(values, 'remote'); > } > + values.disable = !values.enable; > + delete values.enable; > + > + return values; > + }, > + onSetValues: function (values) { > + let _me = this; > + values.enable = !values.disable; > + delete values.disable; > + > return values; > }, > cbind: { > @@ -203,13 +217,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..b4eda822f 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.disable = true; > + } > + me.callParent([values]); > + }, > + > items: { > xtype: 'inputpanel', > onGetValues: function (values) { > @@ -88,6 +96,16 @@ Ext.define('PBS.window.VerifyJobEdit', { > if (!values.id && me.up('pbsVerifyJobEdit').isCreate) { > values.id = 'v-' + Ext.data.identifier.Uuid.Global.generate().slice(0, 13); > } > + values.disable = !values.enable; > + delete values.enable; > + > + return values; > + }, > + onSetValues: function (values) { > + let _me = this; > + values.enable = !values.disable; > + delete values.disable; > + > return values; > }, > column1: [ > @@ -124,14 +142,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}', > }, > }, > {