]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/form/MultiPCISelector.js
1 Ext
.define('PVE.form.MultiPCISelector', {
2 extend
: 'Ext.grid.Panel',
3 alias
: 'widget.pveMultiPCISelector',
5 emptyText
: gettext('No Devices found'),
8 field
: 'Ext.form.field.Field',
11 // will be called after loading finished
12 onLoadCallBack
: Ext
.emptyFn
,
14 getValue: function() {
16 return me
.value
?? [];
19 getSubmitData: function() {
22 res
[me
.name
] = me
.getValue();
26 setValue: function(value
) {
31 me
.updateSelectedDevices(value
);
33 return me
.mixins
.field
.setValue
.call(me
, value
);
36 getErrors: function() {
39 let errorCls
= ['x-form-trigger-wrap-default', 'x-form-trigger-wrap-invalid'];
41 if (me
.getValue().length
< 1) {
42 let error
= gettext("Must choose at least one device");
44 me
.getActionEl()?.dom
.setAttribute('data-errorqtip', error
);
49 me
.removeCls(errorCls
);
50 me
.getActionEl()?.dom
.setAttribute('data-errorqtip', "");
56 getRowClass: function(record
) {
57 if (record
.data
.disabled
=== true) {
58 return 'x-item-disabled';
64 updateSelectedDevices: function(value
= []) {
68 let store
= me
.getStore();
70 for (const map
of value
) {
71 let parsed
= PVE
.Parser
.parsePropertyString(map
);
72 if (parsed
.node
!== me
.nodename
) {
76 let rec
= store
.getById(parsed
.path
);
82 me
.suspendEvent('change');
84 me
.setSelection(recs
);
85 me
.resumeEvent('change');
88 setNodename: function(nodename
) {
91 if (!nodename
|| me
.nodename
=== nodename
) {
95 me
.nodename
= nodename
;
97 me
.getStore().setProxy({
99 url
: '/api2/json/nodes/' + me
.nodename
+ '/hardware/pci?pci-class-blacklist=',
105 callback
: (recs
, op
, success
) => me
.addSlotRecords(recs
, op
, success
),
109 setMdev: function(mdev
) {
112 me
.getStore().addFilter({
119 me
.getStore().removeFilter('mdev-filter');
124 // adds the virtual 'slot' records (e.g. '0000:01:00') to the store
125 addSlotRecords: function(records
, _op
, success
) {
132 records
.forEach((rec
) => {
133 let slotname
= rec
.data
.id
.slice(0, -2); // remove function
134 if (slots
[slotname
] !== undefined) {
135 slots
[slotname
].count
++;
136 rec
.set('slot', slots
[slotname
]);
143 rec
.set('slot', slots
[slotname
]);
145 if (rec
.data
.id
.endsWith('.0')) {
146 slots
[slotname
].device
= rec
.data
;
150 let store
= me
.getStore();
152 for (const [slot
, { count
, device
}] of Object
.entries(slots
)) {
156 store
.add(Ext
.apply({}, {
159 device_name
: gettext('Pass through all functions as one device'),
163 me
.updateSelectedDevices(me
.value
);
166 selectionChange: function(_grid
, selection
) {
171 .filter(rec
=> rec
.data
.id
.indexOf('.') === -1)
172 .forEach((rec
) => { ids
[rec
.data
.id
] = true; });
176 me
.getStore().each(rec
=> {
177 let id
= rec
.data
.id
;
178 rec
.set('disabled', false);
179 if (id
.indexOf('.') === -1) {
182 let slot
= id
.slice(0, -2); // remove function
185 to_disable
.push(rec
);
186 rec
.set('disabled', true);
190 me
.suspendEvent('selectionchange');
191 me
.getSelectionModel().deselect(to_disable
);
192 me
.resumeEvent('selectionchange');
194 me
.value
= me
.getSelection().map((rec
) => {
198 id
: `${rec.data.vendor}:${rec.data.device}`.replace(/0x/g, ''),
199 'subsystem-id': `${rec.data.subsystem_vendor}:${rec.data.subsystem_device}`.replace(/0x/g, ''),
202 if (rec
.data
.iommugroup
!== -1) {
203 res
.iommugroup
= rec
.data
.iommugroup
;
206 return PVE
.Parser
.printPropertyString(res
);
212 type
: 'checkboxmodel',
220 renderer: function(value
, _md
, rec
) {
221 if (value
.match(/\.[0-9a-f]/i) && rec
.data
.slot
?.count
> 1) {
222 return ` ${value}`;
229 header
: gettext('IOMMU Group'),
230 dataIndex
: 'iommugroup',
231 renderer
: (v
, _md
, rec
) => rec
.data
.slot
=== rec
.data
.id
? '' : v
=== -1 ? '-' : v
,
235 header
: gettext('Vendor'),
236 dataIndex
: 'vendor_name',
240 header
: gettext('Device'),
241 dataIndex
: 'device_name',
245 header
: gettext('Mediated Devices'),
248 renderer: function(val
) {
249 return Proxmox
.Utils
.format_boolean(!!val
);
255 selectionchange: function() {
256 this.selectionChange(...arguments
);
262 'id', 'vendor_name', 'device_name', 'vendor', 'device', 'iommugroup', 'mdev',
263 'subsystem_vendor', 'subsystem_device', 'disabled',
265 name
: 'subsystem-vendor',
266 calculate: function(data
) {
267 return data
.subsystem_vendor
;
271 name
: 'subsystem-device',
272 calculate: function(data
) {
273 return data
.subsystem_device
;
285 initComponent: function() {
288 let nodename
= me
.nodename
;
289 me
.nodename
= undefined;
293 me
.mon(me
.getStore(), 'load', me
.onLoadCallBack
);
295 Proxmox
.Utils
.monStoreErrors(me
, me
.getStore(), true);
297 me
.setNodename(nodename
);