2565fdd075
this fixes some bugs related to selection handling in the treelist: * datastores were not selected after a reload * reloading when in a tabpanel on any tab but the first, would not select a treenode * changing between datastores on any tab but the first would not select the same tab on the new datastore fixed those by mostly rewriting the changePath handling for datastores and tabpanels in general Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
281 lines
6.1 KiB
JavaScript
281 lines
6.1 KiB
JavaScript
Ext.define('PBS.MainView', {
|
|
extend: 'Ext.container.Container',
|
|
xtype: 'mainview',
|
|
|
|
title: 'Proxmox Backup Server',
|
|
|
|
controller: {
|
|
xclass: 'Ext.app.ViewController',
|
|
routes: {
|
|
':path:subpath': {
|
|
action: 'changePath',
|
|
before: 'beforeChangePath',
|
|
conditions: {
|
|
':path': '(?:([%a-zA-Z0-9\\-\\_\\s,.]+))',
|
|
':subpath': '(?:(?::)([%a-zA-Z0-9\\-\\_\\s,]+))?',
|
|
},
|
|
},
|
|
},
|
|
|
|
beforeChangePath: function(path, subpath, action) {
|
|
var me = this;
|
|
|
|
let xtype = path;
|
|
let datastore;
|
|
let isDataStore = PBS.Utils.isDataStorePath(path);
|
|
if (isDataStore) {
|
|
xtype = 'pbsDataStorePanel';
|
|
datastore = PBS.Utils.getDataStoreFromPath(path);
|
|
}
|
|
|
|
if (!Ext.ClassManager.getByAlias(`widget.${xtype}`)) {
|
|
console.warn(`xtype ${xtype} not found`);
|
|
action.stop();
|
|
return;
|
|
}
|
|
|
|
var lastpanel = me.lookupReference('contentpanel').getLayout().getActiveItem();
|
|
if (lastpanel && lastpanel.xtype === xtype) {
|
|
if (isDataStore) {
|
|
if (datastore === lastpanel.datastore) {
|
|
action.stop();
|
|
return;
|
|
}
|
|
} else {
|
|
// we have the right component already,
|
|
// we just need to select the correct tab
|
|
// default to the first
|
|
subpath = subpath || 0;
|
|
if (lastpanel.getActiveTab) {
|
|
// we assume lastpanel is a tabpanel
|
|
if (lastpanel.getActiveTab().getItemId() !== subpath) {
|
|
// set the active tab
|
|
lastpanel.setActiveTab(subpath);
|
|
}
|
|
// else we are already there
|
|
}
|
|
action.stop();
|
|
return;
|
|
}
|
|
}
|
|
|
|
action.resume();
|
|
},
|
|
|
|
changePath: function(path, subpath) {
|
|
var me = this;
|
|
var contentpanel = me.lookupReference('contentpanel');
|
|
var lastpanel = contentpanel.getLayout().getActiveItem();
|
|
|
|
let tabChangeListener = function(tp, newc, oldc) {
|
|
let newpath = path;
|
|
|
|
// only add the subpath part for the
|
|
// non-default tabs
|
|
if (tp.items.findIndex('id', newc.id) !== 0) {
|
|
newpath += `:${newc.getItemId()}`;
|
|
}
|
|
|
|
me.redirectTo(newpath);
|
|
};
|
|
|
|
let xtype = path;
|
|
var obj;
|
|
let datastore;
|
|
if (PBS.Utils.isDataStorePath(path)) {
|
|
datastore = PBS.Utils.getDataStoreFromPath(path);
|
|
if (lastpanel && lastpanel.xtype === 'pbsDataStorePanel' && !subpath) {
|
|
let activeTab = lastpanel.getActiveTab();
|
|
let newpath = path;
|
|
if (lastpanel.items.indexOf(activeTab) !== 0) {
|
|
subpath = activeTab.getItemId();
|
|
newpath += `:${subpath}`;
|
|
}
|
|
me.redirectTo(newpath);
|
|
}
|
|
xtype = 'pbsDataStorePanel';
|
|
}
|
|
obj = contentpanel.add({
|
|
xtype,
|
|
datastore,
|
|
nodename: 'localhost',
|
|
border: false,
|
|
activeTab: subpath || 0,
|
|
listeners: {
|
|
tabchange: tabChangeListener,
|
|
},
|
|
});
|
|
|
|
var treelist = me.lookupReference('navtree');
|
|
|
|
treelist.select(path, true);
|
|
|
|
contentpanel.setActiveItem(obj);
|
|
|
|
if (lastpanel) {
|
|
contentpanel.remove(lastpanel, { destroy: true });
|
|
}
|
|
},
|
|
|
|
logout: function() {
|
|
PBS.app.logout();
|
|
},
|
|
|
|
navigate: function(treelist, item) {
|
|
this.redirectTo(item.get('path'));
|
|
},
|
|
|
|
control: {
|
|
'[reference=logoutButton]': {
|
|
click: 'logout',
|
|
},
|
|
},
|
|
|
|
init: function(view) {
|
|
var me = this;
|
|
|
|
PBS.data.RunningTasksStore.startUpdate();
|
|
me.lookupReference('usernameinfo').setText(Proxmox.UserName);
|
|
|
|
// show login on requestexception
|
|
// fixme: what about other errors
|
|
Ext.Ajax.on('requestexception', function(conn, response, options) {
|
|
if (response.status === 401 || response.status === '401') { // auth failure
|
|
me.logout();
|
|
}
|
|
});
|
|
|
|
// get ticket periodically
|
|
Ext.TaskManager.start({
|
|
run: function() {
|
|
var 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',
|
|
failure: function() {
|
|
me.logout();
|
|
},
|
|
success: function(response, opts) {
|
|
var obj = Ext.decode(response.responseText);
|
|
PBS.Utils.updateLoginData(obj.data);
|
|
},
|
|
});
|
|
},
|
|
interval: 15*60*1000,
|
|
});
|
|
|
|
|
|
// select treeitem and load page from url fragment, if set
|
|
let token = Ext.util.History.getToken() || 'pbsDashboard';
|
|
this.redirectTo(token, true);
|
|
},
|
|
},
|
|
|
|
plugins: 'viewport',
|
|
|
|
layout: { type: 'border' },
|
|
|
|
items: [
|
|
{
|
|
region: 'north',
|
|
xtype: 'container',
|
|
layout: {
|
|
type: 'hbox',
|
|
align: 'middle',
|
|
},
|
|
margin: '2 0 2 5',
|
|
height: 38,
|
|
items: [
|
|
{
|
|
xtype: 'proxmoxlogo',
|
|
prefix: '',
|
|
},
|
|
{
|
|
padding: '0 0 0 5',
|
|
xtype: 'versioninfo',
|
|
},
|
|
{
|
|
padding: 5,
|
|
html: '<a href="https://bugzilla.proxmox.com" target="_blank">BETA</a>',
|
|
baseCls: 'x-plain',
|
|
},
|
|
{
|
|
flex: 1,
|
|
baseCls: 'x-plain',
|
|
},
|
|
{
|
|
xtype: 'button',
|
|
baseCls: 'x-btn',
|
|
cls: 'x-btn-default-toolbar-small proxmox-inline-button',
|
|
iconCls: 'fa fa-book x-btn-icon-el-default-toolbar-small ',
|
|
text: gettext('Documentation'),
|
|
href: '/docs/index.html',
|
|
margin: '0 5 0 0',
|
|
},
|
|
{
|
|
xtype: 'pbsTaskButton',
|
|
margin: '0 5 0 0',
|
|
},
|
|
{
|
|
xtype: 'button',
|
|
reference: 'usernameinfo',
|
|
style: {
|
|
// proxmox dark grey p light grey as border
|
|
backgroundColor: '#464d4d',
|
|
borderColor: '#ABBABA',
|
|
},
|
|
margin: '0 5 0 0',
|
|
iconCls: 'fa fa-user',
|
|
menu: [
|
|
{
|
|
reference: 'logoutButton',
|
|
iconCls: 'fa fa-sign-out',
|
|
text: gettext('Logout'),
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
xtype: 'panel',
|
|
scrollable: 'y',
|
|
border: false,
|
|
region: 'west',
|
|
layout: {
|
|
type: 'vbox',
|
|
align: 'stretch',
|
|
},
|
|
items: [{
|
|
xtype: 'navigationtree',
|
|
minWidth: 180,
|
|
reference: 'navtree',
|
|
// we have to define it here until extjs 6.2
|
|
// because of a bug where a viewcontroller does not detect
|
|
// the selectionchange event of a treelist
|
|
listeners: {
|
|
selectionchange: 'navigate',
|
|
},
|
|
}, {
|
|
xtype: 'box',
|
|
cls: 'x-treelist-nav',
|
|
flex: 1,
|
|
}],
|
|
},
|
|
{
|
|
xtype: 'panel',
|
|
layout: { type: 'card' },
|
|
region: 'center',
|
|
border: false,
|
|
reference: 'contentpanel',
|
|
},
|
|
],
|
|
});
|