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