mirror of
				https://git.proxmox.com/git/proxmox-backup
				synced 2025-11-02 15:18:42 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			286 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			286 lines
		
	
	
		
			6.2 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',
 | 
						|
		},
 | 
						|
		{
 | 
						|
		    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: [
 | 
						|
			{
 | 
						|
			    iconCls: 'fa fa-language',
 | 
						|
			    text: gettext('Language'),
 | 
						|
			    reference: 'languageButton',
 | 
						|
			    handler: () => Ext.create('Proxmox.window.LanguageEditWindow', {
 | 
						|
				cookieName: 'PBSLangCookie',
 | 
						|
				autoShow: true,
 | 
						|
			    }),
 | 
						|
			},
 | 
						|
			'-',
 | 
						|
			{
 | 
						|
			    iconCls: 'fa fa-sign-out',
 | 
						|
			    text: gettext('Logout'),
 | 
						|
			    reference: 'logoutButton',
 | 
						|
			},
 | 
						|
		    ],
 | 
						|
		},
 | 
						|
	    ],
 | 
						|
	},
 | 
						|
	{
 | 
						|
	    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',
 | 
						|
	},
 | 
						|
    ],
 | 
						|
});
 |