Upstream proxmox-git/pve-manager state of the touched files before 55c76c2746
This commit is contained in:
1 parent
11c2368e04
commit
8814724567
3 files changed
+765
No files matched your search
@@ -0,0 +1,208 @@
|
|||||||
|
Ext.define('PVE.window.DirMapEditWindow', {
|
||||||
|
extend: 'Proxmox.window.Edit',
|
||||||
|
|
||||||
|
mixins: ['Proxmox.Mixin.CBind'],
|
||||||
|
|
||||||
|
cbindData: function (initialConfig) {
|
||||||
|
let me = this;
|
||||||
|
me.isCreate = !me.name;
|
||||||
|
me.method = me.isCreate ? 'POST' : 'PUT';
|
||||||
|
me.hideMapping = !!me.entryOnly;
|
||||||
|
me.hideComment = me.name && !me.entryOnly;
|
||||||
|
me.hideNodeSelector = me.nodename || me.entryOnly;
|
||||||
|
me.hideNode = !me.nodename || !me.hideNodeSelector;
|
||||||
|
return {
|
||||||
|
name: me.name,
|
||||||
|
nodename: me.nodename,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
submitUrl: function (_url, data) {
|
||||||
|
let me = this;
|
||||||
|
let name = me.isCreate ? '' : me.name;
|
||||||
|
return `/cluster/mapping/dir/${name}`;
|
||||||
|
},
|
||||||
|
|
||||||
|
title: gettext('Add Directory Mapping'),
|
||||||
|
|
||||||
|
onlineHelp: 'resource_mapping',
|
||||||
|
|
||||||
|
method: 'POST',
|
||||||
|
|
||||||
|
controller: {
|
||||||
|
xclass: 'Ext.app.ViewController',
|
||||||
|
|
||||||
|
onGetValues: function (values) {
|
||||||
|
let me = this;
|
||||||
|
let view = me.getView();
|
||||||
|
values.node ??= view.nodename;
|
||||||
|
|
||||||
|
let name = values.name;
|
||||||
|
let description = values.description;
|
||||||
|
let deletes = values.delete;
|
||||||
|
|
||||||
|
delete values.description;
|
||||||
|
delete values.name;
|
||||||
|
delete values.delete;
|
||||||
|
|
||||||
|
let map = [];
|
||||||
|
if (me.originalMap) {
|
||||||
|
map = PVE.Parser.filterPropertyStringList(
|
||||||
|
me.originalMap,
|
||||||
|
(e) => e.node !== values.node,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (values.path) {
|
||||||
|
// TODO: Remove this when property string supports quotation of properties
|
||||||
|
if (!/^\/[^;,=()]+/.test(values.path)) {
|
||||||
|
let errMsg =
|
||||||
|
'Value does not look like a valid absolute path.' +
|
||||||
|
' These symbols are currently not allowed in path: ;,=()\n';
|
||||||
|
Ext.Msg.alert(gettext('Error'), errMsg);
|
||||||
|
// prevent sending a broken property string to the API
|
||||||
|
throw errMsg;
|
||||||
|
}
|
||||||
|
map.push(PVE.Parser.printPropertyString(values));
|
||||||
|
}
|
||||||
|
values = { map };
|
||||||
|
|
||||||
|
if (description) {
|
||||||
|
values.description = description;
|
||||||
|
}
|
||||||
|
if (deletes && !view.isCreate) {
|
||||||
|
values.delete = deletes;
|
||||||
|
}
|
||||||
|
if (view.isCreate) {
|
||||||
|
values.id = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
},
|
||||||
|
|
||||||
|
onSetValues: function (values) {
|
||||||
|
let me = this;
|
||||||
|
let view = me.getView();
|
||||||
|
me.originalMap = [...values.map];
|
||||||
|
let configuredNodes = [];
|
||||||
|
PVE.Parser.filterPropertyStringList(values.map, (e) => {
|
||||||
|
configuredNodes.push(e.node);
|
||||||
|
if (e.node === view.nodename) {
|
||||||
|
values = e;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
me.lookup('nodeselector').disallowedNodes = configuredNodes;
|
||||||
|
|
||||||
|
return values;
|
||||||
|
},
|
||||||
|
|
||||||
|
init: function (view) {
|
||||||
|
let _me = this;
|
||||||
|
|
||||||
|
if (!view.nodename) {
|
||||||
|
//throw "no nodename given";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
xtype: 'inputpanel',
|
||||||
|
onGetValues: function (values) {
|
||||||
|
return this.up('window').getController().onGetValues(values);
|
||||||
|
},
|
||||||
|
|
||||||
|
onSetValues: function (values) {
|
||||||
|
return this.up('window').getController().onSetValues(values);
|
||||||
|
},
|
||||||
|
|
||||||
|
columnT: [
|
||||||
|
{
|
||||||
|
xtype: 'displayfield',
|
||||||
|
reference: 'directory-hint',
|
||||||
|
columnWidth: 1,
|
||||||
|
value: 'Make sure the directory exists.',
|
||||||
|
cbind: {
|
||||||
|
disabled: '{hideMapping}',
|
||||||
|
hidden: '{hideMapping}',
|
||||||
|
},
|
||||||
|
userCls: 'pmx-hint',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
column1: [
|
||||||
|
{
|
||||||
|
xtype: 'pmxDisplayEditField',
|
||||||
|
fieldLabel: gettext('Name'),
|
||||||
|
cbind: {
|
||||||
|
editable: '{!name}',
|
||||||
|
value: '{name}',
|
||||||
|
submitValue: '{isCreate}',
|
||||||
|
},
|
||||||
|
name: 'name',
|
||||||
|
allowBlank: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'pveNodeSelector',
|
||||||
|
reference: 'nodeselector',
|
||||||
|
fieldLabel: gettext('Node'),
|
||||||
|
name: 'node',
|
||||||
|
cbind: {
|
||||||
|
disabled: '{hideNodeSelector}',
|
||||||
|
hidden: '{hideNodeSelector}',
|
||||||
|
},
|
||||||
|
allowBlank: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
column2: [
|
||||||
|
{
|
||||||
|
xtype: 'fieldcontainer',
|
||||||
|
defaultType: 'radiofield',
|
||||||
|
layout: 'fit',
|
||||||
|
cbind: {
|
||||||
|
disabled: '{hideMapping}',
|
||||||
|
hidden: '{hideMapping}',
|
||||||
|
},
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
xtype: 'textfield',
|
||||||
|
name: 'path',
|
||||||
|
reference: 'path',
|
||||||
|
value: '',
|
||||||
|
emptyText: gettext('/some/path'),
|
||||||
|
cbind: {
|
||||||
|
nodename: '{nodename}',
|
||||||
|
disabled: '{hideMapping}',
|
||||||
|
},
|
||||||
|
allowBlank: false,
|
||||||
|
fieldLabel: gettext('Path'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
columnB: [
|
||||||
|
{
|
||||||
|
xtype: 'fieldcontainer',
|
||||||
|
defaultType: 'radiofield',
|
||||||
|
layout: 'fit',
|
||||||
|
cbind: {
|
||||||
|
disabled: '{hideComment}',
|
||||||
|
hidden: '{hideComment}',
|
||||||
|
},
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
xtype: 'proxmoxtextfield',
|
||||||
|
fieldLabel: gettext('Comment'),
|
||||||
|
submitValue: true,
|
||||||
|
name: 'description',
|
||||||
|
deleteEmpty: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
@@ -0,0 +1,305 @@
|
|||||||
|
Ext.define('PVE.window.PCIMapEditWindow', {
|
||||||
|
extend: 'Proxmox.window.Edit',
|
||||||
|
|
||||||
|
mixins: ['Proxmox.Mixin.CBind'],
|
||||||
|
|
||||||
|
width: 800,
|
||||||
|
|
||||||
|
subject: gettext('PCI mapping'),
|
||||||
|
|
||||||
|
onlineHelp: 'resource_mapping',
|
||||||
|
|
||||||
|
method: 'POST',
|
||||||
|
|
||||||
|
cbindData: function (initialConfig) {
|
||||||
|
let me = this;
|
||||||
|
me.isCreate = (!me.name || !me.nodename) && !me.entryOnly;
|
||||||
|
me.method = me.name ? 'PUT' : 'POST';
|
||||||
|
me.hideMapping = !!me.entryOnly;
|
||||||
|
me.globalEdit = !me.name || me.entryOnly;
|
||||||
|
me.hideNodeSelector = me.nodename || me.entryOnly;
|
||||||
|
me.hideNode = !me.nodename || !me.hideNodeSelector;
|
||||||
|
return {
|
||||||
|
name: me.name,
|
||||||
|
nodename: me.nodename,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
submitUrl: function (_url, data) {
|
||||||
|
let me = this;
|
||||||
|
let name = me.method === 'PUT' ? me.name : '';
|
||||||
|
return `/cluster/mapping/pci/${name}`;
|
||||||
|
},
|
||||||
|
|
||||||
|
controller: {
|
||||||
|
xclass: 'Ext.app.ViewController',
|
||||||
|
|
||||||
|
onGetValues: function (values) {
|
||||||
|
let me = this;
|
||||||
|
let view = me.getView();
|
||||||
|
if (view.method === 'POST') {
|
||||||
|
delete me.digest;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values.iommugroup === -1) {
|
||||||
|
delete values.iommugroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
let nodename = values.node ?? view.nodename;
|
||||||
|
delete values.node;
|
||||||
|
if (me.originalMap) {
|
||||||
|
let otherMaps = PVE.Parser.filterPropertyStringList(
|
||||||
|
me.originalMap,
|
||||||
|
(e) => e.node !== nodename,
|
||||||
|
);
|
||||||
|
if (otherMaps.length) {
|
||||||
|
values.map = values.map.concat(otherMaps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
},
|
||||||
|
|
||||||
|
onSetValues: function (values) {
|
||||||
|
let me = this;
|
||||||
|
let view = me.getView();
|
||||||
|
me.originalMap = [...values.map];
|
||||||
|
let configuredNodes = [];
|
||||||
|
values.map = PVE.Parser.filterPropertyStringList(values.map, (e) => {
|
||||||
|
configuredNodes.push(e.node);
|
||||||
|
return e.node === view.nodename;
|
||||||
|
});
|
||||||
|
|
||||||
|
me.lookup('nodeselector').disallowedNodes = configuredNodes;
|
||||||
|
return values;
|
||||||
|
},
|
||||||
|
|
||||||
|
checkIommu: function (store, records, success) {
|
||||||
|
let me = this;
|
||||||
|
if (!success || !records.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
me.lookup('iommu_warning').setVisible(
|
||||||
|
records.every((val) => val.data.iommugroup === -1),
|
||||||
|
);
|
||||||
|
|
||||||
|
let value = me.lookup('pciselector').getValue();
|
||||||
|
me.checkIsolated(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
checkIsolated: function (value) {
|
||||||
|
let me = this;
|
||||||
|
|
||||||
|
let store = me.lookup('pciselector').getStore();
|
||||||
|
|
||||||
|
let isIsolated = function (entry) {
|
||||||
|
let isolated = true;
|
||||||
|
let parsed = PVE.Parser.parsePropertyString(entry);
|
||||||
|
parsed.iommugroup = parseInt(parsed.iommugroup, 10);
|
||||||
|
if (!parsed.iommugroup) {
|
||||||
|
return isolated;
|
||||||
|
}
|
||||||
|
store.each(({ data }) => {
|
||||||
|
let isSubDevice = data.id.startsWith(parsed.path);
|
||||||
|
if (
|
||||||
|
data.iommugroup === parsed.iommugroup &&
|
||||||
|
data.id !== parsed.path &&
|
||||||
|
!isSubDevice
|
||||||
|
) {
|
||||||
|
isolated = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return isolated;
|
||||||
|
};
|
||||||
|
|
||||||
|
let showWarning = false;
|
||||||
|
if (Ext.isArray(value)) {
|
||||||
|
for (const entry of value) {
|
||||||
|
if (!isIsolated(entry)) {
|
||||||
|
showWarning = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showWarning = isIsolated(value);
|
||||||
|
}
|
||||||
|
me.lookup('group_warning').setVisible(showWarning);
|
||||||
|
},
|
||||||
|
|
||||||
|
mdevChange: function (mdevField, value) {
|
||||||
|
this.lookup('pciselector').setMdev(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
nodeChange: function (field, value) {
|
||||||
|
if (!field.isDisabled()) {
|
||||||
|
this.lookup('pciselector').setNodename(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
pciChange: function (_field, value) {
|
||||||
|
let me = this;
|
||||||
|
me.lookup('multiple_warning').setVisible(Ext.isArray(value) && value.length > 1);
|
||||||
|
me.checkIsolated(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
control: {
|
||||||
|
'field[name=mdev]': {
|
||||||
|
change: 'mdevChange',
|
||||||
|
},
|
||||||
|
pveNodeSelector: {
|
||||||
|
change: 'nodeChange',
|
||||||
|
},
|
||||||
|
pveMultiPCISelector: {
|
||||||
|
change: 'pciChange',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
xtype: 'inputpanel',
|
||||||
|
onGetValues: function (values) {
|
||||||
|
return this.up('window').getController().onGetValues(values);
|
||||||
|
},
|
||||||
|
|
||||||
|
onSetValues: function (values) {
|
||||||
|
return this.up('window').getController().onSetValues(values);
|
||||||
|
},
|
||||||
|
|
||||||
|
columnT: [
|
||||||
|
{
|
||||||
|
xtype: 'displayfield',
|
||||||
|
reference: 'iommu_warning',
|
||||||
|
hidden: true,
|
||||||
|
columnWidth: 1,
|
||||||
|
padding: '0 0 10 0',
|
||||||
|
value: gettext(
|
||||||
|
'No IOMMU detected, please activate it. See Documentation for further information.',
|
||||||
|
),
|
||||||
|
userCls: 'pmx-hint',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'displayfield',
|
||||||
|
reference: 'multiple_warning',
|
||||||
|
hidden: true,
|
||||||
|
columnWidth: 1,
|
||||||
|
padding: '0 0 10 0',
|
||||||
|
value: gettext(
|
||||||
|
'When multiple devices are selected, the first free one will be chosen on guest start.',
|
||||||
|
),
|
||||||
|
userCls: 'pmx-hint',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'displayfield',
|
||||||
|
reference: 'group_warning',
|
||||||
|
hidden: true,
|
||||||
|
columnWidth: 1,
|
||||||
|
padding: '0 0 10 0',
|
||||||
|
itemId: 'iommuwarning',
|
||||||
|
value: gettext(
|
||||||
|
'A selected device is not in a separate IOMMU group, make sure this is intended.',
|
||||||
|
),
|
||||||
|
userCls: 'pmx-hint',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
column1: [
|
||||||
|
{
|
||||||
|
xtype: 'pmxDisplayEditField',
|
||||||
|
fieldLabel: gettext('Name'),
|
||||||
|
labelWidth: 120,
|
||||||
|
cbind: {
|
||||||
|
editable: '{!name}',
|
||||||
|
value: '{name}',
|
||||||
|
submitValue: '{isCreate}',
|
||||||
|
},
|
||||||
|
name: 'id',
|
||||||
|
allowBlank: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'displayfield',
|
||||||
|
fieldLabel: gettext('Mapping on Node'),
|
||||||
|
labelWidth: 120,
|
||||||
|
name: 'node',
|
||||||
|
cbind: {
|
||||||
|
value: '{nodename}',
|
||||||
|
disabled: '{hideNode}',
|
||||||
|
hidden: '{hideNode}',
|
||||||
|
},
|
||||||
|
allowBlank: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'pveNodeSelector',
|
||||||
|
reference: 'nodeselector',
|
||||||
|
fieldLabel: gettext('Mapping on Node'),
|
||||||
|
labelWidth: 120,
|
||||||
|
name: 'node',
|
||||||
|
cbind: {
|
||||||
|
disabled: '{hideNodeSelector}',
|
||||||
|
hidden: '{hideNodeSelector}',
|
||||||
|
},
|
||||||
|
allowBlank: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
column2: [
|
||||||
|
{
|
||||||
|
xtype: 'proxmoxcheckbox',
|
||||||
|
fieldLabel: gettext('Use with Mediated Devices'),
|
||||||
|
labelWidth: 200,
|
||||||
|
reference: 'mdev',
|
||||||
|
name: 'mdev',
|
||||||
|
cbind: {
|
||||||
|
deleteEmpty: '{!isCreate}',
|
||||||
|
disabled: '{!globalEdit}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'proxmoxcheckbox',
|
||||||
|
fieldLabel: gettext('Live Migration Capable'),
|
||||||
|
labelWidth: 200,
|
||||||
|
boxLabel: `<i class="fa fa-exclamation-triangle warning"></i> ${gettext('Experimental')}`,
|
||||||
|
reference: 'live-migration-capable',
|
||||||
|
name: 'live-migration-capable',
|
||||||
|
cbind: {
|
||||||
|
deleteEmpty: '{!isCreate}',
|
||||||
|
disabled: '{!globalEdit}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
columnB: [
|
||||||
|
{
|
||||||
|
xtype: 'pveMultiPCISelector',
|
||||||
|
fieldLabel: gettext('Device'),
|
||||||
|
labelWidth: 120,
|
||||||
|
height: 300,
|
||||||
|
reference: 'pciselector',
|
||||||
|
name: 'map',
|
||||||
|
cbind: {
|
||||||
|
nodename: '{nodename}',
|
||||||
|
disabled: '{hideMapping}',
|
||||||
|
hidden: '{hideMapping}',
|
||||||
|
},
|
||||||
|
allowBlank: false,
|
||||||
|
onLoadCallBack: 'checkIommu',
|
||||||
|
margin: '0 0 10 0',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'proxmoxtextfield',
|
||||||
|
fieldLabel: gettext('Comment'),
|
||||||
|
labelWidth: 120,
|
||||||
|
submitValue: true,
|
||||||
|
name: 'description',
|
||||||
|
cbind: {
|
||||||
|
deleteEmpty: '{!isCreate}',
|
||||||
|
disabled: '{!globalEdit}',
|
||||||
|
hidden: '{!globalEdit}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
@@ -0,0 +1,252 @@
|
|||||||
|
Ext.define('PVE.window.USBMapEditWindow', {
|
||||||
|
extend: 'Proxmox.window.Edit',
|
||||||
|
|
||||||
|
mixins: ['Proxmox.Mixin.CBind'],
|
||||||
|
|
||||||
|
cbindData: function (initialConfig) {
|
||||||
|
let me = this;
|
||||||
|
me.isCreate = !me.name;
|
||||||
|
me.method = me.isCreate ? 'POST' : 'PUT';
|
||||||
|
me.hideMapping = !!me.entryOnly;
|
||||||
|
me.hideComment = me.name && !me.entryOnly;
|
||||||
|
me.hideNodeSelector = me.nodename || me.entryOnly;
|
||||||
|
me.hideNode = !me.nodename || !me.hideNodeSelector;
|
||||||
|
return {
|
||||||
|
name: me.name,
|
||||||
|
nodename: me.nodename,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
submitUrl: function (_url, data) {
|
||||||
|
let me = this;
|
||||||
|
let name = me.isCreate ? '' : me.name;
|
||||||
|
return `/cluster/mapping/usb/${name}`;
|
||||||
|
},
|
||||||
|
|
||||||
|
title: gettext('Add USB mapping'),
|
||||||
|
|
||||||
|
onlineHelp: 'resource_mapping',
|
||||||
|
|
||||||
|
method: 'POST',
|
||||||
|
|
||||||
|
controller: {
|
||||||
|
xclass: 'Ext.app.ViewController',
|
||||||
|
|
||||||
|
onGetValues: function (values) {
|
||||||
|
let me = this;
|
||||||
|
let view = me.getView();
|
||||||
|
values.node ??= view.nodename;
|
||||||
|
|
||||||
|
let type = me.getView().down('radiofield').getGroupValue();
|
||||||
|
let name = values.name;
|
||||||
|
let description = values.description;
|
||||||
|
delete values.description;
|
||||||
|
delete values.name;
|
||||||
|
|
||||||
|
if (type === 'path') {
|
||||||
|
let usbsel = me.lookup(type);
|
||||||
|
let usbDev = usbsel
|
||||||
|
.getStore()
|
||||||
|
.findRecord('usbid', values[type], 0, false, true, true);
|
||||||
|
|
||||||
|
if (!usbDev) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
values.id = `${usbDev.data.vendid}:${usbDev.data.prodid}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let map = [];
|
||||||
|
if (me.originalMap) {
|
||||||
|
map = PVE.Parser.filterPropertyStringList(
|
||||||
|
me.originalMap,
|
||||||
|
(e) => e.node !== values.node,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (values.id) {
|
||||||
|
map.push(PVE.Parser.printPropertyString(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
values = { map };
|
||||||
|
if (description) {
|
||||||
|
values.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (view.isCreate) {
|
||||||
|
values.id = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
},
|
||||||
|
|
||||||
|
onSetValues: function (values) {
|
||||||
|
let me = this;
|
||||||
|
let view = me.getView();
|
||||||
|
me.originalMap = [...values.map];
|
||||||
|
let configuredNodes = [];
|
||||||
|
PVE.Parser.filterPropertyStringList(values.map, (e) => {
|
||||||
|
configuredNodes.push(e.node);
|
||||||
|
if (e.node === view.nodename) {
|
||||||
|
values = e;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
me.lookup('nodeselector').disallowedNodes = configuredNodes;
|
||||||
|
if (values.path) {
|
||||||
|
values.usb = 'path';
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
},
|
||||||
|
|
||||||
|
modeChange: function (field, value) {
|
||||||
|
let me = this;
|
||||||
|
let type = field.inputValue;
|
||||||
|
let usbsel = me.lookup(type);
|
||||||
|
usbsel.setDisabled(!value);
|
||||||
|
},
|
||||||
|
|
||||||
|
nodeChange: function (field, value) {
|
||||||
|
if (!field.isDisabled()) {
|
||||||
|
this.lookup('id').setNodename(value);
|
||||||
|
this.lookup('path').setNodename(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
init: function (view) {
|
||||||
|
let _me = this;
|
||||||
|
|
||||||
|
if (!view.nodename) {
|
||||||
|
//throw "no nodename given";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
control: {
|
||||||
|
radiofield: {
|
||||||
|
change: 'modeChange',
|
||||||
|
},
|
||||||
|
pveNodeSelector: {
|
||||||
|
change: 'nodeChange',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
xtype: 'inputpanel',
|
||||||
|
onGetValues: function (values) {
|
||||||
|
return this.up('window').getController().onGetValues(values);
|
||||||
|
},
|
||||||
|
|
||||||
|
onSetValues: function (values) {
|
||||||
|
return this.up('window').getController().onSetValues(values);
|
||||||
|
},
|
||||||
|
|
||||||
|
column1: [
|
||||||
|
{
|
||||||
|
xtype: 'pmxDisplayEditField',
|
||||||
|
fieldLabel: gettext('Name'),
|
||||||
|
cbind: {
|
||||||
|
editable: '{!name}',
|
||||||
|
value: '{name}',
|
||||||
|
submitValue: '{isCreate}',
|
||||||
|
},
|
||||||
|
name: 'name',
|
||||||
|
allowBlank: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'displayfield',
|
||||||
|
fieldLabel: gettext('Mapping on Node'),
|
||||||
|
labelWidth: 120,
|
||||||
|
name: 'node',
|
||||||
|
cbind: {
|
||||||
|
value: '{nodename}',
|
||||||
|
disabled: '{hideNode}',
|
||||||
|
hidden: '{hideNode}',
|
||||||
|
},
|
||||||
|
allowBlank: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'pveNodeSelector',
|
||||||
|
reference: 'nodeselector',
|
||||||
|
fieldLabel: gettext('Mapping on Node'),
|
||||||
|
labelWidth: 120,
|
||||||
|
name: 'node',
|
||||||
|
cbind: {
|
||||||
|
disabled: '{hideNodeSelector}',
|
||||||
|
hidden: '{hideNodeSelector}',
|
||||||
|
},
|
||||||
|
allowBlank: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
column2: [
|
||||||
|
{
|
||||||
|
xtype: 'fieldcontainer',
|
||||||
|
defaultType: 'radiofield',
|
||||||
|
layout: 'fit',
|
||||||
|
cbind: {
|
||||||
|
disabled: '{hideMapping}',
|
||||||
|
hidden: '{hideMapping}',
|
||||||
|
},
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
name: 'usb',
|
||||||
|
inputValue: 'id',
|
||||||
|
checked: true,
|
||||||
|
boxLabel: gettext('Use USB Vendor/Device ID'),
|
||||||
|
submitValue: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'pveUSBSelector',
|
||||||
|
type: 'device',
|
||||||
|
reference: 'id',
|
||||||
|
name: 'id',
|
||||||
|
cbind: {
|
||||||
|
nodename: '{nodename}',
|
||||||
|
disabled: '{hideMapping}',
|
||||||
|
},
|
||||||
|
editable: true,
|
||||||
|
allowBlank: false,
|
||||||
|
fieldLabel: gettext('Choose Device'),
|
||||||
|
labelAlign: 'right',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'usb',
|
||||||
|
inputValue: 'path',
|
||||||
|
boxLabel: gettext('Use USB Port'),
|
||||||
|
submitValue: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'pveUSBSelector',
|
||||||
|
disabled: true,
|
||||||
|
name: 'path',
|
||||||
|
reference: 'path',
|
||||||
|
cbind: {
|
||||||
|
nodename: '{nodename}',
|
||||||
|
},
|
||||||
|
editable: true,
|
||||||
|
type: 'port',
|
||||||
|
allowBlank: false,
|
||||||
|
fieldLabel: gettext('Choose Port'),
|
||||||
|
labelAlign: 'right',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
columnB: [
|
||||||
|
{
|
||||||
|
xtype: 'proxmoxtextfield',
|
||||||
|
fieldLabel: gettext('Comment'),
|
||||||
|
submitValue: true,
|
||||||
|
name: 'description',
|
||||||
|
cbind: {
|
||||||
|
disabled: '{hideComment}',
|
||||||
|
hidden: '{hideComment}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
Reference in new issue
Block a user