panel: notification: add gui for SMTP endpoints

This new endpoint configuration panel is embedded in the existing
EndpointEditBase dialog window. This commit also factors out some of
the non-trivial common form elements that are shared between the new
panel and the already existing SendmailEditPanel into a separate panel
EmailRecipientPanel.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
This commit is contained in:
Lukas Wagner 2023-11-14 13:59:51 +01:00 committed by Thomas Lamprecht
parent de0cec409a
commit 3003f37779
5 changed files with 281 additions and 55 deletions

View File

@ -71,7 +71,9 @@ JSSRC= \
panel/ACMEAccount.js \
panel/ACMEPlugin.js \
panel/ACMEDomains.js \
panel/EmailRecipientPanel.js \
panel/SendmailEditPanel.js \
panel/SmtpEditPanel.js \
panel/StatusView.js \
panel/TfaView.js \
panel/NotesView.js \

View File

@ -43,6 +43,11 @@ Ext.define('Proxmox.Schema', { // a singleton
ipanel: 'pmxSendmailEditPanel',
iconCls: 'fa-envelope-o',
},
smtp: {
name: gettext('SMTP'),
ipanel: 'pmxSmtpEditPanel',
iconCls: 'fa-envelope-o',
},
gotify: {
name: 'Gotify',
ipanel: 'pmxGotifyEditPanel',

View File

@ -0,0 +1,88 @@
Ext.define('Proxmox.panel.EmailRecipientPanel', {
extend: 'Ext.panel.Panel',
xtype: 'pmxEmailRecipientPanel',
mixins: ['Proxmox.Mixin.CBind'],
border: false,
mailValidator: function() {
let mailto_user = this.down(`[name=mailto-user]`);
let mailto = this.down(`[name=mailto]`);
if (!mailto_user.getValue()?.length && !mailto.getValue()) {
return gettext('Either mailto or mailto-user must be set');
}
return true;
},
items: [
{
layout: 'anchor',
border: false,
items: [
{
xtype: 'pmxUserSelector',
name: 'mailto-user',
multiSelect: true,
allowBlank: true,
editable: false,
skipEmptyText: true,
fieldLabel: gettext('Recipient(s)'),
cbind: {
deleteEmpty: '{!isCreate}',
},
validator: function() {
return this.up('pmxEmailRecipientPanel').mailValidator();
},
autoEl: {
tag: 'div',
'data-qtip': gettext('The notification will be sent to the user\'s configured mail address'),
},
listConfig: {
width: 600,
columns: [
{
header: gettext('User'),
sortable: true,
dataIndex: 'userid',
renderer: Ext.String.htmlEncode,
flex: 1,
},
{
header: gettext('E-Mail'),
sortable: true,
dataIndex: 'email',
renderer: Ext.String.htmlEncode,
flex: 1,
},
{
header: gettext('Comment'),
sortable: false,
dataIndex: 'comment',
renderer: Ext.String.htmlEncode,
flex: 1,
},
],
},
},
{
xtype: 'proxmoxtextfield',
fieldLabel: gettext('Additional Recipient(s)'),
name: 'mailto',
allowBlank: true,
emptyText: 'user@example.com, ...',
cbind: {
deleteEmpty: '{!isCreate}',
},
autoEl: {
tag: 'div',
'data-qtip': gettext('Multiple recipients must be separated by spaces, commas or semicolons'),
},
validator: function() {
return this.up('pmxEmailRecipientPanel').mailValidator();
},
},
],
},
],
});

View File

@ -28,62 +28,10 @@ Ext.define('Proxmox.panel.SendmailEditPanel', {
allowBlank: false,
},
{
xtype: 'pmxUserSelector',
name: 'mailto-user',
reference: 'mailto-user',
multiSelect: true,
allowBlank: true,
editable: false,
skipEmptyText: true,
fieldLabel: gettext('User(s)'),
// provides 'mailto' and 'mailto-user' fields
xtype: 'pmxEmailRecipientPanel',
cbind: {
deleteEmpty: '{!isCreate}',
},
validator: function() {
return this.up('pmxSendmailEditPanel').mailValidator();
},
listConfig: {
width: 600,
columns: [
{
header: gettext('User'),
sortable: true,
dataIndex: 'userid',
renderer: Ext.String.htmlEncode,
flex: 1,
},
{
header: gettext('E-Mail'),
sortable: true,
dataIndex: 'email',
renderer: Ext.String.htmlEncode,
flex: 1,
},
{
header: gettext('Comment'),
sortable: false,
dataIndex: 'comment',
renderer: Ext.String.htmlEncode,
flex: 1,
},
],
},
},
{
xtype: 'proxmoxtextfield',
fieldLabel: gettext('Additional Recipient(s)'),
name: 'mailto',
reference: 'mailto',
allowBlank: true,
cbind: {
deleteEmpty: '{!isCreate}',
},
autoEl: {
tag: 'div',
'data-qtip': gettext('Multiple recipients must be separated by spaces, commas or semicolons'),
},
validator: function() {
return this.up('pmxSendmailEditPanel').mailValidator();
isCreate: '{isCreate}',
},
},
{

183
src/panel/SmtpEditPanel.js Normal file
View File

@ -0,0 +1,183 @@
Ext.define('Proxmox.panel.SmtpEditPanel', {
extend: 'Proxmox.panel.InputPanel',
xtype: 'pmxSmtpEditPanel',
mixins: ['Proxmox.Mixin.CBind'],
type: 'smtp',
viewModel: {
xtype: 'viewmodel',
cbind: {
isCreate: "{isCreate}",
},
data: {
mode: 'tls',
authentication: true,
},
formulas: {
portEmptyText: function(get) {
let port;
switch (get('mode')) {
case 'insecure':
port = 25;
break;
case 'starttls':
port = 587;
break;
case 'tls':
port = 465;
break;
}
return `${Proxmox.Utils.defaultText} (${port})`;
},
passwordEmptyText: function(get) {
let isCreate = this.isCreate;
return get('authentication') && !isCreate ? gettext('Unchanged') : '';
},
},
},
columnT: [
{
xtype: 'pmxDisplayEditField',
name: 'name',
cbind: {
value: '{name}',
editable: '{isCreate}',
},
fieldLabel: gettext('Endpoint Name'),
allowBlank: false,
},
],
column1: [
{
xtype: 'proxmoxtextfield',
fieldLabel: gettext('Server'),
name: 'server',
allowBlank: false,
emptyText: gettext('mail.example.com'),
},
{
xtype: 'proxmoxKVComboBox',
name: 'mode',
fieldLabel: gettext('Encryption'),
editable: false,
comboItems: [
['insecure', Proxmox.Utils.noneText + ' (' + gettext('insecure') + ')'],
['starttls', 'STARTTLS'],
['tls', 'TLS'],
],
bind: "{mode}",
cbind: {
deleteEmpty: '{!isCreate}',
},
},
{
xtype: 'proxmoxintegerfield',
name: 'port',
fieldLabel: gettext('Port'),
minValue: 1,
maxValue: 65535,
bind: {
emptyText: "{portEmptyText}",
},
submitEmptyText: false,
cbind: {
deleteEmpty: '{!isCreate}',
},
},
],
column2: [
{
xtype: 'proxmoxcheckbox',
fieldLabel: gettext('Authenticate'),
name: 'authentication',
bind: {
value: '{authentication}',
},
},
{
xtype: 'proxmoxtextfield',
fieldLabel: gettext('Username'),
name: 'username',
allowBlank: false,
cbind: {
deleteEmpty: '{!isCreate}',
},
bind: {
disabled: '{!authentication}',
},
},
{
xtype: 'proxmoxtextfield',
inputType: 'password',
fieldLabel: gettext('Password'),
name: 'password',
allowBlank: true,
bind: {
disabled: '{!authentication}',
emptyText: '{passwordEmptyText}',
},
},
],
columnB: [
{
xtype: 'proxmoxtextfield',
fieldLabel: gettext('From Address'),
name: 'from-address',
allowBlank: false,
emptyText: gettext('user@example.com'),
},
{
// provides 'mailto' and 'mailto-user' fields
xtype: 'pmxEmailRecipientPanel',
cbind: {
isCreate: '{isCreate}',
},
},
{
xtype: 'proxmoxtextfield',
name: 'comment',
fieldLabel: gettext('Comment'),
cbind: {
deleteEmpty: '{!isCreate}',
},
},
],
advancedColumnB: [
{
xtype: 'proxmoxtextfield',
fieldLabel: gettext('Author'),
name: 'author',
allowBlank: true,
emptyText: gettext('Proxmox VE'),
cbind: {
deleteEmpty: '{!isCreate}',
},
},
],
onGetValues: function(values) {
if (values.mailto) {
values.mailto = values.mailto.split(/[\s,;]+/);
}
if (!values.authentication && !this.isCreate) {
Proxmox.Utils.assemble_field_data(values, { 'delete': 'username' });
Proxmox.Utils.assemble_field_data(values, { 'delete': 'password' });
}
delete values.authentication;
return values;
},
onSetValues: function(values) {
values.authentication = !!values.username;
return values;
},
});