]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/window/BulkAction.js
1 Ext
.define('PVE.window.BulkAction', {
2 extend
: 'Ext.window.Window',
13 // the action to set, currently there are: `startall`, `migrateall`, `stopall`, `suspendall`
16 submit: function(params
) {
19 Proxmox
.Utils
.API2Request({
21 url
: `/nodes/${me.nodename}/${me.action}`,
24 failure
: response
=> Ext
.Msg
.alert('Error', response
.htmlStatus
),
25 success: function({ result
}, options
) {
26 Ext
.create('Proxmox.window.TaskViewer', {
30 destroy
: () => me
.close(),
38 initComponent: function() {
42 throw "no node name specified";
45 throw "no action specified";
48 throw "no button text specified";
51 throw "no title specified";
55 if (me
.action
=== 'migrateall') {
58 xtype
: 'fieldcontainer',
62 xtype
: 'pveNodeSelector',
64 disallowedNodes
: [me
.nodename
],
65 fieldLabel
: gettext('Target node'),
68 onlineValidator
: true,
72 xtype
: 'proxmoxintegerfield',
77 fieldLabel
: gettext('Parallel jobs'),
83 xtype
: 'fieldcontainer',
86 xtype
: 'proxmoxcheckbox',
87 fieldLabel
: gettext('Allow local disk migration'),
88 name
: 'with-local-disks',
97 xtype
: 'displayfield',
99 value
: 'Warning: Running CTs will be migrated in Restart Mode.',
100 hidden
: true, // only visible if running container chosen
105 } else if (me
.action
=== 'startall') {
107 xtype
: 'hiddenfield',
111 } else if (me
.action
=== 'stopall') {
113 xtype
: 'fieldcontainer',
116 xtype
: 'proxmoxcheckbox',
119 fieldLabel
: gettext('Force Stop'),
120 boxLabel
: gettext('Force stop guest if shutdown times out.'),
126 xtype
: 'proxmoxintegerfield',
128 fieldLabel
: gettext('Timeout (s)'),
139 let refreshLxcWarning = function(vmids
, records
) {
140 let showWarning
= records
.some(
141 item
=> vmids
.includes(item
.data
.vmid
) && item
.data
.type
=== 'lxc' && item
.data
.status
=== 'running',
143 me
.down('#lxcwarning').setVisible(showWarning
);
146 let defaultStatus
= me
.action
=== 'migrateall' ? '' : me
.action
=== 'startall' ? 'stopped' : 'running';
147 let defaultType
= me
.action
=== 'suspendall' ? 'qemu' : '';
153 PVE
.data
.ResourceStore
.each((rec
) => {
154 if (['qemu', 'lxc'].indexOf(rec
.data
.type
) !== -1) {
155 statusMap
[rec
.data
.status
] = true;
157 if (rec
.data
.type
=== 'pool') {
158 poolMap
[rec
.data
.pool
] = true;
160 if (rec
.data
.hastate
!== "") {
161 haMap
[rec
.data
.hastate
] = true;
163 if (rec
.data
.tags
!== "") {
164 rec
.data
.tags
.split(/[,; ]/).forEach((tag
) => {
172 let statusList
= Object
.keys(statusMap
).map(key
=> [key
, key
]);
173 statusList
.unshift(['', gettext('All')]);
174 let poolList
= Object
.keys(poolMap
).map(key
=> [key
, key
]);
175 let tagList
= Object
.keys(tagMap
).map(key
=> ({ value
: key
}));
176 let haList
= Object
.keys(haMap
).map(key
=> [key
, key
]);
178 let clearFilters = function() {
179 me
.down('#namefilter').setValue('');
180 ['name', 'status', 'pool', 'type', 'hastate', 'includetag', 'excludetag', 'vmid'].forEach((filter
) => {
181 me
.down(`#${filter}filter`).setValue('');
185 let filterChange = function() {
186 let nameValue
= me
.down('#namefilter').getValue();
189 if (nameValue
!== '') {
193 let arrayFiltersData
= [];
194 ['pool', 'hastate'].forEach((filter
) => {
195 let selected
= me
.down(`#${filter}filter`).getValue() ?? [];
196 if (selected
.length
) {
198 arrayFiltersData
.push([filter
, [...selected
]]);
202 let singleFiltersData
= [];
203 ['status', 'type'].forEach((filter
) => {
204 let selected
= me
.down(`#${filter}filter`).getValue() ?? '';
205 if (selected
.length
) {
207 singleFiltersData
.push([filter
, selected
]);
211 let includeTags
= me
.down('#includetagfilter').getValue() ?? [];
212 if (includeTags
.length
) {
215 let excludeTags
= me
.down('#excludetagfilter').getValue() ?? [];
216 if (excludeTags
.length
) {
220 let fieldSet
= me
.down('#filters');
221 let clearBtn
= me
.down('#clearBtn');
223 fieldSet
.setTitle(Ext
.String
.format(gettext('Filters ({0})'), filterCount
));
224 clearBtn
.setDisabled(false);
226 fieldSet
.setTitle(gettext('Filters'));
227 clearBtn
.setDisabled(true);
230 let filterFn = function(value
) {
231 let name
= value
.data
.name
.toLowerCase().indexOf(nameValue
.toLowerCase()) !== -1;
232 let arrayFilters
= arrayFiltersData
.every(([filter
, selected
]) =>
233 !selected
.length
|| selected
.indexOf(value
.data
[filter
]) !== -1);
234 let singleFilters
= singleFiltersData
.every(([filter
, selected
]) =>
235 !selected
.length
|| value
.data
[filter
].indexOf(selected
) !== -1);
236 let tags
= value
.data
.tags
.split(/[;, ]/).filter(t
=> !!t
);
237 let includeFilter
= !includeTags
.length
|| tags
.some(tag
=> includeTags
.indexOf(tag
) !== -1);
238 let excludeFilter
= !excludeTags
.length
|| tags
.every(tag
=> excludeTags
.indexOf(tag
) === -1);
240 return name
&& arrayFilters
&& singleFilters
&& includeFilter
&& excludeFilter
;
242 let vmselector
= me
.down('#vms');
243 vmselector
.getStore().setFilters({
247 vmselector
.checkChange();
248 if (me
.action
=== 'migrateall') {
249 let records
= vmselector
.getSelection();
250 refreshLxcWarning(vmselector
.getValue(), records
);
258 title
: gettext('Filters'),
271 change
: filterChange
,
277 fieldLabel
: gettext("Name"),
278 itemId
: 'namefilter',
283 itemId
: 'statusfilter',
284 fieldLabel
: gettext("Status"),
285 emptyText
: gettext('All'),
287 value
: defaultStatus
,
292 itemId
: 'poolfilter',
293 fieldLabel
: gettext("Pool"),
294 emptyText
: gettext('All'),
311 change
: filterChange
,
318 itemId
: 'typefilter',
319 fieldLabel
: gettext("Type"),
320 emptyText
: gettext('All'),
324 ['', gettext('All')],
325 ['lxc', gettext('CT')],
326 ['qemu', gettext('VM')],
330 xtype
: 'proxmoxComboGrid',
331 itemId
: 'includetagfilter',
332 fieldLabel
: gettext("Include Tags"),
333 emptyText
: gettext('All'),
337 displayField
: 'value',
339 userCls
: 'proxmox-tags-full',
345 PVE
.Utils
.renderTags(value
, PVE
.UIOptions
.tagOverrides
),
353 change
: filterChange
,
357 xtype
: 'proxmoxComboGrid',
358 itemId
: 'excludetagfilter',
359 fieldLabel
: gettext("Exclude Tags"),
360 emptyText
: gettext('None'),
364 displayField
: 'value',
366 userCls
: 'proxmox-tags-full',
372 PVE
.Utils
.renderTags(value
, PVE
.UIOptions
.tagOverrides
),
380 change
: filterChange
,
395 change
: filterChange
,
402 itemId
: 'hastatefilter',
403 fieldLabel
: gettext("HA status"),
404 emptyText
: gettext('All'),
409 change
: filterChange
,
422 text
: gettext('Clear Filters'),
424 handler
: clearFilters
,
442 nodename
: me
.nodename
,
444 selectionchange: function(vmselector
, records
) {
445 if (me
.action
=== 'migrateall') {
446 let vmids
= me
.down('#vms').getValue();
447 refreshLxcWarning(vmids
, records
);
453 me
.formPanel
= Ext
.create('Ext.form.Panel', {
466 let form
= me
.formPanel
.getForm();
468 let submitBtn
= Ext
.create('Ext.Button', {
470 handler: function() {
472 me
.submit(form
.getValues());
477 items
: [me
.formPanel
],
478 buttons
: [submitBtn
],
483 form
.on('validitychange', function() {
484 let valid
= form
.isValid();
485 submitBtn
.setDisabled(!valid
);