]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/dc/Backup.js
ext6migrate: listen to 'activate' events for panels inside a tabpanel
[pve-manager.git] / www / manager6 / dc / Backup.js
1 Ext.define('PVE.dc.BackupEdit', {
2 extend: 'PVE.window.Edit',
3 alias: ['widget.pveDcBackupEdit'],
4
5 initComponent : function() {
6 /*jslint confusion: true */
7 var me = this;
8
9 me.create = !me.jobid;
10
11 var url;
12 var method;
13
14 if (me.create) {
15 url = '/api2/extjs/cluster/backup';
16 method = 'POST';
17 } else {
18 url = '/api2/extjs/cluster/backup/' + me.jobid;
19 method = 'PUT';
20 }
21
22 var vmidField = Ext.create('Ext.form.field.Hidden', {
23 name: 'vmid'
24 });
25
26 var selModeField = Ext.create('PVE.form.KVComboBox', {
27 xtype: 'pveKVComboBox',
28 data: [
29 ['include', gettext('Include selected VMs')],
30 ['all', gettext('All')],
31 ['exclude', gettext('Exclude selected VMs')]
32 ],
33 fieldLabel: gettext('Selection mode'),
34 name: 'selMode',
35 value: ''
36 });
37
38 var insideUpdate = false;
39
40 var sm = Ext.create('Ext.selection.CheckboxModel', {
41 mode: 'SIMPLE',
42 listeners: {
43 selectionchange: function(model, selected) {
44 if (!insideUpdate) { // avoid endless loop
45 var sel = [];
46 Ext.Array.each(selected, function(record) {
47 sel.push(record.data.vmid);
48 });
49
50 insideUpdate = true;
51 vmidField.setValue(sel);
52 insideUpdate = false;
53 }
54 }
55 }
56 });
57
58 var storagesel = Ext.create('PVE.form.StorageSelector', {
59 fieldLabel: gettext('Storage'),
60 nodename: 'localhost',
61 storageContent: 'backup',
62 allowBlank: false,
63 name: 'storage'
64 });
65
66 var store = new Ext.data.Store({
67 model: 'PVEResources',
68 sorters: {
69 property: 'vmid',
70 order: 'ASC'
71 }
72 });
73
74 var vmgrid = Ext.createWidget('grid', {
75 store: store,
76 border: true,
77 height: 300,
78 selModel: sm,
79 disabled: true,
80 columns: [
81 {
82 header: 'ID',
83 dataIndex: 'vmid',
84 width: 60
85 },
86 {
87 header: gettext('Node'),
88 dataIndex: 'node'
89 },
90 {
91 header: gettext('Status'),
92 dataIndex: 'uptime',
93 renderer: function(value) {
94 if (value) {
95 return PVE.Utils.runningText;
96 } else {
97 return PVE.Utils.stoppedText;
98 }
99 }
100 },
101 {
102 header: gettext('Name'),
103 dataIndex: 'name',
104 flex: 1
105 },
106 {
107 header: gettext('Type'),
108 dataIndex: 'type'
109 }
110 ]
111 });
112
113 var nodesel = Ext.create('PVE.form.NodeSelector', {
114 name: 'node',
115 fieldLabel: gettext('Node'),
116 allowBlank: true,
117 editable: true,
118 autoSelect: false,
119 emptyText: '-- ' + gettext('All') + ' --',
120 listeners: {
121 change: function(f, value) {
122 storagesel.setNodename(value || 'localhost');
123 var mode = selModeField.getValue();
124 store.clearFilter();
125 store.filterBy(function(rec) {
126 return (!value || rec.get('node') === value);
127 });
128 if (mode === 'all') {
129 sm.selectAll(true);
130 }
131 }
132 }
133 });
134
135 var column1 = [
136 nodesel,
137 storagesel,
138 {
139 xtype: 'pveDayOfWeekSelector',
140 name: 'dow',
141 fieldLabel: gettext('Day of week'),
142 multiSelect: true,
143 value: ['sat'],
144 allowBlank: false
145 },
146 {
147 xtype: 'timefield',
148 fieldLabel: gettext('Start Time'),
149 name: 'starttime',
150 format: 'H:i',
151 value: '00:00',
152 allowBlank: false
153 },
154 selModeField
155 ];
156
157 var column2 = [
158 {
159 xtype: 'textfield',
160 fieldLabel: gettext('Send email to'),
161 name: 'mailto'
162 },
163 {
164 xtype: 'pveEmailNotificationSelector',
165 fieldLabel: gettext('Email notification'),
166 name: 'mailnotification',
167 deleteEmpty: me.create ? false : true,
168 value: me.create ? 'always' : ''
169 },
170 {
171 xtype: 'pveCompressionSelector',
172 fieldLabel: gettext('Compression'),
173 name: 'compress',
174 deleteEmpty: me.create ? false : true,
175 value: me.create ? 'lzo' : ''
176 },
177 {
178 xtype: 'pveBackupModeSelector',
179 fieldLabel: gettext('Mode'),
180 value: 'snapshot',
181 name: 'mode'
182 },
183 vmidField
184 ];
185
186 var ipanel = Ext.create('PVE.panel.InputPanel', {
187 column1: column1,
188 column2: column2,
189 onGetValues: function(values) {
190 if (!values.node) {
191 if (!me.create) {
192 PVE.Utils.assemble_field_data(values, { 'delete': 'node' });
193 }
194 delete values.node;
195 }
196
197 var selMode = values.selMode;
198 delete values.selMode;
199
200 if (selMode === 'all') {
201 values.all = 1;
202 values.exclude = '';
203 delete values.vmid;
204 } else if (selMode === 'exclude') {
205 values.all = 1;
206 values.exclude = values.vmid;
207 delete values.vmid;
208 }
209 return values;
210 }
211 });
212
213 var update_vmid_selection = function(list, mode) {
214 if (insideUpdate) {
215 return; // should not happen - just to be sure
216 }
217 insideUpdate = true;
218 if (mode !== 'all') {
219 sm.deselectAll(true);
220 if (list) {
221 Ext.Array.each(list.split(','), function(vmid) {
222 var rec = store.findRecord('vmid', vmid);
223 if (rec) {
224 sm.select(rec, true);
225 }
226 });
227 }
228 }
229 insideUpdate = false;
230 };
231
232 vmidField.on('change', function(f, value) {
233 var mode = selModeField.getValue();
234 update_vmid_selection(value, mode);
235 });
236
237 selModeField.on('change', function(f, value, oldValue) {
238 if (value === 'all') {
239 sm.selectAll(true);
240 vmgrid.setDisabled(true);
241 } else {
242 vmgrid.setDisabled(false);
243 }
244 if (oldValue === 'all') {
245 sm.deselectAll(true);
246 vmidField.setValue('');
247 }
248 var list = vmidField.getValue();
249 update_vmid_selection(list, value);
250 });
251
252 var reload = function() {
253 store.load({
254 params: { type: 'vm' },
255 callback: function() {
256 var node = nodesel.getValue();
257 store.clearFilter();
258 store.filterBy(function(rec) {
259 return (!node || rec.get('node') === node);
260 });
261 var list = vmidField.getValue();
262 var mode = selModeField.getValue();
263 if (mode === 'all') {
264 sm.selectAll(true);
265 } else {
266 update_vmid_selection(list, mode);
267 }
268 }
269 });
270 };
271
272 Ext.applyIf(me, {
273 subject: gettext("Backup Job"),
274 url: url,
275 method: method,
276 items: [ ipanel, vmgrid ]
277 });
278
279 me.callParent();
280
281 if (me.create) {
282 selModeField.setValue('include');
283 } else {
284 me.load({
285 success: function(response, options) {
286 var data = response.result.data;
287
288 data.dow = data.dow.split(',');
289
290 if (data.all || data.exclude) {
291 if (data.exclude) {
292 data.vmid = data.exclude;
293 data.selMode = 'exclude';
294 } else {
295 data.vmid = '';
296 data.selMode = 'all';
297 }
298 } else {
299 data.selMode = 'include';
300 }
301
302 me.setValues(data);
303 }
304 });
305 }
306
307 reload();
308 }
309 });
310
311
312 Ext.define('PVE.dc.BackupView', {
313 extend: 'Ext.grid.GridPanel',
314
315 alias: ['widget.pveDcBackupView'],
316
317 allText: '-- ' + gettext('All') + ' --',
318 allExceptText: gettext('All except {0}'),
319
320 initComponent : function() {
321 var me = this;
322
323 var store = new Ext.data.Store({
324 model: 'pve-cluster-backup',
325 proxy: {
326 type: 'pve',
327 url: "/api2/json/cluster/backup"
328 }
329 });
330
331 var reload = function() {
332 store.load();
333 };
334
335 var sm = Ext.create('Ext.selection.RowModel', {});
336
337 var run_editor = function() {
338 var rec = sm.getSelection()[0];
339 if (!rec) {
340 return;
341 }
342
343 var win = Ext.create('PVE.dc.BackupEdit',{
344 jobid: rec.data.id
345 });
346 win.on('destroy', reload);
347 win.show();
348 };
349
350 var edit_btn = new PVE.button.Button({
351 text: gettext('Edit'),
352 disabled: true,
353 selModel: sm,
354 handler: run_editor
355 });
356
357 var remove_btn = new PVE.button.Button({
358 text: gettext('Remove'),
359 disabled: true,
360 selModel: sm,
361 confirmMsg: gettext('Are you sure you want to remove this entry'),
362 handler: function(btn, event, rec) {
363 PVE.Utils.API2Request({
364 url: '/cluster/backup/' + rec.data.id,
365 method: 'DELETE',
366 waitMsgTarget: me,
367 callback: function() {
368 reload();
369 },
370 failure: function (response, opts) {
371 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
372 }
373 });
374 }
375 });
376
377 PVE.Utils.monStoreErrors(me, store);
378
379 Ext.apply(me, {
380 store: store,
381 selModel: sm,
382 stateful: false,
383 viewConfig: {
384 trackOver: false
385 },
386 tbar: [
387 {
388 text: gettext('Add'),
389 handler: function() {
390 var win = Ext.create('PVE.dc.BackupEdit',{});
391 win.on('destroy', reload);
392 win.show();
393 }
394 },
395 remove_btn,
396 edit_btn
397 ],
398 columns: [
399 {
400 header: gettext('Node'),
401 width: 100,
402 sortable: true,
403 dataIndex: 'node',
404 renderer: function(value) {
405 if (value) {
406 return value;
407 }
408 return me.allText;
409 }
410 },
411 {
412 header: gettext('Day of week'),
413 width: 200,
414 sortable: false,
415 dataIndex: 'dow'
416 },
417 {
418 header: gettext('Start Time'),
419 width: 60,
420 sortable: true,
421 dataIndex: 'starttime'
422 },
423 {
424 header: gettext('Storage'),
425 width: 100,
426 sortable: true,
427 dataIndex: 'storage'
428 },
429 {
430 header: gettext('Selection'),
431 flex: 1,
432 sortable: false,
433 dataIndex: 'vmid',
434 renderer: function(value, metaData, record) {
435 /*jslint confusion: true */
436 if (record.data.all) {
437 if (record.data.exclude) {
438 return Ext.String.format(me.allExceptText, record.data.exclude);
439 }
440 return me.allText;
441 }
442 if (record.data.vmid) {
443 return record.data.vmid;
444 }
445
446 return "-";
447 }
448 }
449 ],
450 listeners: {
451 activate: reload,
452 itemdblclick: run_editor
453 }
454 });
455
456 me.callParent();
457 }
458 }, function() {
459
460 Ext.define('pve-cluster-backup', {
461 extend: 'Ext.data.Model',
462 fields: [
463 'id', 'starttime', 'dow',
464 'storage', 'node', 'vmid', 'exclude',
465 'mailto',
466 { name: 'all', type: 'boolean' },
467 { name: 'snapshot', type: 'boolean' },
468 { name: 'stop', type: 'boolean' },
469 { name: 'suspend', type: 'boolean' },
470 { name: 'compress', type: 'boolean' }
471 ]
472 });
473 });