[pve-devel] [PATCH manager 3/3] ui: ceph pool edit: rework with controller and formulas

Aaron Lauterer a.lauterer at proxmox.com
Fri Jan 13 16:09:30 CET 2023


instead of relying purely on listeners that then manually change other
components, we can use binds, formulas and a basic controller.

This makes it quite a bit easier to let multiple components react to
changes.

A cbind is used for the size component to set the initial start value.
Other options, like using setValue in the controller init, will trigger
the change listener and therefore can affect the min size without any
user interaction.

Signed-off-by: Aaron Lauterer <a.lauterer at proxmox.com>
---
 www/manager6/ceph/Pool.js | 87 ++++++++++++++++++++++++++++-----------
 1 file changed, 63 insertions(+), 24 deletions(-)

diff --git a/www/manager6/ceph/Pool.js b/www/manager6/ceph/Pool.js
index 86f83ffb..a38c5b3f 100644
--- a/www/manager6/ceph/Pool.js
+++ b/www/manager6/ceph/Pool.js
@@ -7,6 +7,49 @@ Ext.define('PVE.CephPoolInputPanel', {
     onlineHelp: 'pve_ceph_pools',
 
     subject: 'Ceph Pool',
+
+    viewModel: {
+	data: {
+	    minSize: null,
+	    size: null,
+	},
+	formulas: {
+	    minSizeLabel: (get) => {
+		if (get('showMinSizeOneWarning') || get('showMinSizeHalfWarning')) {
+		    return `${gettext('Min. Size')} <i class="fa fa-exclamation-triangle warning"></i>`;
+		}
+		return gettext('Min. Size');
+	    },
+	    showMinSizeOneWarning: (get) => get('minSize') === 1,
+	    showMinSizeHalfWarning: (get) => {
+		let minSize = get('minSize');
+		let size = get('size');
+		if (minSize === 1) {
+		    return false;
+		}
+		return minSize < (size / 2) && minSize !== size;
+	    },
+	},
+    },
+
+    controller: {
+	xclass: 'Ext.app.ViewController',
+
+	init: function(view) {
+	    let vm = this.getViewModel();
+	    vm.set('size', view.defaultSize ? Number(view.defaultSize) : 3);
+	    vm.set('minSize', view.defaultMinSize ? Number(view.defaultMinSize) : 2);
+	},
+	sizeChange: function(field, val) {
+	    let vm = this.getViewModel();
+	    let minSize = Math.round(val / 2);
+	    if (minSize > 1) {
+		vm.set('minSize', minSize);
+	    }
+	    vm.set('size', val); // bind does not work in a pmxDisplayEditField, update manually
+	},
+    },
+
     column1: [
 	{
 	    xtype: 'pmxDisplayEditField',
@@ -34,12 +77,7 @@ Ext.define('PVE.CephPoolInputPanel', {
 		maxValue: 7,
 		allowBlank: false,
 		listeners: {
-		    change: function(field, val) {
-			let size = Math.round(val / 2);
-			if (size > 1) {
-			    field.up('inputpanel').down('field[name=min_size]').setValue(size);
-			}
-		    },
+		    change: 'sizeChange',
 		},
 	    },
 	},
@@ -77,10 +115,13 @@ Ext.define('PVE.CephPoolInputPanel', {
     advancedColumn1: [
 	{
 	    xtype: 'proxmoxintegerfield',
-	    fieldLabel: gettext('Min. Size'),
+	    bind: {
+		fieldLabel: '{minSizeLabel}',
+		value: '{minSize}',
+	    },
 	    name: 'min_size',
+	    reference: 'min_size',
 	    cbind: {
-		value: (get) => get('defaultMinSize') ?? 2,
 		minValue: (get) => {
 		    if (Number(get('defaultMinSize')) === 1) {
 			return 1;
@@ -91,28 +132,26 @@ Ext.define('PVE.CephPoolInputPanel', {
 	    },
 	    maxValue: 7,
 	    allowBlank: false,
-	    listeners: {
-		change: function(field, minSize) {
-		    let panel = field.up('inputpanel');
-		    let size = panel.down('field[name=size]').getValue();
-
-		    let showWarning = minSize < (size / 2) && minSize !== size;
-
-		    let fieldLabel = gettext('Min. Size');
-		    if (showWarning) {
-			fieldLabel = gettext('Min. Size') + ' <i class="fa fa-exclamation-triangle warning"></i>';
-		    }
-		    panel.down('field[name=min_size-warning]').setHidden(!showWarning);
-		    field.setFieldLabel(fieldLabel);
-		},
-	    },
 	},
 	{
 	    xtype: 'displayfield',
-	    name: 'min_size-warning',
+	    name: 'min_size_half-warning',
+	    bind: {
+		hidden: '{!showMinSizeHalfWarning}',
+	    },
+	    hidden: true,
 	    userCls: 'pmx-hint',
 	    value: gettext('min_size < size/2 can lead to data loss, incomplete PGs or unfound objects.'),
+	},
+	{
+	    xtype: 'displayfield',
+	    name: 'min_size_one-warning',
+	    bind: {
+		hidden: '{!showMinSizeOneWarning}',
+	    },
 	    hidden: true,
+	    userCls: 'pmx-hint',
+	    value: gettext('a min_size of 1 is not recommended and can lead to data loss'),
 	},
 	{
 	    xtype: 'pmxDisplayEditField',
-- 
2.30.2






More information about the pve-devel mailing list