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