comments inline

On 7/17/23 17:00, Lukas Wagner wrote:
Signed-off-by: Lukas Wagner <l.wag...@proxmox.com>
---
  src/Makefile                            |   1 +
  src/Schema.js                           |   5 +
  src/panel/NotificationGroupEditPanel.js | 177 ++++++++++++++++++++++++
  src/window/EndpointEditBase.js          |   6 +-
  4 files changed, 188 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..0a7a469
--- /dev/null
+++ b/src/panel/NotificationGroupEditPanel.js
@@ -0,0 +1,177 @@
+Ext.define('Proxmox.panel.NotificationGroupEditPanel', {
+    extend: 'Proxmox.panel.InputPanel',
+    xtype: 'pmxNotificationGroupEditPanel',
+    mixins: ['Proxmox.Mixin.CBind'],
+
+    type: 'group',
+
+    columnT: [
+       {
+           xtype: 'pmxDisplayEditField',
+           name: 'name',
+           cbind: {
+               value: '{name}',
+               editable: '{isCreate}',
+           },
+           fieldLabel: gettext('Group Name'),
+           allowBlank: false,
+       },
+       {
+           xtype: 'pmxNotificationEndpointSelector',
+           name: 'endpoint',
+           allowBlank: false,
+       },
+    ],
+
+    column1: [],
+
+    column2: [],
+
+    columnB: [
+       {
+           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',
+    },

when implementing the field mixin you have to (quote from the extjs docs)

---8<---
You will also need to make sure that initField is called during the component's 
initialization.
--->8---

so you normally need a (small) initComponent that calls that
(otherwise you can have some strange effects when using the field)

+
+    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();
+       let selection = sm.getSelection();
+       let values = [];
+       selection.forEach(function(item) {
+           values.push(item.data.name);
+       });
+       return values;

could also be:

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 [];
+    },
+});
diff --git a/src/window/EndpointEditBase.js b/src/window/EndpointEditBase.js
index 81e5951..bcf6879 100644
--- a/src/window/EndpointEditBase.js
+++ b/src/window/EndpointEditBase.js
@@ -16,7 +16,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';



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to