]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/Workspace.js
4 * popup login window when auth fails (call onLogin handler)
5 * update (re-login) ticket every 15 minutes
9 Ext
.define('PVE.Workspace', {
10 extend
: 'Ext.container.Viewport',
12 title
: 'Proxmox Virtual Environment',
14 loginData
: null, // Data from last login call
16 onLogin: function(loginData
) {
21 updateLoginData: function(loginData
) {
23 me
.loginData
= loginData
;
24 Proxmox
.Utils
.setAuthData(loginData
);
26 let rt
= me
.down('pveResourceTree');
27 rt
.setDatacenterText(loginData
.clustername
);
28 PVE
.ClusterName
= loginData
.clustername
;
31 Ext
.state
.Manager
.set('GuiCap', loginData
.cap
);
33 me
.response401count
= 0;
35 me
.onLogin(loginData
);
39 showLogin: function() {
42 Proxmox
.Utils
.authClear();
43 Ext
.state
.Manager
.clear('GuiCap');
44 Proxmox
.UserName
= null;
48 me
.login
= Ext
.create('PVE.window.LoginWindow', {
49 handler: function(data
) {
51 me
.updateLoginData(data
);
52 Proxmox
.Utils
.checked_command(Ext
.emptyFn
); // display subscription status
60 initComponent: function() {
63 Ext
.tip
.QuickTipManager
.init();
65 // fixme: what about other errors
66 Ext
.Ajax
.on('requestexception', function(conn
, response
, options
) {
67 if ((response
.status
=== 401 || response
.status
=== '401') && !PVE
.Utils
.silenceAuthFailures
) { // auth failure
68 // don't immediately show as logged out to cope better with some big
69 // upgrades, which may temporarily produce a false positive 401 err
70 me
.response401count
++;
71 if (me
.response401count
> 5) {
79 if (!Proxmox
.Utils
.authOK()) {
81 } else if (me
.loginData
) {
82 me
.onLogin(me
.loginData
);
85 Ext
.TaskManager
.start({
87 let ticket
= Proxmox
.Utils
.authOK();
88 if (!ticket
|| !Proxmox
.UserName
) {
94 username
: Proxmox
.UserName
,
97 url
: '/api2/json/access/ticket',
99 success: function(response
, opts
) {
100 let obj
= Ext
.decode(response
.responseText
);
101 me
.updateLoginData(obj
.data
);
105 interval
: 15 * 60 * 1000,
110 Ext
.define('PVE.StdWorkspace', {
111 extend
: 'PVE.Workspace',
113 alias
: ['widget.pveStdWorkspace'],
116 setContent: function(comp
) {
119 let view
= me
.child('#content');
120 let layout
= view
.getLayout();
121 let current
= layout
.getActiveItem();
124 Proxmox
.Utils
.setErrorMask(view
, false);
127 if (current
!== null && layout
.getNext()) {
129 let task
= Ext
.create('Ext.util.DelayedTask', function() {
130 view
.remove(current
);
135 view
.removeAll(); // helper for cleaning the content when logging out
139 selectById: function(nodeid
) {
141 me
.down('pveResourceTree').selectById(nodeid
);
144 onLogin: function(loginData
) {
150 PVE
.data
.ResourceStore
.startUpdate();
152 Proxmox
.Utils
.API2Request({
155 success: function(response
) {
156 PVE
.VersionInfo
= response
.result
.data
;
157 me
.updateVersionInfo();
161 PVE
.UIOptions
.update();
163 Proxmox
.Utils
.API2Request({
166 success: function(response
) {
167 PVE
.SDNInfo
= response
.result
.data
;
169 failure: function(response
) {
171 let ui
= Ext
.ComponentQuery
.query('treelistitem[text="SDN"]')[0];
173 ui
.addCls('x-hidden-display');
178 Proxmox
.Utils
.API2Request({
179 url
: '/access/domains',
181 success: function(response
) {
182 let [_username
, realm
] = Proxmox
.Utils
.parse_userid(Proxmox
.UserName
);
183 response
.result
.data
.forEach((domain
) => {
184 if (domain
.realm
=== realm
) {
185 let schema
= PVE
.Utils
.authSchema
[domain
.type
];
187 me
.query('#tfaitem')[0].setHidden(!schema
.tfa
);
188 me
.query('#passworditem')[0].setHidden(!schema
.pwchange
);
197 updateUserInfo: function() {
199 let ui
= me
.query('#userinfo')[0];
200 ui
.setText(Ext
.String
.htmlEncode(Proxmox
.UserName
|| ''));
204 updateVersionInfo: function() {
207 let ui
= me
.query('#versioninfo')[0];
209 if (PVE
.VersionInfo
) {
210 let version
= PVE
.VersionInfo
.version
;
211 ui
.update('Virtual Environment ' + version
);
213 ui
.update('Virtual Environment');
218 initComponent: function() {
223 let appState
= Ext
.create('PVE.StateProvider');
224 Ext
.state
.Manager
.setProvider(appState
);
226 let selview
= Ext
.create('PVE.form.ViewSelector', {
231 let rtree
= Ext
.createWidget('pveResourceTree', {
232 viewFilter
: selview
.getViewFilter(),
235 selType
: 'treemodel',
237 selectionchange: function(sm
, selected
) {
238 if (selected
.length
<= 0) {
241 let treeNode
= selected
[0];
242 let treeTypeToClass
= {
243 root
: 'PVE.dc.Config',
244 node
: 'PVE.node.Config',
245 qemu
: 'PVE.qemu.Config',
247 storage
: 'PVE.storage.Browser',
248 sdn
: 'PVE.sdn.Browser',
249 pool
: 'pvePoolConfig',
251 PVE
.curSelectedNode
= treeNode
;
253 xtype
: treeTypeToClass
[treeNode
.data
.type
|| 'root'] || 'pvePanelConfig',
254 showSearch
: treeNode
.data
.id
=== 'root' || Ext
.isDefined(treeNode
.data
.groupbyid
),
255 pveSelNode
: treeNode
,
257 viewFilter
: selview
.getViewFilter(),
264 selview
.on('select', function(combo
, records
) {
266 let view
= combo
.getViewFilter();
267 rtree
.setViewFilter(view
);
271 let caps
= appState
.get('GuiCap');
273 let createVM
= Ext
.createWidget('button', {
277 iconCls
: 'fa fa-desktop',
278 text
: gettext("Create VM"),
279 disabled
: !caps
.vms
['VM.Allocate'],
280 handler: function() {
281 let wiz
= Ext
.create('PVE.qemu.CreateWizard', {});
286 let createCT
= Ext
.createWidget('button', {
290 iconCls
: 'fa fa-cube',
291 text
: gettext("Create CT"),
292 disabled
: !caps
.vms
['VM.Allocate'],
293 handler: function() {
294 let wiz
= Ext
.create('PVE.lxc.CreateWizard', {});
299 appState
.on('statechange', function(sp
, key
, value
) {
300 if (key
=== 'GuiCap' && value
) {
302 createVM
.setDisabled(!caps
.vms
['VM.Allocate']);
303 createCT
.setDisabled(!caps
.vms
['VM.Allocate']);
308 layout
: { type
: 'border' },
313 title
: gettext('Header'), // for ARIA
314 header
: false, // avoid rendering the title
327 xtype
: 'proxmoxlogo',
332 html
: 'Virtual Environment',
335 'line-height': '18px',
339 xtype
: 'pveGlobalSearchField',
346 xtype
: 'proxmoxHelpButton',
349 iconCls
: 'fa fa-book x-btn-icon-el-default-toolbar-small ',
350 listenToGlobalEvent
: false,
351 onlineHelp
: 'pve_documentation_index',
352 text
: gettext('Documentation'),
364 // proxmox dark grey p light grey as border
365 backgroundColor
: '#464d4d',
366 borderColor
: '#ABBABA',
368 iconCls
: 'fa fa-user',
371 iconCls
: 'fa fa-gear',
372 text
: gettext('My Settings'),
373 handler: function() {
374 var win
= Ext
.create('PVE.window.Settings');
379 text
: gettext('Password'),
380 itemId
: 'passworditem',
381 iconCls
: 'fa fa-fw fa-key',
382 handler: function() {
383 var win
= Ext
.create('Proxmox.window.PasswordEdit', {
384 userid
: Proxmox
.UserName
,
385 confirmCurrentPassword
: Proxmox
.UserName
!== 'root@pam',
393 iconCls
: 'fa fa-fw fa-lock',
394 handler: function(btn
, event
, rec
) {
395 Ext
.state
.Manager
.getProvider().set('dctab', { value
: 'tfa' }, true);
396 me
.selectById('root');
400 iconCls
: 'fa fa-paint-brush',
401 text
: gettext('Color Theme'),
402 handler: function() {
403 Ext
.create('Proxmox.window.ThemeEditWindow')
408 iconCls
: 'fa fa-language',
409 text
: gettext('Language'),
410 handler: function() {
411 Ext
.create('Proxmox.window.LanguageEditWindow')
417 iconCls
: 'fa fa-fw fa-sign-out',
418 text
: gettext("Logout"),
419 handler: function() {
420 PVE
.data
.ResourceStore
.loadData([], false);
423 var rt
= me
.down('pveResourceTree');
424 rt
.setDatacenterText(undefined);
427 // empty the stores of the StatusPanel child items
428 var statusPanels
= Ext
.ComponentQuery
.query('pveStatusPanel grid');
429 Ext
.Array
.forEach(statusPanels
, function(comp
) {
430 if (comp
.getStore()) {
431 comp
.getStore().loadData([], false);
443 stateId
: 'pvecenter',
448 layout
: { type
: 'card' },
460 layout
: { type
: 'vbox', align
: 'stretch' },
473 cls
: 'x-btn-default-toolbar-small',
474 iconCls
: 'fa fa-fw fa-gear x-btn-icon-el-default-toolbar-small',
476 Ext
.create('PVE.window.TreeSettingsEdit', {
478 apiCallDone
: () => PVE
.UIOptions
.fireUIConfigChanged(),
487 resize: function(panel
, width
, height
) {
488 var viewWidth
= me
.getSize().width
;
489 if (width
> viewWidth
- 100 && viewWidth
> 150) {
490 panel
.setWidth(viewWidth
- 100);
496 xtype
: 'pveStatusPanel',
502 title
: gettext('Logs'),
508 resize: function(panel
, width
, height
) {
509 var viewHeight
= me
.getSize().height
;
510 if (height
> viewHeight
- 150 && viewHeight
> 200) {
511 panel
.setHeight(viewHeight
- 150);
523 // on resize, center all modal windows
524 Ext
.on('resize', function() {
525 let modalWindows
= Ext
.ComponentQuery
.query('window[modal]');
526 if (modalWindows
.length
> 0) {
527 modalWindows
.forEach(win
=> win
.alignTo(me
, 'c-c'));
531 let tagSelectors
= [];
532 ['circle', 'dense'].forEach((style
) => {
533 ['dark', 'light'].forEach((variant
) => {
534 tagSelectors
.push(`.proxmox-tags-${style} .proxmox-tag-${variant}`);
538 Ext
.create('Ext.tip.ToolTip', {
540 delegate
: tagSelectors
.join(', '),
542 renderTo
: Ext
.getBody(),
549 userCls
: 'pmx-tag-tooltip',
552 beforeshow: function(tip
) {
553 let tag
= Ext
.htmlEncode(tip
.triggerElement
.innerHTML
);
554 let tagEl
= Proxmox
.Utils
.getTagElement(tag
, PVE
.UIOptions
.tagOverrides
);
555 tip
.update(`<span class="proxmox-tags-full">${tagEl}</span>`);