]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/Workspace.js
ui: use PMX.image.Logo from widget-toolkit
[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 Proxmox.Utils.setAuthData(loginData);
23
24 var rt = me.down('pveResourceTree');
25 rt.setDatacenterText(loginData.clustername);
26
27 if (loginData.cap) {
28 Ext.state.Manager.set('GuiCap', loginData.cap);
29 }
30 me.response401count = 0;
31
32 me.onLogin(loginData);
33 },
34
35 // private
36 showLogin: function() {
37 var me = this;
38
39 Proxmox.Utils.authClear();
40 Ext.state.Manager.clear('GuiCap');
41 Proxmox.UserName = null;
42 me.loginData = null;
43
44 if (!me.login) {
45 me.login = Ext.create('PVE.window.LoginWindow', {
46 handler: function(data) {
47 me.login = null;
48 me.updateLoginData(data);
49 Proxmox.Utils.checked_command(function() {}); // display subscription status
50 }
51 });
52 }
53 me.onLogin(null);
54 me.login.show();
55 },
56
57 initComponent : function() {
58 var me = this;
59
60 Ext.tip.QuickTipManager.init();
61
62 // fixme: what about other errors
63 Ext.Ajax.on('requestexception', function(conn, response, options) {
64 if (response.status == 401 && !PVE.Utils.silenceAuthFailures) { // auth failure
65 // don't immediately show as logged out to cope better with some big
66 // upgrades, which may temporarily produce a false positive 401 err
67 me.response401count++;
68 if (me.response401count > 5) {
69 me.showLogin();
70 }
71 }
72 });
73
74 me.callParent();
75
76 if (!Proxmox.Utils.authOK()) {
77 me.showLogin();
78 } else {
79 if (me.loginData) {
80 me.onLogin(me.loginData);
81 }
82 }
83
84 Ext.TaskManager.start({
85 run: function() {
86 var ticket = Proxmox.Utils.authOK();
87 if (!ticket || !Proxmox.UserName) {
88 return;
89 }
90
91 Ext.Ajax.request({
92 params: {
93 username: Proxmox.UserName,
94 password: ticket
95 },
96 url: '/api2/json/access/ticket',
97 method: 'POST',
98 success: function(response, opts) {
99 var obj = Ext.decode(response.responseText);
100 me.updateLoginData(obj.data);
101 }
102 });
103 },
104 interval: 15*60*1000
105 });
106
107 }
108 });
109
110 Ext.define('PVE.StdWorkspace', {
111 extend: 'PVE.Workspace',
112
113 alias: ['widget.pveStdWorkspace'],
114
115 // private
116 setContent: function(comp) {
117 var me = this;
118
119 var cont = me.child('#content');
120
121 var lay = cont.getLayout();
122
123 var cur = lay.getActiveItem();
124
125 if (comp) {
126 Proxmox.Utils.setErrorMask(cont, false);
127 comp.border = false;
128 cont.add(comp);
129 if (cur !== null && lay.getNext()) {
130 lay.next();
131 var task = Ext.create('Ext.util.DelayedTask', function(){
132 cont.remove(cur);
133 });
134 task.delay(10);
135 }
136 }
137 else {
138 // helper for cleaning the content when logging out
139 cont.removeAll();
140 }
141 },
142
143 selectById: function(nodeid) {
144 var me = this;
145 var tree = me.down('pveResourceTree');
146 tree.selectById(nodeid);
147 },
148
149 onLogin: function(loginData) {
150 var me = this;
151
152 me.updateUserInfo();
153
154 if (loginData) {
155 PVE.data.ResourceStore.startUpdate();
156
157 Proxmox.Utils.API2Request({
158 url: '/version',
159 method: 'GET',
160 success: function(response) {
161 PVE.VersionInfo = response.result.data;
162 me.updateVersionInfo();
163 }
164 });
165
166 Proxmox.Utils.API2Request({
167 url: '/cluster/sdn',
168 method: 'GET',
169 success: function(response) {
170 PVE.SDNInfo = response.result.data;
171 },
172 failure: function(response) {
173 PVE.SDNInfo = null;
174 let ui = Ext.ComponentQuery.query('treelistitem[text="SDN"]')[0];
175 if (ui) {
176 ui.addCls('x-hidden-display');
177 }
178 },
179 });
180 }
181 },
182
183 updateUserInfo: function() {
184 var me = this;
185 var ui = me.query('#userinfo')[0];
186 ui.setText(Ext.String.htmlEncode(Proxmox.UserName || ''));
187 ui.updateLayout();
188 },
189
190 updateVersionInfo: function() {
191 var me = this;
192
193 var ui = me.query('#versioninfo')[0];
194
195 if (PVE.VersionInfo) {
196 var version = PVE.VersionInfo.version;
197 ui.update('Virtual Environment ' + version);
198 } else {
199 ui.update('Virtual Environment');
200 }
201 ui.updateLayout();
202 },
203
204 initComponent : function() {
205 var me = this;
206
207 Ext.History.init();
208
209 var sprovider = Ext.create('PVE.StateProvider');
210 Ext.state.Manager.setProvider(sprovider);
211
212 var selview = Ext.create('PVE.form.ViewSelector');
213
214 var rtree = Ext.createWidget('pveResourceTree', {
215 viewFilter: selview.getViewFilter(),
216 flex: 1,
217 selModel: {
218 selType: 'treemodel',
219 listeners: {
220 selectionchange: function(sm, selected) {
221 if (selected.length > 0) {
222 var n = selected[0];
223 var tlckup = {
224 root: 'PVE.dc.Config',
225 node: 'PVE.node.Config',
226 qemu: 'PVE.qemu.Config',
227 lxc: 'PVE.lxc.Config',
228 storage: 'PVE.storage.Browser',
229 sdn: 'PVE.sdn.Browser',
230 pool: 'pvePoolConfig'
231 };
232 var comp = {
233 xtype: tlckup[n.data.type || 'root'] ||
234 'pvePanelConfig',
235 showSearch: (n.data.id === 'root') ||
236 Ext.isDefined(n.data.groupbyid),
237 pveSelNode: n,
238 workspace: me,
239 viewFilter: selview.getViewFilter()
240 };
241 PVE.curSelectedNode = n;
242 me.setContent(comp);
243 }
244 }
245 }
246 }
247 });
248
249 selview.on('select', function(combo, records) {
250 if (records) {
251 var view = combo.getViewFilter();
252 rtree.setViewFilter(view);
253 }
254 });
255
256 var caps = sprovider.get('GuiCap');
257
258 var createVM = Ext.createWidget('button', {
259 pack: 'end',
260 margin: '3 5 0 0',
261 baseCls: 'x-btn',
262 iconCls: 'fa fa-desktop',
263 text: gettext("Create VM"),
264 disabled: !caps.vms['VM.Allocate'],
265 handler: function() {
266 var wiz = Ext.create('PVE.qemu.CreateWizard', {});
267 wiz.show();
268 }
269 });
270
271 var createCT = Ext.createWidget('button', {
272 pack: 'end',
273 margin: '3 5 0 0',
274 baseCls: 'x-btn',
275 iconCls: 'fa fa-cube',
276 text: gettext("Create CT"),
277 disabled: !caps.vms['VM.Allocate'],
278 handler: function() {
279 var wiz = Ext.create('PVE.lxc.CreateWizard', {});
280 wiz.show();
281 }
282 });
283
284 sprovider.on('statechange', function(sp, key, value) {
285 if (key === 'GuiCap' && value) {
286 caps = value;
287 createVM.setDisabled(!caps.vms['VM.Allocate']);
288 createCT.setDisabled(!caps.vms['VM.Allocate']);
289 }
290 });
291
292 Ext.apply(me, {
293 layout: { type: 'border' },
294 border: false,
295 items: [
296 {
297 region: 'north',
298 layout: {
299 type: 'hbox',
300 align: 'middle'
301 },
302 baseCls: 'x-plain',
303 defaults: {
304 baseCls: 'x-plain'
305 },
306 border: false,
307 margin: '2 0 2 5',
308 items: [
309 {
310 xtype: 'proxmoxlogo',
311 },
312 {
313 minWidth: 150,
314 id: 'versioninfo',
315 html: 'Virtual Environment'
316 },
317 {
318 xtype: 'pveGlobalSearchField',
319 tree: rtree
320 },
321 {
322 flex: 1
323 },
324 {
325 xtype: 'proxmoxHelpButton',
326 hidden: false,
327 baseCls: 'x-btn',
328 iconCls: 'fa fa-book x-btn-icon-el-default-toolbar-small ',
329 listenToGlobalEvent: false,
330 onlineHelp: 'pve_documentation_index',
331 text: gettext('Documentation'),
332 margin: '0 5 0 0'
333 },
334 createVM,
335 createCT,
336 {
337 pack: 'end',
338 margin: '0 5 0 0',
339 id: 'userinfo',
340 xtype: 'button',
341 baseCls: 'x-btn',
342 style: {
343 // proxmox dark grey p light grey as border
344 backgroundColor: '#464d4d',
345 borderColor: '#ABBABA'
346 },
347 iconCls: 'fa fa-user',
348 menu: [
349 {
350 iconCls: 'fa fa-gear',
351 text: gettext('My Settings'),
352 handler: function() {
353 var win = Ext.create('PVE.window.Settings');
354 win.show();
355 }
356 },
357 {
358 text: gettext('Password'),
359 iconCls: 'fa fa-fw fa-key',
360 handler: function() {
361 var win = Ext.create('Proxmox.window.PasswordEdit', {
362 userid: Proxmox.UserName
363 });
364 win.show();
365 }
366 },
367 {
368 text: 'TFA',
369 iconCls: 'fa fa-fw fa-lock',
370 handler: function(btn, event, rec) {
371 var win = Ext.create('PVE.window.TFAEdit',{
372 userid: Proxmox.UserName
373 });
374 win.show();
375 }
376 },
377 {
378 iconCls: 'fa fa-language',
379 text: gettext('Language'),
380 handler: function() {
381 Ext.create('Proxmox.window.LanguageEditWindow')
382 .show();
383 },
384 },
385 '-',
386 {
387 iconCls: 'fa fa-fw fa-sign-out',
388 text: gettext("Logout"),
389 handler: function() {
390 PVE.data.ResourceStore.loadData([], false);
391 me.showLogin();
392 me.setContent(null);
393 var rt = me.down('pveResourceTree');
394 rt.setDatacenterText(undefined);
395 rt.clearTree();
396
397 // empty the stores of the StatusPanel child items
398 var statusPanels = Ext.ComponentQuery.query('pveStatusPanel grid');
399 Ext.Array.forEach(statusPanels, function(comp) {
400 if (comp.getStore()) {
401 comp.getStore().loadData([], false);
402 }
403 });
404 }
405 }
406 ]
407 }
408 ]
409 },
410 {
411 region: 'center',
412 stateful: true,
413 stateId: 'pvecenter',
414 minWidth: 100,
415 minHeight: 100,
416 id: 'content',
417 xtype: 'container',
418 layout: { type: 'card' },
419 border: false,
420 margin: '0 5 0 0',
421 items: []
422 },
423 {
424 region: 'west',
425 stateful: true,
426 stateId: 'pvewest',
427 itemId: 'west',
428 xtype: 'container',
429 border: false,
430 layout: { type: 'vbox', align: 'stretch' },
431 margin: '0 0 0 5',
432 split: true,
433 width: 200,
434 items: [ selview, rtree ],
435 listeners: {
436 resize: function(panel, width, height) {
437 var viewWidth = me.getSize().width;
438 if (width > viewWidth - 100) {
439 panel.setWidth(viewWidth - 100);
440 }
441 }
442 }
443 },
444 {
445 xtype: 'pveStatusPanel',
446 stateful: true,
447 stateId: 'pvesouth',
448 itemId: 'south',
449 region: 'south',
450 margin:'0 5 5 5',
451 title: gettext('Logs'),
452 collapsible: true,
453 header: false,
454 height: 200,
455 split:true,
456 listeners: {
457 resize: function(panel, width, height) {
458 var viewHeight = me.getSize().height;
459 if (height > (viewHeight - 150)) {
460 panel.setHeight(viewHeight - 150);
461 }
462 }
463 }
464 }
465 ]
466 });
467
468 me.callParent();
469
470 me.updateUserInfo();
471
472 // on resize, center all modal windows
473 Ext.on('resize', function(){
474 var wins = Ext.ComponentQuery.query('window[modal]');
475 if (wins.length > 0) {
476 wins.forEach(function(win){
477 win.alignTo(me, 'c-c');
478 });
479 }
480 });
481 }
482 });
483