]> git.proxmox.com Git - proxmox-backup.git/blobdiff - www/MainView.js
ui: user menu: allow changing language while logged in
[proxmox-backup.git] / www / MainView.js
index edff93f4ac66a67a845755272b02dad1ee6bee82..10bc8eeb9c96d20b87270fd8c848b898e92c4eb7 100644 (file)
@@ -10,31 +10,173 @@ Ext.define('PBS.MainView', {
            ':path:subpath': {
                action: 'changePath',
                before: 'beforeChangePath',
-                conditions : {
-                   ':path'    : '(?:([%a-zA-Z0-9\\-\\_\\s,]+))',
-                   ':subpath' : '(?:(?::)([%a-zA-Z0-9\\-\\_\\s,]+))?'
-               }
-           }
+                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) {
+
+       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;
-           console.log("init");
 
-       }
+           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',
@@ -47,33 +189,70 @@ Ext.define('PBS.MainView', {
            xtype: 'container',
            layout: {
                type: 'hbox',
-               align: 'middle'
+               align: 'middle',
            },
-           margin: '2 5 2 5',
+           margin: '2 0 2 5',
            height: 38,
            items: [
                {
-                   xtype: 'proxmoxlogo'
+                   xtype: 'proxmoxlogo',
+                   prefix: '',
                },
                {
-                   xtype: 'versioninfo'
+                   padding: '0 0 0 5',
+                   xtype: 'versioninfo',
                },
                {
-                   flex: 1
+                   padding: 5,
+                   html: '<a href="https://bugzilla.proxmox.com" target="_blank">BETA</a>',
+                   baseCls: 'x-plain',
                },
                {
+                   flex: 1,
                    baseCls: 'x-plain',
-                   reference: 'usernameinfo',
-                   padding: '0 5',
-                   tpl: Ext.String.format(gettext("You are logged in as {0}"), "'{username}'")
                },
                {
-                   reference: 'logoutButton',
                    xtype: 'button',
-                   iconCls: 'fa fa-sign-out',
-                   text: gettext('Logout')
-               }
-           ]
+                   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',
@@ -82,18 +261,30 @@ Ext.define('PBS.MainView', {
            region: 'west',
            layout: {
                type: 'vbox',
-               align: 'stretch'
+               align: 'stretch',
            },
-           items: [{ html: "test" }]
+           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'
-       }
-    ]
+           reference: 'contentpanel',
+       },
+    ],
 });
-