[pve-devel] [PATCH v6 proxmox-widget-toolkit 27/30] notification: add gui for notification groups
Lukas Wagner
l.wagner at proxmox.com
Thu Aug 3 14:17:16 CEST 2023
The GUI is based on the 'plugin-based' dialog window EndpointEditBase
that was introduced in an earlier commit.
Signed-off-by: Lukas Wagner <l.wagner at proxmox.com>
---
Notes:
Changes since v5:
- Extended commit message
Changes since v3:
- Use items/advancedItems instead of columns
- Call initField in EndpointSelector
- Minor code style improvements
src/Makefile | 1 +
src/Schema.js | 5 +
src/panel/NotificationGroupEditPanel.js | 174 ++++++++++++++++++++++++
src/window/EndpointEditBase.js | 6 +-
4 files changed, 185 insertions(+), 1 deletion(-)
create mode 100644 src/panel/NotificationGroupEditPanel.js
diff --git a/src/Makefile b/src/Makefile
index 2e620e3..829081d 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -61,6 +61,7 @@ JSSRC= \
panel/LogView.js \
panel/NodeInfoRepoStatus.js \
panel/NotificationConfigView.js \
+ panel/NotificationGroupEditPanel.js \
panel/JournalView.js \
panel/PermissionView.js \
panel/PruneKeepPanel.js \
diff --git a/src/Schema.js b/src/Schema.js
index 37ecd88..a7ffdf8 100644
--- a/src/Schema.js
+++ b/src/Schema.js
@@ -48,6 +48,11 @@ Ext.define('Proxmox.Schema', { // a singleton
ipanel: 'pmxGotifyEditPanel',
iconCls: 'fa-bell-o',
},
+ group: {
+ name: gettext('Notification Group'),
+ ipanel: 'pmxNotificationGroupEditPanel',
+ iconCls: 'fa-bell-o',
+ },
},
pxarFileTypes: {
diff --git a/src/panel/NotificationGroupEditPanel.js b/src/panel/NotificationGroupEditPanel.js
new file mode 100644
index 0000000..910d15a
--- /dev/null
+++ b/src/panel/NotificationGroupEditPanel.js
@@ -0,0 +1,174 @@
+Ext.define('Proxmox.panel.NotificationGroupEditPanel', {
+ extend: 'Proxmox.panel.InputPanel',
+ xtype: 'pmxNotificationGroupEditPanel',
+ mixins: ['Proxmox.Mixin.CBind'],
+
+ type: 'group',
+
+ items: [
+ {
+ xtype: 'pmxDisplayEditField',
+ name: 'name',
+ cbind: {
+ value: '{name}',
+ editable: '{isCreate}',
+ },
+ fieldLabel: gettext('Group Name'),
+ allowBlank: false,
+ },
+ {
+ xtype: 'pmxNotificationEndpointSelector',
+ name: 'endpoint',
+ allowBlank: false,
+ },
+ {
+ xtype: 'proxmoxtextfield',
+ name: 'comment',
+ fieldLabel: gettext('Comment'),
+ cbind: {
+ deleteEmpty: '{!isCreate}',
+ },
+ },
+ ],
+});
+
+Ext.define('Proxmox.form.NotificationEndpointSelector', {
+ extend: 'Ext.grid.Panel',
+ alias: 'widget.pmxNotificationEndpointSelector',
+
+ mixins: {
+ field: 'Ext.form.field.Field',
+ },
+
+ padding: '0 0 10 0',
+
+ allowBlank: true,
+ selectAll: false,
+ isFormField: true,
+
+ store: {
+ autoLoad: true,
+ model: 'proxmox-notification-endpoints',
+ sorters: 'name',
+ filters: item => item.data.type !== 'group',
+ },
+
+ columns: [
+ {
+ header: gettext('Endpoint Name'),
+ dataIndex: 'name',
+ flex: 1,
+ },
+ {
+ header: gettext('Type'),
+ dataIndex: 'type',
+ flex: 1,
+ },
+ {
+ header: gettext('Comment'),
+ dataIndex: 'comment',
+ flex: 3,
+ },
+ ],
+
+ selModel: {
+ selType: 'checkboxmodel',
+ mode: 'SIMPLE',
+ },
+
+ checkChangeEvents: [
+ 'selectionchange',
+ 'change',
+ ],
+
+ listeners: {
+ selectionchange: function() {
+ // to trigger validity and error checks
+ this.checkChange();
+ },
+ },
+
+ getSubmitData: function() {
+ let me = this;
+ let res = {};
+ res[me.name] = me.getValue();
+ return res;
+ },
+
+ getValue: function() {
+ let me = this;
+ if (me.savedValue !== undefined) {
+ return me.savedValue;
+ }
+ let sm = me.getSelectionModel();
+ return (sm.getSelection() ?? []).map(item => item.data.name);
+ },
+
+ setValueSelection: function(value) {
+ let me = this;
+
+ let store = me.getStore();
+
+ let notFound = [];
+ let selection = value.map(item => {
+ let found = store.findRecord('name', item, 0, false, true, true);
+ if (!found) {
+ notFound.push(item);
+ }
+ return found;
+ }).filter(r => r);
+
+ for (const name of notFound) {
+ let rec = store.add({
+ name,
+ type: '-',
+ comment: gettext('Included endpoint does not exist!'),
+ });
+ selection.push(rec[0]);
+ }
+
+ let sm = me.getSelectionModel();
+ if (selection.length) {
+ sm.select(selection);
+ } else {
+ sm.deselectAll();
+ }
+ // to correctly trigger invalid class
+ me.getErrors();
+ },
+
+ setValue: function(value) {
+ let me = this;
+
+ let store = me.getStore();
+ if (!store.isLoaded()) {
+ me.savedValue = value;
+ store.on('load', function() {
+ me.setValueSelection(value);
+ delete me.savedValue;
+ }, { single: true });
+ } else {
+ me.setValueSelection(value);
+ }
+ return me.mixins.field.setValue.call(me, value);
+ },
+
+ getErrors: function(value) {
+ let me = this;
+ if (!me.isDisabled() && me.allowBlank === false &&
+ me.getSelectionModel().getCount() === 0) {
+ me.addBodyCls(['x-form-trigger-wrap-default', 'x-form-trigger-wrap-invalid']);
+ return [gettext('No endpoint selected')];
+ }
+
+ me.removeBodyCls(['x-form-trigger-wrap-default', 'x-form-trigger-wrap-invalid']);
+ return [];
+ },
+
+ initComponent: function() {
+ let me = this;
+ me.callParent();
+ me.initField();
+ },
+
+});
diff --git a/src/window/EndpointEditBase.js b/src/window/EndpointEditBase.js
index 7e4c910..9230b99 100644
--- a/src/window/EndpointEditBase.js
+++ b/src/window/EndpointEditBase.js
@@ -18,7 +18,11 @@ Ext.define('Proxmox.window.EndpointEditBase', {
throw "baseUrl not set";
}
- me.url = `/api2/extjs${me.baseUrl}/endpoints/${me.type}`;
+ if (me.type === 'group') {
+ me.url = `/api2/extjs${me.baseUrl}/groups`;
+ } else {
+ me.url = `/api2/extjs${me.baseUrl}/endpoints/${me.type}`;
+ }
if (me.isCreate) {
me.method = 'POST';
--
2.39.2
More information about the pve-devel
mailing list