]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/window/BulkAction.js
ui: bulk shutdown: expose new timeout and force-stop to user
[pve-manager.git] / www / manager6 / window / BulkAction.js
1 Ext.define('PVE.window.BulkAction', {
2 extend: 'Ext.window.Window',
3
4 resizable: true,
5 width: 800,
6 modal: true,
7 layout: {
8 type: 'fit',
9 },
10 border: false,
11
12 // the action to set, currently there are: `startall`, `migrateall`, `stopall`
13 action: undefined,
14
15 submit: function(params) {
16 let me = this;
17
18 Proxmox.Utils.API2Request({
19 params: params,
20 url: `/nodes/${me.nodename}/${me.action}`,
21 waitMsgTarget: me,
22 method: 'POST',
23 failure: response => Ext.Msg.alert('Error', response.htmlStatus),
24 success: function({ result }, options) {
25 Ext.create('Proxmox.window.TaskViewer', {
26 autoShow: true,
27 upid: result.data,
28 listeners: {
29 destroy: () => me.close(),
30 },
31 });
32 me.hide();
33 },
34 });
35 },
36
37 initComponent: function() {
38 let me = this;
39
40 if (!me.nodename) {
41 throw "no node name specified";
42 }
43 if (!me.action) {
44 throw "no action specified";
45 }
46 if (!me.btnText) {
47 throw "no button text specified";
48 }
49 if (!me.title) {
50 throw "no title specified";
51 }
52
53 let items = [];
54 if (me.action === 'migrateall') {
55 items.push(
56 {
57 xtype: 'pveNodeSelector',
58 name: 'target',
59 disallowedNodes: [me.nodename],
60 fieldLabel: gettext('Target node'),
61 allowBlank: false,
62 onlineValidator: true,
63 },
64 {
65 xtype: 'proxmoxintegerfield',
66 name: 'maxworkers',
67 minValue: 1,
68 maxValue: 100,
69 value: 1,
70 fieldLabel: gettext('Parallel jobs'),
71 allowBlank: false,
72 },
73 {
74 xtype: 'fieldcontainer',
75 fieldLabel: gettext('Allow local disk migration'),
76 layout: 'hbox',
77 items: [{
78 xtype: 'proxmoxcheckbox',
79 name: 'with-local-disks',
80 checked: true,
81 uncheckedValue: 0,
82 listeners: {
83 change: (cb, val) => me.down('#localdiskwarning').setVisible(val),
84 },
85 },
86 {
87 itemId: 'localdiskwarning',
88 xtype: 'displayfield',
89 flex: 1,
90 padding: '0 0 0 10',
91 userCls: 'pmx-hint',
92 value: 'Note: Migration with local disks might take long.',
93 }],
94 },
95 {
96 itemId: 'lxcwarning',
97 xtype: 'displayfield',
98 userCls: 'pmx-hint',
99 value: 'Warning: Running CTs will be migrated in Restart Mode.',
100 hidden: true, // only visible if running container chosen
101 },
102 );
103 } else if (me.action === 'startall') {
104 items.push({
105 xtype: 'hiddenfield',
106 name: 'force',
107 value: 1,
108 });
109 } else if (me.action === 'stopall') {
110 items.push(
111 {
112 xtype: 'proxmoxcheckbox',
113 name: 'force-stop',
114 fieldLabel: gettext('Force Stop'),
115 boxLabel: gettext('Force stop guest if shutdown times out.'),
116 checked: true,
117 uncheckedValue: 0,
118 },
119 {
120 xtype: 'proxmoxintegerfield',
121 name: 'timeout',
122 fieldLabel: gettext('Timeout (s)'),
123 emptyText: '180',
124 minValue: 0,
125 maxValue: 7200,
126 allowBlank: true,
127 },
128 );
129 }
130
131 items.push({
132 xtype: 'vmselector',
133 itemId: 'vms',
134 name: 'vms',
135 flex: 1,
136 height: 300,
137 selectAll: true,
138 allowBlank: false,
139 nodename: me.nodename,
140 action: me.action,
141 listeners: {
142 selectionchange: function(vmselector, records) {
143 if (me.action === 'migrateall') {
144 let showWarning = records.some(
145 item => item.data.type === 'lxc' && item.data.status === 'running',
146 );
147 me.down('#lxcwarning').setVisible(showWarning);
148 }
149 },
150 },
151 });
152
153 me.formPanel = Ext.create('Ext.form.Panel', {
154 bodyPadding: 10,
155 border: false,
156 layout: {
157 type: 'vbox',
158 align: 'stretch',
159 },
160 fieldDefaults: {
161 labelWidth: me.action === 'migrateall' ? 300 : 120,
162 anchor: '100%',
163 },
164 items: items,
165 });
166
167 let form = me.formPanel.getForm();
168
169 let submitBtn = Ext.create('Ext.Button', {
170 text: me.btnText,
171 handler: function() {
172 form.isValid();
173 me.submit(form.getValues());
174 },
175 });
176
177 Ext.apply(me, {
178 items: [me.formPanel],
179 buttons: [submitBtn],
180 });
181
182 me.callParent();
183
184 form.on('validitychange', function() {
185 let valid = form.isValid();
186 submitBtn.setDisabled(!valid);
187 });
188 form.isValid();
189 },
190 });