public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH manager v2 0/6] fix #1408: ui: make tree sorting configurable
@ 2023-02-02 14:41 Dominik Csapak
  2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 1/6] ui: remove 'Storage View' Dominik Csapak
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-02-02 14:41 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 via browser local storage

the first 2 patches are not really related but popped up during
development

changes from v1:
* drop the datacenter config options for now
* rename TreeSortingEdit into TreeSortingEdit
* since we don't have a fallback besides the default, display the
  defauls in the dropdowns
* don't use booleanfield anymore (because of above change)
* rename sp into localStorage
* use fieldDefaults
* refactor stuff into PVE.UIOptions (a new singleton)
* remove storage view
* remove booleanfield

Dominik Csapak (6):
  ui: remove 'Storage View'
  ui: remove unused booleanfield
  ui: refactor ui option related methods into UIOptions
  ui: refactor refreshing the the resource store/tree
  ui: add window for changing tree related options
  fix #1408: ui: ResourceTree: sort the tree according to tree-sorting
    options

 www/manager6/Makefile                   |   3 +-
 www/manager6/UIOptions.js               | 107 ++++++++++++++++++++++++
 www/manager6/Utils.js                   |  92 +-------------------
 www/manager6/Workspace.js               |  28 ++++++-
 www/manager6/data/ResourceStore.js      |   2 +-
 www/manager6/dc/OptionView.js           |  23 ++---
 www/manager6/form/Boolean.js            |  10 ---
 www/manager6/form/GlobalSearchField.js  |   2 +-
 www/manager6/form/Tag.js                |   6 +-
 www/manager6/form/TagColorGrid.js       |   2 +-
 www/manager6/form/TagEdit.js            |  10 +--
 www/manager6/form/ViewSelector.js       |   7 --
 www/manager6/tree/ResourceTree.js       |  56 ++++++++++---
 www/manager6/window/TreeSettingsEdit.js |  87 +++++++++++++++++++
 14 files changed, 289 insertions(+), 146 deletions(-)
 create mode 100644 www/manager6/UIOptions.js
 delete mode 100644 www/manager6/form/Boolean.js
 create mode 100644 www/manager6/window/TreeSettingsEdit.js

-- 
2.30.2





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

* [pve-devel] [PATCH manager v2 1/6] ui: remove 'Storage View'
  2023-02-02 14:41 [pve-devel] [PATCH manager v2 0/6] fix #1408: ui: make tree sorting configurable Dominik Csapak
@ 2023-02-02 14:41 ` Dominik Csapak
  2023-02-09 16:22   ` Thomas Lamprecht
  2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 2/6] ui: remove unused booleanfield Dominik Csapak
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: Dominik Csapak @ 2023-02-02 14:41 UTC (permalink / raw)
  To: pve-devel

it is basically the 'Server View' but with less content, and has often
times lead to confusion when uses accidentally selected it.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/manager6/form/ViewSelector.js | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/www/manager6/form/ViewSelector.js b/www/manager6/form/ViewSelector.js
index 45fabd7ef..e25547c41 100644
--- a/www/manager6/form/ViewSelector.js
+++ b/www/manager6/form/ViewSelector.js
@@ -26,13 +26,6 @@ Ext.define('PVE.form.ViewSelector', {
 		text: gettext('Folder View'),
 		groups: ['type'],
 	    },
-	    storage: {
-		text: gettext('Storage View'),
-		groups: ['node'],
-		filterfn: function(node) {
-		    return node.data.type === 'storage' || node.data.type === 'node';
-		},
-	    },
 	    pool: {
 		text: gettext('Pool View'),
 		groups: ['pool'],
-- 
2.30.2





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

* [pve-devel] [PATCH manager v2 2/6] ui: remove unused booleanfield
  2023-02-02 14:41 [pve-devel] [PATCH manager v2 0/6] fix #1408: ui: make tree sorting configurable Dominik Csapak
  2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 1/6] ui: remove 'Storage View' Dominik Csapak
@ 2023-02-02 14:41 ` Dominik Csapak
  2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 3/6] ui: refactor ui option related methods into UIOptions Dominik Csapak
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-02-02 14:41 UTC (permalink / raw)
  To: pve-devel

it's not used anymore, does not belong into pve-manager (rather in
proxmox-widget-toolkit), does not have a proper alias.

it's simple enough to recreate should we ever need it again

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/manager6/Makefile        |  1 -
 www/manager6/form/Boolean.js | 10 ----------
 2 files changed, 11 deletions(-)
 delete mode 100644 www/manager6/form/Boolean.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index 05afeda40..6a0cb73b7 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -19,7 +19,6 @@ JSSRC= 							\
 	form/AgentFeatureSelector.js			\
 	form/BackupModeSelector.js			\
 	form/BandwidthSelector.js			\
-	form/Boolean.js					\
 	form/BridgeSelector.js				\
 	form/BusTypeSelector.js				\
 	form/CPUModelSelector.js			\
diff --git a/www/manager6/form/Boolean.js b/www/manager6/form/Boolean.js
deleted file mode 100644
index f67c72445..000000000
--- a/www/manager6/form/Boolean.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// boolean type including 'Default' (delete property from file)
-Ext.define('PVE.form.Boolean', {
-    extend: 'Proxmox.form.KVComboBox',
-    alias: ['widget.booleanfield'],
-    comboItems: [
-	['__default__', gettext('Default')],
-	[1, gettext('Yes')],
-	[0, gettext('No')],
-    ],
-});
-- 
2.30.2





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

* [pve-devel] [PATCH manager v2 3/6] ui: refactor ui option related methods into UIOptions
  2023-02-02 14:41 [pve-devel] [PATCH manager v2 0/6] fix #1408: ui: make tree sorting configurable Dominik Csapak
  2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 1/6] ui: remove 'Storage View' Dominik Csapak
  2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 2/6] ui: remove unused booleanfield Dominik Csapak
@ 2023-02-02 14:41 ` Dominik Csapak
  2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 4/6] ui: refactor refreshing the the resource store/tree Dominik Csapak
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-02-02 14:41 UTC (permalink / raw)
  To: pve-devel

a new singleton like Utils/Parser, intended for holding stuff for
ui options, such as the tag settings/overrides

no behavioural change intended

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/manager6/Makefile                  |  1 +
 www/manager6/UIOptions.js              | 92 ++++++++++++++++++++++++++
 www/manager6/Utils.js                  | 92 +-------------------------
 www/manager6/Workspace.js              |  2 +-
 www/manager6/data/ResourceStore.js     |  2 +-
 www/manager6/dc/OptionView.js          | 22 +++---
 www/manager6/form/GlobalSearchField.js |  2 +-
 www/manager6/form/Tag.js               |  6 +-
 www/manager6/form/TagColorGrid.js      |  2 +-
 www/manager6/form/TagEdit.js           | 10 +--
 www/manager6/tree/ResourceTree.js      |  2 +-
 11 files changed, 119 insertions(+), 114 deletions(-)
 create mode 100644 www/manager6/UIOptions.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index 6a0cb73b7..2c487655f 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -4,6 +4,7 @@ JSSRC= 							\
 	Parser.js					\
 	StateProvider.js				\
 	Utils.js					\
+	UIOptions.js					\
 	Toolkit.js					\
 	VNCConsole.js					\
 	button/ConsoleButton.js				\
diff --git a/www/manager6/UIOptions.js b/www/manager6/UIOptions.js
new file mode 100644
index 000000000..c80a7c859
--- /dev/null
+++ b/www/manager6/UIOptions.js
@@ -0,0 +1,92 @@
+Ext.define('PVE.UIOptions', {
+    singleton: true,
+
+    options: {
+	'allowed-tags': [],
+    },
+
+    update: function() {
+	Proxmox.Utils.API2Request({
+	    url: '/cluster/options',
+	    method: 'GET',
+	    success: function(response) {
+		for (const option of ['allowed-tags', 'console', 'tag-style']) {
+		    PVE.UIOptions.options[option] = response?.result?.data?.[option];
+		}
+
+		PVE.UIOptions.updateTagList(PVE.UIOptions.options['allowed-tags']);
+		PVE.UIOptions.updateTagSettings(PVE.UIOptions.options['tag-style']);
+	    },
+	});
+    },
+
+    tagList: [],
+
+    updateTagList: function(tags) {
+	PVE.UIOptions.tagList = [...new Set([...tags])].sort();
+    },
+
+    parseTagOverrides: function(overrides) {
+	let colors = {};
+	(overrides || "").split(';').forEach(color => {
+	    if (!color) {
+		return;
+	    }
+	    let [tag, color_hex, font_hex] = color.split(':');
+	    let r = parseInt(color_hex.slice(0, 2), 16);
+	    let g = parseInt(color_hex.slice(2, 4), 16);
+	    let b = parseInt(color_hex.slice(4, 6), 16);
+	    colors[tag] = [r, g, b];
+	    if (font_hex) {
+		colors[tag].push(parseInt(font_hex.slice(0, 2), 16));
+		colors[tag].push(parseInt(font_hex.slice(2, 4), 16));
+		colors[tag].push(parseInt(font_hex.slice(4, 6), 16));
+	    }
+	});
+	return colors;
+    },
+
+    tagOverrides: {},
+
+    updateTagOverrides: function(colors) {
+	let sp = Ext.state.Manager.getProvider();
+	let color_state = sp.get('colors', '');
+	let browser_colors = PVE.UIOptions.parseTagOverrides(color_state);
+	PVE.UIOptions.tagOverrides = Ext.apply({}, browser_colors, colors);
+    },
+
+    updateTagSettings: function(style) {
+	let overrides = style?.['color-map'];
+	PVE.UIOptions.updateTagOverrides(PVE.UIOptions.parseTagOverrides(overrides ?? ""));
+
+	let shape = style?.shape ?? 'circle';
+	if (shape === '__default__') {
+	    style = 'circle';
+	}
+
+	Ext.ComponentQuery.query('pveResourceTree')[0].setUserCls(`proxmox-tags-${shape}`);
+
+	if (!PVE.data.ResourceStore.isLoading() && PVE.data.ResourceStore.isLoaded()) {
+	    PVE.data.ResourceStore.fireEvent('load');
+	}
+	Ext.GlobalEvents.fireEvent('loadedUiOptions');
+    },
+
+    tagTreeStyles: {
+	'__default__': `${Proxmox.Utils.defaultText} (${gettext('Circle')})`,
+	'full': gettext('Full'),
+	'circle': gettext('Circle'),
+	'dense': gettext('Dense'),
+	'none': Proxmox.Utils.NoneText,
+    },
+
+    tagOrderOptions: {
+	'__default__': `${Proxmox.Utils.defaultText} (${gettext('Alphabetical')})`,
+	'config': gettext('Configuration'),
+	'alphabetical': gettext('Alphabetical'),
+    },
+
+    shouldSortTags: function() {
+	return !(PVE.UIOptions.options['tag-style']?.ordering === 'config');
+    },
+});
diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
index fcc668c3a..7bf3955a1 100644
--- a/www/manager6/Utils.js
+++ b/www/manager6/Utils.js
@@ -1334,7 +1334,7 @@ Ext.define('PVE.Utils', {
 	    allowSpice = consoles.spice;
 	    allowXtermjs = !!consoles.xtermjs;
 	}
-	let dv = PVE.UIOptions.console || (type === 'kvm' ? 'vv' : 'xtermjs');
+	let dv = PVE.UIOptions.options.console || (type === 'kvm' ? 'vv' : 'xtermjs');
 	if (dv === 'vv' && !allowSpice) {
 	    dv = allowXtermjs ? 'xtermjs' : 'html5';
 	} else if (dv === 'xtermjs' && !allowXtermjs) {
@@ -1857,95 +1857,11 @@ Ext.define('PVE.Utils', {
 
     notesTemplateVars: ['cluster', 'guestname', 'node', 'vmid'],
 
-    updateUIOptions: function() {
-	Proxmox.Utils.API2Request({
-	    url: '/cluster/options',
-	    method: 'GET',
-	    success: function(response) {
-		PVE.UIOptions = {
-		    'allowed-tags': [],
-		};
-		for (const option of ['allowed-tags', 'console', 'tag-style']) {
-		    PVE.UIOptions[option] = response?.result?.data?.[option];
-		}
-
-		PVE.Utils.updateTagList(PVE.UIOptions['allowed-tags']);
-		PVE.Utils.updateTagSettings(PVE.UIOptions?.['tag-style']);
-	    },
-	});
-    },
-
-    tagList: [],
-
-    updateTagList: function(tags) {
-	PVE.Utils.tagList = [...new Set([...tags])].sort();
-    },
-
-    parseTagOverrides: function(overrides) {
-	let colors = {};
-	(overrides || "").split(';').forEach(color => {
-	    if (!color) {
-		return;
-	    }
-	    let [tag, color_hex, font_hex] = color.split(':');
-	    let r = parseInt(color_hex.slice(0, 2), 16);
-	    let g = parseInt(color_hex.slice(2, 4), 16);
-	    let b = parseInt(color_hex.slice(4, 6), 16);
-	    colors[tag] = [r, g, b];
-	    if (font_hex) {
-		colors[tag].push(parseInt(font_hex.slice(0, 2), 16));
-		colors[tag].push(parseInt(font_hex.slice(2, 4), 16));
-		colors[tag].push(parseInt(font_hex.slice(4, 6), 16));
-	    }
-	});
-	return colors;
-    },
-
-    tagOverrides: {},
-
-    updateTagOverrides: function(colors) {
-	let sp = Ext.state.Manager.getProvider();
-	let color_state = sp.get('colors', '');
-	let browser_colors = PVE.Utils.parseTagOverrides(color_state);
-	PVE.Utils.tagOverrides = Ext.apply({}, browser_colors, colors);
-    },
-
-    updateTagSettings: function(style) {
-	let overrides = style?.['color-map'];
-	PVE.Utils.updateTagOverrides(PVE.Utils.parseTagOverrides(overrides ?? ""));
-
-	let shape = style?.shape ?? 'circle';
-	if (shape === '__default__') {
-	    style = 'circle';
-	}
-
-	Ext.ComponentQuery.query('pveResourceTree')[0].setUserCls(`proxmox-tags-${shape}`);
-
-	if (!PVE.data.ResourceStore.isLoading() && PVE.data.ResourceStore.isLoaded()) {
-	    PVE.data.ResourceStore.fireEvent('load');
-	}
-	Ext.GlobalEvents.fireEvent('loadedUiOptions');
-    },
-
-    tagTreeStyles: {
-	'__default__': `${Proxmox.Utils.defaultText} (${gettext('Circle')})`,
-	'full': gettext('Full'),
-	'circle': gettext('Circle'),
-	'dense': gettext('Dense'),
-	'none': Proxmox.Utils.NoneText,
-    },
-
-    tagOrderOptions: {
-	'__default__': `${Proxmox.Utils.defaultText} (${gettext('Alphabetical')})`,
-	'config': gettext('Configuration'),
-	'alphabetical': gettext('Alphabetical'),
-    },
-
     renderTags: function(tagstext, overrides) {
 	let text = '';
 	if (tagstext) {
 	    let tags = (tagstext.split(/[,; ]/) || []).filter(t => !!t);
-	    if (PVE.Utils.shouldSortTags()) {
+	    if (PVE.UIOptions.shouldSortTags()) {
 		tags = tags.sort((a, b) => {
 		    let alc = a.toLowerCase();
 		    let blc = b.toLowerCase();
@@ -1960,10 +1876,6 @@ Ext.define('PVE.Utils', {
 	return text;
     },
 
-    shouldSortTags: function() {
-	return !(PVE.UIOptions?.['tag-style']?.ordering === 'config');
-    },
-
     tagCharRegex: /^[a-z0-9+_.-]+$/i,
 
     verificationStateOrder: {
diff --git a/www/manager6/Workspace.js b/www/manager6/Workspace.js
index d0f7ff760..a3872b560 100644
--- a/www/manager6/Workspace.js
+++ b/www/manager6/Workspace.js
@@ -158,7 +158,7 @@ Ext.define('PVE.StdWorkspace', {
 		},
 	    });
 
-	    PVE.Utils.updateUIOptions();
+	    PVE.UIOptions.update();
 
 	    Proxmox.Utils.API2Request({
 		url: '/cluster/sdn',
diff --git a/www/manager6/data/ResourceStore.js b/www/manager6/data/ResourceStore.js
index 91473a547..f3a5c4d81 100644
--- a/www/manager6/data/ResourceStore.js
+++ b/www/manager6/data/ResourceStore.js
@@ -295,7 +295,7 @@ Ext.define('PVE.data.ResourceStore', {
 	    },
 	    tags: {
 		header: gettext('Tags'),
-		renderer: (value) => PVE.Utils.renderTags(value, PVE.Utils.tagOverrides),
+		renderer: (value) => PVE.Utils.renderTags(value, PVE.UIOptions.tagOverrides),
 		type: 'string',
 		sortable: true,
 		flex: 1,
diff --git a/www/manager6/dc/OptionView.js b/www/manager6/dc/OptionView.js
index 9c803beef..4435876dd 100644
--- a/www/manager6/dc/OptionView.js
+++ b/www/manager6/dc/OptionView.js
@@ -358,11 +358,11 @@ Ext.define('PVE.dc.OptionView', {
 		if (value === undefined) {
 		    return gettext('No Overrides');
 		}
-		let colors = PVE.Utils.parseTagOverrides(value?.['color-map']);
+		let colors = PVE.UIOptions.parseTagOverrides(value?.['color-map']);
 		let shape = value.shape;
-		let shapeText = PVE.Utils.tagTreeStyles[shape ?? '__default__'];
+		let shapeText = PVE.UIOptions.tagTreeStyles[shape ?? '__default__'];
 		let txt = Ext.String.format(gettext("Tree Shape: {0}"), shapeText);
-		let orderText = PVE.Utils.tagOrderOptions[value.ordering ?? '__default__'];
+		let orderText = PVE.UIOptions.tagOrderOptions[value.ordering ?? '__default__'];
 		txt += `, ${Ext.String.format(gettext("Ordering: {0}"), orderText)}`;
 		if (value['case-sensitive']) {
 		    txt += `, ${gettext('Case-Sensitive')}`;
@@ -453,7 +453,7 @@ Ext.define('PVE.dc.OptionView', {
 				    ],
 				},
 				store: {
-				    data: Object.entries(PVE.Utils.tagTreeStyles).map(v => ({
+				    data: Object.entries(PVE.UIOptions.tagTreeStyles).map(v => ({
 					value: v[0],
 					display: v[1],
 				    })),
@@ -466,7 +466,7 @@ Ext.define('PVE.dc.OptionView', {
 				name: 'ordering',
 				xtype: 'proxmoxKVComboBox',
 				fieldLabel: gettext('Ordering'),
-				comboItems: Object.entries(PVE.Utils.tagOrderOptions),
+				comboItems: Object.entries(PVE.UIOptions.tagOrderOptions),
 				defaultValue: '__default__',
 				value: '__default__',
 				deleteEmpty: true,
@@ -503,7 +503,7 @@ Ext.define('PVE.dc.OptionView', {
 		let mode = value?.['user-allow'] ?? 'free';
 		let list = value?.['user-allow-list']?.join(',') ?? '';
 		let modeTxt = Ext.String.format(gettext('Mode: {0}'), mode);
-		let overrides = PVE.Utils.tagOverrides;
+		let overrides = PVE.UIOptions.tagOverrides;
 		let tags = PVE.Utils.renderTags(list, overrides);
 		let listTxt = tags !== '' ? `, ${gettext('Pre-defined:')} ${tags}` : '';
 		return `${modeTxt}${listTxt}`;
@@ -520,7 +520,7 @@ Ext.define('PVE.dc.OptionView', {
 		if (value === undefined) {
 		    return gettext('No Registered Tags');
 		}
-		let overrides = PVE.Utils.tagOverrides;
+		let overrides = PVE.UIOptions.tagOverrides;
 		return PVE.Utils.renderTags(value.join(','), overrides);
 	    },
 	    header: gettext('Registered Tags'),
@@ -559,13 +559,13 @@ Ext.define('PVE.dc.OptionView', {
 	    }
 
 	    var rec = store.getById('console');
-	    PVE.UIOptions.console = rec.data.value;
+	    PVE.UIOptions.options.console = rec.data.value;
 	    if (rec.data.value === '__default__') {
-		delete PVE.UIOptions.console;
+		delete PVE.UIOptions.options.console;
 	    }
 
-	    PVE.UIOptions['tag-style'] = store.getById('tag-style')?.data?.value;
-	    PVE.Utils.updateTagSettings(PVE.UIOptions['tag-style']);
+	    PVE.UIOptions.options['tag-style'] = store.getById('tag-style')?.data?.value;
+	    PVE.UIOptions.updateTagSettings(PVE.UIOptions.options['tag-style']);
 	});
 
 	me.on('activate', me.rstore.startUpdate);
diff --git a/www/manager6/form/GlobalSearchField.js b/www/manager6/form/GlobalSearchField.js
index 8e815d4f5..c009ac8b7 100644
--- a/www/manager6/form/GlobalSearchField.js
+++ b/www/manager6/form/GlobalSearchField.js
@@ -80,7 +80,7 @@ Ext.define('PVE.form.GlobalSearchField', {
 		flex: 1,
 		dataIndex: 'text',
 		renderer: function(value, mD, rec) {
-		    let overrides = PVE.Utils.tagOverrides;
+		    let overrides = PVE.UIOptions.tagOverrides;
 		    let tags = PVE.Utils.renderTags(rec.data.tags, overrides);
 		    return `${value}${tags}`;
 		},
diff --git a/www/manager6/form/Tag.js b/www/manager6/form/Tag.js
index 6fda2e848..be72d7ba9 100644
--- a/www/manager6/form/Tag.js
+++ b/www/manager6/form/Tag.js
@@ -61,7 +61,7 @@ Ext.define('Proxmox.form.Tag', {
 		userCls: 'proxmox-tags-full',
 		displayField: 'tag',
 		itemTpl: [
-		    '{[Proxmox.Utils.getTagElement(values.tag, PVE.Utils.tagOverrides)]}',
+		    '{[Proxmox.Utils.getTagElement(values.tag, PVE.UIOptions.tagOverrides)]}',
 		],
 		store: [],
 		listeners: {
@@ -76,7 +76,7 @@ Ext.define('Proxmox.form.Tag', {
 	    });
 	}
 	me.picker.getStore()?.clearFilter();
-	let taglist = PVE.Utils.tagList.filter(v => !me.filter.includes(v)).map(v => ({ tag: v }));
+	let taglist = PVE.UIOptions.tagList.filter(v => !me.filter.includes(v)).map(v => ({ tag: v }));
 	if (taglist.length < 1) {
 	    return;
 	}
@@ -154,7 +154,7 @@ Ext.define('Proxmox.form.Tag', {
 
     setColor: function(tag) {
 	let me = this;
-	let rgb = PVE.Utils.tagOverrides[tag] ?? Proxmox.Utils.stringToRGB(tag);
+	let rgb = PVE.UIOptions.tagOverrides[tag] ?? Proxmox.Utils.stringToRGB(tag);
 
 	let cls = Proxmox.Utils.getTextContrastClass(rgb);
 	let color = Proxmox.Utils.rgbToCss(rgb);
diff --git a/www/manager6/form/TagColorGrid.js b/www/manager6/form/TagColorGrid.js
index 3ad8e07f0..310f18e66 100644
--- a/www/manager6/form/TagColorGrid.js
+++ b/www/manager6/form/TagColorGrid.js
@@ -295,7 +295,7 @@ Ext.define('PVE.form.TagColorGrid', {
 	    dataIndex: 'tag',
 	    xtype: 'widgetcolumn',
 	    onWidgetAttach: function(col, widget, rec) {
-		widget.getStore().setData(PVE.Utils.tagList.map(v => ({ tag: v })));
+		widget.getStore().setData(PVE.UIOptions.tagList.map(v => ({ tag: v })));
 	    },
 	    widget: {
 		xtype: 'combobox',
diff --git a/www/manager6/form/TagEdit.js b/www/manager6/form/TagEdit.js
index e1cd4af67..094f44626 100644
--- a/www/manager6/form/TagEdit.js
+++ b/www/manager6/form/TagEdit.js
@@ -41,7 +41,7 @@ Ext.define('PVE.panel.TagEditContainer', {
 	onRender: function(v) {
 	    let me = this;
 	    let view = me.getView();
-	    view.toggleCls('hide-handles', PVE.Utils.shouldSortTags());
+	    view.toggleCls('hide-handles', PVE.UIOptions.shouldSortTags());
 
 	    view.dragzone = Ext.create('Ext.dd.DragZone', v.getEl(), {
 		getDragData: function(e) {
@@ -53,7 +53,7 @@ Ext.define('PVE.panel.TagEditContainer', {
 		    let cmp = Ext.getCmp(sourceId);
 		    let ddel = document.createElement('div');
 		    ddel.classList.add('proxmox-tags-full');
-		    ddel.innerHTML = Proxmox.Utils.getTagElement(cmp.tag, PVE.Utils.tagOverrides);
+		    ddel.innerHTML = Proxmox.Utils.getTagElement(cmp.tag, PVE.UIOptions.tagOverrides);
 		    let repairXY = Ext.fly(source).getXY();
 		    cmp.setDisabled(true);
 		    ddel.id = Ext.id();
@@ -141,7 +141,7 @@ Ext.define('PVE.panel.TagEditContainer', {
 
 	    // get a current tag list for editing
 	    if (editMode) {
-		PVE.Utils.updateUIOptions();
+		PVE.UIOptions.update();
 	    }
 
 	    me.forEachTag((tag) => {
@@ -192,7 +192,7 @@ Ext.define('PVE.panel.TagEditContainer', {
 	    let view = me.getView();
 	    let vm = me.getViewModel();
 	    let index = view.items.length - 5;
-	    if (PVE.Utils.shouldSortTags() && !isNew) {
+	    if (PVE.UIOptions.shouldSortTags() && !isNew) {
 		index = view.items.findIndexBy(tagField => {
 		    if (tagField.reference === 'noTagsField') {
 			return false;
@@ -255,7 +255,7 @@ Ext.define('PVE.panel.TagEditContainer', {
 	    me.getViewModel().set('canEdit', view.canEdit);
 
 	    me.mon(Ext.GlobalEvents, 'loadedUiOptions', () => {
-		view.toggleCls('hide-handles', PVE.Utils.shouldSortTags());
+		view.toggleCls('hide-handles', PVE.UIOptions.shouldSortTags());
 		me.loadTags(me.oldTags, true); // refresh tag colors and order
 	    });
 	},
diff --git a/www/manager6/tree/ResourceTree.js b/www/manager6/tree/ResourceTree.js
index 5c92d4128..7fcdfed5d 100644
--- a/www/manager6/tree/ResourceTree.js
+++ b/www/manager6/tree/ResourceTree.js
@@ -116,7 +116,7 @@ Ext.define('PVE.tree.ResourceTree', {
 	    }
 	}
 
-	info.text += PVE.Utils.renderTags(info.tags, PVE.Utils.tagOverrides);
+	info.text += PVE.Utils.renderTags(info.tags, PVE.UIOptions.tagOverrides);
 
 	info.text = status + info.text;
     },
-- 
2.30.2





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

* [pve-devel] [PATCH manager v2 4/6] ui: refactor refreshing the the resource store/tree
  2023-02-02 14:41 [pve-devel] [PATCH manager v2 0/6] fix #1408: ui: make tree sorting configurable Dominik Csapak
                   ` (2 preceding siblings ...)
  2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 3/6] ui: refactor ui option related methods into UIOptions Dominik Csapak
@ 2023-02-02 14:41 ` Dominik Csapak
  2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 5/6] ui: add window for changing tree related options Dominik Csapak
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-02-02 14:41 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/UIOptions.js     | 13 ++++++++-----
 www/manager6/dc/OptionView.js |  1 +
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/www/manager6/UIOptions.js b/www/manager6/UIOptions.js
index c80a7c859..dcdf01ee1 100644
--- a/www/manager6/UIOptions.js
+++ b/www/manager6/UIOptions.js
@@ -16,6 +16,7 @@ Ext.define('PVE.UIOptions', {
 
 		PVE.UIOptions.updateTagList(PVE.UIOptions.options['allowed-tags']);
 		PVE.UIOptions.updateTagSettings(PVE.UIOptions.options['tag-style']);
+		PVE.UIOptions.fireUIConfigChanged();
 	    },
 	});
     },
@@ -65,11 +66,6 @@ Ext.define('PVE.UIOptions', {
 	}
 
 	Ext.ComponentQuery.query('pveResourceTree')[0].setUserCls(`proxmox-tags-${shape}`);
-
-	if (!PVE.data.ResourceStore.isLoading() && PVE.data.ResourceStore.isLoaded()) {
-	    PVE.data.ResourceStore.fireEvent('load');
-	}
-	Ext.GlobalEvents.fireEvent('loadedUiOptions');
     },
 
     tagTreeStyles: {
@@ -89,4 +85,11 @@ Ext.define('PVE.UIOptions', {
     shouldSortTags: function() {
 	return !(PVE.UIOptions.options['tag-style']?.ordering === 'config');
     },
+
+    fireUIConfigChanged: function() {
+	if (!PVE.data.ResourceStore.isLoading() && PVE.data.ResourceStore.isLoaded()) {
+	    PVE.data.ResourceStore.fireEvent('load');
+	}
+	Ext.GlobalEvents.fireEvent('loadedUiOptions');
+    },
 });
diff --git a/www/manager6/dc/OptionView.js b/www/manager6/dc/OptionView.js
index 4435876dd..f36a68560 100644
--- a/www/manager6/dc/OptionView.js
+++ b/www/manager6/dc/OptionView.js
@@ -566,6 +566,7 @@ Ext.define('PVE.dc.OptionView', {
 
 	    PVE.UIOptions.options['tag-style'] = store.getById('tag-style')?.data?.value;
 	    PVE.UIOptions.updateTagSettings(PVE.UIOptions.options['tag-style']);
+	    PVE.UIOptions.fireUIConfigChanged();
 	});
 
 	me.on('activate', me.rstore.startUpdate);
-- 
2.30.2





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

* [pve-devel] [PATCH manager v2 5/6] ui: add window for changing tree related options
  2023-02-02 14:41 [pve-devel] [PATCH manager v2 0/6] fix #1408: ui: make tree sorting configurable Dominik Csapak
                   ` (3 preceding siblings ...)
  2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 4/6] ui: refactor refreshing the the resource store/tree Dominik Csapak
@ 2023-02-02 14:41 ` Dominik Csapak
  2023-02-09 10:33   ` Aaron Lauterer
  2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 6/6] fix #1408: ui: ResourceTree: sort the tree according to tree-sorting options Dominik Csapak
  2023-02-09 10:34 ` [pve-devel] [PATCH manager v2 0/6] fix #1408: ui: make tree sorting configurable Aaron Lauterer
  6 siblings, 1 reply; 10+ messages in thread
From: Dominik Csapak @ 2023-02-02 14:41 UTC (permalink / raw)
  To: pve-devel

such as the sorting/grouping of guests. saves them in the browser local
storage under 'pve-tree-sorting'

adds a button for it next to the the view selector

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/manager6/Makefile                   |  1 +
 www/manager6/Workspace.js               | 26 +++++++-
 www/manager6/window/TreeSettingsEdit.js | 87 +++++++++++++++++++++++++
 3 files changed, 112 insertions(+), 2 deletions(-)
 create mode 100644 www/manager6/window/TreeSettingsEdit.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index 2c487655f..b73b729ad 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -119,6 +119,7 @@ JSSRC= 							\
 	window/ScheduleSimulator.js			\
 	window/Wizard.js				\
 	window/GuestDiskReassign.js				\
+	window/TreeSettingsEdit.js			\
 	ha/Fencing.js					\
 	ha/GroupEdit.js					\
 	ha/GroupSelector.js				\
diff --git a/www/manager6/Workspace.js b/www/manager6/Workspace.js
index a3872b560..b80a4a2f6 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,27 @@ 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.TreeSettingsEdit', {
+					    autoShow: true,
+					    apiCallDone: () => PVE.UIOptions.fireUIConfigChanged(),
+					});
+				    },
+				},
+			    ],
+			},
+			rtree,
+		    ],
 		    listeners: {
 			resize: function(panel, width, height) {
 			    var viewWidth = me.getSize().width;
diff --git a/www/manager6/window/TreeSettingsEdit.js b/www/manager6/window/TreeSettingsEdit.js
new file mode 100644
index 000000000..058980dc1
--- /dev/null
+++ b/www/manager6/window/TreeSettingsEdit.js
@@ -0,0 +1,87 @@
+Ext.define('PVE.window.TreeSettingsEdit', {
+    extend: 'Proxmox.window.Edit',
+    alias: 'widget.pveTreeSettingsEdit',
+
+    title: gettext('Tree Settings'),
+
+    isCreate: false,
+
+    // we don't want an url, we override submit(), but it is needed by the parent class
+    url: 'bogus',
+
+    fieldDefaults: {
+	labelWidth: 120,
+    },
+
+    items: [
+	{
+	    xtype: 'inputpanel',
+	    items: [
+		{
+		    xtype: 'proxmoxKVComboBox',
+		    name: 'sort-field',
+		    fieldLabel: gettext('Sort Field'),
+		    comboItems: [
+			['__default__', `${Proxmox.Utils.defaultText} (VMID)`],
+			['vmid', 'VMID'],
+			['name', gettext('Name')],
+		    ],
+		    defaultValue: '__default__',
+		    value: '__default__',
+		    deleteEmpty: false,
+		},
+		{
+		    xtype: 'proxmoxKVComboBox',
+		    name: 'group-templates',
+		    fieldLabel: gettext('Group Templates'),
+		    comboItems: [
+			['__default__', `${Proxmox.Utils.defaultText} (${gettext("Yes")})`],
+			[1, gettext('Yes')],
+			[0, gettext('No')],
+		    ],
+		    defaultValue: '__default__',
+		    value: '__default__',
+		    deleteEmpty: false,
+		},
+		{
+		    xtype: 'proxmoxKVComboBox',
+		    name: 'group-guest-types',
+		    fieldLabel: gettext('Group Types'),
+		    comboItems: [
+			['__default__', `${Proxmox.Utils.defaultText} (${gettext("Yes")})`],
+			[1, gettext('Yes')],
+			[0, gettext('No')],
+		    ],
+		    defaultValue: '__default__',
+		    value: '__default__',
+		    deleteEmpty: false,
+		},
+		{
+		    xtype: 'displayfield',
+		    userCls: 'pmx-hint',
+		    value: gettext('Settings are saved in the browser local storage'),
+		},
+	    ],
+	},
+    ],
+
+    submit: function() {
+	let me = this;
+
+	let localStorage = Ext.state.Manager.getProvider();
+	localStorage.set('pve-tree-sorting', me.down('inputpanel').getValues() || null);
+
+	me.apiCallDone();
+	me.close();
+    },
+
+    initComponent: function() {
+	let me = this;
+
+	me.callParent();
+
+	let localStorage = Ext.state.Manager.getProvider();
+	me.down('inputpanel').setValues(localStorage.get('pve-tree-sorting'));
+    },
+
+});
-- 
2.30.2





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

* [pve-devel] [PATCH manager v2 6/6] fix #1408: ui: ResourceTree: sort the tree according to tree-sorting options
  2023-02-02 14:41 [pve-devel] [PATCH manager v2 0/6] fix #1408: ui: make tree sorting configurable Dominik Csapak
                   ` (4 preceding siblings ...)
  2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 5/6] ui: add window for changing tree related options Dominik Csapak
@ 2023-02-02 14:41 ` Dominik Csapak
  2023-02-09 10:34 ` [pve-devel] [PATCH manager v2 0/6] fix #1408: ui: make tree sorting configurable Aaron Lauterer
  6 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-02-02 14:41 UTC (permalink / raw)
  To: pve-devel

Considers the newly added options from browser local storage. 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/UIOptions.js         | 12 +++++++
 www/manager6/tree/ResourceTree.js | 54 ++++++++++++++++++++++++-------
 2 files changed, 54 insertions(+), 12 deletions(-)

diff --git a/www/manager6/UIOptions.js b/www/manager6/UIOptions.js
index dcdf01ee1..cb5a17552 100644
--- a/www/manager6/UIOptions.js
+++ b/www/manager6/UIOptions.js
@@ -86,6 +86,18 @@ Ext.define('PVE.UIOptions', {
 	return !(PVE.UIOptions.options['tag-style']?.ordering === 'config');
     },
 
+    getTreeSortingValue: function(key) {
+	let localStorage = Ext.state.Manager.getProvider();
+	let browserValues = localStorage.get('pve-tree-sorting');
+	let defaults = {
+	    'sort-field': 'vmid',
+	    'group-templates': true,
+	    'group-guest-types': true,
+	};
+
+	return browserValues?.[key] ?? defaults[key];
+    },
+
     fireUIConfigChanged: function() {
 	if (!PVE.data.ResourceStore.isLoading() && PVE.data.ResourceStore.isLoaded()) {
 	    PVE.data.ResourceStore.fireEvent('load');
diff --git a/www/manager6/tree/ResourceTree.js b/www/manager6/tree/ResourceTree.js
index 7fcdfed5d..7d7900b59 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.UIOptions.getTreeSortingValue('sort-field') !== 'vmid') {
+		info.text = `${info.name} (${String(info.vmid)})`;
+	    }
+	}
 
 	info.text += PVE.Utils.renderTags(info.tags, PVE.UIOptions.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.UIOptions.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] 10+ messages in thread

* Re: [pve-devel] [PATCH manager v2 5/6] ui: add window for changing tree related options
  2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 5/6] ui: add window for changing tree related options Dominik Csapak
@ 2023-02-09 10:33   ` Aaron Lauterer
  0 siblings, 0 replies; 10+ messages in thread
From: Aaron Lauterer @ 2023-02-09 10:33 UTC (permalink / raw)
  To: Proxmox VE development discussion, Dominik Csapak

two small nits inline

On 2/2/23 15:41, Dominik Csapak wrote:
> such as the sorting/grouping of guests. saves them in the browser local
> storage under 'pve-tree-sorting'
> 
> adds a button for it next to the the view selector
> 
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
>   www/manager6/Makefile                   |  1 +
>   www/manager6/Workspace.js               | 26 +++++++-
>   www/manager6/window/TreeSettingsEdit.js | 87 +++++++++++++++++++++++++
>   3 files changed, 112 insertions(+), 2 deletions(-)
>   create mode 100644 www/manager6/window/TreeSettingsEdit.js
> 
> diff --git a/www/manager6/Makefile b/www/manager6/Makefile
> index 2c487655f..b73b729ad 100644
> --- a/www/manager6/Makefile
> +++ b/www/manager6/Makefile
> @@ -119,6 +119,7 @@ JSSRC= 							\
>   	window/ScheduleSimulator.js			\
>   	window/Wizard.js				\
>   	window/GuestDiskReassign.js				\
> +	window/TreeSettingsEdit.js			\
>   	ha/Fencing.js					\
>   	ha/GroupEdit.js					\
>   	ha/GroupSelector.js				\
> diff --git a/www/manager6/Workspace.js b/www/manager6/Workspace.js
> index a3872b560..b80a4a2f6 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,27 @@ 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',

It currently looks a bit cramped.
Can we add a
margin: '0 0 0 5',
here? This way we leave the same space to the drop down menu to the left as 
everywhere else in that part of the UI.

> +				    iconCls: 'fa fa-fw fa-gear',
> +				    handler: () => {
> +					Ext.create('PVE.window.TreeSettingsEdit', {
> +					    autoShow: true,
> +					    apiCallDone: () => PVE.UIOptions.fireUIConfigChanged(),
> +					});
> +				    },
> +				},
> +			    ],
> +			},
> +			rtree,
> +		    ],
>   		    listeners: {
>   			resize: function(panel, width, height) {
>   			    var viewWidth = me.getSize().width;
> diff --git a/www/manager6/window/TreeSettingsEdit.js b/www/manager6/window/TreeSettingsEdit.js
> new file mode 100644
> index 000000000..058980dc1
> --- /dev/null
> +++ b/www/manager6/window/TreeSettingsEdit.js
> @@ -0,0 +1,87 @@
> +Ext.define('PVE.window.TreeSettingsEdit', {
> +    extend: 'Proxmox.window.Edit',
> +    alias: 'widget.pveTreeSettingsEdit',
> +
> +    title: gettext('Tree Settings'),
> +
> +    isCreate: false,
> +
> +    // we don't want an url, we override submit(), but it is needed by the parent class
> +    url: 'bogus',
> +
> +    fieldDefaults: {
> +	labelWidth: 120,
> +    },
> +
> +    items: [
> +	{
> +	    xtype: 'inputpanel',
> +	    items: [
> +		{
> +		    xtype: 'proxmoxKVComboBox',
> +		    name: 'sort-field',
> +		    fieldLabel: gettext('Sort Field'),
> +		    comboItems: [
> +			['__default__', `${Proxmox.Utils.defaultText} (VMID)`],
> +			['vmid', 'VMID'],
> +			['name', gettext('Name')],
> +		    ],
> +		    defaultValue: '__default__',
> +		    value: '__default__',
> +		    deleteEmpty: false,
> +		},
> +		{
> +		    xtype: 'proxmoxKVComboBox',
> +		    name: 'group-templates',
> +		    fieldLabel: gettext('Group Templates'),
> +		    comboItems: [
> +			['__default__', `${Proxmox.Utils.defaultText} (${gettext("Yes")})`],
> +			[1, gettext('Yes')],
> +			[0, gettext('No')],
> +		    ],
> +		    defaultValue: '__default__',
> +		    value: '__default__',
> +		    deleteEmpty: false,
> +		},
> +		{
> +		    xtype: 'proxmoxKVComboBox',
> +		    name: 'group-guest-types',
> +		    fieldLabel: gettext('Group Types'),
> +		    comboItems: [
> +			['__default__', `${Proxmox.Utils.defaultText} (${gettext("Yes")})`],
> +			[1, gettext('Yes')],
> +			[0, gettext('No')],
> +		    ],
> +		    defaultValue: '__default__',
> +		    value: '__default__',
> +		    deleteEmpty: false,
> +		},
> +		{
> +		    xtype: 'displayfield',
> +		    userCls: 'pmx-hint',
> +		    value: gettext('Settings are saved in the browser local storage'),

s/browser/browser's/  to indicate possession. Or we could rephrase it to 
"Settings are saved in the local storage of the browser".

> +		},
> +	    ],
> +	},
> +    ],
> +
> +    submit: function() {
> +	let me = this;
> +
> +	let localStorage = Ext.state.Manager.getProvider();
> +	localStorage.set('pve-tree-sorting', me.down('inputpanel').getValues() || null);
> +
> +	me.apiCallDone();
> +	me.close();
> +    },
> +
> +    initComponent: function() {
> +	let me = this;
> +
> +	me.callParent();
> +
> +	let localStorage = Ext.state.Manager.getProvider();
> +	me.down('inputpanel').setValues(localStorage.get('pve-tree-sorting'));
> +    },
> +
> +});




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

* Re: [pve-devel] [PATCH manager v2 0/6] fix #1408: ui: make tree sorting configurable
  2023-02-02 14:41 [pve-devel] [PATCH manager v2 0/6] fix #1408: ui: make tree sorting configurable Dominik Csapak
                   ` (5 preceding siblings ...)
  2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 6/6] fix #1408: ui: ResourceTree: sort the tree according to tree-sorting options Dominik Csapak
@ 2023-02-09 10:34 ` Aaron Lauterer
  6 siblings, 0 replies; 10+ messages in thread
From: Aaron Lauterer @ 2023-02-09 10:34 UTC (permalink / raw)
  To: Proxmox VE development discussion, Dominik Csapak

Had two small nits in patch 5/6. Otherwise it seems to work nicely. Tested all 
options and also had tags with tag overrides configured in my tests.

Consider this

Tested-By: Aaron Lauterer <a.lauterer@proxmox.com>

On 2/2/23 15:41, Dominik Csapak wrote:
> 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 via browser local storage
> 
> the first 2 patches are not really related but popped up during
> development
> 
> changes from v1:
> * drop the datacenter config options for now
> * rename TreeSortingEdit into TreeSortingEdit
> * since we don't have a fallback besides the default, display the
>    defauls in the dropdowns
> * don't use booleanfield anymore (because of above change)
> * rename sp into localStorage
> * use fieldDefaults
> * refactor stuff into PVE.UIOptions (a new singleton)
> * remove storage view
> * remove booleanfield
> 
> Dominik Csapak (6):
>    ui: remove 'Storage View'
>    ui: remove unused booleanfield
>    ui: refactor ui option related methods into UIOptions
>    ui: refactor refreshing the the resource store/tree
>    ui: add window for changing tree related options
>    fix #1408: ui: ResourceTree: sort the tree according to tree-sorting
>      options
> 
>   www/manager6/Makefile                   |   3 +-
>   www/manager6/UIOptions.js               | 107 ++++++++++++++++++++++++
>   www/manager6/Utils.js                   |  92 +-------------------
>   www/manager6/Workspace.js               |  28 ++++++-
>   www/manager6/data/ResourceStore.js      |   2 +-
>   www/manager6/dc/OptionView.js           |  23 ++---
>   www/manager6/form/Boolean.js            |  10 ---
>   www/manager6/form/GlobalSearchField.js  |   2 +-
>   www/manager6/form/Tag.js                |   6 +-
>   www/manager6/form/TagColorGrid.js       |   2 +-
>   www/manager6/form/TagEdit.js            |  10 +--
>   www/manager6/form/ViewSelector.js       |   7 --
>   www/manager6/tree/ResourceTree.js       |  56 ++++++++++---
>   www/manager6/window/TreeSettingsEdit.js |  87 +++++++++++++++++++
>   14 files changed, 289 insertions(+), 146 deletions(-)
>   create mode 100644 www/manager6/UIOptions.js
>   delete mode 100644 www/manager6/form/Boolean.js
>   create mode 100644 www/manager6/window/TreeSettingsEdit.js
> 




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

* Re: [pve-devel] [PATCH manager v2 1/6] ui: remove 'Storage View'
  2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 1/6] ui: remove 'Storage View' Dominik Csapak
@ 2023-02-09 16:22   ` Thomas Lamprecht
  0 siblings, 0 replies; 10+ messages in thread
From: Thomas Lamprecht @ 2023-02-09 16:22 UTC (permalink / raw)
  To: Proxmox VE development discussion, Dominik Csapak

On 02/02/2023 15:41, Dominik Csapak wrote:
> it is basically the 'Server View' but with less content, and has often
> times lead to confusion when uses accidentally selected it.
> 
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
>  www/manager6/form/ViewSelector.js | 7 -------
>  1 file changed, 7 deletions(-)
> 
> diff --git a/www/manager6/form/ViewSelector.js b/www/manager6/form/ViewSelector.js
> index 45fabd7ef..e25547c41 100644
> --- a/www/manager6/form/ViewSelector.js
> +++ b/www/manager6/form/ViewSelector.js
> @@ -26,13 +26,6 @@ Ext.define('PVE.form.ViewSelector', {
>  		text: gettext('Folder View'),
>  		groups: ['type'],
>  	    },
> -	    storage: {
> -		text: gettext('Storage View'),
> -		groups: ['node'],
> -		filterfn: function(node) {
> -		    return node.data.type === 'storage' || node.data.type === 'node';
> -		},
> -	    },
>  	    pool: {
>  		text: gettext('Pool View'),
>  		groups: ['pool'],

I'm fully agreeing with removing this useless view, just not sure if a minor
point release is right for that, but otoh. we could simply reinstate this if
we it turns out that we really got users out there depending on that view...

So, if there are no objection from any dev/user now already I'd go ahead with
applying this one.




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

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

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-02 14:41 [pve-devel] [PATCH manager v2 0/6] fix #1408: ui: make tree sorting configurable Dominik Csapak
2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 1/6] ui: remove 'Storage View' Dominik Csapak
2023-02-09 16:22   ` Thomas Lamprecht
2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 2/6] ui: remove unused booleanfield Dominik Csapak
2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 3/6] ui: refactor ui option related methods into UIOptions Dominik Csapak
2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 4/6] ui: refactor refreshing the the resource store/tree Dominik Csapak
2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 5/6] ui: add window for changing tree related options Dominik Csapak
2023-02-09 10:33   ` Aaron Lauterer
2023-02-02 14:41 ` [pve-devel] [PATCH manager v2 6/6] fix #1408: ui: ResourceTree: sort the tree according to tree-sorting options Dominik Csapak
2023-02-09 10:34 ` [pve-devel] [PATCH manager v2 0/6] fix #1408: ui: make tree sorting configurable Aaron Lauterer

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