]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/storage/ContentView.js
copy storage/ContentView.js from manager to manager6
[pve-manager.git] / www / manager6 / storage / ContentView.js
CommitLineData
4a580e60
DM
1Ext.define('PVE.grid.TemplateSelector', {
2 extend: 'Ext.grid.GridPanel',
3
4 alias: ['widget.pveTemplateSelector'],
5
6 initComponent : function() {
7 var me = this;
8
9 if (!me.nodename) {
10 throw "no node name specified";
11 }
12
13 var baseurl = "/nodes/" + me.nodename + "/aplinfo";
14 var store = new Ext.data.Store({
15 model: 'pve-aplinfo',
16 groupField: 'section',
17 proxy: {
18 type: 'pve',
19 url: '/api2/json' + baseurl
20 }
21 });
22
23 var sm = Ext.create('Ext.selection.RowModel', {});
24
25 var groupingFeature = Ext.create('Ext.grid.feature.Grouping',{
26 groupHeaderTpl: '{[ "Section: " + values.name ]} ({rows.length} Item{[values.rows.length > 1 ? "s" : ""]})'
27 });
28
29 var reload = function() {
30 store.load();
31 };
32
33 PVE.Utils.monStoreErrors(me, store);
34
35 Ext.apply(me, {
36 store: store,
37 selModel: sm,
38 stateful: false,
39 viewConfig: {
40 trackOver: false
41 },
42 features: [ groupingFeature ],
43 columns: [
44 {
45 header: gettext('Type'),
46 width: 80,
47 dataIndex: 'type'
48 },
49 {
50 header: gettext('Package'),
51 flex: 1,
52 dataIndex: 'package'
53 },
54 {
55 header: gettext('Version'),
56 width: 80,
57 dataIndex: 'version'
58 },
59 {
60 header: gettext('Description'),
61 flex: 1.5,
62 dataIndex: 'headline'
63 }
64 ],
65 listeners: {
66 afterRender: reload
67 }
68 });
69
70 me.callParent();
71 }
72
73}, function() {
74
75 Ext.define('pve-aplinfo', {
76 extend: 'Ext.data.Model',
77 fields: [
78 'template', 'type', 'package', 'version', 'headline', 'infopage',
79 'description', 'os', 'section'
80 ],
81 idProperty: 'template'
82 });
83
84});
85
86Ext.define('PVE.storage.TemplateDownload', {
87 extend: 'Ext.window.Window',
88 alias: ['widget.pveTemplateDownload'],
89
90 modal: true,
91
92 initComponent : function() {
93 /*jslint confusion: true */
94 var me = this;
95
96 var grid = Ext.create('PVE.grid.TemplateSelector', {
97 border: false,
98 autoScroll: true,
99 nodename: me.nodename
100 });
101
102 var sm = grid.getSelectionModel();
103
104 var submitBtn = Ext.create('PVE.button.Button', {
105 text: gettext('Download'),
106 disabled: true,
107 selModel: sm,
108 handler: function(button, event, rec) {
109 PVE.Utils.API2Request({
110 url: '/nodes/' + me.nodename + '/aplinfo',
111 params: {
112 storage: me.storage,
113 template: rec.data.template
114 },
115 method: 'POST',
116 failure: function (response, opts) {
117 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
118 },
119 success: function(response, options) {
120 var upid = response.result.data;
121
122 var win = Ext.create('PVE.window.TaskViewer', {
123 upid: upid
124 });
125 win.show();
126 me.close();
127 }
128 });
129 }
130 });
131
132 Ext.applyIf(me, {
133 title: gettext('Templates'),
134 layout: 'fit',
135 width: 600,
136 height: 400,
137 items: grid,
138 buttons: [ submitBtn ]
139 });
140
141 me.callParent();
142 }
143});
144
145Ext.define('PVE.storage.Upload', {
146 extend: 'Ext.window.Window',
147 alias: ['widget.pveStorageUpload'],
148
149 resizable: false,
150
151 modal: true,
152
153 initComponent : function() {
154 /*jslint confusion: true */
155 var me = this;
156
157 var xhr;
158
159 if (!me.nodename) {
160 throw "no node name specified";
161 }
162
163 if (!me.storage) {
164 throw "no storage ID specified";
165 }
166
167 var baseurl = "/nodes/" + me.nodename + "/storage/" + me.storage + "/upload";
168
169 var pbar = Ext.create('Ext.ProgressBar', {
170 text: 'Ready',
171 hidden: true
172 });
173
174 me.formPanel = Ext.create('Ext.form.Panel', {
175 method: 'POST',
176 waitMsgTarget: true,
177 bodyPadding: 10,
178 border: false,
179 width: 300,
180 fieldDefaults: {
181 labelWidth: 100,
182 anchor: '100%'
183 },
184 items: [
185 {
186 xtype: 'pveContentTypeSelector',
187 cts: ['iso', 'vztmpl'],
188 fieldLabel: gettext('Content'),
189 name: 'content',
190 value: 'iso'
191 },
192 {
193 xtype: 'filefield',
194 name: 'filename',
195 buttonText: gettext('Select File...'),
196 allowBlank: false
197 },
198 pbar
199 ]
200 });
201
202 var form = me.formPanel.getForm();
203
204 var doStandardSubmit = function() {
205 form.submit({
206 url: "/api2/htmljs" + baseurl,
207 waitMsg: gettext('Uploading file...'),
208 success: function(f, action) {
209 me.close();
210 },
211 failure: function(f, action) {
212 var msg = PVE.Utils.extractFormActionError(action);
213 Ext.Msg.alert(gettext('Error'), msg);
214 }
215 });
216 };
217
218 var updateProgress = function(per, bytes) {
219 var text = (per * 100).toFixed(2) + '%';
220 if (bytes) {
221 text += " (" + PVE.Utils.format_size(bytes) + ')';
222 }
223 pbar.updateProgress(per, text);
224 };
225
226 var abortBtn = Ext.create('Ext.Button', {
227 text: gettext('Abort'),
228 disabled: true,
229 handler: function() {
230 me.close();
231 }
232 });
233
234 var submitBtn = Ext.create('Ext.Button', {
235 text: gettext('Upload'),
236 disabled: true,
237 handler: function(button) {
238 var fd;
239 try {
240 fd = new FormData();
241 } catch (err) {
242 doStandardSubmit();
243 return;
244 }
245
246 button.setDisabled(true);
247 abortBtn.setDisabled(false);
248
249 var field = form.findField('content');
250 fd.append("content", field.getValue());
251 field.setDisabled(true);
252
253 field = form.findField('filename');
254 var file = field.fileInputEl.dom;
255 fd.append("filename", file.files[0]);
256 field.setDisabled(true);
257
258 pbar.setVisible(true);
259 updateProgress(0);
260
261 xhr = new XMLHttpRequest();
262
263 xhr.addEventListener("load", function(e) {
264 if (xhr.status == 200) {
265 me.close();
266 } else {
267 var msg = gettext('Error') + " " + xhr.status.toString() + ": " + Ext.htmlEncode(xhr.statusText);
268 var result = Ext.decode(xhr.responseText);
269 result.message = msg;
270 var htmlStatus = PVE.Utils.extractRequestError(result, true);
271 Ext.Msg.alert(gettext('Error'), htmlStatus, function(btn) {
272 me.close();
273 });
274
275 }
276 }, false);
277
278 xhr.addEventListener("error", function(e) {
279 var msg = "Error " + e.target.status.toString() + " occurred while receiving the document.";
280 Ext.Msg.alert(gettext('Error'), msg, function(btn) {
281 me.close();
282 });
283 });
284
285 xhr.upload.addEventListener("progress", function(evt) {
286 if (evt.lengthComputable) {
287 var percentComplete = evt.loaded / evt.total;
288 updateProgress(percentComplete, evt.loaded);
289 }
290 }, false);
291
292 xhr.open("POST", "/api2/json" + baseurl, true);
293 xhr.send(fd);
294 }
295 });
296
297 form.on('validitychange', function(f, valid) {
298 submitBtn.setDisabled(!valid);
299 });
300
301 Ext.applyIf(me, {
302 title: gettext('Upload'),
303 items: me.formPanel,
304 buttons: [ abortBtn, submitBtn ],
305 listeners: {
306 close: function() {
307 if (xhr) {
308 xhr.abort();
309 }
310 }
311 }
312 });
313
314 me.callParent();
315 }
316});
317
318Ext.define('PVE.storage.ContentView', {
319 extend: 'Ext.grid.GridPanel',
320
321 alias: ['widget.pveStorageContentView'],
322
323 initComponent : function() {
324 var me = this;
325
326 var nodename = me.pveSelNode.data.node;
327 if (!nodename) {
328 throw "no node name specified";
329 }
330
331 var storage = me.pveSelNode.data.storage;
332 if (!storage) {
333 throw "no storage ID specified";
334 }
335
336 var baseurl = "/nodes/" + nodename + "/storage/" + storage + "/content";
337 var store = new Ext.data.Store({
338 model: 'pve-storage-content',
339 groupField: 'content',
340 proxy: {
341 type: 'pve',
342 url: '/api2/json' + baseurl
343 },
344 sorters: {
345 property: 'volid',
346 order: 'DESC'
347 }
348 });
349
350 var sm = Ext.create('Ext.selection.RowModel', {});
351
352 var groupingFeature = Ext.create('Ext.grid.feature.Grouping',{
353 groupHeaderTpl: '{[ PVE.Utils.format_content_types(values.name) ]} ({rows.length} Item{[values.rows.length > 1 ? "s" : ""]})'
354 });
355
356 var reload = function() {
357 store.load();
358 };
359
360 PVE.Utils.monStoreErrors(me, store);
361
362 Ext.apply(me, {
363 store: store,
364 selModel: sm,
365 stateful: false,
366 viewConfig: {
367 trackOver: false
368 },
369 features: [ groupingFeature ],
370 tbar: [
371 {
372 xtype: 'pveButton',
373 text: gettext('Restore'),
374 selModel: sm,
375 disabled: true,
376 enableFn: function(rec) {
377 return rec && rec.data.content === 'backup';
378 },
379 handler: function(b, e, rec) {
380 var vmtype;
381 if (rec.data.volid.match(/vzdump-qemu-/)) {
382 vmtype = 'qemu';
383 } else if (rec.data.volid.match(/vzdump-openvz-/) || rec.data.volid.match(/vzdump-lxc-/)) {
384 vmtype = 'lxc';
385 } else {
386 return;
387 }
388
389 var win = Ext.create('PVE.window.Restore', {
390 nodename: nodename,
391 volid: rec.data.volid,
392 volidText: PVE.Utils.render_storage_content(rec.data.volid, {}, rec),
393 vmtype: vmtype
394 });
395 win.show();
396 win.on('destroy', reload);
397 }
398 },
399 {
400 xtype: 'pveButton',
401 text: gettext('Remove'),
402 selModel: sm,
403 disabled: true,
404 confirmMsg: function(rec) {
405 return Ext.String.format(gettext('Are you sure you want to remove entry {0}'),
406 "'" + rec.data.volid + "'");
407 },
408 enableFn: function(rec) {
409 return rec && rec.data.content !== 'images';
410 },
411 handler: function(b, e, rec) {
412 PVE.Utils.API2Request({
413 url: baseurl + '/' + rec.data.volid,
414 method: 'DELETE',
415 waitMsgTarget: me,
416 callback: function() {
417 reload();
418 },
419 failure: function (response, opts) {
420 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
421 }
422 });
423 }
424 },
425 {
426 text: gettext('Templates'),
427 handler: function() {
428 var win = Ext.create('PVE.storage.TemplateDownload', {
429 nodename: nodename,
430 storage: storage
431 });
432 win.show();
433 win.on('destroy', reload);
434 }
435 },
436 {
437 text: gettext('Upload'),
438 handler: function() {
439 var win = Ext.create('PVE.storage.Upload', {
440 nodename: nodename,
441 storage: storage
442 });
443 win.show();
444 win.on('destroy', reload);
445 }
446 },
447 '->',
448 gettext('Search') + ':', ' ',
449 {
450 xtype: 'textfield',
451 width: 200,
452 enableKeyEvents: true,
453 listeners: {
454 buffer: 500,
455 keyup: function(field) {
456 store.clearFilter(true);
457 store.filter([
458 {
459 property: 'text',
460 value: field.getValue(),
461 anyMatch: true,
462 caseSensitive: false
463 }
464 ]);
465 }
466 }
467 }
468 ],
469 columns: [
470 {
471 header: gettext('Name'),
472 flex: 1,
473 sortable: true,
474 renderer: PVE.Utils.render_storage_content,
475 dataIndex: 'text'
476 },
477 {
478 header: gettext('Format'),
479 width: 100,
480 dataIndex: 'format'
481 },
482 {
483 header: gettext('Size'),
484 width: 100,
485 renderer: PVE.Utils.format_size,
486 dataIndex: 'size'
487 }
488 ],
489 listeners: {
490 show: reload
491 }
492 });
493
494 me.callParent();
495 }
496}, function() {
497
498 Ext.define('pve-storage-content', {
499 extend: 'Ext.data.Model',
500 fields: [
501 'volid', 'content', 'format', 'size', 'used', 'vmid',
502 'channel', 'id', 'lun',
503 {
504 name: 'text',
505 convert: function(value, record) {
506 if (value) {
507 return value;
508 }
509 return PVE.Utils.render_storage_content(value, {}, record);
510 }
511 }
512 ],
513 idProperty: 'volid'
514 });
515
516});