[pve-devel] [PATCH v3 proxmox-widget-toolkit 63/66] notification: add gui for notification groups
Dominik Csapak
d.csapak at proxmox.com
Wed Jul 19 15:32:50 CEST 2023
comments inline
On 7/17/23 17:00, Lukas Wagner wrote:
> Signed-off-by: Lukas Wagner <l.wagner at 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';
More information about the pve-devel
mailing list