]>
Commit | Line | Data |
---|---|---|
42aff488 DC |
1 | /* filter is a javascript builtin, but extjs calls it also filter */ |
2 | Ext.define('PVE.form.VMSelector', { | |
3 | extend: 'Ext.grid.Panel', | |
4 | alias: 'widget.vmselector', | |
5 | ||
6 | mixins: { | |
f6710aac | 7 | field: 'Ext.form.field.Field', |
42aff488 DC |
8 | }, |
9 | ||
10 | allowBlank: true, | |
11 | selectAll: false, | |
12 | isFormField: true, | |
13 | ||
14 | plugins: 'gridfilters', | |
15 | ||
16 | store: { | |
17 | model: 'PVEResources', | |
18 | autoLoad: true, | |
19 | sorters: 'vmid', | |
20 | filters: [{ | |
21 | property: 'type', | |
f6710aac TL |
22 | value: /lxc|qemu/, |
23 | }], | |
42aff488 DC |
24 | }, |
25 | columns: [ | |
26 | { | |
27 | header: 'ID', | |
28 | dataIndex: 'vmid', | |
29 | width: 80, | |
30 | filter: { | |
f6710aac TL |
31 | type: 'number', |
32 | }, | |
42aff488 DC |
33 | }, |
34 | { | |
35 | header: gettext('Node'), | |
f6710aac | 36 | dataIndex: 'node', |
42aff488 DC |
37 | }, |
38 | { | |
39 | header: gettext('Status'), | |
40 | dataIndex: 'status', | |
41 | filter: { | |
f6710aac TL |
42 | type: 'list', |
43 | }, | |
42aff488 DC |
44 | }, |
45 | { | |
46 | header: gettext('Name'), | |
47 | dataIndex: 'name', | |
48 | flex: 1, | |
49 | filter: { | |
f6710aac TL |
50 | type: 'string', |
51 | }, | |
42aff488 DC |
52 | }, |
53 | { | |
54 | header: gettext('Pool'), | |
55 | dataIndex: 'pool', | |
56 | filter: { | |
f6710aac TL |
57 | type: 'list', |
58 | }, | |
42aff488 DC |
59 | }, |
60 | { | |
61 | header: gettext('Type'), | |
62 | dataIndex: 'type', | |
63 | width: 120, | |
64 | renderer: function(value) { | |
65 | if (value === 'qemu') { | |
66 | return gettext('Virtual Machine'); | |
67 | } else if (value === 'lxc') { | |
68 | return gettext('LXC Container'); | |
69 | } | |
70 | ||
71 | return ''; | |
72 | }, | |
73 | filter: { | |
74 | type: 'list', | |
75 | store: { | |
76 | data: [ | |
8058410f TL |
77 | { id: 'qemu', text: gettext('Virtual Machine') }, |
78 | { id: 'lxc', text: gettext('LXC Container') }, | |
42aff488 | 79 | ], |
5807b3a0 TL |
80 | un: function() { |
81 | // Due to EXTJS-18711. we have to do a static list via a store but to avoid | |
82 | // creating an object, we have to have an empty pseudo un function | |
83 | }, | |
f6710aac TL |
84 | }, |
85 | }, | |
c9329af1 TL |
86 | }, |
87 | { | |
88 | header: 'HA ' + gettext('Status'), | |
89 | dataIndex: 'hastate', | |
90 | flex: 1, | |
91 | filter: { | |
f6710aac TL |
92 | type: 'list', |
93 | }, | |
94 | }, | |
42aff488 DC |
95 | ], |
96 | ||
97 | selModel: { | |
98 | selType: 'checkboxmodel', | |
f6710aac | 99 | mode: 'SIMPLE', |
42aff488 DC |
100 | }, |
101 | ||
102 | checkChangeEvents: [ | |
103 | 'selectionchange', | |
f6710aac | 104 | 'change', |
42aff488 DC |
105 | ], |
106 | ||
107 | listeners: { | |
108 | selectionchange: function() { | |
109 | // to trigger validity and error checks | |
110 | this.checkChange(); | |
f6710aac | 111 | }, |
42aff488 DC |
112 | }, |
113 | ||
114 | getValue: function() { | |
115 | var me = this; | |
116 | var sm = me.getSelectionModel(); | |
117 | var selection = sm.getSelection(); | |
118 | var values = []; | |
119 | var store = me.getStore(); | |
120 | selection.forEach(function(item) { | |
121 | // only add if not filtered | |
122 | if (store.findExact('vmid', item.data.vmid) !== -1) { | |
123 | values.push(item.data.vmid); | |
124 | } | |
125 | }); | |
126 | return values; | |
127 | }, | |
128 | ||
129 | setValue: function(value) { | |
5807b3a0 | 130 | let me = this; |
42aff488 DC |
131 | if (!Ext.isArray(value)) { |
132 | value = value.split(','); | |
133 | } | |
42aff488 | 134 | |
5807b3a0 TL |
135 | let store = me.getStore(); |
136 | let selection = value.map(item => store.findRecord('vmid', item, 0, false, true, true)).filter(r => r); | |
42aff488 | 137 | |
5807b3a0 | 138 | me.getSelectionModel().select(selection); |
42aff488 DC |
139 | |
140 | return me.mixins.field.setValue.call(me, value); | |
141 | }, | |
142 | ||
143 | getErrors: function(value) { | |
5807b3a0 | 144 | let me = this; |
8058410f | 145 | if (me.allowBlank === false && |
42aff488 | 146 | me.getSelectionModel().getCount() === 0) { |
f6710aac | 147 | me.addBodyCls(['x-form-trigger-wrap-default', 'x-form-trigger-wrap-invalid']); |
42aff488 DC |
148 | return [gettext('No VM selected')]; |
149 | } | |
150 | ||
f6710aac | 151 | me.removeBodyCls(['x-form-trigger-wrap-default', 'x-form-trigger-wrap-invalid']); |
42aff488 DC |
152 | return []; |
153 | }, | |
154 | ||
155 | initComponent: function() { | |
5807b3a0 | 156 | let me = this; |
42aff488 DC |
157 | |
158 | me.callParent(); | |
159 | ||
160 | if (me.nodename) { | |
161 | me.store.filters.add({ | |
162 | property: 'node', | |
5c6b8a65 | 163 | exactMatch: true, |
f6710aac | 164 | value: me.nodename, |
42aff488 DC |
165 | }); |
166 | } | |
167 | ||
eb882c6f DC |
168 | // only show the relevant guests by default |
169 | if (me.action) { | |
919ae0f7 | 170 | var statusfilter = ''; |
eb882c6f DC |
171 | switch (me.action) { |
172 | case 'startall': | |
919ae0f7 | 173 | statusfilter = 'stopped'; |
eb882c6f DC |
174 | break; |
175 | case 'stopall': | |
919ae0f7 | 176 | statusfilter = 'running'; |
eb882c6f DC |
177 | break; |
178 | } | |
919ae0f7 DC |
179 | if (statusfilter !== '') { |
180 | me.store.filters.add({ | |
181 | property: 'template', | |
f6710aac TL |
182 | value: 0, |
183 | }, { | |
919ae0f7 DC |
184 | id: 'x-gridfilter-status', |
185 | operator: 'in', | |
186 | property: 'status', | |
f6710aac | 187 | value: [statusfilter], |
919ae0f7 DC |
188 | }); |
189 | } | |
eb882c6f DC |
190 | } |
191 | ||
42aff488 | 192 | if (me.selectAll) { |
5807b3a0 | 193 | me.mon(me.getStore(), 'load', function() { |
42aff488 DC |
194 | me.getSelectionModel().selectAll(false); |
195 | }); | |
196 | } | |
f6710aac | 197 | }, |
42aff488 | 198 | }); |
a86b4daf TL |
199 | |
200 | ||
201 | Ext.define('PVE.form.VMComboSelector', { | |
0fc95a12 | 202 | extend: 'Proxmox.form.ComboGrid', |
a86b4daf TL |
203 | alias: 'widget.vmComboSelector', |
204 | ||
205 | valueField: 'vmid', | |
206 | displayField: 'vmid', | |
207 | ||
208 | autoSelect: false, | |
209 | editable: true, | |
210 | anyMatch: true, | |
211 | forceSelection: true, | |
212 | ||
213 | store: { | |
214 | model: 'PVEResources', | |
215 | autoLoad: true, | |
216 | sorters: 'vmid', | |
217 | filters: [{ | |
218 | property: 'type', | |
f6710aac TL |
219 | value: /lxc|qemu/, |
220 | }], | |
a86b4daf TL |
221 | }, |
222 | ||
223 | listConfig: { | |
224 | width: 600, | |
225 | plugins: 'gridfilters', | |
226 | columns: [ | |
227 | { | |
228 | header: 'ID', | |
229 | dataIndex: 'vmid', | |
230 | width: 80, | |
231 | filter: { | |
f6710aac TL |
232 | type: 'number', |
233 | }, | |
a86b4daf TL |
234 | }, |
235 | { | |
236 | header: gettext('Name'), | |
237 | dataIndex: 'name', | |
238 | flex: 1, | |
239 | filter: { | |
f6710aac TL |
240 | type: 'string', |
241 | }, | |
a86b4daf TL |
242 | }, |
243 | { | |
244 | header: gettext('Node'), | |
f6710aac | 245 | dataIndex: 'node', |
a86b4daf TL |
246 | }, |
247 | { | |
248 | header: gettext('Status'), | |
249 | dataIndex: 'status', | |
250 | filter: { | |
f6710aac TL |
251 | type: 'list', |
252 | }, | |
a86b4daf TL |
253 | }, |
254 | { | |
255 | header: gettext('Pool'), | |
256 | dataIndex: 'pool', | |
257 | hidden: true, | |
258 | filter: { | |
f6710aac TL |
259 | type: 'list', |
260 | }, | |
a86b4daf TL |
261 | }, |
262 | { | |
263 | header: gettext('Type'), | |
264 | dataIndex: 'type', | |
265 | width: 120, | |
266 | renderer: function(value) { | |
267 | if (value === 'qemu') { | |
268 | return gettext('Virtual Machine'); | |
269 | } else if (value === 'lxc') { | |
270 | return gettext('LXC Container'); | |
271 | } | |
272 | ||
273 | return ''; | |
274 | }, | |
275 | filter: { | |
276 | type: 'list', | |
277 | store: { | |
278 | data: [ | |
8058410f TL |
279 | { id: 'qemu', text: gettext('Virtual Machine') }, |
280 | { id: 'lxc', text: gettext('LXC Container') }, | |
a86b4daf | 281 | ], |
5807b3a0 | 282 | un: function() { /* due to EXTJS-18711 */ }, |
f6710aac TL |
283 | }, |
284 | }, | |
a86b4daf TL |
285 | }, |
286 | { | |
287 | header: 'HA ' + gettext('Status'), | |
288 | dataIndex: 'hastate', | |
289 | hidden: true, | |
290 | flex: 1, | |
291 | filter: { | |
f6710aac TL |
292 | type: 'list', |
293 | }, | |
294 | }, | |
295 | ], | |
296 | }, | |
a86b4daf | 297 | }); |