]>
Commit | Line | Data |
---|---|---|
c9164975 DM |
1 | Ext.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 | ||
86 | Ext.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', { | |
c9164975 DM |
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) { | |
0070ee37 | 117 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); |
c9164975 DM |
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, { | |
6b21ab95 | 133 | title: gettext('Templates'), |
c452ded3 DM |
134 | layout: 'fit', |
135 | width: 600, | |
136 | height: 400, | |
c9164975 DM |
137 | items: grid, |
138 | buttons: [ submitBtn ] | |
139 | }); | |
140 | ||
141 | me.callParent(); | |
142 | } | |
143 | }); | |
144 | ||
2baf0139 DM |
145 | Ext.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() { | |
a2f57991 | 154 | /*jslint confusion: true */ |
2baf0139 DM |
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 | ||
7a567cb1 | 167 | var baseurl = "/nodes/" + me.nodename + "/storage/" + me.storage + "/upload"; |
2baf0139 DM |
168 | |
169 | var pbar = Ext.create('Ext.ProgressBar', { | |
170 | text: 'Ready', | |
171 | hidden: true | |
a2f57991 | 172 | }); |
2baf0139 DM |
173 | |
174 | me.formPanel = Ext.create('Ext.form.Panel', { | |
2baf0139 DM |
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: 'pveKVComboBox', | |
187 | data: [ | |
0070ee37 DP |
188 | ['iso', gettext('ISO image')], |
189 | ['backup', gettext('VZDump backup file')], | |
190 | ['vztmpl', gettext('OpenVZ template')] | |
2baf0139 | 191 | ], |
7e6b14a8 | 192 | fieldLabel: gettext('Content'), |
2baf0139 DM |
193 | name: 'content', |
194 | value: 'iso' | |
195 | }, | |
196 | { | |
197 | xtype: 'filefield', | |
198 | name: 'filename', | |
7e6b14a8 | 199 | buttonText: gettext('Select File...'), |
2baf0139 DM |
200 | allowBlank: false |
201 | }, | |
202 | pbar | |
203 | ] | |
204 | }); | |
205 | ||
206 | var form = me.formPanel.getForm(); | |
207 | ||
208 | var doStandardSubmit = function() { | |
209 | form.submit({ | |
7a567cb1 | 210 | url: "/api2/htmljs" + baseurl, |
7e6b14a8 | 211 | waitMsg: gettext('Uploading file...'), |
2baf0139 DM |
212 | success: function(f, action) { |
213 | me.close(); | |
214 | }, | |
215 | failure: function(f, action) { | |
216 | var msg = PVE.Utils.extractFormActionError(action); | |
7e6b14a8 | 217 | Ext.Msg.alert(gettext('Error'), msg); |
2baf0139 DM |
218 | } |
219 | }); | |
220 | }; | |
221 | ||
222 | var updateProgress = function(per, bytes) { | |
223 | var text = (per * 100).toFixed(2) + '%'; | |
224 | if (bytes) { | |
225 | text += " (" + PVE.Utils.format_size(bytes) + ')'; | |
226 | } | |
227 | pbar.updateProgress(per, text); | |
228 | }; | |
229 | ||
230 | var abortBtn = Ext.create('Ext.Button', { | |
7e6b14a8 | 231 | text: gettext('Abort'), |
2baf0139 DM |
232 | disabled: true, |
233 | handler: function() { | |
234 | me.close(); | |
235 | } | |
236 | }); | |
237 | ||
238 | var submitBtn = Ext.create('Ext.Button', { | |
7e6b14a8 | 239 | text: gettext('Upload'), |
2baf0139 DM |
240 | disabled: true, |
241 | handler: function(button) { | |
a2f57991 | 242 | var fd; |
2baf0139 | 243 | try { |
a2f57991 | 244 | fd = new FormData(); |
2baf0139 DM |
245 | } catch (err) { |
246 | doStandardSubmit(); | |
247 | return; | |
248 | } | |
249 | ||
250 | button.setDisabled(true); | |
251 | abortBtn.setDisabled(false); | |
252 | ||
253 | var field = form.findField('content'); | |
254 | fd.append("content", field.getValue()); | |
255 | field.setDisabled(true); | |
256 | ||
a2f57991 | 257 | field = form.findField('filename'); |
2baf0139 DM |
258 | var file = field.fileInputEl.dom; |
259 | fd.append("filename", file.files[0]); | |
260 | field.setDisabled(true); | |
261 | ||
262 | pbar.setVisible(true); | |
263 | updateProgress(0); | |
264 | ||
265 | xhr = new XMLHttpRequest(); | |
266 | ||
267 | xhr.addEventListener("load", function(e) { | |
7a567cb1 | 268 | if (xhr.status == 200) { |
2baf0139 DM |
269 | me.close(); |
270 | } else { | |
0070ee37 | 271 | var msg = gettext('Error') + " " + xhr.status.toString() + ": " + Ext.htmlEncode(xhr.statusText); |
6735c379 DM |
272 | var result = Ext.decode(xhr.responseText); |
273 | result.message = msg; | |
274 | var htmlStatus = PVE.Utils.extractRequestError(result, true); | |
275 | Ext.Msg.alert(gettext('Error'), htmlStatus, function(btn) { | |
2baf0139 DM |
276 | me.close(); |
277 | }); | |
278 | ||
279 | } | |
280 | }, false); | |
281 | ||
6735c379 DM |
282 | xhr.addEventListener("error", function(e) { |
283 | var msg = "Error " + e.target.status.toString() + " occurred while receiving the document."; | |
7e6b14a8 | 284 | Ext.Msg.alert(gettext('Error'), msg, function(btn) { |
2baf0139 DM |
285 | me.close(); |
286 | }); | |
287 | }); | |
288 | ||
289 | xhr.upload.addEventListener("progress", function(evt) { | |
290 | if (evt.lengthComputable) { | |
291 | var percentComplete = evt.loaded / evt.total; | |
292 | updateProgress(percentComplete, evt.loaded); | |
293 | } | |
294 | }, false); | |
295 | ||
7a567cb1 | 296 | xhr.open("POST", "/api2/json" + baseurl, true); |
2baf0139 DM |
297 | xhr.send(fd); |
298 | } | |
299 | }); | |
300 | ||
301 | form.on('validitychange', function(f, valid) { | |
302 | submitBtn.setDisabled(!valid); | |
303 | }); | |
304 | ||
305 | Ext.applyIf(me, { | |
7e6b14a8 | 306 | title: gettext('Upload'), |
a2f57991 | 307 | items: me.formPanel, |
2baf0139 DM |
308 | buttons: [ abortBtn, submitBtn ], |
309 | listeners: { | |
310 | close: function() { | |
311 | if (xhr) { | |
312 | xhr.abort(); | |
313 | } | |
314 | } | |
315 | } | |
316 | }); | |
317 | ||
318 | me.callParent(); | |
319 | } | |
320 | }); | |
321 | ||
aff192e6 DM |
322 | Ext.define('PVE.storage.ContentView', { |
323 | extend: 'Ext.grid.GridPanel', | |
324 | ||
325 | alias: ['widget.pveStorageContentView'], | |
326 | ||
327 | initComponent : function() { | |
328 | var me = this; | |
329 | ||
330 | var nodename = me.pveSelNode.data.node; | |
331 | if (!nodename) { | |
332 | throw "no node name specified"; | |
333 | } | |
334 | ||
335 | var storage = me.pveSelNode.data.storage; | |
336 | if (!storage) { | |
337 | throw "no storage ID specified"; | |
338 | } | |
339 | ||
e4740457 | 340 | var baseurl = "/nodes/" + nodename + "/storage/" + storage + "/content"; |
aff192e6 DM |
341 | var store = new Ext.data.Store({ |
342 | model: 'pve-storage-content', | |
2baf0139 | 343 | groupField: 'content', |
aff192e6 DM |
344 | proxy: { |
345 | type: 'pve', | |
a2f57991 | 346 | url: '/api2/json' + baseurl |
aff192e6 DM |
347 | }, |
348 | sorters: { | |
349 | property: 'volid', | |
350 | order: 'DESC' | |
351 | } | |
352 | }); | |
353 | ||
3406680a DM |
354 | var sm = Ext.create('Ext.selection.RowModel', {}); |
355 | ||
2baf0139 | 356 | var groupingFeature = Ext.create('Ext.grid.feature.Grouping',{ |
ca03c7cd | 357 | groupHeaderTpl: '{[ PVE.Utils.format_content_types(values.name) ]} ({rows.length} Item{[values.rows.length > 1 ? "s" : ""]})' |
2baf0139 DM |
358 | }); |
359 | ||
360 | var reload = function() { | |
361 | store.load(); | |
362 | }; | |
aff192e6 | 363 | |
aa3d04f2 DM |
364 | PVE.Utils.monStoreErrors(me, store); |
365 | ||
a2f57991 | 366 | Ext.apply(me, { |
aff192e6 | 367 | store: store, |
3406680a | 368 | selModel: sm, |
aff192e6 DM |
369 | stateful: false, |
370 | viewConfig: { | |
371 | trackOver: false | |
372 | }, | |
2baf0139 DM |
373 | features: [ groupingFeature ], |
374 | tbar: [ | |
375 | { | |
7404e8fe | 376 | xtype: 'pveButton', |
7e6b14a8 | 377 | text: gettext('Restore'), |
7404e8fe DM |
378 | selModel: sm, |
379 | disabled: true, | |
380 | enableFn: function(rec) { | |
381 | return rec && rec.data.content === 'backup'; | |
382 | }, | |
383 | handler: function(b, e, rec) { | |
384 | var vmtype; | |
385 | if (rec.data.volid.match(/vzdump-qemu-/)) { | |
386 | vmtype = 'qemu'; | |
387 | } else if (rec.data.volid.match(/vzdump-openvz-/)) { | |
388 | vmtype = 'openvz'; | |
389 | } else { | |
390 | return; | |
391 | } | |
392 | ||
393 | var win = Ext.create('PVE.window.Restore', { | |
394 | nodename: nodename, | |
395 | volid: rec.data.volid, | |
396 | volidText: PVE.Utils.render_storage_content(rec.data.volid, {}, rec), | |
397 | vmtype: vmtype | |
398 | }); | |
399 | win.show(); | |
400 | win.on('destroy', reload); | |
401 | } | |
2baf0139 | 402 | }, |
3406680a DM |
403 | { |
404 | xtype: 'pveButton', | |
7e6b14a8 | 405 | text: gettext('Remove'), |
3406680a DM |
406 | selModel: sm, |
407 | disabled: true, | |
408 | confirmMsg: function(rec) { | |
7e6b14a8 DM |
409 | return Ext.String.format(gettext('Are you sure you want to remove entry {0}'), |
410 | "'" + rec.data.volid + "'"); | |
3406680a DM |
411 | }, |
412 | enableFn: function(rec) { | |
413 | return rec && rec.data.content !== 'images'; | |
414 | }, | |
415 | handler: function(b, e, rec) { | |
416 | PVE.Utils.API2Request({ | |
417 | url: baseurl + '/' + rec.data.volid, | |
418 | method: 'DELETE', | |
419 | waitMsgTarget: me, | |
420 | callback: function() { | |
421 | reload(); | |
422 | }, | |
423 | failure: function (response, opts) { | |
7e6b14a8 | 424 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); |
3406680a DM |
425 | } |
426 | }); | |
427 | } | |
428 | }, | |
c9164975 DM |
429 | { |
430 | text: gettext('Templates'), | |
431 | handler: function() { | |
432 | var win = Ext.create('PVE.storage.TemplateDownload', { | |
433 | nodename: nodename, | |
434 | storage: storage | |
435 | }); | |
436 | win.show(); | |
437 | win.on('destroy', reload); | |
438 | } | |
439 | }, | |
2baf0139 | 440 | { |
7e6b14a8 | 441 | text: gettext('Upload'), |
2baf0139 DM |
442 | handler: function() { |
443 | var win = Ext.create('PVE.storage.Upload', { | |
444 | nodename: nodename, | |
445 | storage: storage | |
446 | }); | |
447 | win.show(); | |
448 | win.on('destroy', reload); | |
449 | } | |
450 | } | |
451 | ], | |
aff192e6 DM |
452 | columns: [ |
453 | { | |
7e6b14a8 | 454 | header: gettext('Name'), |
aff192e6 DM |
455 | flex: 1, |
456 | sortable: true, | |
457 | renderer: PVE.Utils.render_storage_content, | |
46a53f1b | 458 | dataIndex: 'text' |
aff192e6 DM |
459 | }, |
460 | { | |
7e6b14a8 | 461 | header: gettext('Format'), |
aff192e6 DM |
462 | width: 100, |
463 | dataIndex: 'format' | |
464 | }, | |
465 | { | |
7e6b14a8 | 466 | header: gettext('Size'), |
aff192e6 DM |
467 | width: 100, |
468 | renderer: PVE.Utils.format_size, | |
469 | dataIndex: 'size' | |
470 | } | |
471 | ], | |
472 | listeners: { | |
3406680a | 473 | show: reload |
aff192e6 DM |
474 | } |
475 | }); | |
476 | ||
477 | me.callParent(); | |
478 | } | |
479 | }, function() { | |
480 | ||
481 | Ext.define('pve-storage-content', { | |
482 | extend: 'Ext.data.Model', | |
483 | fields: [ | |
2baf0139 | 484 | 'volid', 'content', 'format', 'size', 'used', 'vmid', |
46a53f1b DM |
485 | 'channel', 'id', 'lun', |
486 | { | |
487 | name: 'text', | |
488 | convert: function(value, record) { | |
489 | if (value) { | |
490 | return value; | |
491 | } | |
492 | return PVE.Utils.render_storage_content(value, {}, record); | |
493 | } | |
494 | } | |
aff192e6 DM |
495 | ], |
496 | idProperty: 'volid' | |
497 | }); | |
498 | ||
0070ee37 | 499 | }); |