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