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 E4EF01FF0C2 for ; Thu, 22 Oct 2026 14:49:45 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id C6A612196E; Thu, 22 Oct 2026 14:48:32 +0200 (CEST) From: Arthur Bied-Charreton To: pve-devel@lists.proxmox.com Subject: [PATCH pve-manager v4 20/27] ui: firewall: add a common widget for handling dangling references Date: Thu, 22 Oct 2026 14:47:01 +0200 Message-ID: <20261022124708.429069-21-a.bied-charreton@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261022124708.429069-1-a.bied-charreton@proxmox.com> References: <20261022124708.429069-1-a.bied-charreton@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1792673237831 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.855 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: V2IFJS4YNV6IWOTL2NT3YRHIBG4DACPH X-Message-ID-Hash: V2IFJS4YNV6IWOTL2NT3YRHIBG4DACPH X-MailFrom: a.bied-charreton@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 VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: The ipset and alias grids both need to let users decide what happens to the rules and IPSet members referencing an object they are about to rename or delete. Add the pieces as reusable components. FirewallReferenceAction is a ComboGrid over a list of actions, submitting the chosen one as 'dangling-references'. The picker shows each action's description in its own column. The actions differ per endpoint so they are passed by the caller. FirewallObjectRemove extends ConfirmRemoveDialog with such a selector, for the delete paths that StdRemoveButton cannot handle because it submits no extra parameters. The selector sits in an 'Advanced' section there. Callers will be added in subsequent commits. Signed-off-by: Arthur Bied-Charreton --- www/manager6/Makefile | 1 + www/manager6/grid/FirewallObjectCommon.js | 134 ++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 www/manager6/grid/FirewallObjectCommon.js diff --git a/www/manager6/Makefile b/www/manager6/Makefile index d2ea786b..e211ad40 100644 --- a/www/manager6/Makefile +++ b/www/manager6/Makefile @@ -98,6 +98,7 @@ JSSRC= \ form/TagFieldSet.js \ form/IsoSelector.js \ grid/BackupView.js \ + grid/FirewallObjectCommon.js \ grid/FirewallAliases.js \ grid/FirewallOptions.js \ grid/FirewallRules.js \ diff --git a/www/manager6/grid/FirewallObjectCommon.js b/www/manager6/grid/FirewallObjectCommon.js new file mode 100644 index 00000000..04dddf48 --- /dev/null +++ b/www/manager6/grid/FirewallObjectCommon.js @@ -0,0 +1,134 @@ +Ext.define('PVE.window.FirewallObjectRemove', { + extend: 'Proxmox.window.ConfirmRemoveDialog', + alias: 'widget.pveFirewallObjectRemove', + + width: 500, + + // [{ value, text, description }, ...] + referenceActions: undefined, + + initComponent: function () { + let me = this; + + let stateProvider = Ext.state.Manager.getProvider(); + let advanced = stateProvider.get('proxmox-advanced-cb'); + + me.additionalItems = [ + { + xtype: 'pveFirewallReferenceAction', + // API default is 'keep' for backwards compatibility + preferredValue: 'drop', + referenceActions: me.referenceActions, + hidden: !advanced, + }, + ]; + + me.callParent(); + + let field = me.down('pveFirewallReferenceAction'); + let footer = me.down('[dock=bottom]'); + + footer.insert(0, { + xtype: 'container', + flex: 1, + layout: { type: 'hbox', align: 'middle', pack: 'end' }, + items: [ + { + xtype: 'proxmoxcheckbox', + boxLabel: gettext('Advanced'), + boxLabelAlign: 'before', + margin: '0 10 0 0', + stateId: 'proxmox-advanced-cb', + value: advanced, + listeners: { + change: function (checkbox, value) { + field.setVisible(value); + stateProvider.set('proxmox-advanced-cb', value); + }, + }, + }, + ], + }); + + footer.add({ + xtype: 'container', + flex: 1, + layout: { type: 'hbox', align: 'middle', pack: 'start' }, + items: [ + { + xtype: 'proxmoxHelpButton', + onlineHelp: 'pve_firewall_dangling_references', + listenToGlobalEvent: false, + hidden: false, + margin: '0 0 0 10', + }, + ], + }); + }, + + getParams: function () { + let me = this; + + let field = me.down('pveFirewallReferenceAction'); + + me.params = Ext.applyIf({ [field.getName()]: field.getValue() }, me.params); + + return me.callParent(); + }, +}); + +Ext.define('PVE.form.FirewallReferenceAction', { + extend: 'Proxmox.form.ComboGrid', + alias: 'widget.pveFirewallReferenceAction', + + fieldLabel: gettext('Dangling references'), + + // submitted parameter + name: 'dangling-references', + + preferredValue: 'keep', + + editable: false, + allowBlank: false, + valueField: 'value', + displayField: 'text', + + // [{ value, text, description }, ...] + referenceActions: undefined, + + initComponent: function () { + let me = this; + + if (!me.referenceActions?.length) { + throw new Error('no reference actions given, cannot initialize component'); + } + + me.store = Ext.create('Ext.data.Store', { + fields: ['value', 'text', 'description'], + data: me.referenceActions, + }); + + me.listConfig = { + width: 560, + resizable: true, + columns: [ + { + header: gettext('Action'), + dataIndex: 'text', + flex: 1, + }, + { + header: gettext('Description'), + dataIndex: 'description', + cellWrap: true, + flex: 4, + }, + ], + }; + + me.callParent(); + + // ComboGrid applies preferredValue on store load + me.setValue(me.preferredValue); + }, +}); -- 2.47.3