From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <d.csapak@proxmox.com>
Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (2048 bits))
 (No client certificate requested)
 by lists.proxmox.com (Postfix) with ESMTPS id 7AF1F9B3D2
 for <pve-devel@lists.proxmox.com>; Mon, 20 Nov 2023 14:20:47 +0100 (CET)
Received: from firstgate.proxmox.com (localhost [127.0.0.1])
 by firstgate.proxmox.com (Proxmox) with ESMTP id 54C8819D59
 for <pve-devel@lists.proxmox.com>; Mon, 20 Nov 2023 14:20:17 +0100 (CET)
Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com
 [94.136.29.106])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (2048 bits))
 (No client certificate requested)
 by firstgate.proxmox.com (Proxmox) with ESMTPS
 for <pve-devel@lists.proxmox.com>; Mon, 20 Nov 2023 14:20:16 +0100 (CET)
Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1])
 by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 2B1AD43476;
 Mon, 20 Nov 2023 14:20:16 +0100 (CET)
Message-ID: <00b0eb49-a0e2-4bee-a408-969132ef92b5@proxmox.com>
Date: Mon, 20 Nov 2023 14:20:15 +0100
MIME-Version: 1.0
User-Agent: Mozilla Thunderbird Beta
Content-Language: en-US
To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>,
 Stefan Hanreich <s.hanreich@proxmox.com>
References: <20231117114011.834002-1-s.hanreich@proxmox.com>
 <20231117114011.834002-20-s.hanreich@proxmox.com>
From: Dominik Csapak <d.csapak@proxmox.com>
In-Reply-To: <20231117114011.834002-20-s.hanreich@proxmox.com>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
X-SPAM-LEVEL: Spam detection results:  0
 AWL 0.017 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
 SPF_HELO_NONE           0.001 SPF: HELO does not publish an SPF Record
 SPF_PASS               -0.001 SPF: sender matches SPF record
 T_SCC_BODY_TEXT_LINE    -0.01 -
Subject: Re: [pve-devel] [PATCH v4 pve-manager 19/33] sdn: subnet: add panel
 for editing dhcp ranges
X-BeenThere: pve-devel@lists.proxmox.com
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/>
List-Post: <mailto:pve-devel@lists.proxmox.com>
List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe>
X-List-Received-Date: Mon, 20 Nov 2023 13:20:47 -0000

hi, a few issues here:

high level:

adding/modifying/deleting dhcp ranges does not trigger form 'isDirty'
check properly, leading to me unable to add dhcp ranges
to an existing subnet without also changing something else on
the first tab (there are probably some 'checkChange' triggers missing?)

also i can send invalid data because the 'getErrors' function is not implemented
i don't think we should be able to do this

also i'd show the dhcp ranges in the grid too, even if it's just
a hidden by default

remaining comments inline:

On 11/17/23 12:39, Stefan Hanreich wrote:
> Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
> ---
>   www/manager6/Makefile          |   1 +
>   www/manager6/sdn/SubnetEdit.js | 160 ++++++++++++++++++++++++++++++++-
>   2 files changed, 160 insertions(+), 1 deletion(-)
> 
> diff --git a/www/manager6/Makefile b/www/manager6/Makefile
> index dccd2ba1c..093452cd7 100644
> --- a/www/manager6/Makefile
> +++ b/www/manager6/Makefile
> @@ -274,6 +274,7 @@ JSSRC= 							\
>   	sdn/ZoneContentView.js				\
>   	sdn/ZoneContentPanel.js				\
>   	sdn/ZoneView.js					\
> +	sdn/IpamEdit.js					\
>   	sdn/OptionsPanel.js				\
>   	sdn/controllers/Base.js				\
>   	sdn/controllers/EvpnEdit.js			\
> diff --git a/www/manager6/sdn/SubnetEdit.js b/www/manager6/sdn/SubnetEdit.js
> index b9825d2a3..4fe16ab92 100644
> --- a/www/manager6/sdn/SubnetEdit.js
> +++ b/www/manager6/sdn/SubnetEdit.js
> @@ -56,6 +56,147 @@ Ext.define('PVE.sdn.SubnetInputPanel', {
>       ],
>   });
>   
> +Ext.define('PVE.sdn.SubnetDhcpRangePanel', {
> +    extend: 'Ext.form.FieldContainer',
> +    mixins: ['Ext.form.field.Field'],
> +
> +    initComponent: function() {
> +	let me = this;
> +
> +	me.callParent();
> +	me.initField();
> +    },
> +
> +    getValue: function() {
> +	let me = this;
> +	let store = me.lookup('grid').getStore();
> +
> +	let data = [];
> +
> +	store.getData()
> +	    .each((item) =>
> +		data.push(`start-address=${item.data['start-address']},end-address=${item.data['end-address']}`),
> +	    );

i'd not indent the 'each', because then you have one level less for the 'data.push'

> +
> +	return data;
> +    },
> +
> +    getSubmitData: function() {
> +	let me = this;
> +
> +	let data = {};
> +	let value = me.getValue();
> +
> +	if (value.length) {
> +	    data[me.getName()] = value;
> +	}
> +
> +	return data;
> +    },
> +
> +    setValue: function(dhcpRanges) {
> +	let me = this;
> +	let store = me.lookup('grid').getStore();
> +	store.setData(dhcpRanges);
> +    },

not sure if it's because of this, but it seems not to reset properly
the field always becomes empty but still has the reset enabled

> +
> +    getErrors: function() {
> +	let me = this;
> +        let errors = [];
> +
> +	return errors;
> +    },

please implement this (even if rudimentary) so users cannot send
invalid values

> +
> +    controller: {
> +	xclass: 'Ext.app.ViewController',
> +
> +	addRange: function() {
> +	    let me = this;
> +	    me.lookup('grid').getStore().add({});


i guess here would be a good place to add a 'me.getView().checkChange()'


> +	},
> +
> +	removeRange: function(field) {
> +	    let me = this;
> +	    let record = field.getWidgetRecord();
> +
> +	    me.lookup('grid').getStore().remove(record);


here too

> +	},
> +
> +	onValueChange: function(field, value) {
> +	    let me = this;
> +	    let record = field.getWidgetRecord();
> +	    let column = field.getWidgetColumn();
> +
> +	    record.set(column.dataIndex, value);
> +	    record.commit();


and here too


> +	},
> +
> +	control: {
> +	    'grid button': {
> +		click: 'removeRange',
> +	    },
> +	    'field': {
> +		change: 'onValueChange',
> +	    },
> +	},
> +    },
> +
> +    items: [
> +	{
> +	    xtype: 'grid',
> +	    reference: 'grid',
> +	    scrollable: true,
> +	    store: {
> +		fields: ['start-address', 'end-address'],
> +	    },
> +	    columns: [
> +		{
> +		    text: gettext('Start Address'),
> +		    xtype: 'widgetcolumn',
> +		    dataIndex: 'start-address',
> +		    flex: 1,
> +		    widget: {
> +			xtype: 'textfield',
> +			vtype: 'IP64Address',
> +		    },
> +		},
> +		{
> +		    text: gettext('End Address'),
> +		    xtype: 'widgetcolumn',
> +		    dataIndex: 'end-address',
> +		    flex: 1,
> +		    widget: {
> +			xtype: 'textfield',
> +			vtype: 'IP64Address',
> +		    },
> +		},
> +		{
> +		    xtype: 'widgetcolumn',
> +		    width: 40,
> +		    widget: {
> +			xtype: 'button',
> +			iconCls: 'fa fa-trash-o',
> +		    },
> +		},
> +	    ],
> +	},
> +	{
> +	    xtype: 'container',
> +	    layout: {
> +		type: 'hbox',
> +	    },
> +	    items: [
> +		{
> +		    xtype: 'button',
> +		    text: gettext('Add'),
> +		    iconCls: 'fa fa-plus-circle',
> +		    handler: 'addRange',
> +		},
> +	    ],
> +	},
> +    ],
> +});
> +
>   Ext.define('PVE.sdn.SubnetEdit', {
>       extend: 'Proxmox.window.Edit',
>   
> @@ -67,6 +208,8 @@ Ext.define('PVE.sdn.SubnetEdit', {
>   
>       base_url: undefined,
>   
> +    bodyPadding: 0,
> +
>       initComponent: function() {
>   	var me = this;
>   
> @@ -82,11 +225,22 @@ Ext.define('PVE.sdn.SubnetEdit', {
>   
>   	let ipanel = Ext.create('PVE.sdn.SubnetInputPanel', {
>   	    isCreate: me.isCreate,
> +	    title: gettext('General'),
> +	});
> +
> +	let dhcpPanel = Ext.create('PVE.sdn.SubnetDhcpRangePanel', {
> +	    isCreate: me.isCreate,
> +	    title: gettext('DHCP Ranges'),
> +	    name: 'dhcp-range',
>   	});
>   
>   	Ext.apply(me, {
>   	    items: [
> -		ipanel,
> +		{
> +		    xtype: 'tabpanel',
> +		    bodyPadding: 10,
> +		    items: [ipanel, dhcpPanel],
> +		},
>   	    ],
>   	});
>   
> @@ -97,6 +251,10 @@ Ext.define('PVE.sdn.SubnetEdit', {
>   		success: function(response, options) {
>   		    let values = response.result.data;
>   		    ipanel.setValues(values);
> +
> +		    if (values['dhcp-range']) {
> +			dhcpPanel.setValue(values['dhcp-range']);
> +		    }
>   		},
>   	    });
>   	}