]>
Commit | Line | Data |
---|---|---|
aff192e6 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', | |
aff192e6 DM |
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; | |
8fb7d745 DM |
24 | |
25 | if (loginData.cap) { | |
26 | Ext.state.Manager.set('GuiCap', loginData.cap); | |
27 | } | |
28 | ||
485dd03d DM |
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); | |
aff192e6 DM |
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 | } | |
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) { | |
62 | if (response.status == 401) { // auth failure | |
63 | me.showLogin(); | |
64 | } | |
65 | }); | |
66 | ||
67 | document.title = me.title; | |
68 | ||
69 | me.callParent(); | |
70 | ||
71 | if (!PVE.Utils.authOK()) { | |
72 | me.showLogin(); | |
73 | } else { | |
74 | if (me.loginData) { | |
75 | me.onLogin(me.loginData); | |
76 | } | |
77 | } | |
78 | ||
79 | Ext.TaskManager.start({ | |
80 | run: function() { | |
81 | var ticket = PVE.Utils.authOK(); | |
82 | if (!ticket || !PVE.UserName) { | |
83 | return; | |
84 | } | |
85 | ||
86 | Ext.Ajax.request({ | |
87 | params: { | |
88 | username: PVE.UserName, | |
89 | password: ticket | |
90 | }, | |
91 | url: '/api2/json/access/ticket', | |
92 | method: 'POST', | |
93 | success: function(response, opts) { | |
aff192e6 DM |
94 | var obj = Ext.decode(response.responseText); |
95 | me.updateLoginData(obj.data); | |
96 | } | |
97 | }); | |
98 | }, | |
99 | interval: 15*60*1000 | |
100 | }); | |
101 | ||
102 | } | |
103 | }); | |
104 | ||
105 | Ext.define('PVE.ConsoleWorkspace', { | |
106 | extend: 'PVE.Workspace', | |
aff192e6 DM |
107 | |
108 | alias: ['widget.pveConsoleWorkspace'], | |
109 | ||
7e6b14a8 | 110 | title: gettext('Console'), |
aff192e6 DM |
111 | |
112 | initComponent : function() { | |
113 | var me = this; | |
114 | ||
115 | var param = Ext.Object.fromQueryString(window.location.search); | |
116 | var consoleType = me.consoleType || param.console; | |
117 | ||
118 | var content; | |
119 | if (consoleType === 'kvm') { | |
120 | me.title = "VM " + param.vmid; | |
fb3feb55 DM |
121 | if (param.vmname) { |
122 | me.title += " ('" + param.vmname + "')"; | |
123 | } | |
aff192e6 DM |
124 | content = { |
125 | xtype: 'pveKVMConsole', | |
126 | vmid: param.vmid, | |
127 | nodename: param.node, | |
fb3feb55 | 128 | vmname: param.vmname, |
1a7bfb86 DM |
129 | toplevel: true |
130 | }; | |
131 | } else if (consoleType === 'openvz') { | |
132 | me.title = "CT " + param.vmid; | |
fb3feb55 DM |
133 | if (param.vmname) { |
134 | me.title += " ('" + param.vmname + "')"; | |
135 | } | |
1a7bfb86 DM |
136 | content = { |
137 | xtype: 'pveOpenVZConsole', | |
138 | vmid: param.vmid, | |
139 | nodename: param.node, | |
fb3feb55 | 140 | vmname: param.vmname, |
aff192e6 DM |
141 | toplevel: true |
142 | }; | |
143 | } else if (consoleType === 'shell') { | |
7e6b14a8 | 144 | me.title = "node '" + param.node; |
aff192e6 DM |
145 | content = { |
146 | xtype: 'pveShell', | |
147 | nodename: param.node, | |
148 | toplevel: true | |
149 | }; | |
150 | } else { | |
151 | content = { | |
152 | border: false, | |
153 | bodyPadding: 10, | |
154 | html: 'Error: No such console type' | |
155 | }; | |
156 | } | |
157 | ||
158 | Ext.apply(me, { | |
159 | layout: { type: 'fit' }, | |
160 | border: false, | |
161 | items: [ content ] | |
162 | }); | |
163 | ||
164 | me.callParent(); | |
165 | } | |
166 | }); | |
167 | ||
168 | Ext.define('PVE.StdWorkspace', { | |
169 | extend: 'PVE.Workspace', | |
aff192e6 DM |
170 | |
171 | alias: ['widget.pveStdWorkspace'], | |
172 | ||
173 | // private | |
aff192e6 DM |
174 | setContent: function(comp) { |
175 | var me = this; | |
176 | ||
aff192e6 DM |
177 | var cont = me.child('#content'); |
178 | cont.removeAll(true); | |
3732a665 DM |
179 | |
180 | if (comp) { | |
524710d6 | 181 | PVE.Utils.setErrorMask(cont, false); |
3732a665 DM |
182 | comp.border = false; |
183 | cont.add(comp); | |
184 | cont.doLayout(); | |
42476072 DM |
185 | } |
186 | // else { | |
b3a1dbbb DM |
187 | // TODO: display something useful |
188 | ||
189 | // Note:: error mask has wrong zindex, so we do not | |
190 | // use that - see bug 114 | |
191 | // PVE.Utils.setErrorMask(cont, 'nothing selected'); | |
42476072 | 192 | //} |
aff192e6 DM |
193 | }, |
194 | ||
195 | selectById: function(nodeid) { | |
196 | var me = this; | |
197 | var tree = me.down('pveResourceTree'); | |
198 | tree.selectById(nodeid); | |
199 | }, | |
200 | ||
72482751 | 201 | checkVmMigration: function(record) { |
52df9bc1 DM |
202 | var me = this; |
203 | var tree = me.down('pveResourceTree'); | |
72482751 | 204 | tree.checkVmMigration(record); |
52df9bc1 DM |
205 | }, |
206 | ||
aff192e6 DM |
207 | onLogin: function(loginData) { |
208 | var me = this; | |
209 | ||
210 | me.updateUserInfo(); | |
211 | ||
212 | if (loginData) { | |
213 | PVE.data.ResourceStore.startUpdate(); | |
214 | } | |
215 | }, | |
216 | ||
217 | updateUserInfo: function() { | |
218 | var me = this; | |
219 | ||
220 | var ui = me.query('#userinfo')[0]; | |
221 | ||
222 | if (PVE.UserName) { | |
a2dca26b DM |
223 | var msg = Ext.String.format(gettext("You are logged in as {0}"), "'" + PVE.UserName + "'"); |
224 | ui.update('<div class="x-unselectable" style="white-space:nowrap;">' + msg + '</div>'); | |
aff192e6 DM |
225 | } else { |
226 | ui.update(''); | |
227 | } | |
228 | ui.doLayout(); | |
229 | }, | |
230 | ||
231 | initComponent : function() { | |
232 | var me = this; | |
233 | ||
234 | Ext.History.init(); | |
aff192e6 | 235 | |
2840e622 DM |
236 | var sprovider = Ext.create('PVE.StateProvider'); |
237 | Ext.state.Manager.setProvider(sprovider); | |
238 | ||
3732a665 | 239 | var selview = new PVE.form.ViewSelector({}); |
aff192e6 DM |
240 | |
241 | var rtree = Ext.createWidget('pveResourceTree', { | |
aff192e6 | 242 | viewFilter: selview.getViewFilter(), |
3732a665 | 243 | flex: 1, |
aff192e6 DM |
244 | selModel: new Ext.selection.TreeModel({ |
245 | listeners: { | |
246 | selectionchange: function(sm, selected) { | |
247 | var comp; | |
248 | var tlckup = { | |
249 | root: 'PVE.dc.Config', | |
250 | node: 'PVE.node.Config', | |
251 | qemu: 'PVE.qemu.Config', | |
6521f904 | 252 | openvz: 'PVE.openvz.Config', |
0004edad DM |
253 | storage: 'PVE.storage.Browser', |
254 | pool: 'pvePoolConfig' | |
aff192e6 DM |
255 | }; |
256 | ||
257 | if (selected.length > 0) { | |
258 | var n = selected[0]; | |
259 | comp = { | |
260 | xtype: tlckup[n.data.type || 'root'] || | |
524710d6 | 261 | 'pvePanelConfig', |
aff192e6 DM |
262 | layout: { type: 'fit' }, |
263 | showSearch: (n.data.id === 'root') || | |
264 | Ext.isDefined(n.data.groupbyid), | |
265 | pveSelNode: n, | |
52df9bc1 | 266 | workspace: me, |
aff192e6 DM |
267 | viewFilter: selview.getViewFilter() |
268 | }; | |
269 | } | |
270 | ||
271 | me.setContent(comp); | |
272 | } | |
273 | } | |
274 | }) | |
275 | }); | |
276 | ||
3732a665 DM |
277 | selview.on('select', function(combo, records) { |
278 | if (records && records.length) { | |
279 | var view = combo.getViewFilter(); | |
280 | rtree.setViewFilter(view); | |
281 | } | |
282 | }); | |
283 | ||
2840e622 DM |
284 | var caps = sprovider.get('GuiCap'); |
285 | ||
286 | var createVM = Ext.createWidget('button', { | |
287 | pack: 'end', | |
288 | margins: '3 5 0 0', | |
289 | baseCls: 'x-btn', | |
290 | text: gettext("Create VM"), | |
291 | disabled: !caps.vms['VM.Allocate'], | |
292 | handler: function() { | |
293 | var wiz = Ext.create('PVE.qemu.CreateWizard', {}); | |
294 | wiz.show(); | |
295 | } | |
296 | }); | |
297 | ||
298 | var createCT = Ext.createWidget('button', { | |
299 | pack: 'end', | |
300 | margins: '3 5 0 0', | |
301 | baseCls: 'x-btn', | |
302 | text: gettext("Create CT"), | |
303 | disabled: !caps.vms['VM.Allocate'], | |
304 | handler: function() { | |
305 | var wiz = Ext.create('PVE.openvz.CreateWizard', {}); | |
306 | wiz.show(); | |
307 | } | |
308 | }); | |
309 | ||
310 | sprovider.on('statechange', function(sp, key, value) { | |
311 | if (key === 'GuiCap' && value) { | |
312 | caps = value; | |
313 | createVM.setDisabled(!caps.vms['VM.Allocate']); | |
314 | createCT.setDisabled(!caps.vms['VM.Allocate']); | |
315 | } | |
316 | }); | |
317 | ||
aff192e6 DM |
318 | Ext.apply(me, { |
319 | layout: { type: 'border' }, | |
320 | border: false, | |
321 | items: [ | |
322 | { | |
323 | region: 'north', | |
324 | height: 30, | |
325 | layout: { | |
326 | type: 'hbox', | |
327 | align : 'middle' | |
328 | }, | |
329 | baseCls: 'x-plain', | |
330 | defaults: { | |
331 | baseCls: 'x-plain' | |
332 | }, | |
333 | border: false, | |
334 | margins: '2 0 5 0', | |
335 | items: [ | |
336 | { | |
337 | margins: '0 0 0 4', | |
338 | html: '<a class="x-unselectable" target=_blank href="http://www.proxmox.com">' + | |
339 | '<img height=30 width=209 src="/pve2/images/proxmox_logo.png"/></a>' | |
340 | }, | |
341 | { | |
342 | minWidth: 200, | |
343 | flex: 1, | |
7e6b14a8 | 344 | html: '<span class="x-panel-header-text">Proxmox Virtual Environment<br>' + gettext('Version') + ' ' + PVE.GUIVersion + "</span>" |
aff192e6 DM |
345 | }, |
346 | { | |
347 | pack: 'end', | |
348 | margins: '8 10 0 10', | |
349 | id: 'userinfo', | |
350 | stateful: false | |
351 | }, | |
352 | { | |
353 | pack: 'end', | |
354 | margins: '3 5 0 0', | |
355 | xtype: 'button', | |
356 | baseCls: 'x-btn', | |
a2dca26b | 357 | text: gettext("Logout"), |
aff192e6 DM |
358 | handler: function() { |
359 | PVE.data.ResourceStore.stopUpdate(); | |
360 | me.showLogin(); | |
361 | me.setContent(); | |
362 | var rt = me.down('pveResourceTree'); | |
363 | rt.clearTree(); | |
364 | } | |
2840e622 DM |
365 | }, |
366 | createVM, | |
367 | createCT | |
aff192e6 DM |
368 | ] |
369 | }, | |
370 | { | |
371 | region: 'center', | |
372 | id: 'content', | |
3732a665 | 373 | xtype: 'container', |
aff192e6 DM |
374 | layout: { type: 'fit' }, |
375 | border: false, | |
376 | stateful: false, | |
3732a665 DM |
377 | margins: '0 5 0 0', |
378 | items: [] | |
379 | }, | |
380 | { | |
381 | region: 'west', | |
382 | xtype: 'container', | |
383 | border: false, | |
384 | layout: { type: 'vbox', align: 'stretch' }, | |
385 | margins: '0 0 0 5', | |
386 | split: true, | |
387 | width: 200, | |
388 | items: [ selview, rtree ] | |
aff192e6 | 389 | }, |
aff192e6 DM |
390 | { |
391 | xtype: 'pveStatusPanel', | |
392 | region: 'south', | |
393 | margins:'0 5 5 5', | |
394 | height: 200, | |
aff192e6 DM |
395 | split:true |
396 | } | |
397 | ] | |
398 | }); | |
399 | ||
400 | me.callParent(); | |
401 | ||
402 | me.updateUserInfo(); | |
403 | } | |
404 | }); | |
405 |