public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH cluster/manager] fix #1408: ui: make tree sorting configurable
@ 2023-02-01 15:49 Dominik Csapak
  2023-02-01 15:49 ` [pve-devel] [PATCH cluster 1/1] datacenter config: add options for sorting the gui tree Dominik Csapak
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Dominik Csapak @ 2023-02-01 15:49 UTC (permalink / raw)
  To: pve-devel

this series allows configuring the sorting of the resource tree

options are the sort-field, if guest types are grouped and if templates
are grouped seperately

it's configurable in the datacenter config and the browser local storage
(latter takes precedence)

not completely sure if the displaying/selecting the default is really
optimal by just showing 'Default'. (more in the comment of the specific
patch 2/3 in pve-manager)

pve-cluster:

Dominik Csapak (1):
  datacenter config: add options for sorting the gui tree

 data/PVE/DataCenterConfig.pm | 37 ++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

pve-manager:

Dominik Csapak (3):
  ui: Utils: refactor refreshing the the resource store/tree
  ui: add TreeSortingEdit window
  fix #1408: ui: ResourceTree: sort the tree according to tree-sorting
    options

 www/manager6/Makefile                  |   1 +
 www/manager6/Utils.js                  |  17 +++-
 www/manager6/Workspace.js              |  27 +++++-
 www/manager6/dc/OptionView.js          |  11 +++
 www/manager6/tree/ResourceTree.js      |  54 +++++++++---
 www/manager6/window/TreeSortingEdit.js | 113 +++++++++++++++++++++++++
 6 files changed, 208 insertions(+), 15 deletions(-)
 create mode 100644 www/manager6/window/TreeSortingEdit.js

-- 
2.30.2





^ permalink raw reply	[flat|nested] 8+ messages in thread

* [pve-devel] [PATCH cluster 1/1] datacenter config: add options for sorting the gui tree
  2023-02-01 15:49 [pve-devel] [PATCH cluster/manager] fix #1408: ui: make tree sorting configurable Dominik Csapak
@ 2023-02-01 15:49 ` Dominik Csapak
  2023-02-01 15:49 ` [pve-devel] [PATCH manager 1/3] ui: Utils: refactor refreshing the the resource store/tree Dominik Csapak
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Dominik Csapak @ 2023-02-01 15:49 UTC (permalink / raw)
  To: pve-devel

namely the 'sort-field' (either vmid or name), 'group-templates' (if the
guest templates should be grouped seperately) and 'group-guest-types'
(if the guest types should be grouped or not)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 data/PVE/DataCenterConfig.pm | 37 ++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/data/PVE/DataCenterConfig.pm b/data/PVE/DataCenterConfig.pm
index 7a24870..36e0ea6 100644
--- a/data/PVE/DataCenterConfig.pm
+++ b/data/PVE/DataCenterConfig.pm
@@ -219,6 +219,28 @@ my $user_tag_privs_format = {
     },
 };
 
+my $tree_sorting_format = {
+    'sort-field' => {
+	optional => 1,
+	type => 'string',
+	enum => ['vmid', 'name'],
+	default => 'vmid',
+	description => "Controls the field to use as sort order and primary display.",
+    },
+    'group-templates' => {
+	optional => 1,
+	type => 'boolean',
+	default => 1,
+	description => "If enabled, groups the guest templates seperately from regular guests.",
+    },
+    'group-guest-types' => {
+	optional => 1,
+	type => 'boolean',
+	default => 1,
+	description => "If enabled, groups the guests by type.",
+    },
+};
+
 my $datacenter_schema = {
     type => "object",
     additionalProperties => 0,
@@ -374,6 +396,12 @@ my $datacenter_schema = {
 	    pattern => "(?:${PVE::JSONSchema::PVE_TAG_RE};)*${PVE::JSONSchema::PVE_TAG_RE}",
 	    typetext => "<tag>[;<tag>...]",
 	},
+	'tree-sorting' => {
+	    optional => 1,
+	    type => 'string',
+	    description => "Tree sorting and grouping options",
+	    format => $tree_sorting_format,
+	},
     },
 };
 
@@ -442,6 +470,10 @@ sub parse_datacenter_config {
 	$res->{'registered-tags'} = [split(';', $admin_tags)];
     }
 
+    if (my $tree_sorting = $res->{'tree-sorting'}) {
+	$res->{'tree-sorting'} = parse_property_string($tree_sorting_format, $tree_sorting);
+    }
+
     # for backwards compatibility only, new migration property has precedence
     if (defined($res->{migration_unsecure})) {
 	if (defined($res->{migration}->{type})) {
@@ -524,6 +556,11 @@ sub write_datacenter_config {
 	$cfg->{'registered-tags'} = join(';', sort $admin_tags->@*);
     }
 
+    if (ref(my $tree_sorting = $cfg->{'tree-sorting'})) {
+	$cfg->{'tree-sorting'} =
+	    PVE::JSONSchema::print_property_string($tree_sorting, $tree_sorting_format);
+    }
+
     my $comment = '';
     # add description as comment to top of file
     my $description = $cfg->{description} || '';
-- 
2.30.2





^ permalink raw reply	[flat|nested] 8+ messages in thread

* [pve-devel] [PATCH manager 1/3] ui: Utils: refactor refreshing the the resource store/tree
  2023-02-01 15:49 [pve-devel] [PATCH cluster/manager] fix #1408: ui: make tree sorting configurable Dominik Csapak
  2023-02-01 15:49 ` [pve-devel] [PATCH cluster 1/1] datacenter config: add options for sorting the gui tree Dominik Csapak
@ 2023-02-01 15:49 ` Dominik Csapak
  2023-02-02 10:22   ` Thomas Lamprecht
  2023-02-01 15:49 ` [pve-devel] [PATCH manager 2/3] ui: add TreeSortingEdit window Dominik Csapak
  2023-02-01 15:49 ` [pve-devel] [PATCH manager 3/3] fix #1408: ui: ResourceTree: sort the tree according to tree-sorting options Dominik Csapak
  3 siblings, 1 reply; 8+ messages in thread
From: Dominik Csapak @ 2023-02-01 15:49 UTC (permalink / raw)
  To: pve-devel

we'll need it elsewhere too, and it was rather hidden in the
updateTagSettings call.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/manager6/Utils.js         | 3 +++
 www/manager6/dc/OptionView.js | 1 +
 2 files changed, 4 insertions(+)

diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
index fcc668c3a..ee9e4bd5d 100644
--- a/www/manager6/Utils.js
+++ b/www/manager6/Utils.js
@@ -1871,6 +1871,7 @@ Ext.define('PVE.Utils', {
 
 		PVE.Utils.updateTagList(PVE.UIOptions['allowed-tags']);
 		PVE.Utils.updateTagSettings(PVE.UIOptions?.['tag-style']);
+		PVE.Utils.fireUIUpdate();
 	    },
 	});
     },
@@ -1920,7 +1921,9 @@ Ext.define('PVE.Utils', {
 	}
 
 	Ext.ComponentQuery.query('pveResourceTree')[0].setUserCls(`proxmox-tags-${shape}`);
+    },
 
+    fireUIUpdate: function() {
 	if (!PVE.data.ResourceStore.isLoading() && PVE.data.ResourceStore.isLoaded()) {
 	    PVE.data.ResourceStore.fireEvent('load');
 	}
diff --git a/www/manager6/dc/OptionView.js b/www/manager6/dc/OptionView.js
index 9c803beef..2e4f76263 100644
--- a/www/manager6/dc/OptionView.js
+++ b/www/manager6/dc/OptionView.js
@@ -566,6 +566,7 @@ Ext.define('PVE.dc.OptionView', {
 
 	    PVE.UIOptions['tag-style'] = store.getById('tag-style')?.data?.value;
 	    PVE.Utils.updateTagSettings(PVE.UIOptions['tag-style']);
+	    PVE.Utils.fireUIUpdate();
 	});
 
 	me.on('activate', me.rstore.startUpdate);
-- 
2.30.2





^ permalink raw reply	[flat|nested] 8+ messages in thread

* [pve-devel] [PATCH manager 2/3] ui: add TreeSortingEdit window
  2023-02-01 15:49 [pve-devel] [PATCH cluster/manager] fix #1408: ui: make tree sorting configurable Dominik Csapak
  2023-02-01 15:49 ` [pve-devel] [PATCH cluster 1/1] datacenter config: add options for sorting the gui tree Dominik Csapak
  2023-02-01 15:49 ` [pve-devel] [PATCH manager 1/3] ui: Utils: refactor refreshing the the resource store/tree Dominik Csapak
@ 2023-02-01 15:49 ` Dominik Csapak
  2023-02-02 10:56   ` Thomas Lamprecht
  2023-02-01 15:49 ` [pve-devel] [PATCH manager 3/3] fix #1408: ui: ResourceTree: sort the tree according to tree-sorting options Dominik Csapak
  3 siblings, 1 reply; 8+ messages in thread
From: Dominik Csapak @ 2023-02-01 15:49 UTC (permalink / raw)
  To: pve-devel

in cluster options (for datacenter.cfg) and besides the view selector
(for the browser local storage)

the edit window is the same for bot but either makes an api call or
saves the resulting values into the browser local storage.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
not sure about just showing 'Default' for the options in both cases.
I could make the text different for the datacenter options (there it's
fixed) and make the text dynamic for the browser local storage, but it
does not seem worth it really...

could also always show the inherent defaults, but that would be wrong
for the local storage when something is set in the datacenter config...

 www/manager6/Makefile                  |   1 +
 www/manager6/Utils.js                  |   2 +-
 www/manager6/Workspace.js              |  27 +++++-
 www/manager6/dc/OptionView.js          |  10 +++
 www/manager6/window/TreeSortingEdit.js | 113 +++++++++++++++++++++++++
 5 files changed, 150 insertions(+), 3 deletions(-)
 create mode 100644 www/manager6/window/TreeSortingEdit.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index 05afeda40..157d4da52 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -119,6 +119,7 @@ JSSRC= 							\
 	window/ScheduleSimulator.js			\
 	window/Wizard.js				\
 	window/GuestDiskReassign.js				\
+	window/TreeSortingEdit.js			\
 	ha/Fencing.js					\
 	ha/GroupEdit.js					\
 	ha/GroupSelector.js				\
diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
index ee9e4bd5d..0c57e0844 100644
--- a/www/manager6/Utils.js
+++ b/www/manager6/Utils.js
@@ -1865,7 +1865,7 @@ Ext.define('PVE.Utils', {
 		PVE.UIOptions = {
 		    'allowed-tags': [],
 		};
-		for (const option of ['allowed-tags', 'console', 'tag-style']) {
+		for (const option of ['allowed-tags', 'console', 'tag-style', 'tree-sorting']) {
 		    PVE.UIOptions[option] = response?.result?.data?.[option];
 		}
 
diff --git a/www/manager6/Workspace.js b/www/manager6/Workspace.js
index d0f7ff760..1963dc3f2 100644
--- a/www/manager6/Workspace.js
+++ b/www/manager6/Workspace.js
@@ -223,7 +223,9 @@ Ext.define('PVE.StdWorkspace', {
 	let appState = Ext.create('PVE.StateProvider');
 	Ext.state.Manager.setProvider(appState);
 
-	let selview = Ext.create('PVE.form.ViewSelector');
+	let selview = Ext.create('PVE.form.ViewSelector', {
+	    flex: 1,
+	});
 
 	let rtree = Ext.createWidget('pveResourceTree', {
 	    viewFilter: selview.getViewFilter(),
@@ -449,7 +451,28 @@ Ext.define('PVE.StdWorkspace', {
 		    margin: '0 0 0 5',
 		    split: true,
 		    width: 300,
-		    items: [selview, rtree],
+		    items: [
+			{
+			    xtype: 'container',
+			    layout: 'hbox',
+			    padding: '0 0 5 0',
+			    items: [
+				selview,
+				{
+				    xtype: 'button',
+				    iconCls: 'fa fa-fw fa-gear',
+				    handler: () => {
+					Ext.create('PVE.window.TreeSortingEdit', {
+					    autoShow: true,
+					    browserSettings: true,
+					    apiCallDone: () => PVE.Utils.fireUIUpdate(),
+					});
+				    },
+				},
+			    ],
+			},
+			rtree,
+		    ],
 		    listeners: {
 			resize: function(panel, width, height) {
 			    var viewWidth = me.getSize().width;
diff --git a/www/manager6/dc/OptionView.js b/www/manager6/dc/OptionView.js
index 2e4f76263..0f5eaa680 100644
--- a/www/manager6/dc/OptionView.js
+++ b/www/manager6/dc/OptionView.js
@@ -529,6 +529,15 @@ Ext.define('PVE.dc.OptionView', {
 	    },
 	};
 
+	me.rows['tree-sorting'] = {
+	    required: true,
+	    renderer: (value) => value ? PVE.Parser.printPropertyString(value) : gettext('No sorting overrides'),
+	    header: gettext('Tree Sorting'),
+	    editor: {
+		xtype: 'pveTreeSortingEdit',
+	    },
+	};
+
 	me.selModel = Ext.create('Ext.selection.RowModel', {});
 
 	Ext.apply(me, {
@@ -565,6 +574,7 @@ Ext.define('PVE.dc.OptionView', {
 	    }
 
 	    PVE.UIOptions['tag-style'] = store.getById('tag-style')?.data?.value;
+	    PVE.UIOptions['tree-sorting'] = store.getById('tree-sorting')?.data?.value;
 	    PVE.Utils.updateTagSettings(PVE.UIOptions['tag-style']);
 	    PVE.Utils.fireUIUpdate();
 	});
diff --git a/www/manager6/window/TreeSortingEdit.js b/www/manager6/window/TreeSortingEdit.js
new file mode 100644
index 000000000..eff7f3f21
--- /dev/null
+++ b/www/manager6/window/TreeSortingEdit.js
@@ -0,0 +1,113 @@
+Ext.define('PVE.window.TreeSortingEdit', {
+    extend: 'Proxmox.window.Edit',
+    alias: 'widget.pveTreeSortingEdit',
+    mixins: ['Proxmox.Mixin.CBind'],
+
+    title: gettext('Tree Sorting'),
+
+    isCreate: false,
+
+    url: '/cluster/options',
+
+    browserSettings: false,
+
+    items: [
+	{
+	    xtype: 'inputpanel',
+	    cbind: {},
+	    onSetValues: (values) => values?.['tree-sorting'] ?? {},
+	    onGetValues: function(values) {
+		if (this.up('window').browserSettings) {
+		    let sp = Ext.state.Manager.getProvider();
+		    let state = values ? values : null;
+		    sp.set('pve-tree-sorting', state);
+		    return {};
+		}
+		PVE.Utils.delete_if_default(values, 'group-templates', "1");
+		PVE.Utils.delete_if_default(values, 'group-guest-types', "1");
+		// no delete in property strings
+		delete values.delete;
+
+		let value = PVE.Parser.printPropertyString(values);
+
+		if (value === '') {
+		    return { 'delete': 'tree-sorting' };
+		}
+		return { 'tree-sorting': value };
+	    },
+	    items: [
+		{
+		    name: 'sort-field',
+		    xtype: 'proxmoxKVComboBox',
+		    fieldLabel: gettext('Sort Field'),
+		    labelWidth: 120,
+		    comboItems: [
+			['__default__', Proxmox.Utils.defaultText],
+			['vmid', gettext('VMID')],
+			['name', gettext('Name')],
+		    ],
+		    defaultValue: '__default__',
+		    value: '__default__',
+		    deleteEmpty: false,
+		},
+		{
+		    name: 'group-templates',
+		    xtype: 'booleanfield',
+		    fieldLabel: gettext('Group Templates'),
+		    defaultValue: '__default__',
+		    value: '__default__',
+		    deleteEmpty: false,
+		    labelWidth: 120,
+		},
+		{
+		    name: 'group-guest-types',
+		    xtype: 'booleanfield',
+		    fieldLabel: gettext('Group Types'),
+		    defaultValue: '__default__',
+		    value: '__default__',
+		    deleteEmpty: false,
+		    labelWidth: 120,
+		},
+		{
+		    xtype: 'displayfield',
+		    userCls: 'pmx-hint',
+		    value: gettext('Settings are saved in the browser local storage'),
+		    hidden: true,
+		    cbind: {
+			hidden: '{!browserSettings}',
+		    },
+		}
+	    ],
+	},
+    ],
+
+    submit: function() {
+	let me = this;
+
+	if (me.browserSettings) {
+	    me.down('inputpanel').getValues();
+	    me.apiCallDone();
+	    me.close();
+	} else {
+	    me.callParent();
+	}
+    },
+
+    initComponent: function() {
+	let me = this;
+
+	me.callParent();
+
+	me.load({
+	    success: function(response) {
+		let values = response?.result?.data?.['tree-sorting'] ?? {};
+		if (me.browserSettings) {
+		    let sp = Ext.state.Manager.getProvider();
+		    values = sp.get('pve-tree-sorting');
+		}
+		me.down('inputpanel').setValues({ 'tree-sorting': values });
+	    },
+	});
+    },
+
+});
-- 
2.30.2





^ permalink raw reply	[flat|nested] 8+ messages in thread

* [pve-devel] [PATCH manager 3/3] fix #1408: ui: ResourceTree: sort the tree according to tree-sorting options
  2023-02-01 15:49 [pve-devel] [PATCH cluster/manager] fix #1408: ui: make tree sorting configurable Dominik Csapak
                   ` (2 preceding siblings ...)
  2023-02-01 15:49 ` [pve-devel] [PATCH manager 2/3] ui: add TreeSortingEdit window Dominik Csapak
@ 2023-02-01 15:49 ` Dominik Csapak
  3 siblings, 0 replies; 8+ messages in thread
From: Dominik Csapak @ 2023-02-01 15:49 UTC (permalink / raw)
  To: pve-devel

Considers the newly added options from both browser local storage(preferred)
or from the datacenter config we have to save the last sorting mechanism
there, so we can detect if it changes and trigger the movement/text changes
(otherwise the tree nodes won't be updated/moved)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/manager6/Utils.js             | 12 +++++++
 www/manager6/tree/ResourceTree.js | 54 ++++++++++++++++++++++++-------
 2 files changed, 54 insertions(+), 12 deletions(-)

diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
index 0c57e0844..14f03e6d1 100644
--- a/www/manager6/Utils.js
+++ b/www/manager6/Utils.js
@@ -1930,6 +1930,18 @@ Ext.define('PVE.Utils', {
 	Ext.GlobalEvents.fireEvent('loadedUiOptions');
     },
 
+    getTreeSortingValue: function(key) {
+	let sp = Ext.state.Manager.getProvider();
+	let browserValues = sp.get('pve-tree-sorting');
+	let defaults = {
+	    'sort-field': 'vmid',
+	    'group-templates': true,
+	    'group-guest-types': true,
+	};
+
+	return browserValues?.[key] ?? PVE.UIOptions?.['tree-sorting']?.[key] ?? defaults[key];
+    },
+
     tagTreeStyles: {
 	'__default__': `${Proxmox.Utils.defaultText} (${gettext('Circle')})`,
 	'full': gettext('Full'),
diff --git a/www/manager6/tree/ResourceTree.js b/www/manager6/tree/ResourceTree.js
index 5c92d4128..5456a7eda 100644
--- a/www/manager6/tree/ResourceTree.js
+++ b/www/manager6/tree/ResourceTree.js
@@ -44,24 +44,34 @@ Ext.define('PVE.tree.ResourceTree', {
 
     // private
     nodeSortFn: function(node1, node2) {
+	let me = this;
 	let n1 = node1.data, n2 = node2.data;
 
 	if (!n1.groupbyid === !n2.groupbyid) {
-	    // first sort (group) by type
-	    if (n1.type > n2.type) {
-		return 1;
-	    } else if (n1.type < n2.type) {
-		return -1;
+	    let n1IsGuest = n1.type === 'qemu' || n1.type === 'lxc';
+	    let n2IsGuest = n2.type === 'qemu' || n2.type === 'lxc';
+	    if (me['group-guest-types'] || !n1IsGuest || !n2IsGuest) {
+		// first sort (group) by type
+		if (n1.type > n2.type) {
+		    return 1;
+		} else if (n1.type < n2.type) {
+		    return -1;
+		}
 	    }
+
 	    // then sort (group) by ID
-	    if (n1.type === 'qemu' || n2.type === 'lxc') {
-		if (!n1.template !== !n2.template) {
+	    if (n1IsGuest) {
+		if (me['group-templates'] && (!n1.template !== !n2.template)) {
 		    return n1.template ? 1 : -1; // sort templates after regular VMs
 		}
-		if (n1.vmid > n2.vmid) { // prefer VMID as metric for guests
-		    return 1;
-		} else if (n1.vmid < n2.vmid) {
-		    return -1;
+		if (me['sort-field'] === 'vmid') {
+		    if (n1.vmid > n2.vmid) { // prefer VMID as metric for guests
+			return 1;
+		    } else if (n1.vmid < n2.vmid) {
+			return -1;
+		    }
+		} else {
+		    return n1.name.localeCompare(n2.name);
 		}
 	    }
 	    // same types but not a guest
@@ -115,6 +125,11 @@ Ext.define('PVE.tree.ResourceTree', {
 		status += '</div> ';
 	    }
 	}
+	if (Ext.isNumeric(info.vmid) && info.vmid > 0) {
+	    if (PVE.Utils.getTreeSortingValue('sort-field') !== 'vmid') {
+		info.text = `${info.name} (${String(info.vmid)})`;
+	    }
+	}
 
 	info.text += PVE.Utils.renderTags(info.tags, PVE.Utils.tagOverrides);
 
@@ -203,8 +218,22 @@ Ext.define('PVE.tree.ResourceTree', {
 	return me.addChildSorted(node, info);
     },
 
+    saveSortingOptions: function() {
+	let me = this;
+	let changed = false;
+	for (const key of ['sort-field', 'group-templates', 'group-guest-types']) {
+	    let newValue = PVE.Utils.getTreeSortingValue(key);
+	    if (me[key] !== newValue) {
+		me[key] = newValue;
+		changed = true;
+	    }
+	}
+	return changed;
+    },
+
     initComponent: function() {
 	let me = this;
+	me.saveSortingOptions();
 
 	let rstore = PVE.data.ResourceStore;
 	let sp = Ext.state.Manager.getProvider();
@@ -242,6 +271,7 @@ Ext.define('PVE.tree.ResourceTree', {
 	    let sm = me.getSelectionModel();
 	    let lastsel = sm.getSelection()[0];
 	    let parents = [];
+	    let sorting_changed = me.saveSortingOptions();
 	    for (let node = lastsel; node; node = node.parentNode) {
 		parents.push(node);
 	    }
@@ -258,7 +288,7 @@ Ext.define('PVE.tree.ResourceTree', {
 		// getById() use find(), which is slow (ExtJS4 DP5)
 		let item = rstore.data.get(olditem.data.id);
 
-		let changed = false, moved = false;
+		let changed = sorting_changed, moved = sorting_changed;
 		if (item) {
 		    // test if any grouping attributes changed, catches migrated tree-nodes in server view too
 		    for (const attr of moveCheckAttrs) {
-- 
2.30.2





^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pve-devel] [PATCH manager 1/3] ui: Utils: refactor refreshing the the resource store/tree
  2023-02-01 15:49 ` [pve-devel] [PATCH manager 1/3] ui: Utils: refactor refreshing the the resource store/tree Dominik Csapak
@ 2023-02-02 10:22   ` Thomas Lamprecht
  0 siblings, 0 replies; 8+ messages in thread
From: Thomas Lamprecht @ 2023-02-02 10:22 UTC (permalink / raw)
  To: Proxmox VE development discussion, Dominik Csapak

Am 01/02/2023 um 16:49 schrieb Dominik Csapak:
> we'll need it elsewhere too, and it was rather hidden in the
> updateTagSettings call.
> 
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
>  www/manager6/Utils.js         | 3 +++
>  www/manager6/dc/OptionView.js | 1 +
>  2 files changed, 4 insertions(+)
> 
> diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
> index fcc668c3a..ee9e4bd5d 100644
> --- a/www/manager6/Utils.js
> +++ b/www/manager6/Utils.js
> @@ -1871,6 +1871,7 @@ Ext.define('PVE.Utils', {
>  
>  		PVE.Utils.updateTagList(PVE.UIOptions['allowed-tags']);
>  		PVE.Utils.updateTagSettings(PVE.UIOptions?.['tag-style']);
> +		PVE.Utils.fireUIUpdate();
>  	    },
>  	});
>      },
> @@ -1920,7 +1921,9 @@ Ext.define('PVE.Utils', {
>  	}
>  
>  	Ext.ComponentQuery.query('pveResourceTree')[0].setUserCls(`proxmox-tags-${shape}`);
> +    },
>  
> +    fireUIUpdate: function() {

naming is off for this as it uses the action desired (but that's not future proof)
instead of using the actual event being fired, e.g., do s/fireUIUpdate/fireUIConfigChange/

btw, utils _really_ is a convoluted mess that needs some basic cleanup rather sooner
than later...

>  	if (!PVE.data.ResourceStore.isLoading() && PVE.data.ResourceStore.isLoaded()) {
>  	    PVE.data.ResourceStore.fireEvent('load');
>  	}
> diff --git a/www/manager6/dc/OptionView.js b/www/manager6/dc/OptionView.js
> index 9c803beef..2e4f76263 100644
> --- a/www/manager6/dc/OptionView.js
> +++ b/www/manager6/dc/OptionView.js
> @@ -566,6 +566,7 @@ Ext.define('PVE.dc.OptionView', {
>  
>  	    PVE.UIOptions['tag-style'] = store.getById('tag-style')?.data?.value;
>  	    PVE.Utils.updateTagSettings(PVE.UIOptions['tag-style']);
> +	    PVE.Utils.fireUIUpdate();
>  	});
>  
>  	me.on('activate', me.rstore.startUpdate);





^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pve-devel] [PATCH manager 2/3] ui: add TreeSortingEdit window
  2023-02-01 15:49 ` [pve-devel] [PATCH manager 2/3] ui: add TreeSortingEdit window Dominik Csapak
@ 2023-02-02 10:56   ` Thomas Lamprecht
  2023-02-02 12:16     ` Dominik Csapak
  0 siblings, 1 reply; 8+ messages in thread
From: Thomas Lamprecht @ 2023-02-02 10:56 UTC (permalink / raw)
  To: Proxmox VE development discussion, Dominik Csapak

looks like going in the right direction and feasible, some comments inline

high level: subject is using module name 1:1, as mentioned a few times please
avoid that, for ~ 99.9% cases it's not useful, for sure not for d/changelog but
not really for other devs in `git log` (sorting trees can mean widely different
things), maybe:

ui: add edit window for changing resource tree sort behavior

And for the module/file name I maybe wouldn't imply that this is for sorting
only, I could immagine that we expose other knobs for the tree behavior or
visuals in the future (e.g., add more font-weight to names, or 

Am 01/02/2023 um 16:49 schrieb Dominik Csapak:
> in cluster options (for datacenter.cfg) and besides the view selector
> (for the browser local storage)

I'd rather do it browser-local storage only, that way we can play a bit
around possbly adding or changing knob (names) and once stable for a time
and users are happy we can commit to adding this to datacenter config w

> 
> the edit window is the same for bot but either makes an api call or
> saves the resulting values into the browser local storage.
> 
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
> not sure about just showing 'Default' for the options in both cases.
> I could make the text different for the datacenter options (there it's
> fixed) and make the text dynamic for the browser local storage, but it
> does not seem worth it really...
> 
> could also always show the inherent defaults, but that would be wrong
> for the local storage when something is set in the datacenter config...
> 
>  www/manager6/Makefile                  |   1 +
>  www/manager6/Utils.js                  |   2 +-
>  www/manager6/Workspace.js              |  27 +++++-
>  www/manager6/dc/OptionView.js          |  10 +++
>  www/manager6/window/TreeSortingEdit.js | 113 +++++++++++++++++++++++++
>  5 files changed, 150 insertions(+), 3 deletions(-)
>  create mode 100644 www/manager6/window/TreeSortingEdit.js
> 
> diff --git a/www/manager6/Makefile b/www/manager6/Makefile
> index 05afeda40..157d4da52 100644
> --- a/www/manager6/Makefile
> +++ b/www/manager6/Makefile
> @@ -119,6 +119,7 @@ JSSRC= 							\
>  	window/ScheduleSimulator.js			\
>  	window/Wizard.js				\
>  	window/GuestDiskReassign.js				\
> +	window/TreeSortingEdit.js			\
>  	ha/Fencing.js					\
>  	ha/GroupEdit.js					\
>  	ha/GroupSelector.js				\
> diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
> index ee9e4bd5d..0c57e0844 100644
> --- a/www/manager6/Utils.js
> +++ b/www/manager6/Utils.js
> @@ -1865,7 +1865,7 @@ Ext.define('PVE.Utils', {
>  		PVE.UIOptions = {
>  		    'allowed-tags': [],
>  		};
> -		for (const option of ['allowed-tags', 'console', 'tag-style']) {
> +		for (const option of ['allowed-tags', 'console', 'tag-style', 'tree-sorting']) {
>  		    PVE.UIOptions[option] = response?.result?.data?.[option];

a thought: why doesn't "PVE.UIOptions" real, i.e., a full fledged module that
hosts the respective functions and state that now is (mostly?) in Utils?

>  		}
>  
> diff --git a/www/manager6/Workspace.js b/www/manager6/Workspace.js
> index d0f7ff760..1963dc3f2 100644
> --- a/www/manager6/Workspace.js
> +++ b/www/manager6/Workspace.js
> @@ -223,7 +223,9 @@ Ext.define('PVE.StdWorkspace', {
>  	let appState = Ext.create('PVE.StateProvider');
>  	Ext.state.Manager.setProvider(appState);
>  
> -	let selview = Ext.create('PVE.form.ViewSelector');
> +	let selview = Ext.create('PVE.form.ViewSelector', {
> +	    flex: 1,
> +	});
>  
>  	let rtree = Ext.createWidget('pveResourceTree', {
>  	    viewFilter: selview.getViewFilter(),
> @@ -449,7 +451,28 @@ Ext.define('PVE.StdWorkspace', {
>  		    margin: '0 0 0 5',
>  		    split: true,
>  		    width: 300,
> -		    items: [selview, rtree],
> +		    items: [
> +			{
> +			    xtype: 'container',
> +			    layout: 'hbox',
> +			    padding: '0 0 5 0',
> +			    items: [
> +				selview,
> +				{
> +				    xtype: 'button',
> +				    iconCls: 'fa fa-fw fa-gear',
> +				    handler: () => {
> +					Ext.create('PVE.window.TreeSortingEdit', {
> +					    autoShow: true,
> +					    browserSettings: true,



> +					    apiCallDone: () => PVE.Utils.fireUIUpdate(),
> +					});
> +				    },
> +				},
> +			    ],
> +			},
> +			rtree,
> +		    ],
>  		    listeners: {
>  			resize: function(panel, width, height) {
>  			    var viewWidth = me.getSize().width;
> diff --git a/www/manager6/dc/OptionView.js b/www/manager6/dc/OptionView.js
> index 2e4f76263..0f5eaa680 100644
> --- a/www/manager6/dc/OptionView.js
> +++ b/www/manager6/dc/OptionView.js
> @@ -529,6 +529,15 @@ Ext.define('PVE.dc.OptionView', {
>  	    },
>  	};
>  
> +	me.rows['tree-sorting'] = {
> +	    required: true,
> +	    renderer: (value) => value ? PVE.Parser.printPropertyString(value) : gettext('No sorting overrides'),
> +	    header: gettext('Tree Sorting'),
> +	    editor: {
> +		xtype: 'pveTreeSortingEdit',
> +	    },
> +	};
> +
>  	me.selModel = Ext.create('Ext.selection.RowModel', {});
>  
>  	Ext.apply(me, {
> @@ -565,6 +574,7 @@ Ext.define('PVE.dc.OptionView', {
>  	    }
>  
>  	    PVE.UIOptions['tag-style'] = store.getById('tag-style')?.data?.value;
> +	    PVE.UIOptions['tree-sorting'] = store.getById('tree-sorting')?.data?.value;
>  	    PVE.Utils.updateTagSettings(PVE.UIOptions['tag-style']);
>  	    PVE.Utils.fireUIUpdate();
>  	});
> diff --git a/www/manager6/window/TreeSortingEdit.js b/www/manager6/window/TreeSortingEdit.js
> new file mode 100644
> index 000000000..eff7f3f21
> --- /dev/null
> +++ b/www/manager6/window/TreeSortingEdit.js
> @@ -0,0 +1,113 @@
> +Ext.define('PVE.window.TreeSortingEdit', {
> +    extend: 'Proxmox.window.Edit',
> +    alias: 'widget.pveTreeSortingEdit',
> +    mixins: ['Proxmox.Mixin.CBind'],
> +
> +    title: gettext('Tree Sorting'),
> +
> +    isCreate: false,
> +
> +    url: '/cluster/options',
> +
> +    browserSettings: false,

is above a preparation of exposing this additonally in the Datacenter Options
panel for configuring the backend config values, not the browser local ones?

I'd probably favor doing that via two widgets, one deriving from the other - but
if we only allow brwoser local storage as starter we'd need the differentation
at all for now.

> +
> +    items: [
> +	{
> +	    xtype: 'inputpanel',
> +	    cbind: {},
> +	    onSetValues: (values) => values?.['tree-sorting'] ?? {},
> +	    onGetValues: function(values) {
> +		if (this.up('window').browserSettings) {
> +		    let sp = Ext.state.Manager.getProvider();

nit: would like to avoid very short abbreviations which could get confusing if
this ever expands or gets used as template and copied.

s/sp/stateProvider/ or maybe even s/sp/localStorage/

> +		    let state = values ? values : null;
> +		    sp.set('pve-tree-sorting', state);

could drop intermediate variable

sp.set('pve-tree-sorting', values || null);

> +		    return {};
> +		}
> +		PVE.Utils.delete_if_default(values, 'group-templates', "1");
> +		PVE.Utils.delete_if_default(values, 'group-guest-types', "1");
> +		// no delete in property strings
> +		delete values.delete;
> +
> +		let value = PVE.Parser.printPropertyString(values);
> +
> +		if (value === '') {
> +		    return { 'delete': 'tree-sorting' };
> +		}
> +		return { 'tree-sorting': value };
> +	    },
> +	    items: [
> +		{
> +		    name: 'sort-field',
> +		    xtype: 'proxmoxKVComboBox',

please put xtype first

> +		    fieldLabel: gettext('Sort Field'),
> +		    labelWidth: 120,

might want to but that in a defaults: {} config at inputpanel level

> +		    comboItems: [
> +			['__default__', Proxmox.Utils.defaultText],
> +			['vmid', gettext('VMID')],

do we really translate VMID, as in, is there a (updated in the last 12 months)
translation that sets this to something different and sensible?

> +			['name', gettext('Name')],
> +		    ],
> +		    defaultValue: '__default__',
> +		    value: '__default__',
> +		    deleteEmpty: false,
> +		},
> +		{
> +		    name: 'group-templates',
> +		    xtype: 'booleanfield',

please put xtype first

besides that and unrelated to your series, this widget is a bit odd and as it
has no pve/proxmox prefix (I initially thought it's a ExtJS one that I just
never stumbled uppon) and should get renamed to something more telling like
pmxBooleanComboBox, probably should move to widget toolkit too

> +		    fieldLabel: gettext('Group Templates'),
> +		    defaultValue: '__default__',
> +		    value: '__default__',
> +		    deleteEmpty: false,
> +		    labelWidth: 120,
> +		},
> +		{
> +		    name: 'group-guest-types',
> +		    xtype: 'booleanfield',

please put xtype first

> +		    fieldLabel: gettext('Group Types'),
> +		    defaultValue: '__default__',
> +		    value: '__default__',
> +		    deleteEmpty: false,
> +		    labelWidth: 120,
> +		},
> +		{
> +		    xtype: 'displayfield',
> +		    userCls: 'pmx-hint',
> +		    value: gettext('Settings are saved in the browser local storage'),
> +		    hidden: true,
> +		    cbind: {
> +			hidden: '{!browserSettings}',
> +		    },
> +		}
> +	    ],
> +	},
> +    ],
> +
> +    submit: function() {
> +	let me = this;
> +
> +	if (me.browserSettings) {
> +	    me.down('inputpanel').getValues();
> +	    me.apiCallDone();
> +	    me.close();
> +	} else {
> +	    me.callParent();
> +	}
> +    },
> +
> +    initComponent: function() {
> +	let me = this;
> +
> +	me.callParent();
> +
> +	me.load({
> +	    success: function(response) {
> +		let values = response?.result?.data?.['tree-sorting'] ?? {};
> +		if (me.browserSettings) {
> +		    let sp = Ext.state.Manager.getProvider();
> +		    values = sp.get('pve-tree-sorting');
> +		}
> +		me.down('inputpanel').setValues({ 'tree-sorting': values });
> +	    },
> +	});
> +    },
> +
> +});





^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pve-devel] [PATCH manager 2/3] ui: add TreeSortingEdit window
  2023-02-02 10:56   ` Thomas Lamprecht
@ 2023-02-02 12:16     ` Dominik Csapak
  0 siblings, 0 replies; 8+ messages in thread
From: Dominik Csapak @ 2023-02-02 12:16 UTC (permalink / raw)
  To: Thomas Lamprecht, Proxmox VE development discussion

On 2/2/23 11:56, Thomas Lamprecht wrote:
> looks like going in the right direction and feasible, some comments inline
> 
> high level: subject is using module name 1:1, as mentioned a few times please
> avoid that, for ~ 99.9% cases it's not useful, for sure not for d/changelog but
> not really for other devs in `git log` (sorting trees can mean widely different
> things), maybe:
> 
> ui: add edit window for changing resource tree sort behavior

yes, sorry, for adding new widgets i still default in my head to just
adding the class name...

> 
> And for the module/file name I maybe wouldn't imply that this is for sorting
> only, I could immagine that we expose other knobs for the tree behavior or
> visuals in the future (e.g., add more font-weight to names, or

yeah sure, does 'TreeSettingsEdit' (or 'TreeOptionsEdit') make sense?

> 
> Am 01/02/2023 um 16:49 schrieb Dominik Csapak:
>> in cluster options (for datacenter.cfg) and besides the view selector
>> (for the browser local storage)
> 
> I'd rather do it browser-local storage only, that way we can play a bit
> around possbly adding or changing knob (names) and once stable for a time
> and users are happy we can commit to adding this to datacenter config w
> 

yeah sure

>>
>> the edit window is the same for bot but either makes an api call or
>> saves the resulting values into the browser local storage.
>>
>> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
>> ---
>> not sure about just showing 'Default' for the options in both cases.
>> I could make the text different for the datacenter options (there it's
>> fixed) and make the text dynamic for the browser local storage, but it
>> does not seem worth it really...
>>
>> could also always show the inherent defaults, but that would be wrong
>> for the local storage when something is set in the datacenter config...

any commend on this?


>>
>>   www/manager6/Makefile                  |   1 +
>>   www/manager6/Utils.js                  |   2 +-
>>   www/manager6/Workspace.js              |  27 +++++-
>>   www/manager6/dc/OptionView.js          |  10 +++
>>   www/manager6/window/TreeSortingEdit.js | 113 +++++++++++++++++++++++++
>>   5 files changed, 150 insertions(+), 3 deletions(-)
>>   create mode 100644 www/manager6/window/TreeSortingEdit.js
>>
>> diff --git a/www/manager6/Makefile b/www/manager6/Makefile
>> index 05afeda40..157d4da52 100644
>> --- a/www/manager6/Makefile
>> +++ b/www/manager6/Makefile
>> @@ -119,6 +119,7 @@ JSSRC= 							\
>>   	window/ScheduleSimulator.js			\
>>   	window/Wizard.js				\
>>   	window/GuestDiskReassign.js				\
>> +	window/TreeSortingEdit.js			\
>>   	ha/Fencing.js					\
>>   	ha/GroupEdit.js					\
>>   	ha/GroupSelector.js				\
>> diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
>> index ee9e4bd5d..0c57e0844 100644
>> --- a/www/manager6/Utils.js
>> +++ b/www/manager6/Utils.js
>> @@ -1865,7 +1865,7 @@ Ext.define('PVE.Utils', {
>>   		PVE.UIOptions = {
>>   		    'allowed-tags': [],
>>   		};
>> -		for (const option of ['allowed-tags', 'console', 'tag-style']) {
>> +		for (const option of ['allowed-tags', 'console', 'tag-style', 'tree-sorting']) {
>>   		    PVE.UIOptions[option] = response?.result?.data?.[option];
> 
> a thought: why doesn't "PVE.UIOptions" real, i.e., a full fledged module that
> hosts the respective functions and state that now is (mostly?) in Utils?

there wasn't that much in there, but i agree it's own module does make more sense,
i'll do a refactor in a v2

> 
>>   		}
>>   
>> diff --git a/www/manager6/Workspace.js b/www/manager6/Workspace.js
>> index d0f7ff760..1963dc3f2 100644
>> --- a/www/manager6/Workspace.js
>> +++ b/www/manager6/Workspace.js
>> @@ -223,7 +223,9 @@ Ext.define('PVE.StdWorkspace', {
>>   	let appState = Ext.create('PVE.StateProvider');
>>   	Ext.state.Manager.setProvider(appState);
>>   
>> -	let selview = Ext.create('PVE.form.ViewSelector');
>> +	let selview = Ext.create('PVE.form.ViewSelector', {
>> +	    flex: 1,
>> +	});
>>   
>>   	let rtree = Ext.createWidget('pveResourceTree', {
>>   	    viewFilter: selview.getViewFilter(),
>> @@ -449,7 +451,28 @@ Ext.define('PVE.StdWorkspace', {
>>   		    margin: '0 0 0 5',
>>   		    split: true,
>>   		    width: 300,
>> -		    items: [selview, rtree],
>> +		    items: [
>> +			{
>> +			    xtype: 'container',
>> +			    layout: 'hbox',
>> +			    padding: '0 0 5 0',
>> +			    items: [
>> +				selview,
>> +				{
>> +				    xtype: 'button',
>> +				    iconCls: 'fa fa-fw fa-gear',
>> +				    handler: () => {
>> +					Ext.create('PVE.window.TreeSortingEdit', {
>> +					    autoShow: true,
>> +					    browserSettings: true,
> 
> 
> 
>> +					    apiCallDone: () => PVE.Utils.fireUIUpdate(),
>> +					});
>> +				    },
>> +				},
>> +			    ],
>> +			},
>> +			rtree,
>> +		    ],
>>   		    listeners: {
>>   			resize: function(panel, width, height) {
>>   			    var viewWidth = me.getSize().width;
>> diff --git a/www/manager6/dc/OptionView.js b/www/manager6/dc/OptionView.js
>> index 2e4f76263..0f5eaa680 100644
>> --- a/www/manager6/dc/OptionView.js
>> +++ b/www/manager6/dc/OptionView.js
>> @@ -529,6 +529,15 @@ Ext.define('PVE.dc.OptionView', {
>>   	    },
>>   	};
>>   
>> +	me.rows['tree-sorting'] = {
>> +	    required: true,
>> +	    renderer: (value) => value ? PVE.Parser.printPropertyString(value) : gettext('No sorting overrides'),
>> +	    header: gettext('Tree Sorting'),
>> +	    editor: {
>> +		xtype: 'pveTreeSortingEdit',
>> +	    },
>> +	};
>> +
>>   	me.selModel = Ext.create('Ext.selection.RowModel', {});
>>   
>>   	Ext.apply(me, {
>> @@ -565,6 +574,7 @@ Ext.define('PVE.dc.OptionView', {
>>   	    }
>>   
>>   	    PVE.UIOptions['tag-style'] = store.getById('tag-style')?.data?.value;
>> +	    PVE.UIOptions['tree-sorting'] = store.getById('tree-sorting')?.data?.value;
>>   	    PVE.Utils.updateTagSettings(PVE.UIOptions['tag-style']);
>>   	    PVE.Utils.fireUIUpdate();
>>   	});
>> diff --git a/www/manager6/window/TreeSortingEdit.js b/www/manager6/window/TreeSortingEdit.js
>> new file mode 100644
>> index 000000000..eff7f3f21
>> --- /dev/null
>> +++ b/www/manager6/window/TreeSortingEdit.js
>> @@ -0,0 +1,113 @@
>> +Ext.define('PVE.window.TreeSortingEdit', {
>> +    extend: 'Proxmox.window.Edit',
>> +    alias: 'widget.pveTreeSortingEdit',
>> +    mixins: ['Proxmox.Mixin.CBind'],
>> +
>> +    title: gettext('Tree Sorting'),
>> +
>> +    isCreate: false,
>> +
>> +    url: '/cluster/options',
>> +
>> +    browserSettings: false,
> 
> is above a preparation of exposing this additonally in the Datacenter Options
> panel for configuring the backend config values, not the browser local ones?
> 
> I'd probably favor doing that via two widgets, one deriving from the other - but
> if we only allow brwoser local storage as starter we'd need the differentation
> at all for now.

yeah i'm using that in the next patch to also expose it in the datacenter options
but i'll drop it for browser local storage only

> 
>> +
>> +    items: [
>> +	{
>> +	    xtype: 'inputpanel',
>> +	    cbind: {},
>> +	    onSetValues: (values) => values?.['tree-sorting'] ?? {},
>> +	    onGetValues: function(values) {
>> +		if (this.up('window').browserSettings) {
>> +		    let sp = Ext.state.Manager.getProvider();
> 
> nit: would like to avoid very short abbreviations which could get confusing if
> this ever expands or gets used as template and copied.
> 
> s/sp/stateProvider/ or maybe even s/sp/localStorage/
> 
>> +		    let state = values ? values : null;
>> +		    sp.set('pve-tree-sorting', state);
> 
> could drop intermediate variable
> 
> sp.set('pve-tree-sorting', values || null);
> 
>> +		    return {};
>> +		}
>> +		PVE.Utils.delete_if_default(values, 'group-templates', "1");
>> +		PVE.Utils.delete_if_default(values, 'group-guest-types', "1");
>> +		// no delete in property strings
>> +		delete values.delete;
>> +
>> +		let value = PVE.Parser.printPropertyString(values);
>> +
>> +		if (value === '') {
>> +		    return { 'delete': 'tree-sorting' };
>> +		}
>> +		return { 'tree-sorting': value };
>> +	    },
>> +	    items: [
>> +		{
>> +		    name: 'sort-field',
>> +		    xtype: 'proxmoxKVComboBox',
> 
> please put xtype first
> 
>> +		    fieldLabel: gettext('Sort Field'),
>> +		    labelWidth: 120,
> 
> might want to but that in a defaults: {} config at inputpanel level
> 
>> +		    comboItems: [
>> +			['__default__', Proxmox.Utils.defaultText],
>> +			['vmid', gettext('VMID')],
> 
> do we really translate VMID, as in, is there a (updated in the last 12 months)
> translation that sets this to something different and sensible?

only arabic seems to translate VMID, and not even consistent
(it's VMID in some other arabic strings) so i think we would be fine to
drop that. we're not consitently using gettext for it anyway

> 
>> +			['name', gettext('Name')],
>> +		    ],
>> +		    defaultValue: '__default__',
>> +		    value: '__default__',
>> +		    deleteEmpty: false,
>> +		},
>> +		{
>> +		    name: 'group-templates',
>> +		    xtype: 'booleanfield',
> 
> please put xtype first
> 
> besides that and unrelated to your series, this widget is a bit odd and as it
> has no pve/proxmox prefix (I initially thought it's a ExtJS one that I just
> never stumbled uppon) and should get renamed to something more telling like
> pmxBooleanComboBox, probably should move to widget toolkit too

sure

> 
>> +		    fieldLabel: gettext('Group Templates'),
>> +		    defaultValue: '__default__',
>> +		    value: '__default__',
>> +		    deleteEmpty: false,
>> +		    labelWidth: 120,
>> +		},
>> +		{
>> +		    name: 'group-guest-types',
>> +		    xtype: 'booleanfield',
> 
> please put xtype first
> 
>> +		    fieldLabel: gettext('Group Types'),
>> +		    defaultValue: '__default__',
>> +		    value: '__default__',
>> +		    deleteEmpty: false,
>> +		    labelWidth: 120,
>> +		},
>> +		{
>> +		    xtype: 'displayfield',
>> +		    userCls: 'pmx-hint',
>> +		    value: gettext('Settings are saved in the browser local storage'),
>> +		    hidden: true,
>> +		    cbind: {
>> +			hidden: '{!browserSettings}',
>> +		    },
>> +		}
>> +	    ],
>> +	},
>> +    ],
>> +
>> +    submit: function() {
>> +	let me = this;
>> +
>> +	if (me.browserSettings) {
>> +	    me.down('inputpanel').getValues();
>> +	    me.apiCallDone();
>> +	    me.close();
>> +	} else {
>> +	    me.callParent();
>> +	}
>> +    },
>> +
>> +    initComponent: function() {
>> +	let me = this;
>> +
>> +	me.callParent();
>> +
>> +	me.load({
>> +	    success: function(response) {
>> +		let values = response?.result?.data?.['tree-sorting'] ?? {};
>> +		if (me.browserSettings) {
>> +		    let sp = Ext.state.Manager.getProvider();
>> +		    values = sp.get('pve-tree-sorting');
>> +		}
>> +		me.down('inputpanel').setValues({ 'tree-sorting': values });
>> +	    },
>> +	});
>> +    },
>> +
>> +});
> 





^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-02-02 12:16 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-01 15:49 [pve-devel] [PATCH cluster/manager] fix #1408: ui: make tree sorting configurable Dominik Csapak
2023-02-01 15:49 ` [pve-devel] [PATCH cluster 1/1] datacenter config: add options for sorting the gui tree Dominik Csapak
2023-02-01 15:49 ` [pve-devel] [PATCH manager 1/3] ui: Utils: refactor refreshing the the resource store/tree Dominik Csapak
2023-02-02 10:22   ` Thomas Lamprecht
2023-02-01 15:49 ` [pve-devel] [PATCH manager 2/3] ui: add TreeSortingEdit window Dominik Csapak
2023-02-02 10:56   ` Thomas Lamprecht
2023-02-02 12:16     ` Dominik Csapak
2023-02-01 15:49 ` [pve-devel] [PATCH manager 3/3] fix #1408: ui: ResourceTree: sort the tree according to tree-sorting options Dominik Csapak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal