diff --git a/js/Application.js b/js/Application.js index 9d36655..05714e9 100644 --- a/js/Application.js +++ b/js/Application.js @@ -24,7 +24,16 @@ Ext.define('PMG.Application', { // show login window if not loggedin var loggedin = Proxmox.Utils.authOK(); Ext.on('resize', me.realignWindows); - Ext.create({ xtype: loggedin ? 'mainview' : 'loginview' }); + + if (loggedin) { + if (location.pathname === "/quarantine") { + Ext.create({ xtype: 'quarantineview' }); + } else { + Ext.create({ xtype: 'mainview' }); + } + } else { + Ext.create({ xtype: 'loginview' }); + } } }); diff --git a/js/LoginView.js b/js/LoginView.js index 0ecd617..a831501 100644 --- a/js/LoginView.js +++ b/js/LoginView.js @@ -29,7 +29,7 @@ Ext.define('PMG.LoginView', { PMG.Utils.updateLoginData(response.result.data); // change view to mainview view.destroy(); - Ext.create({ xtype: 'mainview' }); + Ext.create({ xtype: 'quarantineview' }); }, failure: function(form, action) { loginForm.unmask(); @@ -53,7 +53,12 @@ Ext.define('PMG.LoginView', { PMG.Utils.updateLoginData(action.result.data); // change view to mainview me.getView().destroy(); - Ext.create({ xtype: 'mainview' }); + + if (location.pathname === "/quarantine") { + Ext.create({ xtype: 'quarantineview' }); + } else { + Ext.create({ xtype: 'mainview' }); + } }, failure: function(form, action) { loginForm.unmask(); diff --git a/js/Makefile b/js/Makefile index ffeb764..3aba16e 100644 --- a/js/Makefile +++ b/js/Makefile @@ -18,6 +18,9 @@ JSSRC= \ RuleEditor.js \ Logo.js \ MainView.js \ + SpamQuarantine.js \ + UserBlackWhiteList.js \ + QuarantineView.js \ Dashboard.js \ VersionInfo.js \ NavigationTree.js \ diff --git a/js/QuarantineView.js b/js/QuarantineView.js new file mode 100644 index 0000000..77d7c35 --- /dev/null +++ b/js/QuarantineView.js @@ -0,0 +1,213 @@ +Ext.define('PMG.QuarantineNavigationTree', { + extend: 'Ext.list.Tree', + xtype: 'quarantinenavigationtree', + + select: function(path) { + var me = this; + var item = me.getStore().findRecord('path', path, 0, false, true, true); + me.setSelection(item); + }, + + store: { + xcalss: 'Ext.data.TreeStore', + root: { + expanded: true, + children: [ + { + text: gettext('Spam Quarantine'), + iconCls: 'fa fa-cubes', + path: 'pmgSpamQuarantine', + expanded: true, + children: [ + { + text: gettext('Whitelist'), + //iconCls: 'fa fa-cubes', + path: 'pmgUserWhitelist', + leaf: true, + }, + { + text: gettext('Blacklist'), + //iconCls: 'fa fa-cubes', + path: 'pmgUserBlacklist', + leaf: true, + } + ] + } + ] + } + }, + + animation: false, + expanderOnly: true, + expanderFirst: false, + ui: 'nav' +}); + +Ext.define('PMG.QuarantineView', { + extend: 'Ext.container.Container', + xtype: 'quarantineview', + + title: 'Proxmox Mail Gateway Quarantine', + + 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; + + if (!Ext.ClassManager.getByAlias('widget.'+ path)) { + console.warn('xtype "'+path+'" not found'); + action.stop(); + return; + } + + var lastpanel = me.lookupReference('contentpanel').getLayout().getActiveItem(); + if (lastpanel && lastpanel.xtype === path) { + // 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) { + // we are already there + } else { + // set the active tab + lastpanel.setActiveTab(subpath); + } + } + action.stop(); + return; + } + + action.resume(); + }, + + changePath: function(path,subpath) { + var me = this; + var contentpanel = me.lookupReference('contentpanel'); + var lastpanel = contentpanel.getLayout().getActiveItem(); + + var obj = contentpanel.add({ xtype: path }); + var treelist = me.lookupReference('navtree'); + + treelist.suspendEvents(); + treelist.select(path); + treelist.resumeEvents(); + + if (Ext.isFunction(obj.setActiveTab)) { + obj.setActiveTab(subpath || 0); + obj.addListener('tabchange', function(tabpanel, newc, oldc) { + var newpath = path; + + // only add the subpath part for the + // non-default tabs + if (tabpanel.items.findIndex('id', newc.id) !== 0) { + newpath += ":" + newc.getItemId(); + } + + me.redirectTo(newpath); + }); + } + + contentpanel.setActiveItem(obj); + + if (lastpanel) { + contentpanel.remove(lastpanel, { destroy: true }); + } + }, + + logout: function() { + var me = this; + Proxmox.Utils.authClear(); + me.getView().destroy(); + Ext.create({ xtype: 'loginview'}); + }, + + navigate: function(treelist, item) { + this.redirectTo(item.get('path')); + }, + + init: function(view) { + var me = this; + + // load username + me.lookupReference('usernameinfo').update({username:Proxmox.UserName}); + + // show login on requestexception + // fixme: what about other errors + Ext.Ajax.on('requestexception', function(conn, response, options) { + if (response.status == 401) { // auth failure + me.logout(); + } + }); + + // select treeitem and load page from url fragment + var token = Ext.util.History.getToken(); + this.redirectTo(token, true); + } + }, + + plugins: 'viewport', + + layout: 'border', + + items: [ + { + region: 'north', + xtype: 'container', + layout: { + type: 'hbox', + align: 'middle' + }, + margin: '4 5 4 5', + items: [ + { + xtype: 'proxmoxlogo' + }, + { + xtype: 'versioninfo' + }, + { + flex: 1 + }, + { + baseCls: 'x-plain', + reference: 'usernameinfo', + padding: '0 5', + tpl: Ext.String.format(gettext("You are logged in as '{0}'"), '{username}') + } + ] + }, + { + xtype: 'quarantinenavigationtree', + reference: 'navtree', + minWidth: 177, + border: false, + region: 'west', + // 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: 'panel', + layout: 'card', + region: 'center', + border: false, + reference: 'contentpanel', + } + ] +}); diff --git a/js/SpamQuarantine.js b/js/SpamQuarantine.js new file mode 100644 index 0000000..8ee142a --- /dev/null +++ b/js/SpamQuarantine.js @@ -0,0 +1,24 @@ +Ext.define('PMG.SpamQuarantine', { + extend: 'Ext.tab.Panel', + xtype: 'pmgSpamQuarantine', + + title: gettext('Spam Quarantine') + ': ' + Proxmox.UserName, + border: false, + scrollable: true, + defaults: { border: false }, + + items: [ + { + title: gettext('Today'), + itemId: 'today', + html: "Backup" + }, + { + title: gettext('Archive'), + itemId: 'archive', + html: "Archive" + } + ] +}); + + diff --git a/js/UserBlackWhiteList.js b/js/UserBlackWhiteList.js new file mode 100644 index 0000000..2704f9a --- /dev/null +++ b/js/UserBlackWhiteList.js @@ -0,0 +1,21 @@ +Ext.define('PMG.UserBlacklist', { + extend: 'Ext.panel.Panel', + xtype: 'pmgUserBlacklist', + + title: gettext('Blacklist'), + border: false, + + html: "Blacklist" +}); + +Ext.define('PMG.UserWhitelist', { + extend: 'Ext.panel.Panel', + xtype: 'pmgUserWhitelist', + + title: gettext('Whitelist'), + border: false, + + html: "Whitelist" +}); + +