From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 51BD21FF144 for ; Tue, 24 Mar 2026 11:41:20 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 8064DB84D; Tue, 24 Mar 2026 11:41:39 +0100 (CET) Message-ID: <2d359aed-cac8-4597-a696-5d1d3cd90f52@proxmox.com> Date: Tue, 24 Mar 2026 11:41:34 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Beta Subject: Re: [PATCH proxmox-backup v5 7/9] ui: add move group action To: Hannes Laimer , pbs-devel@lists.proxmox.com References: <20260319161325.206846-1-h.laimer@proxmox.com> <20260319161325.206846-8-h.laimer@proxmox.com> Content-Language: en-US From: Dominik Csapak In-Reply-To: <20260319161325.206846-8-h.laimer@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: 1774348848430 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.040 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. 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: V3NO5T4JDPRNYRLPPCPRDCUCZCUQLMZU X-Message-ID-Hash: V3NO5T4JDPRNYRLPPCPRDCUCZCUQLMZU X-MailFrom: d.csapak@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: code looks good to me, but please add more information in the commit message. On 3/19/26 5:13 PM, Hannes Laimer wrote: > Signed-off-by: Hannes Laimer > --- > www/Makefile | 1 + > www/datastore/Content.js | 47 +++++++++++++++++++++++++++++++++ > www/window/GroupMove.js | 56 ++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 104 insertions(+) > create mode 100644 www/window/GroupMove.js > > diff --git a/www/Makefile b/www/Makefile > index 9ebf0445..7745d9f4 100644 > --- a/www/Makefile > +++ b/www/Makefile > @@ -76,6 +76,7 @@ JSSRC= \ > config/PruneAndGC.js \ > window/ACLEdit.js \ > window/BackupGroupChangeOwner.js \ > + window/GroupMove.js \ > window/CreateDirectory.js \ > window/DataStoreEdit.js \ > window/NamespaceEdit.js \ > diff --git a/www/datastore/Content.js b/www/datastore/Content.js > index 981acdc7..b56cc4ac 100644 > --- a/www/datastore/Content.js > +++ b/www/datastore/Content.js > @@ -667,6 +667,27 @@ Ext.define('PBS.DataStoreContent', { > }); > }, > > + moveGroup: function (data) { > + let me = this; > + let view = me.getView(); > + let group = `${data.backup_type}/${data.backup_id}`; > + Ext.create('PBS.window.GroupMove', { > + datastore: view.datastore, > + namespace: view.namespace, > + backupType: data.backup_type, > + backupId: data.backup_id, > + group, > + taskDone: () => me.reload(), > + }).show(); > + }, > + > + onMove: function (table, rI, cI, item, e, { data }) { > + let me = this; > + if (data.ty === 'group') { > + me.moveGroup(data); > + } > + }, > + > forgetGroup: function (data) { > let me = this; > let view = me.getView(); > @@ -971,6 +992,7 @@ Ext.define('PBS.DataStoreContent', { > onVerify: createControllerCallback('onVerify'), > onChangeOwner: createControllerCallback('onChangeOwner'), > onPrune: createControllerCallback('onPrune'), > + onMove: createControllerCallback('onMove'), > onForget: createControllerCallback('onForget'), > }); > } else if (record.data.ty === 'dir') { > @@ -1085,6 +1107,20 @@ Ext.define('PBS.DataStoreContent', { > : 'pmx-hidden', > isActionDisabled: (v, r, c, i, rec) => !!rec.data.leaf, > }, > + { > + handler: 'onMove', > + getTip: (v, m, { data }) => { > + if (data.ty === 'group') { > + return Ext.String.format(gettext("Move group '{0}'"), v); > + } > + return ''; > + }, > + getClass: (v, m, { data }) => { > + if (data.ty === 'group') { return 'fa fa-arrows'; } > + return 'pmx-hidden'; > + }, > + isActionDisabled: (v, r, c, i, { data }) => false, > + }, > { > handler: 'onChangeOwner', > getClass: (v, m, { data }) => > @@ -1437,6 +1473,7 @@ Ext.define('PBS.datastore.GroupCmdMenu', { > onVerify: undefined, > onChangeOwner: undefined, > onPrune: undefined, > + onMove: undefined, > onForget: undefined, > > items: [ > @@ -1460,6 +1497,16 @@ Ext.define('PBS.datastore.GroupCmdMenu', { > hidden: '{!onVerify}', > }, > }, > + { > + text: gettext('Move'), > + iconCls: 'fa fa-arrows', > + handler: function () { > + this.up('menu').onMove(); > + }, > + cbind: { > + hidden: '{!onMove}', > + }, > + }, > { > text: gettext('Change owner'), > iconCls: 'fa fa-user', > diff --git a/www/window/GroupMove.js b/www/window/GroupMove.js > new file mode 100644 > index 00000000..f663c606 > --- /dev/null > +++ b/www/window/GroupMove.js > @@ -0,0 +1,56 @@ > +Ext.define('PBS.window.GroupMove', { > + extend: 'Proxmox.window.Edit', > + alias: 'widget.pbsGroupMove', > + mixins: ['Proxmox.Mixin.CBind'], > + > + onlineHelp: 'storage-namespaces', > + > + isCreate: true, > + submitText: gettext('Move'), > + showTaskViewer: true, > + > + cbind: { > + url: '/api2/extjs/admin/datastore/{datastore}/groups', > + title: (get) => Ext.String.format(gettext("Move Backup Group '{0}'"), get('group')), > + }, > + method: 'PUT', > + > + width: 400, > + fieldDefaults: { > + labelWidth: 120, > + }, > + > + items: { > + xtype: 'inputpanel', > + onGetValues: function (values) { > + let win = this.up('window'); > + let result = { > + 'backup-type': win.backupType, > + 'backup-id': win.backupId, > + 'new-ns': values['new-ns'] || '', > + }; > + if (win.namespace && win.namespace !== '') { > + result.ns = win.namespace; > + } > + return result; > + }, > + items: [ > + { > + xtype: 'displayfield', > + fieldLabel: gettext('Group'), > + cbind: { > + value: '{group}', > + }, > + }, > + { > + xtype: 'pbsNamespaceSelector', > + name: 'new-ns', > + fieldLabel: gettext('Target Namespace'), > + allowBlank: true, > + cbind: { > + datastore: '{datastore}', > + }, > + }, > + ], > + }, > +});