pve-manager/www/manager6/Workspace.js
Thomas Lamprecht 063997ed16 ui: workspace: eslint fixes and code cleanup/refactoring
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-05-17 19:40:33 +02:00

475 lines
10 KiB
JavaScript

/*
* Workspace base class
*
* popup login window when auth fails (call onLogin handler)
* update (re-login) ticket every 15 minutes
*
*/
Ext.define('PVE.Workspace', {
extend: 'Ext.container.Viewport',
title: 'Proxmox Virtual Environment',
loginData: null, // Data from last login call
onLogin: function(loginData) {
// override me
},
// private
updateLoginData: function(loginData) {
let me = this;
me.loginData = loginData;
Proxmox.Utils.setAuthData(loginData);
let rt = me.down('pveResourceTree');
rt.setDatacenterText(loginData.clustername);
PVE.ClusterName = loginData.clustername;
if (loginData.cap) {
Ext.state.Manager.set('GuiCap', loginData.cap);
}
me.response401count = 0;
me.onLogin(loginData);
},
// private
showLogin: function() {
let me = this;
Proxmox.Utils.authClear();
Ext.state.Manager.clear('GuiCap');
Proxmox.UserName = null;
me.loginData = null;
if (!me.login) {
me.login = Ext.create('PVE.window.LoginWindow', {
handler: function(data) {
me.login = null;
me.updateLoginData(data);
Proxmox.Utils.checked_command(Ext.emptyFn); // display subscription status
},
});
}
me.onLogin(null);
me.login.show();
},
initComponent: function() {
let me = this;
Ext.tip.QuickTipManager.init();
// fixme: what about other errors
Ext.Ajax.on('requestexception', function(conn, response, options) {
if ((response.status === 401 || response.status === '401') && !PVE.Utils.silenceAuthFailures) { // auth failure
// don't immediately show as logged out to cope better with some big
// upgrades, which may temporarily produce a false positive 401 err
me.response401count++;
if (me.response401count > 5) {
me.showLogin();
}
}
});
me.callParent();
if (!Proxmox.Utils.authOK()) {
me.showLogin();
} else if (me.loginData) {
me.onLogin(me.loginData);
}
Ext.TaskManager.start({
run: function() {
let ticket = Proxmox.Utils.authOK();
if (!ticket || !Proxmox.UserName) {
return;
}
Ext.Ajax.request({
params: {
username: Proxmox.UserName,
password: ticket,
},
url: '/api2/json/access/ticket',
method: 'POST',
success: function(response, opts) {
let obj = Ext.decode(response.responseText);
me.updateLoginData(obj.data);
},
});
},
interval: 15 * 60 * 1000,
});
},
});
Ext.define('PVE.StdWorkspace', {
extend: 'PVE.Workspace',
alias: ['widget.pveStdWorkspace'],
// private
setContent: function(comp) {
let me = this;
let view = me.child('#content');
let layout = view.getLayout();
let current = layout.getActiveItem();
if (comp) {
Proxmox.Utils.setErrorMask(view, false);
comp.border = false;
view.add(comp);
if (current !== null && layout.getNext()) {
layout.next();
let task = Ext.create('Ext.util.DelayedTask', function() {
view.remove(current);
});
task.delay(10);
}
} else {
view.removeAll(); // helper for cleaning the content when logging out
}
},
selectById: function(nodeid) {
let me = this;
me.down('pveResourceTree').selectById(nodeid);
},
onLogin: function(loginData) {
let me = this;
me.updateUserInfo();
if (loginData) {
PVE.data.ResourceStore.startUpdate();
Proxmox.Utils.API2Request({
url: '/version',
method: 'GET',
success: function(response) {
PVE.VersionInfo = response.result.data;
me.updateVersionInfo();
},
});
Proxmox.Utils.API2Request({
url: '/cluster/sdn',
method: 'GET',
success: function(response) {
PVE.SDNInfo = response.result.data;
},
failure: function(response) {
PVE.SDNInfo = null;
let ui = Ext.ComponentQuery.query('treelistitem[text="SDN"]')[0];
if (ui) {
ui.addCls('x-hidden-display');
}
},
});
}
},
updateUserInfo: function() {
let me = this;
let ui = me.query('#userinfo')[0];
ui.setText(Ext.String.htmlEncode(Proxmox.UserName || ''));
ui.updateLayout();
},
updateVersionInfo: function() {
let me = this;
let ui = me.query('#versioninfo')[0];
if (PVE.VersionInfo) {
let version = PVE.VersionInfo.version;
ui.update('Virtual Environment ' + version);
} else {
ui.update('Virtual Environment');
}
ui.updateLayout();
},
initComponent: function() {
let me = this;
Ext.History.init();
let appState = Ext.create('PVE.StateProvider');
Ext.state.Manager.setProvider(appState);
let selview = Ext.create('PVE.form.ViewSelector');
let rtree = Ext.createWidget('pveResourceTree', {
viewFilter: selview.getViewFilter(),
flex: 1,
selModel: {
selType: 'treemodel',
listeners: {
selectionchange: function(sm, selected) {
if (selected.length <= 0) {
return;
}
let treeNode = selected[0];
let treeTypeToClass = {
root: 'PVE.dc.Config',
node: 'PVE.node.Config',
qemu: 'PVE.qemu.Config',
lxc: 'PVE.lxc.Config',
storage: 'PVE.storage.Browser',
sdn: 'PVE.sdn.Browser',
pool: 'pvePoolConfig',
};
PVE.curSelectedNode = treeNode;
me.setContent({
xtype: treeTypeToClass[treeNode.data.type || 'root'] || 'pvePanelConfig',
showSearch: treeNode.data.id === 'root' || Ext.isDefined(treeNode.data.groupbyid),
pveSelNode: treeNode,
workspace: me,
viewFilter: selview.getViewFilter(),
});
},
},
},
});
selview.on('select', function(combo, records) {
if (records) {
let view = combo.getViewFilter();
rtree.setViewFilter(view);
}
});
let caps = appState.get('GuiCap');
let createVM = Ext.createWidget('button', {
pack: 'end',
margin: '3 5 0 0',
baseCls: 'x-btn',
iconCls: 'fa fa-desktop',
text: gettext("Create VM"),
disabled: !caps.vms['VM.Allocate'],
handler: function() {
let wiz = Ext.create('PVE.qemu.CreateWizard', {});
wiz.show();
},
});
let createCT = Ext.createWidget('button', {
pack: 'end',
margin: '3 5 0 0',
baseCls: 'x-btn',
iconCls: 'fa fa-cube',
text: gettext("Create CT"),
disabled: !caps.vms['VM.Allocate'],
handler: function() {
let wiz = Ext.create('PVE.lxc.CreateWizard', {});
wiz.show();
},
});
appState.on('statechange', function(sp, key, value) {
if (key === 'GuiCap' && value) {
caps = value;
createVM.setDisabled(!caps.vms['VM.Allocate']);
createCT.setDisabled(!caps.vms['VM.Allocate']);
}
});
Ext.apply(me, {
layout: { type: 'border' },
border: false,
items: [
{
region: 'north',
layout: {
type: 'hbox',
align: 'middle',
},
baseCls: 'x-plain',
defaults: {
baseCls: 'x-plain',
},
border: false,
margin: '2 0 2 5',
items: [
{
xtype: 'proxmoxlogo',
},
{
minWidth: 150,
id: 'versioninfo',
html: 'Virtual Environment',
},
{
xtype: 'pveGlobalSearchField',
tree: rtree,
},
{
flex: 1,
},
{
xtype: 'proxmoxHelpButton',
hidden: false,
baseCls: 'x-btn',
iconCls: 'fa fa-book x-btn-icon-el-default-toolbar-small ',
listenToGlobalEvent: false,
onlineHelp: 'pve_documentation_index',
text: gettext('Documentation'),
margin: '0 5 0 0',
},
createVM,
createCT,
{
pack: 'end',
margin: '0 5 0 0',
id: 'userinfo',
xtype: 'button',
baseCls: 'x-btn',
style: {
// proxmox dark grey p light grey as border
backgroundColor: '#464d4d',
borderColor: '#ABBABA',
},
iconCls: 'fa fa-user',
menu: [
{
iconCls: 'fa fa-gear',
text: gettext('My Settings'),
handler: function() {
var win = Ext.create('PVE.window.Settings');
win.show();
},
},
{
text: gettext('Password'),
iconCls: 'fa fa-fw fa-key',
handler: function() {
var win = Ext.create('Proxmox.window.PasswordEdit', {
userid: Proxmox.UserName,
});
win.show();
},
},
{
text: 'TFA',
iconCls: 'fa fa-fw fa-lock',
handler: function(btn, event, rec) {
var win = Ext.create('PVE.window.TFAEdit', {
userid: Proxmox.UserName,
});
win.show();
},
},
{
iconCls: 'fa fa-language',
text: gettext('Language'),
handler: function() {
Ext.create('Proxmox.window.LanguageEditWindow')
.show();
},
},
'-',
{
iconCls: 'fa fa-fw fa-sign-out',
text: gettext("Logout"),
handler: function() {
PVE.data.ResourceStore.loadData([], false);
me.showLogin();
me.setContent(null);
var rt = me.down('pveResourceTree');
rt.setDatacenterText(undefined);
rt.clearTree();
// empty the stores of the StatusPanel child items
var statusPanels = Ext.ComponentQuery.query('pveStatusPanel grid');
Ext.Array.forEach(statusPanels, function(comp) {
if (comp.getStore()) {
comp.getStore().loadData([], false);
}
});
},
},
],
},
],
},
{
region: 'center',
stateful: true,
stateId: 'pvecenter',
minWidth: 100,
minHeight: 100,
id: 'content',
xtype: 'container',
layout: { type: 'card' },
border: false,
margin: '0 5 0 0',
items: [],
},
{
region: 'west',
stateful: true,
stateId: 'pvewest',
itemId: 'west',
xtype: 'container',
border: false,
layout: { type: 'vbox', align: 'stretch' },
margin: '0 0 0 5',
split: true,
width: 200,
items: [selview, rtree],
listeners: {
resize: function(panel, width, height) {
var viewWidth = me.getSize().width;
if (width > viewWidth - 100) {
panel.setWidth(viewWidth - 100);
}
},
},
},
{
xtype: 'pveStatusPanel',
stateful: true,
stateId: 'pvesouth',
itemId: 'south',
region: 'south',
margin: '0 5 5 5',
title: gettext('Logs'),
collapsible: true,
header: false,
height: 200,
split: true,
listeners: {
resize: function(panel, width, height) {
var viewHeight = me.getSize().height;
if (height > viewHeight - 150) {
panel.setHeight(viewHeight - 150);
}
},
},
},
],
});
me.callParent();
me.updateUserInfo();
// on resize, center all modal windows
Ext.on('resize', function() {
let modalWindows = Ext.ComponentQuery.query('window[modal]');
if (modalWindows.length > 0) {
modalWindows.forEach(win => win.alignTo(me, 'c-c'));
}
});
},
});