[pbs-devel] [PATCH v4 proxmox-backup 6/6] ui: add option to change the maintenance type

Hannes Laimer h.laimer at proxmox.com
Fri Nov 12 13:30:19 CET 2021


---
The renderer is set in the init function because a context where view is
accessable was needed. Since only the renderer function needs this
context the rest of the 'maintenance-type' row is defined declaratively.
I also tried to somehow inject the active operations values into the
store, since its passed to the renderer function, but that seemed a little
'hacky'.

 www/Makefile                     |  1 +
 www/Utils.js                     | 23 ++++++++++
 www/datastore/OptionView.js      | 30 +++++++++++++
 www/window/MaintenanceOptions.js | 72 ++++++++++++++++++++++++++++++++
 4 files changed, 126 insertions(+)
 create mode 100644 www/window/MaintenanceOptions.js

diff --git a/www/Makefile b/www/Makefile
index 4aec6e2c..8f6b17ed 100644
--- a/www/Makefile
+++ b/www/Makefile
@@ -63,6 +63,7 @@ JSSRC=							\
 	window/BackupGroupChangeOwner.js		\
 	window/CreateDirectory.js			\
 	window/DataStoreEdit.js				\
+	window/MaintenanceOptions.js			\
 	window/NotesEdit.js				\
 	window/RemoteEdit.js				\
 	window/NotifyOptions.js				\
diff --git a/www/Utils.js b/www/Utils.js
index 36a94211..db23645a 100644
--- a/www/Utils.js
+++ b/www/Utils.js
@@ -640,4 +640,27 @@ Ext.define('PBS.Utils', {
 	return `${icon} ${value}`;
     },
 
+    renderMaintenance: function(type, activeTasks) {
+	if (!type) return gettext('None');
+	let at = 0;
+	for (let x of ['read-only-', 'offline-']) {
+	    if (type.startsWith(x)) {
+	        at = x.length;
+	    }
+	}
+
+	const conflictingTasks = activeTasks.write + (type.startsWith('offline') ? activeTasks.read : 0);
+	const checkmarkIcon = '<i class="fa fa-check"></i>';
+	const spinnerIcon = '<i class="fa fa-spinner fa-pulse fa-fw"></i>';
+	const conflictingTasksMessage = `<i>${conflictingTasks} conflicting tasks still active</i>`;
+	const extra = conflictingTasks > 0 ? `| ${spinnerIcon} ${conflictingTasksMessage}` : checkmarkIcon;
+
+	const mode = type.substring(0, at-1);
+	let msg = type.substring(at);
+	if (msg.length > 0) {
+	    msg = `"${msg}"`;
+	}
+	return Ext.String.capitalize(`${gettext(mode)} ${msg} ${extra}`) || gettext('None');
+    },
+
 });
diff --git a/www/datastore/OptionView.js b/www/datastore/OptionView.js
index 5a5e85be..50ccce47 100644
--- a/www/datastore/OptionView.js
+++ b/www/datastore/OptionView.js
@@ -1,3 +1,4 @@
+
 Ext.define('PBS.Datastore.Options', {
     extend: 'Proxmox.grid.ObjectGrid',
     xtype: 'pbsDatastoreOptionView',
@@ -6,6 +7,10 @@ Ext.define('PBS.Datastore.Options', {
     cbindData: function(initial) {
 	let me = this;
 
+	me.maintenanceActiveTasks = {
+	    read: 0,
+	    write: 0,
+	};
 	me.datastore = encodeURIComponent(me.datastore);
 	me.url = `/api2/json/config/datastore/${me.datastore}`;
 	me.editorConfig = {
@@ -18,6 +23,24 @@ Ext.define('PBS.Datastore.Options', {
     controller: {
 	xclass: 'Ext.app.ViewController',
 
+	init: function(view) {
+	    let me = this;
+	    me.callParent();
+	    view.rows['maintenance-type'].renderer =
+		(value) => PBS.Utils.renderMaintenance(value, view.maintenanceActiveTasks);
+
+	    me.activeOperationsRstore = Ext.create('Proxmox.data.ObjectStore', {
+		url: `/api2/json/admin/datastore/${view.datastore}/active-operations`,
+		interval: 3000,
+	    });
+	    me.activeOperationsRstore.startUpdate();
+
+	    view.mon(me.activeOperationsRstore, 'load', (store, data, success) => {
+		me.view.maintenanceActiveTasks.read = data[0].data.value;
+		me.view.maintenanceActiveTasks.write = data[1].data.value;
+	    });
+	},
+
 	edit: function() {
 	    this.getView().run_editor();
 	},
@@ -111,5 +134,12 @@ Ext.define('PBS.Datastore.Options', {
 		},
 	    },
 	},
+	"maintenance-type": {
+	    required: true,
+	    header: gettext('Maintenance mode'),
+	    editor: {
+		xtype: 'pbsMaintenanceOptionEdit',
+	    },
+	},
     },
 });
diff --git a/www/window/MaintenanceOptions.js b/www/window/MaintenanceOptions.js
new file mode 100644
index 00000000..374b69f6
--- /dev/null
+++ b/www/window/MaintenanceOptions.js
@@ -0,0 +1,72 @@
+Ext.define('PBS.form.oaintenanceType', {
+    extend: 'Proxmox.form.KVComboBox',
+    alias: 'widget.pbsMaintenanceType',
+
+    comboItems: [
+	['__default__', gettext('None')],
+	['read-only', gettext('Read only')],
+	['offline', gettext('Offline')],
+    ],
+});
+
+Ext.define('PBS.window.MaintenanceOptions', {
+    extend: 'Proxmox.window.Edit',
+    xtype: 'pbsMaintenanceOptionEdit',
+    mixins: ['Proxmox.Mixin.CBind'],
+
+    subject: gettext('Maintenance mode'),
+
+    width: 450,
+    fieldDefaults: {
+	labelWidth: 120,
+    },
+
+    items: {
+	onGetValues: function(values) {
+	    console.log(values);
+	    if (values['maintenance-type']) {
+		values['maintenance-type'] =
+		    `${values['maintenance-type']}-${values['maintenance-msg'] || ''}`;
+	    }
+	    return values;
+	},
+	xtype: 'inputpanel',
+	items: [
+	    {
+		xtype: 'pbsMaintenanceType',
+		name: 'maintenance-type',
+		fieldLabel: gettext('Maintenance Type'),
+		value: '__default__',
+		deleteEmpty: true,
+	    },
+	    {
+		xtype: 'proxmoxtextfield',
+		name: 'maintenance-msg',
+		fieldLabel: gettext('Description'),
+	    },
+	],
+    },
+    setValues: function(values) {
+	let me = this;
+
+	let options = {
+	    'maintenance-type': '__default__',
+	    'maintenance-msg': '',
+	};
+	if (values['maintenance-type']) {
+	    let type = values['maintenance-type'];
+	    let at = 0;
+	    for (let x of ['read-only-', 'offline-']) {
+		if (type.startsWith(x)) {
+		    at = x.length;
+		}
+	    }
+	    options = {
+		'maintenance-type': type.substr(0, at-1) || '__default__',
+		'maintenance-msg': type.substr(at) || '',
+	    };
+	}
+
+	me.callParent([options]);
+    },
+});
-- 
2.30.2





More information about the pbs-devel mailing list