]> git.proxmox.com Git - pmg-gui.git/blob - js/QuarantineView.js
utils: add custom validator for pmg-email-address
[pmg-gui.git] / js / QuarantineView.js
1 Ext.define('PMG.QuarantineNavigationTree', {
2 extend: 'Ext.list.Tree',
3 xtype: 'quarantinenavigationtree',
4
5 select: function(path) {
6 let me = this;
7 let item = me.getStore().findRecord('path', path, 0, false, true, true);
8 me.setSelection(item);
9 },
10
11 store: {
12 root: {
13 expanded: true,
14 children: [
15 {
16 text: gettext('Spam Quarantine'),
17 iconCls: 'fa fa-cubes',
18 path: 'pmgSpamQuarantine',
19 expanded: true,
20 children: [
21 {
22 text: gettext('Whitelist'),
23 iconCls: 'fa fa-file-o',
24 path: 'pmgUserWhitelist',
25 leaf: true,
26 },
27 {
28 text: gettext('Blacklist'),
29 iconCls: 'fa fa-file',
30 path: 'pmgUserBlacklist',
31 leaf: true,
32 },
33 ],
34 },
35 ],
36 },
37 },
38
39 animation: false,
40 expanderOnly: true,
41 expanderFirst: false,
42 ui: 'pve-nav',
43 });
44
45 Ext.define('PMG.QuarantineView', {
46 extend: 'Ext.container.Container',
47 xtype: 'quarantineview',
48
49 title: 'Proxmox Mail Gateway Quarantine',
50
51 controller: {
52 xclass: 'Ext.app.ViewController',
53 routes: {
54 ':path:subpath': {
55 action: 'changePath',
56 before: 'beforeChangePath',
57 conditions: {
58 ':path': '(?:([%a-zA-Z0-9\\-\\_\\s,]+))',
59 ':subpath': '(?:(?::)([%a-zA-Z0-9\\-\\_\\s,]+))?',
60 },
61 },
62 },
63
64 beforeChangePath: function(path, subpathOrAction, action) {
65 let me = this;
66
67 let subpath = subpathOrAction;
68 if (!action) {
69 action = subpathOrAction;
70 subpath = undefined;
71 }
72
73 if (!Ext.ClassManager.getByAlias('widget.'+ path)) {
74 console.warn('xtype "'+path+'" not found');
75 action.stop();
76 return;
77 }
78
79 let lastpanel = me.lookupReference('contentpanel').getLayout().getActiveItem();
80 if (lastpanel && lastpanel.xtype === path) {
81 // we have the right component already,
82 // we just need to select the correct tab
83 // default to the first
84 subpath = subpath || 0;
85 if (lastpanel.getActiveTab) {
86 // we assume lastpanel is a tabpanel
87 if (lastpanel.getActiveTab().getItemId() !== subpath) {
88 // set the active tab
89 lastpanel.setActiveTab(subpath);
90 }
91 // else we are already there
92 }
93 action.stop();
94 return;
95 }
96
97 action.resume();
98 },
99
100 changePath: function(path, subpath) {
101 let me = this;
102 let contentpanel = me.lookupReference('contentpanel');
103 let lastpanel = contentpanel.getLayout().getActiveItem();
104
105 let obj = contentpanel.add({ xtype: path, cselect: subpath });
106 let treelist = me.lookupReference('navtree');
107
108 treelist.suspendEvents();
109 treelist.select(path);
110 treelist.resumeEvents();
111
112 if (Ext.isFunction(obj.setActiveTab)) {
113 obj.setActiveTab(subpath || 0);
114 obj.addListener('tabchange', function(tabpanel, newc, oldc) {
115 let newpath = path;
116
117 // only add the subpath part for the
118 // non-default tabs
119 if (tabpanel.items.findIndex('id', newc.id) !== 0) {
120 newpath += ":" + newc.getItemId();
121 }
122
123 me.redirectTo(newpath);
124 });
125 }
126
127 contentpanel.setActiveItem(obj);
128
129 if (lastpanel) {
130 contentpanel.remove(lastpanel, { destroy: true });
131 }
132 },
133
134 logout: function() {
135 PMG.app.logout();
136 },
137
138 changeLanguage: function() {
139 Ext.create('Proxmox.window.LanguageEditWindow', {
140 cookieName: 'PMGLangCookie',
141 }).show();
142 },
143
144 navigate: function(treelist, item) {
145 this.redirectTo(item.get('path'));
146 },
147
148 execQuarantineAction: function(qa) {
149 PMG.Utils.doQuarantineAction(qa.action, qa.cselect);
150 },
151
152 control: {
153 '[reference=logoutButton]': {
154 click: 'logout',
155 },
156 '[reference=languageButton]': {
157 click: 'changeLanguage',
158 },
159 },
160
161 init: function(view) {
162 let me = this;
163
164 // load username
165 let username = Proxmox.UserName.replace(/@quarantine$/, '');
166 me.lookupReference('usernameinfo').setText(username);
167
168 // show login on requestexception
169 // fixme: what about other errors
170 Ext.Ajax.on('requestexception', function(conn, response, options) {
171 if (response.status === 401) { // auth failure
172 me.logout();
173 }
174 });
175
176 let qa = PMG.Utils.extractQuarantineAction();
177 let token;
178 if (qa) {
179 token = 'pmgSpamQuarantine';
180 if (qa.action === 'blacklist') { token = 'pmgUserBlacklist'; }
181 if (qa.action === 'whitelist') { token = 'pmgUserWhitelist'; }
182 if (qa.cselect) {
183 token += ':' + qa.cselect;
184 }
185 this.redirectTo(token, true);
186 if (qa.action) {
187 me.execQuarantineAction(qa);
188 }
189 } else {
190 // select treeitem and load page from url fragment
191
192 token = Ext.util.History.getToken() || 'pmgSpamQuarantine';
193 this.redirectTo(token, true);
194 }
195 },
196 },
197
198 plugins: 'viewport',
199
200 layout: {
201 type: 'border',
202 },
203
204 items: [
205 {
206 region: 'north',
207 xtype: 'container',
208 layout: {
209 type: 'hbox',
210 align: 'middle',
211 },
212 margin: '2 0 2 5',
213 height: 38,
214 items: [
215 {
216 xtype: 'proxmoxlogo',
217 },
218 {
219 padding: '0 0 0 5',
220 xtype: 'versioninfo',
221 },
222 {
223 flex: 1,
224 },
225 {
226 xtype: 'button',
227 reference: 'usernameinfo',
228 style: {
229 // proxmox dark grey p light grey as border
230 backgroundColor: '#464d4d',
231 borderColor: '#ABBABA',
232 },
233 margin: '0 5 0 0',
234 iconCls: 'fa fa-user',
235 menu: [
236 {
237 iconCls: 'fa fa-language',
238 text: gettext('Language'),
239 reference: 'languageButton',
240 },
241 '-',
242 {
243 reference: 'logoutButton',
244 iconCls: 'fa fa-sign-out',
245 text: gettext('Logout'),
246 },
247 ],
248 },
249 ],
250 },
251 {
252 xtype: 'panel',
253 scrollable: 'y',
254 border: false,
255 region: 'west',
256 layout: {
257 type: 'vbox',
258 align: 'stretch',
259 },
260 items: [
261 {
262 xtype: 'quarantinenavigationtree',
263 reference: 'navtree',
264 minWidth: 180,
265 // we have to define it here until extjs 6.2 because of a bug where a
266 // viewcontroller does not detect the selectionchange event of a treelist
267 listeners: {
268 selectionchange: 'navigate',
269 },
270 },
271 {
272 xtype: 'box',
273 cls: 'x-treelist-pve-nav',
274 flex: 1,
275 },
276 ],
277 },
278 {
279 xtype: 'panel',
280 layout: {
281 type: 'card',
282 },
283 region: 'center',
284 border: false,
285 reference: 'contentpanel',
286 },
287 ],
288 });