Signed-off-by: Lukas Wagner <l.wag...@proxmox.com>
---
 www/manager6/Makefile                 |   1 +
 www/manager6/dc/Config.js             |  12 ++
 www/manager6/dc/NotificationEvents.js | 238 ++++++++++++++++++++++++++
 3 files changed, 251 insertions(+)
 create mode 100644 www/manager6/dc/NotificationEvents.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index 140b20f0..452abbd4 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -158,6 +158,7 @@ JSSRC=                                                      
\
        dc/Health.js                                    \
        dc/Log.js                                       \
        dc/NodeView.js                                  \
+       dc/NotificationEvents.js                        \
        dc/OptionView.js                                \
        dc/PermissionView.js                            \
        dc/PoolEdit.js                                  \
diff --git a/www/manager6/dc/Config.js b/www/manager6/dc/Config.js
index 04ed04f0..aa025c8d 100644
--- a/www/manager6/dc/Config.js
+++ b/www/manager6/dc/Config.js
@@ -317,6 +317,18 @@ Ext.define('PVE.dc.Config', {
            );
        }
 
+       if (caps.dc['Sys.Audit']) {
+           me.items.push(
+               {
+                   xtype: 'pveNotificationEvents',
+                   title: gettext('Notifications'),
+                   onlineHelp: 'notification_events',
+                   iconCls: 'fa fa-bell-o',
+                   itemId: 'notifications',
+               },
+           );
+       }
+
        if (caps.dc['Sys.Audit']) {
            me.items.push({
                xtype: 'pveDcSupport',
diff --git a/www/manager6/dc/NotificationEvents.js 
b/www/manager6/dc/NotificationEvents.js
new file mode 100644
index 00000000..8ba0a844
--- /dev/null
+++ b/www/manager6/dc/NotificationEvents.js
@@ -0,0 +1,238 @@
+Ext.define('PVE.dc.NotificationEventsPolicySelector', {
+    alias: ['widget.pveNotificationEventsPolicySelector'],
+    extend: 'Proxmox.form.KVComboBox',
+    deleteEmpty: false,
+    value: '__default__',
+    comboItems: [
+       ['__default__', `${Proxmox.Utils.defaultText} (always)`],
+       ['always', gettext('Always')],
+       ['never', gettext('Never')],
+    ],
+    defaultValue: '__default__',
+});
+
+Ext.define('PVE.dc.NotificationEventsTargetSelector', {
+    alias: ['widget.pveNotificationEventsTargetSelector'],
+    extend: 'PVE.form.NotificationTargetSelector',
+    fieldLabel: gettext('Notification Target'),
+    allowBlank: true,
+    editable: true,
+    autoSelect: false,
+    deleteEmpty: false,
+    emptyText: `${Proxmox.Utils.defaultText} (${gettext("mail-to-root")})`,
+});
+
+Ext.define('PVE.dc.NotificationEvents', {
+    extend: 'Proxmox.grid.ObjectGrid',
+    alias: ['widget.pveNotificationEvents'],
+
+    // Taken from OptionView.js, but adapted slightly.
+    addInputPanelRow: function(name, propertyName, text, opts) {
+       let me = this;
+
+       opts = opts || {};
+       me.rows = me.rows || {};
+
+       me.rows[name] = {
+           required: true,
+           defaultValue: opts.defaultValue,
+           header: text,
+           renderer: opts.renderer,
+           name: propertyName,
+           editor: {
+               xtype: 'proxmoxWindowEdit',
+               width: opts.width || 400,
+               subject: text,
+               onlineHelp: opts.onlineHelp,
+               fieldDefaults: {
+                   labelWidth: opts.labelWidth || 150,
+               },
+               setValues: function(values) {
+                   let value = values[propertyName];
+
+                   if (opts.parseBeforeSet) {
+                       value = PVE.Parser.parsePropertyString(value);
+                   }
+
+                   Ext.Array.each(this.query('inputpanel'), function(panel) {
+                       panel.setValues(value);
+                       panel.originalValue = {
+                           ...value,
+                       };
+                   });
+               },
+               url: opts.url,
+               items: [{
+                   xtype: 'inputpanel',
+                   onGetValues: function(values) {
+                       let fields = this.config.items.map(field => 
field.name).filter(n => n);
+
+                       for (const [key, value] of 
Object.entries(this.originalValue)) {
+                           if (!fields.includes(key)) {
+                               values[key] = value;
+                           }
+                       }
+
+                       let value = {};
+                       if (Object.keys(values).length > 0) {
+                           value[propertyName] = 
PVE.Parser.printPropertyString(values);
+                       } else {
+                           Proxmox.Utils.assemble_field_data(value, { 
'delete': propertyName });
+                       }
+
+                       return value;
+                   },
+                   items: opts.items,
+               }],
+           },
+       };
+    },
+
+    initComponent: function() {
+       let me = this;
+
+       // Helper function for rendering the property
+       // Needed since the actual value is always stored in the 'notify' 
property
+       let render_value = (store, target_key, mode_key) => {
+           let value = store.getById('notify')?.get('value') ?? {};
+           let target = value[target_key] ?? gettext('mail-to-root');
+           let template;
+
+           switch (value[mode_key]) {
+               case 'always':
+                   template = gettext('Always, notify via target \'{0}\'');
+                   break;
+               case 'never':
+                   template = gettext('Never');
+                   break;
+               default:
+                   template = gettext('{1} (Always), notify via target 
\'{0}\'');
+                   break;
+           }
+
+           return Ext.String.format(template, target, 
Proxmox.Utils.defaultText);
+       };
+
+       me.addInputPanelRow('fencing', 'notify', gettext('Node Fencing'), {
+           renderer: (value, metaData, record, rowIndex, colIndex, store) =>
+               render_value(store, 'target-fencing', 'fencing'),
+           url: "/api2/extjs/cluster/options",
+           items: [
+               {
+                   xtype: 'pveNotificationEventsPolicySelector',
+                   name: 'fencing',
+                   fieldLabel: gettext('Notify'),
+               },
+               {
+                   xtype: 'pveNotificationEventsTargetSelector',
+                   name: 'target-fencing',
+               },
+               {
+                   xtype: 'displayfield',
+                   userCls: 'pmx-hint',
+                   value: gettext('Disabling notifications is not ' +
+                       'recommended for production systems!'),
+               },
+           ],
+       });
+
+       me.addInputPanelRow('replication', 'notify', gettext('Replication'), {
+           renderer: (value, metaData, record, rowIndex, colIndex, store) =>
+               render_value(store, 'target-replication', 'replication'),
+           url: "/api2/extjs/cluster/options",
+           items: [
+               {
+                   xtype: 'pveNotificationEventsPolicySelector',
+                   name: 'replication',
+                   fieldLabel: gettext('Notify'),
+               },
+               {
+                   xtype: 'pveNotificationEventsTargetSelector',
+                   name: 'target-replication',
+               },
+               {
+                   xtype: 'displayfield',
+                   userCls: 'pmx-hint',
+                   value: gettext('Disabling notifications is not ' +
+                       'recommended for production systems!'),
+               },
+           ],
+       });
+
+       me.addInputPanelRow('updates', 'notify', gettext('Package Updates'), {
+           renderer: (value, metaData, record, rowIndex, colIndex, store) => {
+               value = store.getById('notify')?.get('value') ?? {};
+               let target = value['target-package-updates'] ?? 
gettext('mail-to-root');
+               let template;
+
+               switch (value['package-updates']) {
+                   case 'always':
+                       template = gettext('Always, notify via \'{0}\'');
+                       break;
+                   case 'auto':
+                       template = gettext('Automatically, notify via target 
\'{0}\'');
+                       break;
+                   case 'never':
+                       template = gettext('Never');
+                       break;
+                   default:
+                       template = gettext('{1} (Automatically), notify via 
target \'{0}\'');
+                       break;
+               }
+
+               return Ext.String.format(template, target, 
Proxmox.Utils.defaultText);
+           },
+           url: "/api2/extjs/cluster/options",
+           items: [
+               {
+                   xtype: 'pveNotificationEventsPolicySelector',
+                   name: 'package-updates',
+                   fieldLabel: gettext('Notify'),
+                   comboItems: [
+                       ['__default__', Proxmox.Utils.defaultText + ' (auto)'],
+                       ['auto', gettext('Automatically')],
+                       ['always', gettext('Always')],
+                       ['never', gettext('Never')],
+                   ],
+               },
+               {
+                   xtype: 'pveNotificationEventsTargetSelector',
+                   name: 'target-package-updates',
+               },
+           ],
+       });
+
+       // Hack: Also load the notify property to make it accessible
+       // for our render functions. initComponents later hides it.
+       me.add_text_row('notify', gettext('Notify'), {});
+
+       me.selModel = Ext.create('Ext.selection.RowModel', {});
+
+       Ext.apply(me, {
+           tbar: [{
+               text: gettext('Edit'),
+               xtype: 'proxmoxButton',
+               disabled: true,
+               handler: () => me.run_editor(),
+               selModel: me.selModel,
+           }],
+           url: "/api2/json/cluster/options",
+           editorConfig: {
+               url: "/api2/extjs/cluster/options",
+           },
+           interval: 5000,
+           cwidth1: 200,
+           listeners: {
+               itemdblclick: me.run_editor,
+           },
+       });
+
+       me.callParent();
+
+       me.rows.notify.visible = false;
+
+       me.on('activate', me.rstore.startUpdate);
+       me.on('destroy', me.rstore.stopUpdate);
+       me.on('deactivate', me.rstore.stopUpdate);
+    },
+});
-- 
2.39.2



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

Reply via email to