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