mirror of
https://git.proxmox.com/git/proxmox-widget-toolkit
synced 2025-05-02 20:58:38 +00:00
add ACME domain editing
Same deal, however, here the PVE code is has a little bug where changing the plugin type of a domain makes it disappear, so this also contains some fixups. Additionally, this now also adds the ability to change a domain's "usage" (smtp, api or both), so similar to the uploadButtons info in the Certificates panel, we now have a domainUsages info. If it is set, the edit window will show a multiselect combobox, and the panel will show a usage column. Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
658bfdff32
commit
8915422f90
@ -52,6 +52,7 @@ JSSRC= \
|
||||
panel/Certificates.js \
|
||||
panel/ACMEAccount.js \
|
||||
panel/ACMEPlugin.js \
|
||||
panel/ACMEDomains.js \
|
||||
window/Edit.js \
|
||||
window/PasswordEdit.js \
|
||||
window/SafeDestroy.js \
|
||||
@ -62,6 +63,7 @@ JSSRC= \
|
||||
window/Certificates.js \
|
||||
window/ACMEAccount.js \
|
||||
window/ACMEPluginEdit.js \
|
||||
window/ACMEDomains.js \
|
||||
node/APT.js \
|
||||
node/NetworkEdit.js \
|
||||
node/NetworkView.js \
|
||||
|
492
src/panel/ACMEDomains.js
Normal file
492
src/panel/ACMEDomains.js
Normal file
@ -0,0 +1,492 @@
|
||||
Ext.define('proxmox-acme-domains', {
|
||||
extend: 'Ext.data.Model',
|
||||
fields: ['domain', 'type', 'alias', 'plugin', 'configkey'],
|
||||
idProperty: 'domain',
|
||||
});
|
||||
|
||||
Ext.define('Proxmox.panel.ACMEDomains', {
|
||||
extend: 'Ext.grid.Panel',
|
||||
xtype: 'pmxACMEDomains',
|
||||
mixins: ['Proxmox.Mixin.CBind'],
|
||||
|
||||
margin: '10 0 0 0',
|
||||
title: 'ACME',
|
||||
|
||||
emptyText: gettext('No Domains configured'),
|
||||
|
||||
// URL to the config containing 'acme' and 'acmedomainX' properties
|
||||
url: undefined,
|
||||
|
||||
// array of { name, url, usageLabel }
|
||||
domainUsages: undefined,
|
||||
// if no domainUsages parameter is supllied, the orderUrl is required instead:
|
||||
orderUrl: undefined,
|
||||
|
||||
acmeUrl: undefined,
|
||||
|
||||
cbindData: function(config) {
|
||||
let me = this;
|
||||
return {
|
||||
acmeUrl: me.acmeUrl,
|
||||
accountUrl: `/api2/json/${me.acmeUrl}/account`,
|
||||
};
|
||||
},
|
||||
|
||||
viewModel: {
|
||||
data: {
|
||||
domaincount: 0,
|
||||
account: undefined, // the account we display
|
||||
configaccount: undefined, // the account set in the config
|
||||
accountEditable: false,
|
||||
accountsAvailable: false,
|
||||
hasUsage: false,
|
||||
},
|
||||
|
||||
formulas: {
|
||||
canOrder: (get) => !!get('account') && get('domaincount') > 0,
|
||||
editBtnIcon: (get) => 'fa black fa-' + (get('accountEditable') ? 'check' : 'pencil'),
|
||||
accountTextHidden: (get) => get('accountEditable') || !get('accountsAvailable'),
|
||||
accountValueHidden: (get) => !get('accountEditable') || !get('accountsAvailable'),
|
||||
hasUsage: (get) => get('hasUsage'),
|
||||
},
|
||||
},
|
||||
|
||||
controller: {
|
||||
xclass: 'Ext.app.ViewController',
|
||||
|
||||
init: function(view) {
|
||||
let accountSelector = this.lookup('accountselector');
|
||||
accountSelector.store.on('load', this.onAccountsLoad, this);
|
||||
},
|
||||
|
||||
onAccountsLoad: function(store, records, success) {
|
||||
let me = this;
|
||||
let vm = me.getViewModel();
|
||||
let configaccount = vm.get('configaccount');
|
||||
vm.set('accountsAvailable', records.length > 0);
|
||||
if (me.autoChangeAccount && records.length > 0) {
|
||||
me.changeAccount(records[0].data.name, () => {
|
||||
vm.set('accountEditable', false);
|
||||
me.reload();
|
||||
});
|
||||
me.autoChangeAccount = false;
|
||||
} else if (configaccount) {
|
||||
if (store.findExact('name', configaccount) !== -1) {
|
||||
vm.set('account', configaccount);
|
||||
} else {
|
||||
vm.set('account', null);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
addDomain: function() {
|
||||
let me = this;
|
||||
let view = me.getView();
|
||||
|
||||
Ext.create('Proxmox.window.ACMEDomainEdit', {
|
||||
url: view.url,
|
||||
acmeUrl: view.acmeUrl,
|
||||
nodeconfig: view.nodeconfig,
|
||||
domainUsages: view.domainUsages,
|
||||
apiCallDone: function() {
|
||||
me.reload();
|
||||
},
|
||||
}).show();
|
||||
},
|
||||
|
||||
editDomain: function() {
|
||||
let me = this;
|
||||
let view = me.getView();
|
||||
|
||||
let selection = view.getSelection();
|
||||
if (selection.length < 1) return;
|
||||
|
||||
Ext.create('Proxmox.window.ACMEDomainEdit', {
|
||||
url: view.url,
|
||||
acmeUrl: view.acmeUrl,
|
||||
nodeconfig: view.nodeconfig,
|
||||
domainUsages: view.domainUsages,
|
||||
domain: selection[0].data,
|
||||
apiCallDone: function() {
|
||||
me.reload();
|
||||
},
|
||||
}).show();
|
||||
},
|
||||
|
||||
removeDomain: function() {
|
||||
let me = this;
|
||||
let view = me.getView();
|
||||
let selection = view.getSelection();
|
||||
if (selection.length < 1) return;
|
||||
|
||||
let rec = selection[0].data;
|
||||
let params = {};
|
||||
if (rec.configkey !== 'acme') {
|
||||
params.delete = rec.configkey;
|
||||
} else {
|
||||
let acme = Proxmox.Utils.parseACME(view.nodeconfig.acme);
|
||||
Proxmox.Utils.remove_domain_from_acme(acme, rec.domain);
|
||||
params.acme = Proxmox.Utils.printACME(acme);
|
||||
}
|
||||
|
||||
Proxmox.Utils.API2Request({
|
||||
method: 'PUT',
|
||||
url: view.url,
|
||||
params,
|
||||
success: function(response, opt) {
|
||||
me.reload();
|
||||
},
|
||||
failure: function(response, opt) {
|
||||
Ext.Msg.alert(gettext('Error'), response.htmlStatus);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
toggleEditAccount: function() {
|
||||
let me = this;
|
||||
let vm = me.getViewModel();
|
||||
let editable = vm.get('accountEditable');
|
||||
if (editable) {
|
||||
me.changeAccount(vm.get('account'), function() {
|
||||
vm.set('accountEditable', false);
|
||||
me.reload();
|
||||
});
|
||||
} else {
|
||||
vm.set('accountEditable', true);
|
||||
}
|
||||
},
|
||||
|
||||
changeAccount: function(account, callback) {
|
||||
let me = this;
|
||||
let view = me.getView();
|
||||
let params = {};
|
||||
|
||||
let acme = Proxmox.Utils.parseACME(view.nodeconfig.acme);
|
||||
acme.account = account;
|
||||
params.acme = Proxmox.Utils.printACME(acme);
|
||||
|
||||
Proxmox.Utils.API2Request({
|
||||
method: 'PUT',
|
||||
waitMsgTarget: view,
|
||||
url: view.url,
|
||||
params,
|
||||
success: function(response, opt) {
|
||||
if (Ext.isFunction(callback)) {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
failure: function(response, opt) {
|
||||
Ext.Msg.alert(gettext('Error'), response.htmlStatus);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
order: function(cert) {
|
||||
let me = this;
|
||||
let view = me.getView();
|
||||
|
||||
Proxmox.Utils.API2Request({
|
||||
method: 'POST',
|
||||
params: {
|
||||
force: 1,
|
||||
},
|
||||
url: cert ? cert.url : view.orderUrl,
|
||||
success: function(response, opt) {
|
||||
Ext.create('Proxmox.window.TaskViewer', {
|
||||
upid: response.result.data,
|
||||
taskDone: function(success) {
|
||||
me.orderFinished(success, cert);
|
||||
},
|
||||
}).show();
|
||||
},
|
||||
failure: function(response, opt) {
|
||||
Ext.Msg.alert(gettext('Error'), response.htmlStatus);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
orderFinished: function(success, cert) {
|
||||
if (!success || !cert.reloadUi) return;
|
||||
var txt = gettext('gui will be restarted with new certificates, please reload!');
|
||||
Ext.getBody().mask(txt, ['x-mask-loading']);
|
||||
// reload after 10 seconds automatically
|
||||
Ext.defer(function() {
|
||||
window.location.reload(true);
|
||||
}, 10000);
|
||||
},
|
||||
|
||||
reload: function() {
|
||||
let me = this;
|
||||
let view = me.getView();
|
||||
view.rstore.load();
|
||||
},
|
||||
|
||||
addAccount: function() {
|
||||
let me = this;
|
||||
let view = me.getView();
|
||||
Ext.create('Proxmox.window.ACMEAccountCreate', {
|
||||
autoShow: true,
|
||||
acmeUrl: view.acmeUrl,
|
||||
taskDone: function() {
|
||||
me.reload();
|
||||
let accountSelector = me.lookup('accountselector');
|
||||
me.autoChangeAccount = true;
|
||||
accountSelector.store.load();
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
tbar: [
|
||||
{
|
||||
xtype: 'proxmoxButton',
|
||||
text: gettext('Add'),
|
||||
handler: 'addDomain',
|
||||
selModel: false,
|
||||
},
|
||||
{
|
||||
xtype: 'proxmoxButton',
|
||||
text: gettext('Edit'),
|
||||
disabled: true,
|
||||
handler: 'editDomain',
|
||||
},
|
||||
{
|
||||
xtype: 'proxmoxStdRemoveButton',
|
||||
handler: 'removeDomain',
|
||||
},
|
||||
'-',
|
||||
'order-menu', // placeholder, filled in initComponent
|
||||
'-',
|
||||
{
|
||||
xtype: 'displayfield',
|
||||
value: gettext('Using Account') + ':',
|
||||
bind: {
|
||||
hidden: '{!accountsAvailable}',
|
||||
},
|
||||
},
|
||||
{
|
||||
xtype: 'displayfield',
|
||||
reference: 'accounttext',
|
||||
renderer: (val) => val || Proxmox.Utils.NoneText,
|
||||
bind: {
|
||||
value: '{account}',
|
||||
hidden: '{accountTextHidden}',
|
||||
},
|
||||
},
|
||||
{
|
||||
xtype: 'pmxACMEAccountSelector',
|
||||
hidden: true,
|
||||
reference: 'accountselector',
|
||||
cbind: {
|
||||
url: '{accountUrl}',
|
||||
},
|
||||
bind: {
|
||||
value: '{account}',
|
||||
hidden: '{accountValueHidden}',
|
||||
},
|
||||
},
|
||||
{
|
||||
xtype: 'button',
|
||||
iconCls: 'fa black fa-pencil',
|
||||
baseCls: 'x-plain',
|
||||
userCls: 'pointer',
|
||||
bind: {
|
||||
iconCls: '{editBtnIcon}',
|
||||
hidden: '{!accountsAvailable}',
|
||||
},
|
||||
handler: 'toggleEditAccount',
|
||||
},
|
||||
{
|
||||
xtype: 'displayfield',
|
||||
value: gettext('No Account available.'),
|
||||
bind: {
|
||||
hidden: '{accountsAvailable}',
|
||||
},
|
||||
},
|
||||
{
|
||||
xtype: 'button',
|
||||
hidden: true,
|
||||
reference: 'accountlink',
|
||||
text: gettext('Add ACME Account'),
|
||||
bind: {
|
||||
hidden: '{accountsAvailable}',
|
||||
},
|
||||
handler: 'addAccount',
|
||||
},
|
||||
],
|
||||
|
||||
updateStore: function(store, records, success) {
|
||||
let me = this;
|
||||
let data = [];
|
||||
let rec;
|
||||
if (success && records.length > 0) {
|
||||
rec = records[0];
|
||||
} else {
|
||||
rec = {
|
||||
data: {},
|
||||
};
|
||||
}
|
||||
|
||||
me.nodeconfig = rec.data; // save nodeconfig for updates
|
||||
|
||||
let account = 'default';
|
||||
|
||||
if (rec.data.acme) {
|
||||
let obj = Proxmox.Utils.parseACME(rec.data.acme);
|
||||
(obj.domains || []).forEach(domain => {
|
||||
if (domain === '') return;
|
||||
let record = {
|
||||
domain,
|
||||
type: 'standalone',
|
||||
configkey: 'acme',
|
||||
};
|
||||
data.push(record);
|
||||
});
|
||||
|
||||
if (obj.account) {
|
||||
account = obj.account;
|
||||
}
|
||||
}
|
||||
|
||||
let vm = me.getViewModel();
|
||||
let oldaccount = vm.get('account');
|
||||
|
||||
// account changed, and we do not edit currently, load again to verify
|
||||
if (oldaccount !== account && !vm.get('accountEditable')) {
|
||||
vm.set('configaccount', account);
|
||||
me.lookup('accountselector').store.load();
|
||||
}
|
||||
|
||||
for (let i = 0; i < Proxmox.Utils.acmedomain_count; i++) {
|
||||
let acmedomain = rec.data[`acmedomain${i}`];
|
||||
if (!acmedomain) continue;
|
||||
|
||||
let record = Proxmox.Utils.parsePropertyString(acmedomain, 'domain');
|
||||
record.type = record.plugin ? 'dns' : 'standalone';
|
||||
record.configkey = `acmedomain${i}`;
|
||||
data.push(record);
|
||||
}
|
||||
|
||||
vm.set('domaincount', data.length);
|
||||
me.store.loadData(data, false);
|
||||
},
|
||||
|
||||
listeners: {
|
||||
itemdblclick: 'editDomain',
|
||||
},
|
||||
|
||||
columns: [
|
||||
{
|
||||
dataIndex: 'domain',
|
||||
flex: 5,
|
||||
text: gettext('Domain'),
|
||||
},
|
||||
{
|
||||
dataIndex: 'usage',
|
||||
flex: 1,
|
||||
text: gettext('Usage'),
|
||||
bind: {
|
||||
hidden: '{!hasUsage}',
|
||||
},
|
||||
},
|
||||
{
|
||||
dataIndex: 'type',
|
||||
flex: 1,
|
||||
text: gettext('Type'),
|
||||
},
|
||||
{
|
||||
dataIndex: 'plugin',
|
||||
flex: 1,
|
||||
text: gettext('Plugin'),
|
||||
},
|
||||
],
|
||||
|
||||
initComponent: function() {
|
||||
let me = this;
|
||||
|
||||
if (!me.acmeUrl) {
|
||||
throw "no acmeUrl given";
|
||||
}
|
||||
|
||||
if (!me.url) {
|
||||
throw "no url given";
|
||||
}
|
||||
|
||||
if (!me.nodename) {
|
||||
throw "no nodename given";
|
||||
}
|
||||
|
||||
if (!me.domainUsages && !me.orderUrl) {
|
||||
throw "neither domainUsages nor orderUrl given";
|
||||
}
|
||||
|
||||
me.rstore = Ext.create('Proxmox.data.UpdateStore', {
|
||||
interval: 10 * 1000,
|
||||
autoStart: true,
|
||||
storeid: `proxmox-node-domains-${me.nodename}`,
|
||||
proxy: {
|
||||
type: 'proxmox',
|
||||
url: `/api2/json/${me.url}`,
|
||||
},
|
||||
});
|
||||
|
||||
me.store = Ext.create('Ext.data.Store', {
|
||||
model: 'proxmox-acme-domains',
|
||||
sorters: 'domain',
|
||||
});
|
||||
|
||||
if (me.domainUsages) {
|
||||
let items = [];
|
||||
|
||||
for (const cert of me.domainUsages) {
|
||||
if (!cert.name) {
|
||||
throw "missing certificate url";
|
||||
}
|
||||
|
||||
if (!cert.url) {
|
||||
throw "missing certificate url";
|
||||
}
|
||||
|
||||
items.push({
|
||||
text: Ext.String.format('Order {0} Certificate Now', cert.name),
|
||||
handler: function() {
|
||||
return me.getController().order(cert);
|
||||
},
|
||||
});
|
||||
}
|
||||
me.tbar.splice(
|
||||
me.tbar.indexOf("order-menu"),
|
||||
1,
|
||||
{
|
||||
text: gettext('Order Certificates Now'),
|
||||
menu: {
|
||||
xtype: 'menu',
|
||||
items,
|
||||
},
|
||||
},
|
||||
);
|
||||
} else {
|
||||
me.tbar.splice(
|
||||
me.tbar.indexOf("order-menu"),
|
||||
1,
|
||||
{
|
||||
xtype: 'button',
|
||||
reference: 'order',
|
||||
text: gettext('Order Certificates Now'),
|
||||
bind: {
|
||||
disabled: '{!canOrder}',
|
||||
},
|
||||
handler: function() {
|
||||
return me.getController().order();
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
me.callParent();
|
||||
me.getViewModel().set('hasUsage', !!me.domainUsages);
|
||||
me.mon(me.rstore, 'load', 'updateStore', me);
|
||||
Proxmox.Utils.monStoreErrors(me, me.rstore);
|
||||
me.on('destroy', me.rstore.stopUpdate, me.rstore);
|
||||
},
|
||||
});
|
213
src/window/ACMEDomains.js
Normal file
213
src/window/ACMEDomains.js
Normal file
@ -0,0 +1,213 @@
|
||||
Ext.define('Proxmox.window.ACMEDomainEdit', {
|
||||
extend: 'Proxmox.window.Edit',
|
||||
xtype: 'pmxACMEDomainEdit',
|
||||
mixins: ['Proxmox.Mixin.CBind'],
|
||||
|
||||
subject: gettext('Domain'),
|
||||
isCreate: false,
|
||||
width: 450,
|
||||
//onlineHelp: 'sysadmin_certificate_management',
|
||||
|
||||
acmeUrl: undefined,
|
||||
|
||||
// config url
|
||||
url: undefined,
|
||||
|
||||
// For PMG the we have multiple certificates, so we have a "usage" attribute & column.
|
||||
domainUsages: undefined,
|
||||
|
||||
cbindData: function(config) {
|
||||
let me = this;
|
||||
return {
|
||||
pluginsUrl: `/api2/json/${me.acmeUrl}/plugins`,
|
||||
hasUsage: !!me.domainUsages,
|
||||
};
|
||||
},
|
||||
|
||||
items: [
|
||||
{
|
||||
xtype: 'inputpanel',
|
||||
onGetValues: function(values) {
|
||||
let me = this;
|
||||
let win = me.up('pmxACMEDomainEdit');
|
||||
let nodeconfig = win.nodeconfig;
|
||||
let olddomain = win.domain || {};
|
||||
|
||||
let params = {
|
||||
digest: nodeconfig.digest,
|
||||
};
|
||||
|
||||
let configkey = olddomain.configkey;
|
||||
let acmeObj = Proxmox.Utils.parseACME(nodeconfig.acme);
|
||||
|
||||
let find_free_slot = () => {
|
||||
for (let i = 0; i < Proxmox.Utils.acmedomain_count; i++) {
|
||||
if (nodeconfig[`acmedomain${i}`] === undefined) {
|
||||
return `acmedomain${i}`;
|
||||
}
|
||||
}
|
||||
throw "too many domains configured";
|
||||
};
|
||||
|
||||
// If we have a 'usage' property (pmg), we only use the `acmedomainX` config keys.
|
||||
if (win.domainUsages) {
|
||||
if (!configkey || configkey === 'acme') {
|
||||
configkey = find_free_slot();
|
||||
}
|
||||
delete values.type;
|
||||
params[configkey] = Proxmox.Utils.printPropertyString(values, 'domain');
|
||||
return params;
|
||||
}
|
||||
|
||||
// Otherwise we put the standalone entries into the `domains` list of the `acme`
|
||||
// property string.
|
||||
|
||||
// Then insert the domain depending on its type:
|
||||
if (values.type === 'dns') {
|
||||
if (!olddomain.configkey || olddomain.configkey === 'acme') {
|
||||
configkey = find_free_slot();
|
||||
if (olddomain.domain) {
|
||||
// we have to remove the domain from the acme domainlist
|
||||
Proxmox.Utils.remove_domain_from_acme(acmeObj, olddomain.domain);
|
||||
params.acme = Proxmox.Utils.printACME(acmeObj);
|
||||
}
|
||||
}
|
||||
|
||||
delete values.type;
|
||||
params[configkey] = Proxmox.Utils.printPropertyString(values, 'domain');
|
||||
} else {
|
||||
if (olddomain.configkey && olddomain.configkey !== 'acme') {
|
||||
// delete the old dns entry, unless we need to declare its usage:
|
||||
params.delete = [olddomain.configkey];
|
||||
}
|
||||
|
||||
// add new, remove old and make entries unique
|
||||
Proxmox.Utils.add_domain_to_acme(acmeObj, values.domain);
|
||||
if (olddomain.domain !== values.domain) {
|
||||
Proxmox.Utils.remove_domain_from_acme(acmeObj, olddomain.domain);
|
||||
}
|
||||
params.acme = Proxmox.Utils.printACME(acmeObj);
|
||||
}
|
||||
|
||||
return params;
|
||||
},
|
||||
items: [
|
||||
{
|
||||
xtype: 'proxmoxKVComboBox',
|
||||
name: 'type',
|
||||
fieldLabel: gettext('Challenge Type'),
|
||||
allowBlank: false,
|
||||
value: 'standalone',
|
||||
comboItems: [
|
||||
['standalone', 'HTTP'],
|
||||
['dns', 'DNS'],
|
||||
],
|
||||
validator: function(value) {
|
||||
let me = this;
|
||||
let win = me.up('pmxACMEDomainEdit');
|
||||
let oldconfigkey = win.domain ? win.domain.configkey : undefined;
|
||||
let val = me.getValue();
|
||||
if (val === 'dns' && (!oldconfigkey || oldconfigkey === 'acme')) {
|
||||
// we have to check if there is a 'acmedomain' slot left
|
||||
let found = false;
|
||||
for (let i = 0; i < Proxmox.Utils.acmedomain_count; i++) {
|
||||
if (!win.nodeconfig[`acmedomain${i}`]) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return gettext('Only 5 Domains with type DNS can be configured');
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
listeners: {
|
||||
change: function(cb, value) {
|
||||
let me = this;
|
||||
let view = me.up('pmxACMEDomainEdit');
|
||||
let pluginField = view.down('field[name=plugin]');
|
||||
pluginField.setDisabled(value !== 'dns');
|
||||
pluginField.setHidden(value !== 'dns');
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
xtype: 'hidden',
|
||||
name: 'alias',
|
||||
},
|
||||
{
|
||||
xtype: 'pmxACMEPluginSelector',
|
||||
name: 'plugin',
|
||||
disabled: true,
|
||||
hidden: true,
|
||||
allowBlank: false,
|
||||
cbind: {
|
||||
url: '{pluginsUrl}',
|
||||
},
|
||||
},
|
||||
{
|
||||
xtype: 'proxmoxtextfield',
|
||||
name: 'domain',
|
||||
allowBlank: false,
|
||||
vtype: 'DnsName',
|
||||
value: '',
|
||||
fieldLabel: gettext('Domain'),
|
||||
},
|
||||
{
|
||||
xtype: 'combobox',
|
||||
name: 'usage',
|
||||
multiSelect: true,
|
||||
editable: false,
|
||||
fieldLabel: gettext('Usage'),
|
||||
cbind: {
|
||||
hidden: '{!hasUsage}',
|
||||
allowBlank: '{!hasUsage}',
|
||||
},
|
||||
fields: ['usage', 'name'],
|
||||
displayField: 'name',
|
||||
valueField: 'usage',
|
||||
store: {
|
||||
data: [
|
||||
{ usage: 'api', name: 'API' },
|
||||
{ usage: 'smtp', name: 'SMTP' },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
initComponent: function() {
|
||||
let me = this;
|
||||
|
||||
if (!me.url) {
|
||||
throw 'no url given';
|
||||
}
|
||||
|
||||
if (!me.acmeUrl) {
|
||||
throw 'no acmeUrl given';
|
||||
}
|
||||
|
||||
if (!me.nodeconfig) {
|
||||
throw 'no nodeconfig given';
|
||||
}
|
||||
|
||||
me.isCreate = !me.domain;
|
||||
if (me.isCreate) {
|
||||
me.domain = `${Proxmox.NodeName}.`; // TODO: FQDN of node
|
||||
}
|
||||
|
||||
me.callParent();
|
||||
|
||||
if (!me.isCreate) {
|
||||
let values = { ...me.domain };
|
||||
if (Ext.isDefined(values.usage)) {
|
||||
values.usage = values.usage.split(';');
|
||||
}
|
||||
me.setValues(values);
|
||||
} else {
|
||||
me.setValues({ domain: me.domain });
|
||||
}
|
||||
},
|
||||
});
|
Loading…
Reference in New Issue
Block a user