2018-12-04 19:53:10 +03:00
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' ,
2020-09-25 19:34:54 +03:00
conditions : {
':path' : '(?:([%a-zA-Z0-9\\-\\_\\s,.]+))' ,
':subpath' : '(?:(?::)([%a-zA-Z0-9\\-\\_\\s,]+))?' ,
} ,
} ,
2018-12-04 19:53:10 +03:00
} ,
2019-12-18 21:21:59 +03:00
2021-03-01 14:22:40 +03:00
parseRouterPath : function ( path ) {
2020-05-20 13:15:38 +03:00
let xtype = path ;
2021-03-01 14:22:40 +03:00
let config = { } ;
if ( PBS . Utils . isDataStorePath ( path ) ) {
config . datastore = PBS . Utils . getDataStoreFromPath ( path ) ;
2020-05-20 13:15:38 +03:00
xtype = 'pbsDataStorePanel' ;
2021-03-01 14:22:40 +03:00
} else if ( path . indexOf ( 'Changer-' ) === 0 ) {
config . changer = path . slice ( 'Changer-' . length ) ;
xtype = 'pbsChangerStatus' ;
} else if ( path . indexOf ( 'Drive-' ) === 0 ) {
config . drive = path . slice ( 'Drive-' . length ) ;
xtype = 'pbsDriveStatus' ;
2020-05-20 13:15:38 +03:00
}
2021-03-01 14:22:40 +03:00
return [ xtype , config ] ;
} ,
2021-05-26 12:12:04 +03:00
beforeChangePath : function ( path , subpathOrAction , action ) {
2021-03-01 14:22:40 +03:00
var me = this ;
2021-05-26 12:12:04 +03:00
let subpath = subpathOrAction ;
if ( ! action ) {
action = subpathOrAction ;
subpath = undefined ;
}
2021-03-01 14:22:40 +03:00
let [ xtype , config ] = me . parseRouterPath ( path ) ;
2020-05-20 13:15:38 +03:00
if ( ! Ext . ClassManager . getByAlias ( ` widget. ${ xtype } ` ) ) {
console . warn ( ` xtype ${ xtype } not found ` ) ;
2019-01-22 13:48:00 +03:00
action . stop ( ) ;
return ;
}
var lastpanel = me . lookupReference ( 'contentpanel' ) . getLayout ( ) . getActiveItem ( ) ;
2020-05-20 13:15:38 +03:00
if ( lastpanel && lastpanel . xtype === xtype ) {
2021-03-01 14:22:40 +03:00
for ( const [ prop , value ] of Object . entries ( config ) ) {
if ( lastpanel [ prop ] !== value ) {
action . resume ( ) ;
2019-12-20 14:46:09 +03:00
return ;
}
2021-03-01 14:22:40 +03:00
}
// 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 ) ;
2019-01-22 13:48:00 +03:00
}
2021-03-01 14:22:40 +03:00
// else we are already there
2019-01-22 13:48:00 +03:00
}
2021-03-01 14:22:40 +03:00
action . stop ( ) ;
return ;
2019-01-22 13:48:00 +03:00
}
2018-12-04 19:53:10 +03:00
action . resume ( ) ;
} ,
2019-12-18 21:21:59 +03:00
2019-12-20 14:46:09 +03:00
changePath : function ( path , subpath ) {
2018-12-04 19:53:10 +03:00
var me = this ;
var contentpanel = me . lookupReference ( 'contentpanel' ) ;
var lastpanel = contentpanel . getLayout ( ) . getActiveItem ( ) ;
2020-10-27 18:20:10 +03:00
let tabChangeListener = function ( tp , newc , oldc ) {
let newpath = path ;
2019-01-22 13:48:00 +03:00
2020-10-27 18:20:10 +03:00
// only add the subpath part for the
// non-default tabs
if ( tp . items . findIndex ( 'id' , newc . id ) !== 0 ) {
newpath += ` : ${ newc . getItemId ( ) } ` ;
}
2019-01-22 13:48:00 +03:00
2020-10-27 18:20:10 +03:00
me . redirectTo ( newpath ) ;
} ;
2019-01-22 13:48:00 +03:00
2021-03-01 14:22:40 +03:00
let [ xtype , config ] = me . parseRouterPath ( path ) ;
2020-10-27 18:20:10 +03:00
var obj ;
if ( PBS . Utils . isDataStorePath ( path ) ) {
2021-03-01 14:22:40 +03:00
if ( lastpanel && lastpanel . xtype === xtype && ! subpath ) {
2020-10-27 18:20:10 +03:00
let activeTab = lastpanel . getActiveTab ( ) ;
let newpath = path ;
if ( lastpanel . items . indexOf ( activeTab ) !== 0 ) {
subpath = activeTab . getItemId ( ) ;
newpath += ` : ${ subpath } ` ;
2019-01-22 13:48:00 +03:00
}
me . redirectTo ( newpath ) ;
2020-10-27 18:20:10 +03:00
}
2019-01-22 13:48:00 +03:00
}
2021-03-01 14:22:40 +03:00
obj = contentpanel . add ( Ext . apply ( config , {
2020-10-27 18:20:10 +03:00
xtype ,
nodename : 'localhost' ,
border : false ,
activeTab : subpath || 0 ,
listeners : {
tabchange : tabChangeListener ,
} ,
2021-03-01 14:22:40 +03:00
} ) ) ;
2020-10-27 18:20:10 +03:00
var treelist = me . lookupReference ( 'navtree' ) ;
treelist . select ( path , true ) ;
2019-01-22 13:48:00 +03:00
contentpanel . setActiveItem ( obj ) ;
if ( lastpanel ) {
contentpanel . remove ( lastpanel , { destroy : true } ) ;
}
} ,
2019-01-30 17:14:20 +03:00
logout : function ( ) {
PBS . app . logout ( ) ;
} ,
2019-01-22 13:48:00 +03:00
navigate : function ( treelist , item ) {
this . redirectTo ( item . get ( 'path' ) ) ;
2018-12-04 19:53:10 +03:00
} ,
2019-01-30 17:14:20 +03:00
control : {
2020-07-09 15:24:33 +03:00
'[reference=logoutButton]' : {
2020-09-25 19:34:54 +03:00
click : 'logout' ,
} ,
2019-01-30 17:14:20 +03:00
} ,
2018-12-04 19:53:10 +03:00
init : function ( view ) {
var me = this ;
2020-07-09 14:38:20 +03:00
PBS . data . RunningTasksStore . startUpdate ( ) ;
2020-07-09 15:24:33 +03:00
me . lookupReference ( 'usernameinfo' ) . setText ( Proxmox . UserName ) ;
2019-12-17 16:44:25 +03:00
2019-12-17 16:45:13 +03:00
// show login on requestexception
// fixme: what about other errors
Ext . Ajax . on ( 'requestexception' , function ( conn , response , options ) {
2020-09-25 19:34:54 +03:00
if ( response . status === 401 || response . status === '401' ) { // auth failure
2019-12-17 16:45:13 +03:00
me . logout ( ) ;
}
} ) ;
2019-12-17 16:44:25 +03:00
// 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 ,
2020-09-25 19:34:54 +03:00
password : ticket ,
2019-12-17 16:44:25 +03:00
} ,
url : '/api2/json/access/ticket' ,
method : 'POST' ,
failure : function ( ) {
me . logout ( ) ;
} ,
success : function ( response , opts ) {
var obj = Ext . decode ( response . responseText ) ;
2019-12-17 17:42:59 +03:00
PBS . Utils . updateLoginData ( obj . data ) ;
2020-09-25 19:34:54 +03:00
} ,
2019-12-17 16:44:25 +03:00
} ) ;
} ,
2020-09-25 19:34:54 +03:00
interval : 15 * 60 * 1000 ,
2019-12-17 16:44:25 +03:00
} ) ;
2019-12-18 21:19:30 +03:00
// select treeitem and load page from url fragment, if set
let token = Ext . util . History . getToken ( ) || 'pbsDashboard' ;
2021-05-26 12:12:06 +03:00
this . redirectTo ( token , { force : true } ) ;
2020-09-25 19:34:54 +03:00
} ,
2018-12-04 19:53:10 +03:00
} ,
plugins : 'viewport' ,
layout : { type : 'border' } ,
items : [
{
region : 'north' ,
xtype : 'container' ,
layout : {
type : 'hbox' ,
2020-09-25 19:34:54 +03:00
align : 'middle' ,
2018-12-04 19:53:10 +03:00
} ,
2020-07-09 15:25:14 +03:00
margin : '2 0 2 5' ,
2018-12-04 19:53:10 +03:00
height : 38 ,
items : [
{
2020-05-18 15:18:37 +03:00
xtype : 'proxmoxlogo' ,
prefix : '' ,
2018-12-04 19:53:10 +03:00
} ,
{
2020-07-09 15:25:14 +03:00
padding : '0 0 0 5' ,
xtype : 'versioninfo' ,
2018-12-04 19:53:10 +03:00
} ,
{
2020-07-03 13:48:50 +03:00
flex : 1 ,
baseCls : 'x-plain' ,
2018-12-04 19:53:10 +03:00
} ,
2019-12-16 20:16:06 +03:00
{
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' ,
} ,
2020-07-09 14:38:21 +03:00
{
xtype : 'pbsTaskButton' ,
margin : '0 5 0 0' ,
} ,
2018-12-04 19:53:10 +03:00
{
xtype : 'button' ,
2020-07-09 15:24:33 +03:00
reference : 'usernameinfo' ,
style : {
// proxmox dark grey p light grey as border
backgroundColor : '#464d4d' ,
2020-09-25 19:34:54 +03:00
borderColor : '#ABBABA' ,
2020-07-09 15:24:33 +03:00
} ,
margin : '0 5 0 0' ,
iconCls : 'fa fa-user' ,
menu : [
2021-02-19 17:40:48 +03:00
{
iconCls : 'fa fa-gear' ,
text : gettext ( 'My Settings' ) ,
handler : ( ) => Ext . create ( 'PBS.window.Settings' ) . show ( ) ,
} ,
2020-07-09 15:24:33 +03:00
{
2020-10-30 11:46:04 +03:00
iconCls : 'fa fa-language' ,
text : gettext ( 'Language' ) ,
reference : 'languageButton' ,
handler : ( ) => Ext . create ( 'Proxmox.window.LanguageEditWindow' , {
cookieName : 'PBSLangCookie' ,
autoShow : true ,
} ) ,
} ,
'-' ,
{
2020-07-09 15:24:33 +03:00
iconCls : 'fa fa-sign-out' ,
text : gettext ( 'Logout' ) ,
2020-10-30 11:46:04 +03:00
reference : 'logoutButton' ,
2020-07-09 15:24:33 +03:00
} ,
] ,
} ,
2020-09-25 19:34:54 +03:00
] ,
2018-12-04 19:53:10 +03:00
} ,
{
2021-05-26 12:11:58 +03:00
xtype : 'container' ,
2018-12-04 19:53:10 +03:00
scrollable : 'y' ,
border : false ,
region : 'west' ,
layout : {
type : 'vbox' ,
2020-09-25 19:34:54 +03:00
align : 'stretch' ,
2018-12-04 19:53:10 +03:00
} ,
2019-01-22 13:48:00 +03:00
items : [ {
xtype : 'navigationtree' ,
minWidth : 180 ,
2021-05-26 12:12:02 +03:00
ui : 'pve-nav' ,
2019-01-22 13:48:00 +03:00
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 : {
2020-09-25 19:34:54 +03:00
selectionchange : 'navigate' ,
} ,
2019-01-22 13:48:00 +03:00
} , {
xtype : 'box' ,
2021-05-26 12:12:02 +03:00
cls : 'x-treelist-pve-nav' ,
2020-09-25 19:34:54 +03:00
flex : 1 ,
} ] ,
2018-12-04 19:53:10 +03:00
} ,
{
2021-05-26 12:11:58 +03:00
xtype : 'container' ,
2018-12-04 19:53:10 +03:00
layout : { type : 'card' } ,
region : 'center' ,
border : false ,
2020-09-25 19:34:54 +03:00
reference : 'contentpanel' ,
} ,
] ,
2018-12-04 19:53:10 +03:00
} ) ;