2020-10-27 18:20:09 +03:00
Ext . define ( 'pbs-datastore-list' , {
extend : 'Ext.data.Model' ,
2022-04-26 09:23:32 +03:00
fields : [ 'name' , 'comment' , 'maintenance' ] ,
2020-10-27 18:20:09 +03:00
proxy : {
type : 'proxmox' ,
url : "/api2/json/admin/datastore" ,
} ,
idProperty : 'store' ,
} ) ;
2021-03-01 14:22:41 +03:00
Ext . define ( 'pbs-tape-drive-list' , {
extend : 'Ext.data.Model' ,
fields : [ 'name' , 'changer' ] ,
proxy : {
type : 'proxmox' ,
url : "/api2/json/tape/drive" ,
} ,
idProperty : 'name' ,
} ) ;
2019-01-22 13:48:00 +03:00
Ext . define ( 'PBS.store.NavigationStore' , {
extend : 'Ext.data.TreeStore' ,
storeId : 'NavigationStore' ,
root : {
expanded : true ,
children : [
2019-12-18 19:29:05 +03:00
{
text : gettext ( 'Dashboard' ) ,
iconCls : 'fa fa-tachometer' ,
path : 'pbsDashboard' ,
2020-09-25 19:36:58 +03:00
leaf : true ,
2019-12-18 19:29:05 +03:00
} ,
2022-04-12 13:34:23 +03:00
{
text : gettext ( 'Notes' ) ,
iconCls : 'fa fa-sticky-note-o' ,
path : 'pbsNodeNotes' ,
leaf : true ,
} ,
2019-01-22 13:48:00 +03:00
{
text : gettext ( 'Configuration' ) ,
iconCls : 'fa fa-gears' ,
path : 'pbsSystemConfiguration' ,
expanded : true ,
children : [
2020-05-18 15:18:38 +03:00
{
2020-10-29 18:47:18 +03:00
text : gettext ( 'Access Control' ) ,
iconCls : 'fa fa-key' ,
path : 'pbsAccessControlPanel' ,
2020-09-25 19:36:58 +03:00
leaf : true ,
2020-05-20 13:15:37 +03:00
} ,
2020-05-26 13:23:25 +03:00
{
text : gettext ( 'Remotes' ) ,
iconCls : 'fa fa-server' ,
path : 'pbsRemoteView' ,
leaf : true ,
} ,
2021-11-19 17:42:27 +03:00
{
text : gettext ( 'Traffic Control' ) ,
2021-11-20 23:43:03 +03:00
iconCls : 'fa fa-signal fa-rotate-90' ,
2021-11-19 17:42:27 +03:00
path : 'pbsTrafficControlView' ,
leaf : true ,
} ,
2021-05-03 12:39:58 +03:00
{
text : gettext ( 'Certificates' ) ,
iconCls : 'fa fa-certificate' ,
path : 'pbsCertificateConfiguration' ,
leaf : true ,
} ,
2019-01-22 13:48:00 +03:00
{
text : gettext ( 'Subscription' ) ,
iconCls : 'fa fa-support' ,
path : 'pbsSubscription' ,
2020-09-25 19:36:58 +03:00
leaf : true ,
} ,
] ,
2019-01-22 13:48:00 +03:00
} ,
{
text : gettext ( 'Administration' ) ,
iconCls : 'fa fa-wrench' ,
path : 'pbsServerAdministration' ,
2020-06-16 12:13:34 +03:00
expanded : true ,
leaf : false ,
children : [
2020-11-04 17:35:08 +03:00
{
text : gettext ( 'Shell' ) ,
iconCls : 'fa fa-terminal' ,
path : 'pbsXtermJsConsole' ,
leaf : true ,
} ,
2020-06-16 12:13:34 +03:00
{
2020-11-10 12:15:44 +03:00
text : gettext ( 'Storage / Disks' ) ,
2020-06-16 12:13:34 +03:00
iconCls : 'fa fa-hdd-o' ,
2020-11-10 12:15:44 +03:00
path : 'pbsStorageAndDiskPanel' ,
leaf : true ,
2020-09-25 19:36:58 +03:00
} ,
] ,
2020-06-05 11:11:51 +03:00
} ,
2021-04-12 13:31:56 +03:00
{
text : "Tape Backup" ,
iconCls : 'pbs-icon-tape' ,
id : 'tape_management' ,
path : 'pbsTapeManagement' ,
expanded : true ,
children : [ ] ,
} ,
2020-06-05 11:11:51 +03:00
{
2020-07-02 18:20:38 +03:00
text : gettext ( 'Datastore' ) ,
2020-06-05 11:11:51 +03:00
iconCls : 'fa fa-archive' ,
2020-10-27 18:20:09 +03:00
id : 'datastores' ,
2020-11-09 18:01:30 +03:00
path : 'pbsDataStores' ,
2020-06-05 11:11:51 +03:00
expanded : true ,
2020-10-27 18:20:09 +03:00
expandable : false ,
2020-09-25 19:36:58 +03:00
leaf : false ,
2020-10-27 18:20:09 +03:00
children : [
{
text : gettext ( 'Add Datastore' ) ,
iconCls : 'fa fa-plus-circle' ,
leaf : true ,
id : 'addbutton' ,
2021-04-12 15:10:57 +03:00
virtualEntry : true ,
2020-10-27 18:20:09 +03:00
} ,
] ,
2020-06-05 11:11:51 +03:00
} ,
2020-09-25 19:36:58 +03:00
] ,
} ,
2019-01-22 13:48:00 +03:00
} ) ;
2022-04-26 09:23:35 +03:00
Ext . define ( 'CustomTreeListItem' , {
extend : 'Ext.list.TreeItem' ,
xtype : 'qtiptreelistitem' ,
2022-05-12 15:23:52 +03:00
nodeUpdate : function ( node , modifiedFieldNames ) {
this . callParent ( arguments ) ;
2022-04-26 09:23:35 +03:00
const qtip = node ? node . get ( 'qtip' ) : null ;
if ( qtip ) {
this . element . dom . setAttribute ( 'data-qtip' , qtip ) ;
} else {
this . element . dom . removeAttribute ( 'data-qtip' ) ;
}
} ,
} ) ;
2019-01-22 13:48:00 +03:00
Ext . define ( 'PBS.view.main.NavigationTree' , {
extend : 'Ext.list.Tree' ,
xtype : 'navigationtree' ,
2022-11-24 18:53:22 +03:00
animation : false ,
expanderOnly : true ,
expanderFirst : false ,
store : 'NavigationStore' ,
ui : 'nav' ,
2022-04-26 09:23:35 +03:00
defaults : {
xtype : 'qtiptreelistitem' ,
} ,
2019-01-22 13:48:00 +03:00
2019-12-20 14:46:09 +03:00
controller : {
xclass : 'Ext.app.ViewController' ,
init : function ( view ) {
view . rstore = Ext . create ( 'Proxmox.data.UpdateStore' , {
autoStart : true ,
2022-05-14 15:38:58 +03:00
interval : 15 * 1000 ,
2022-05-14 13:28:01 +03:00
storeId : 'pbs-datastore-list' , // NOTE: this is queried by selectors, avoid change!
2020-09-25 19:36:58 +03:00
model : 'pbs-datastore-list' ,
2019-12-20 14:46:09 +03:00
} ) ;
view . rstore . on ( 'load' , this . onLoad , this ) ;
view . on ( 'destroy' , view . rstore . stopUpdate ) ;
2021-03-01 14:22:41 +03:00
2021-04-12 13:34:26 +03:00
if ( view . tapeStore === undefined ) {
view . tapeStore = Ext . create ( 'Proxmox.data.UpdateStore' , {
2021-04-12 13:31:56 +03:00
autoStart : true ,
interval : 60 * 1000 ,
storeid : 'pbs-tape-drive-list' ,
model : 'pbs-tape-drive-list' ,
} ) ;
2021-04-12 13:34:26 +03:00
view . tapeStore . on ( 'load' , this . onTapeDriveLoad , this ) ;
view . on ( 'destroy' , view . tapeStore . stopUpdate ) ;
2021-03-01 14:22:41 +03:00
}
2019-12-20 14:46:09 +03:00
} ,
2021-03-01 14:22:41 +03:00
onTapeDriveLoad : function ( store , records , success ) {
2020-06-05 11:11:51 +03:00
if ( ! success ) return ;
2019-12-20 14:46:09 +03:00
2021-03-01 14:22:41 +03:00
let view = this . getView ( ) ;
2019-12-20 14:46:09 +03:00
let root = view . getStore ( ) . getRoot ( ) ;
2021-03-01 14:22:41 +03:00
records . sort ( ( a , b ) => a . data . name . localeCompare ( b . data . name ) ) ;
2021-04-12 15:09:29 +03:00
let list = root . findChild ( 'id' , 'tape_management' , false ) ;
let existingChildren = { } ;
2021-03-01 14:22:41 +03:00
for ( const drive of records ) {
let path , text , iconCls ;
if ( drive . data . changer !== undefined ) {
text = drive . data . changer ;
path = ` Changer- ${ text } ` ;
2021-03-08 19:06:49 +03:00
iconCls = 'fa fa-exchange' ;
2021-03-01 14:22:41 +03:00
} else {
text = drive . data . name ;
path = ` Drive- ${ text } ` ;
2021-03-08 19:06:49 +03:00
iconCls = 'pbs-icon-tape-drive' ;
2021-03-01 14:22:41 +03:00
}
2021-04-12 15:09:29 +03:00
existingChildren [ path ] = {
2021-03-01 14:22:41 +03:00
text ,
path ,
iconCls ,
leaf : true ,
} ;
}
2021-04-12 15:09:29 +03:00
let paths = Object . keys ( existingChildren ) . sort ( ) ;
2021-03-01 14:22:41 +03:00
let oldIdx = 0 ;
for ( let newIdx = 0 ; newIdx < paths . length ; newIdx ++ ) {
let newPath = paths [ newIdx ] ;
// find index to insert
while ( oldIdx < list . childNodes . length && newPath > list . getChildAt ( oldIdx ) . data . path ) {
oldIdx ++ ;
}
if ( oldIdx >= list . childNodes . length || list . getChildAt ( oldIdx ) . data . path !== newPath ) {
2021-04-12 15:09:29 +03:00
list . insertChild ( oldIdx , existingChildren [ newPath ] ) ;
2020-12-04 14:50:08 +03:00
}
}
2021-04-12 15:09:29 +03:00
let toRemove = [ ] ;
2021-03-01 14:22:41 +03:00
list . eachChild ( ( child ) => {
2021-04-12 15:09:29 +03:00
if ( ! existingChildren [ child . data . path ] ) {
toRemove . push ( child ) ;
2021-03-01 14:22:41 +03:00
}
} ) ;
2021-04-12 15:09:29 +03:00
toRemove . forEach ( ( child ) => list . removeChild ( child , true ) ) ;
2021-03-01 14:22:41 +03:00
if ( view . pathToSelect !== undefined ) {
let path = view . pathToSelect ;
delete view . pathToSelect ;
view . select ( path , true ) ;
}
} ,
onLoad : function ( store , records , success ) {
2021-04-12 15:09:29 +03:00
if ( ! success ) {
return ;
}
let view = this . getView ( ) ;
2021-03-01 14:22:41 +03:00
let root = view . getStore ( ) . getRoot ( ) ;
2020-10-27 18:20:09 +03:00
records . sort ( ( a , b ) => a . id . localeCompare ( b . id ) ) ;
2020-05-25 20:46:43 +03:00
2021-04-12 15:09:29 +03:00
let list = root . findChild ( 'id' , 'datastores' , false ) ;
let getChildTextAt = i => list . getChildAt ( i ) . data . text ;
let existingChildren = { } ;
for ( let i = 0 , j = 0 , length = records . length ; i < length ; i ++ ) {
2020-09-25 19:36:58 +03:00
let name = records [ i ] . id ;
2021-04-12 15:09:29 +03:00
existingChildren [ name ] = true ;
2020-10-27 18:20:09 +03:00
2021-04-12 15:09:29 +03:00
while ( name . localeCompare ( getChildTextAt ( j ) ) > 0 && ( j + 1 ) < list . childNodes . length ) {
2020-10-27 18:20:09 +03:00
j ++ ;
}
2022-04-26 09:23:35 +03:00
let [ qtip , iconCls ] = [ '' , 'fa fa-database' ] ;
2022-04-26 09:23:32 +03:00
const maintenance = records [ i ] . data . maintenance ;
if ( maintenance ) {
2022-04-26 09:23:35 +03:00
const [ type , message ] = PBS . Utils . parseMaintenanceMode ( maintenance ) ;
qtip = ` ${ type } ${ message ? ': ' + message : '' } ` ;
2022-11-28 17:56:29 +03:00
let mainenanceTypeCls = type === 'delete' ? 'destroying' : 'maintenance' ;
iconCls = ` fa fa-database pmx-tree-icon-custom ${ mainenanceTypeCls } ` ;
2022-04-26 09:23:32 +03:00
}
2021-04-12 15:09:29 +03:00
if ( getChildTextAt ( j ) . localeCompare ( name ) !== 0 ) {
2022-05-12 15:23:52 +03:00
list . insertChild ( j , {
text : name ,
qtip ,
path : ` DataStore- ${ name } ` ,
iconCls ,
leaf : true ,
} ) ;
2022-04-26 09:23:32 +03:00
} else {
2022-05-12 15:23:52 +03:00
let oldChild = list . getChildAt ( j ) ;
oldChild . set ( 'qtip' , qtip ) ;
oldChild . set ( 'iconCls' , iconCls ) ;
2019-12-20 14:46:09 +03:00
}
}
2021-04-12 15:09:29 +03:00
// remove entries which are not existing anymore
let toRemove = [ ] ;
list . eachChild ( child => {
2021-04-12 15:10:57 +03:00
if ( ! existingChildren [ child . data . text ] && ! child . data . virtualEntry ) {
2021-04-12 15:09:29 +03:00
toRemove . push ( child ) ;
2019-12-20 14:46:09 +03:00
}
} ) ;
2021-04-12 15:09:29 +03:00
toRemove . forEach ( child => list . removeChild ( child , true ) ) ;
2020-10-27 18:20:10 +03:00
if ( view . pathToSelect !== undefined ) {
let path = view . pathToSelect ;
delete view . pathToSelect ;
view . select ( path , true ) ;
}
2020-10-27 18:20:09 +03:00
} ,
} ,
listeners : {
itemclick : function ( tl , info ) {
if ( info . node . data . id === 'addbutton' ) {
let me = this ;
Ext . create ( 'PBS.DataStoreEdit' , {
listeners : {
2021-04-12 15:11:18 +03:00
destroy : ( ) => me . rstore . reload ( ) ,
2020-10-27 18:20:09 +03:00
} ,
} ) . show ( ) ;
return false ;
}
return true ;
2020-09-25 19:36:58 +03:00
} ,
2019-12-20 14:46:09 +03:00
} ,
2021-03-10 12:10:47 +03:00
reloadTapeStore : function ( ) {
let me = this ;
2021-04-12 13:34:26 +03:00
me . tapeStore . load ( ) ;
2021-03-10 12:10:47 +03:00
} ,
2020-10-27 18:20:10 +03:00
select : function ( path , silent ) {
2019-01-22 13:48:00 +03:00
var me = this ;
2021-04-12 13:34:26 +03:00
if ( me . rstore . isLoaded ( ) && me . tapeStore . isLoaded ( ) ) {
2020-10-27 18:20:10 +03:00
if ( silent ) {
me . suspendEvents ( false ) ;
}
var item = me . getStore ( ) . findRecord ( 'path' , path , 0 , false , true , true ) ;
me . setSelection ( item ) ;
if ( silent ) {
me . resumeEvents ( true ) ;
}
} else {
me . pathToSelect = path ;
}
2019-01-22 13:48:00 +03:00
} ,
} ) ;