]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/Workspace.js
add ceph statudetail panel
[pve-manager.git] / www / manager6 / Workspace.js
1 /*
2 * Workspace base class
3 *
4 * popup login window when auth fails (call onLogin handler)
5 * update (re-login) ticket every 15 minutes
6 *
7 */
8
9 Ext.define('PVE.Workspace', {
10 extend: 'Ext.container.Viewport',
11
12 title: 'Proxmox Virtual Environment',
13
14 loginData: null, // Data from last login call
15
16 onLogin: function(loginData) {},
17
18 // private
19 updateLoginData: function(loginData) {
20 var me = this;
21 me.loginData = loginData;
22 PVE.CSRFPreventionToken = loginData.CSRFPreventionToken;
23 PVE.UserName = loginData.username;
24
25 if (loginData.cap) {
26 Ext.state.Manager.set('GuiCap', loginData.cap);
27 }
28
29 // creates a session cookie (expire = null)
30 // that way the cookie gets deleted after browser window close
31 Ext.util.Cookies.set('PVEAuthCookie', loginData.ticket, null, '/', null, true);
32 me.onLogin(loginData);
33 },
34
35 // private
36 showLogin: function() {
37 var me = this;
38
39 PVE.Utils.authClear();
40 PVE.UserName = null;
41 me.loginData = null;
42
43 if (!me.login) {
44 me.login = Ext.create('PVE.window.LoginWindow', {
45 handler: function(data) {
46 me.login = null;
47 me.updateLoginData(data);
48 PVE.Utils.checked_command(function() {}); // display subscription status
49 }
50 });
51 }
52 me.onLogin(null);
53 me.login.show();
54 },
55
56 initComponent : function() {
57 var me = this;
58
59 Ext.tip.QuickTipManager.init();
60
61 // fixme: what about other errors
62 Ext.Ajax.on('requestexception', function(conn, response, options) {
63 if (response.status == 401) { // auth failure
64 me.showLogin();
65 }
66 });
67
68 me.callParent();
69
70 if (!PVE.Utils.authOK()) {
71 me.showLogin();
72 } else {
73 if (me.loginData) {
74 me.onLogin(me.loginData);
75 }
76 }
77
78 Ext.TaskManager.start({
79 run: function() {
80 var ticket = PVE.Utils.authOK();
81 if (!ticket || !PVE.UserName) {
82 return;
83 }
84
85 Ext.Ajax.request({
86 params: {
87 username: PVE.UserName,
88 password: ticket
89 },
90 url: '/api2/json/access/ticket',
91 method: 'POST',
92 success: function(response, opts) {
93 var obj = Ext.decode(response.responseText);
94 me.updateLoginData(obj.data);
95 }
96 });
97 },
98 interval: 15*60*1000
99 });
100
101 }
102 });
103
104 Ext.define('PVE.ConsoleWorkspace', {
105 extend: 'PVE.Workspace',
106
107 alias: ['widget.pveConsoleWorkspace'],
108
109 title: gettext('Console'),
110
111 initComponent : function() {
112 // novnc is a string in param
113 // but a boolean in content
114 /*jslint confusion: true*/
115 var me = this;
116
117 var param = Ext.Object.fromQueryString(window.location.search);
118 var consoleType = me.consoleType || param.console;
119
120 param.novnc = (param.novnc === '1') ? true : false;
121
122 var content;
123 if (consoleType === 'kvm') {
124 me.title = "VM " + param.vmid;
125 if (param.vmname) {
126 me.title += " ('" + param.vmname + "')";
127 }
128 content = {
129 xtype: 'pveKVMConsole',
130 novnc: param.novnc,
131 vmid: param.vmid,
132 nodename: param.node,
133 vmname: param.vmname,
134 toplevel: true
135 };
136 } else if (consoleType === 'lxc') {
137 me.title = "CT " + param.vmid;
138 if (param.vmname) {
139 me.title += " ('" + param.vmname + "')";
140 }
141 content = {
142 xtype: 'pveLxcConsole',
143 novnc: param.novnc,
144 vmid: param.vmid,
145 nodename: param.node,
146 vmname: param.vmname,
147 toplevel: true
148 };
149 } else if (consoleType === 'shell') {
150 me.title = "node '" + param.node + "'";
151 content = {
152 xtype: 'pveShell',
153 novnc: param.novnc,
154 nodename: param.node,
155 toplevel: true
156 };
157 } else if (consoleType === 'upgrade') {
158 me.title = Ext.String.format(gettext('System upgrade on node {0}'), "'" + param.node + "'");
159 content = {
160 xtype: 'pveShell',
161 novnc: param.novnc,
162 nodename: param.node,
163 ugradeSystem: true,
164 toplevel: true
165 };
166 } else {
167 content = {
168 border: false,
169 bodyPadding: 10,
170 html: gettext('Error') + ': No such console type'
171 };
172 }
173
174 Ext.apply(me, {
175 layout: { type: 'fit' },
176 border: false,
177 items: [ content ]
178 });
179
180 me.callParent();
181 }
182 });
183
184 Ext.define('PVE.StdWorkspace', {
185 extend: 'PVE.Workspace',
186
187 alias: ['widget.pveStdWorkspace'],
188
189 // private
190 setContent: function(comp) {
191 var me = this;
192
193 var cont = me.child('#content');
194
195 var lay = cont.getLayout();
196
197 var cur = lay.getActiveItem();
198
199 if (comp) {
200 PVE.Utils.setErrorMask(cont, false);
201 comp.border = false;
202 cont.add(comp);
203 if (cur !== null && lay.getNext()) {
204 lay.next();
205 var task = Ext.create('Ext.util.DelayedTask', function(){
206 cont.remove(cur);
207 });
208 task.delay(10);
209 }
210 }
211 else {
212 // helper for cleaning the content when logging out
213 cont.removeAll();
214 }
215 },
216
217 selectById: function(nodeid) {
218 var me = this;
219 var tree = me.down('pveResourceTree');
220 tree.selectById(nodeid);
221 },
222
223 checkVmMigration: function(record) {
224 var me = this;
225 var tree = me.down('pveResourceTree');
226 tree.checkVmMigration(record);
227 },
228
229 onLogin: function(loginData) {
230 var me = this;
231
232 me.updateUserInfo();
233
234 if (loginData) {
235 PVE.data.ResourceStore.startUpdate();
236
237 PVE.Utils.API2Request({
238 url: '/version',
239 method: 'GET',
240 success: function(response) {
241 PVE.VersionInfo = response.result.data;
242 me.updateVersionInfo();
243 }
244 });
245 }
246 },
247
248 updateUserInfo: function() {
249 var me = this;
250
251 var ui = me.query('#userinfo')[0];
252
253 if (PVE.UserName) {
254 var msg = Ext.String.format(gettext("You are logged in as {0}"), "'" + PVE.UserName + "'");
255 ui.update('<div class="x-unselectable" style="white-space:nowrap;">' + msg + '</div>');
256 } else {
257 ui.update('');
258 }
259 ui.updateLayout();
260 },
261
262 updateVersionInfo: function() {
263 var me = this;
264
265 var ui = me.query('#versioninfo')[0];
266
267 if (PVE.VersionInfo) {
268 var version = PVE.VersionInfo.version + '-' + PVE.VersionInfo.release + '/' +
269 PVE.VersionInfo.repoid;
270 ui.update('Virtual Environment ' + version);
271 } else {
272 ui.update('Virtual Environment');
273 }
274 ui.updateLayout();
275 },
276
277 initComponent : function() {
278 var me = this;
279
280 Ext.History.init();
281
282 var sprovider = Ext.create('PVE.StateProvider');
283 Ext.state.Manager.setProvider(sprovider);
284
285 var selview = Ext.create('PVE.form.ViewSelector');
286
287 var rtree = Ext.createWidget('pveResourceTree', {
288 viewFilter: selview.getViewFilter(),
289 flex: 1,
290 selModel: {
291 selType: 'treemodel',
292 listeners: {
293 selectionchange: function(sm, selected) {
294 if (selected.length > 0) {
295 var n = selected[0];
296 var tlckup = {
297 root: 'PVE.dc.Config',
298 node: 'PVE.node.Config',
299 qemu: 'PVE.qemu.Config',
300 lxc: 'PVE.lxc.Config',
301 storage: 'PVE.storage.Browser',
302 pool: 'pvePoolConfig'
303 };
304 var comp = {
305 xtype: tlckup[n.data.type || 'root'] ||
306 'pvePanelConfig',
307 showSearch: (n.data.id === 'root') ||
308 Ext.isDefined(n.data.groupbyid),
309 pveSelNode: n,
310 workspace: me,
311 viewFilter: selview.getViewFilter()
312 };
313 PVE.curSelectedNode = n;
314 me.setContent(comp);
315 }
316 }
317 }
318 }
319 });
320
321 selview.on('select', function(combo, records) {
322 if (records) {
323 var view = combo.getViewFilter();
324 rtree.setViewFilter(view);
325 }
326 });
327
328 var caps = sprovider.get('GuiCap');
329
330 var createVM = Ext.createWidget('button', {
331 pack: 'end',
332 margin: '3 5 0 0',
333 baseCls: 'x-btn',
334 iconCls: 'fa fa-desktop',
335 text: gettext("Create VM"),
336 disabled: !caps.vms['VM.Allocate'],
337 handler: function() {
338 var wiz = Ext.create('PVE.qemu.CreateWizard', {});
339 wiz.show();
340 }
341 });
342
343 var createCT = Ext.createWidget('button', {
344 pack: 'end',
345 margin: '3 5 0 0',
346 baseCls: 'x-btn',
347 iconCls: 'fa fa-cube',
348 text: gettext("Create CT"),
349 disabled: !caps.vms['VM.Allocate'],
350 handler: function() {
351 var wiz = Ext.create('PVE.lxc.CreateWizard', {});
352 wiz.show();
353 }
354 });
355
356 sprovider.on('statechange', function(sp, key, value) {
357 if (key === 'GuiCap' && value) {
358 caps = value;
359 createVM.setDisabled(!caps.vms['VM.Allocate']);
360 createCT.setDisabled(!caps.vms['VM.Allocate']);
361 }
362 });
363
364 Ext.apply(me, {
365 layout: { type: 'border' },
366 border: false,
367 items: [
368 {
369 region: 'north',
370 layout: {
371 type: 'hbox',
372 align: 'middle'
373 },
374 baseCls: 'x-plain',
375 defaults: {
376 baseCls: 'x-plain'
377 },
378 border: false,
379 margin: '2 0 2 5',
380 items: [
381 {
382 html: '<a class="x-unselectable" target=_blank href="http://www.proxmox.com">' +
383 '<img style="padding-top:4px;padding-right:5px" src="/pve2/images/proxmox_logo.png"/></a>'
384 },
385 {
386 minWidth: 200,
387 id: 'versioninfo',
388 html: 'Virtual Environment'
389 },
390 {
391 xtype: 'pveGlobalSearchField',
392 tree: rtree
393 },
394 {
395 flex: 1
396 },
397 {
398 pack: 'end',
399 id: 'userinfo',
400 stateful: false
401 },
402 {
403 xtype: 'button',
404 margin: '0 10 0 3',
405 iconCls: 'fa black fa-gear',
406 style: {
407 cursor: 'pointer'
408 },
409 handler: function() {
410 var win = Ext.create('PVE.window.Settings');
411 win.show();
412 }
413 },
414 {
415 xtype: 'pveHelpButton',
416 hidden: false,
417 baseCls: 'x-btn',
418 iconCls: 'fa fa-info-circle x-btn-icon-el-default-toolbar-small ',
419 listenToGlobalEvent: false,
420 onlineHelp: 'pve_documentation_index',
421 margin: '0 5 0 0'
422 },
423 createVM,
424 createCT,
425 {
426 pack: 'end',
427 margin: '0 5 0 0',
428 xtype: 'button',
429 baseCls: 'x-btn',
430 iconCls: 'fa fa-sign-out',
431 text: gettext("Logout"),
432 handler: function() {
433 PVE.data.ResourceStore.loadData([], false);
434 me.showLogin();
435 me.setContent(null);
436 var rt = me.down('pveResourceTree');
437 rt.clearTree();
438
439 // empty the stores of the StatusPanel child items
440 var statusPanels = Ext.ComponentQuery.query('pveStatusPanel grid');
441 Ext.Array.forEach(statusPanels, function(comp) {
442 if (comp.getStore()) {
443 comp.getStore().loadData([], false);
444 }
445 });
446 }
447 }
448 ]
449 },
450 {
451 region: 'center',
452 stateful: true,
453 stateId: 'pvecenter',
454 minWidth: 100,
455 minHeight: 100,
456 id: 'content',
457 xtype: 'container',
458 layout: { type: 'card' },
459 border: false,
460 margin: '0 5 0 0',
461 items: []
462 },
463 {
464 region: 'west',
465 stateful: true,
466 stateId: 'pvewest',
467 itemId: 'west',
468 xtype: 'container',
469 border: false,
470 layout: { type: 'vbox', align: 'stretch' },
471 margin: '0 0 0 5',
472 split: true,
473 width: 200,
474 items: [ selview, rtree ],
475 listeners: {
476 resize: function(panel, width, height) {
477 var viewWidth = me.getSize().width;
478 if (width > viewWidth - 100) {
479 panel.setWidth(viewWidth - 100);
480 }
481 }
482 }
483 },
484 {
485 xtype: 'pveStatusPanel',
486 stateful: true,
487 stateId: 'pvesouth',
488 itemId: 'south',
489 region: 'south',
490 margin:'0 5 5 5',
491 title: gettext('Logs'),
492 collapsible: true,
493 header: false,
494 height: 200,
495 split:true,
496 listeners: {
497 resize: function(panel, width, height) {
498 var viewHeight = me.getSize().height;
499 if (height > (viewHeight - 150)) {
500 panel.setHeight(viewHeight - 150);
501 }
502 }
503 }
504 }
505 ]
506 });
507
508 me.callParent();
509
510 me.updateUserInfo();
511
512 // on resize, center all modal windows
513 Ext.on('resize', function(){
514 var wins = Ext.ComponentQuery.query('window[modal]');
515 if (wins.length > 0) {
516 wins.forEach(function(win){
517 win.alignTo(me, 'c-c');
518 });
519 }
520 });
521 }
522 });
523