]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/form/USBSelector.js
355bc88ccd002e6e16eea000347bd6ce47cce9e2
[pve-manager.git] / www / manager6 / form / USBSelector.js
1 Ext.define('PVE.form.USBSelector', {
2 extend: 'Proxmox.form.ComboGrid',
3 alias: ['widget.pveUSBSelector'],
4
5 allowBlank: false,
6 autoSelect: false,
7 anyMatch: true,
8 displayField: 'product_and_id',
9 valueField: 'usbid',
10 editable: true,
11
12 validator: function(value) {
13 var me = this;
14 if (!value) {
15 return true; // handled later by allowEmpty in the getErrors call chain
16 }
17 value = me.getValue(); // as the valueField is not the displayfield
18 if (me.type === 'device') {
19 return (/^[a-f0-9]{4}\:[a-f0-9]{4}$/i).test(value);
20 } else if (me.type === 'port') {
21 return (/^[0-9]+\-[0-9]+(\.[0-9]+)*$/).test(value);
22 }
23 return gettext("Invalid Value");
24 },
25
26 initComponent: function() {
27 var me = this;
28
29 var nodename = me.pveSelNode.data.node;
30
31 if (!nodename) {
32 throw "no nodename specified";
33 }
34
35 if (me.type !== 'device' && me.type !== 'port') {
36 throw "no valid type specified";
37 }
38
39 var store = new Ext.data.Store({
40 model: 'pve-usb-' + me.type,
41 proxy: {
42 type: 'proxmox',
43 url: `/api2/json/nodes/${nodename}/hardware/usb`,
44 },
45 filters: [
46 function(item) {
47 return !!item.data.usbpath && !!item.data.prodid && item.data['class'] != 9;
48 },
49 ],
50 });
51 let emptyText = '';
52 if (me.type === 'device') {
53 emptyText = gettext('Passthrough a specific device');
54 } else {
55 emptyText = gettext('Passthrough a full port');
56 }
57
58 Ext.apply(me, {
59 store: store,
60 emptyText: emptyText,
61 listConfig: {
62 width: 520,
63 columns: [
64 {
65 header: me.type === 'device'?gettext('Device'):gettext('Port'),
66 sortable: true,
67 dataIndex: 'usbid',
68 width: 80,
69 },
70 {
71 header: gettext('Manufacturer'),
72 sortable: true,
73 dataIndex: 'manufacturer',
74 width: 150,
75 },
76 {
77 header: gettext('Product'),
78 sortable: true,
79 dataIndex: 'product',
80 flex: 1,
81 },
82 {
83 header: gettext('Speed'),
84 width: 75,
85 sortable: true,
86 dataIndex: 'speed',
87 renderer: function(value) {
88 let speed_map = {
89 "10000": "USB 3.1",
90 "5000": "USB 3.0",
91 "480": "USB 2.0",
92 "12": "USB 1.x",
93 "1.5": "USB 1.x",
94 };
95 return speed_map[value] || value + " Mbps";
96 },
97 },
98 ],
99 },
100 });
101
102 me.callParent();
103
104 store.load();
105 },
106
107 }, function() {
108 Ext.define('pve-usb-device', {
109 extend: 'Ext.data.Model',
110 fields: [
111 {
112 name: 'usbid',
113 convert: function(val, data) {
114 if (val) {
115 return val;
116 }
117 return data.get('vendid') + ':' + data.get('prodid');
118 },
119 },
120 'speed', 'product', 'manufacturer', 'vendid', 'prodid', 'usbpath',
121 { name: 'port', type: 'number' },
122 { name: 'level', type: 'number' },
123 { name: 'class', type: 'number' },
124 { name: 'devnum', type: 'number' },
125 { name: 'busnum', type: 'number' },
126 {
127 name: 'product_and_id',
128 type: 'string',
129 convert: (v, rec) => {
130 let res = rec.data.product || gettext('Unkown');
131 res += " (" + rec.data.usbid + ")";
132 return res;
133 },
134 },
135 ],
136 });
137
138 Ext.define('pve-usb-port', {
139 extend: 'Ext.data.Model',
140 fields: [
141 {
142 name: 'usbid',
143 convert: function(val, data) {
144 if (val) {
145 return val;
146 }
147 return data.get('busnum') + '-' + data.get('usbpath');
148 },
149 },
150 'speed', 'product', 'manufacturer', 'vendid', 'prodid', 'usbpath',
151 { name: 'port', type: 'number' },
152 { name: 'level', type: 'number' },
153 { name: 'class', type: 'number' },
154 { name: 'devnum', type: 'number' },
155 { name: 'busnum', type: 'number' },
156 {
157 name: 'product_and_id',
158 type: 'string',
159 convert: (v, rec) => {
160 let res = rec.data.product || gettext('Unplugged');
161 res += " (" + rec.data.usbid + ")";
162 return res;
163 },
164 },
165 ],
166 });
167 });