notification: add gui for notification groups
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@proxmox.com> Reviewed-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
parent
6669a59fd1
commit
ea5aa12261
@ -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 \
|
||||
|
@ -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: {
|
||||
|
174
src/panel/NotificationGroupEditPanel.js
Normal file
174
src/panel/NotificationGroupEditPanel.js
Normal file
@ -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();
|
||||
},
|
||||
|
||||
});
|
@ -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';
|
||||
|
Loading…
Reference in New Issue
Block a user