]> git.proxmox.com Git - pmg-gui.git/blob - js/QuarantineList.js
code cleanup
[pmg-gui.git] / js / QuarantineList.js
1 Ext.define('PMG.QuarantineList', {
2 extend: 'Ext.grid.GridPanel',
3 xtype: 'pmgQuarantineList',
4
5 emptyText: gettext('No E-Mail address selected'),
6 viewConfig: {
7 deferEmptyText: false,
8 },
9
10 config: {
11 emailSelection: false,
12 notFoundText: gettext('No data in database'),
13 },
14
15 statics: {
16 from: 0,
17 to: 0,
18 },
19
20 allowPositionSave: false,
21
22 controller: {
23 xclass: 'Ext.app.ViewController',
24
25 init: function(view) {
26 let me = this;
27 if (PMG.view === 'quarantineview') {
28 view.emailSelection = false;
29 me.setEmptyText();
30 }
31 let emailCombobox = me.lookupReference('email');
32 emailCombobox.setVisible(view.emailSelection);
33 emailCombobox.setDisabled(!view.emailSelection);
34
35 let from;
36 if (PMG.QuarantineList.from !== 0) {
37 from = new Date(PMG.QuarantineList.from * 1000);
38 } else {
39 from = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
40 }
41
42 let to;
43 if (PMG.QuarantineList.to !== 0) {
44 to = new Date(PMG.QuarantineList.to * 1000);
45 } else {
46 to = new Date();
47 }
48
49 // we to this to trigger the change event of those fields
50 me.lookupReference('from').setValue(from);
51 me.lookupReference('to').setValue(to);
52
53 Proxmox.Utils.monStoreErrors(view.getView(), view.getStore());
54 me.load(function() {
55 if (view.cselect) {
56 view.setSelection(view.getStore().getById(view.cselect));
57 }
58 });
59 },
60 // ExtJS cannot dynamically change the emptyText on grids, so implement ourself
61 setEmptyText: function(emptyText) {
62 let me = this;
63 let view = me.getView();
64 let tableview = view.getView();
65 tableview.emptyText = `<div class="x-grid-empty">${emptyText || view.notFoundText}</div>`;
66 },
67
68 load: function(callback) {
69 let me = this;
70 me.allowPositionSave = false;
71 let view = me.getView();
72 let store = view.getStore();
73 if (view.emailSelection) {
74 if (!me.lookupReference('email').getSelection()) {
75 return; // if the combobox has no selection we do not reload
76 }
77 me.setEmptyText();
78 }
79 // deselect all first, else ExtJS does some funky O(n^3) comparissions as it tries
80 // to keep the selection, but we do not care for that on a new load anyway
81 view.getSelectionModel().deselectAll();
82
83 store.load(function() {
84 if (me.savedPosition !== undefined) {
85 if (store.getCount() - 1 < me.savedPosition) {
86 me.savedPosition = store.getCount() - 1;
87 }
88 view.setSelection(store.getAt(me.savedPosition));
89 } else {
90 view.setSelection();
91 }
92 if (Ext.isFunction(callback)) {
93 callback();
94 }
95 me.allowPositionSave = true;
96 });
97 },
98
99 setFrom: function(from) {
100 let view = this.getView();
101 let params = view.getStore().getProxy().getExtraParams();
102 params.starttime = from;
103 PMG.QuarantineList.from = from;
104 view.getStore().getProxy().setExtraParams(params);
105 },
106
107 setTo: function(to) {
108 let end_of_to = to + 24*60*60; // we want the end of the day
109 let view = this.getView();
110 let params = view.getStore().getProxy().getExtraParams();
111 params.endtime = end_of_to;
112 PMG.QuarantineList.to = to; // we save the start of the day here
113 view.getStore().getProxy().setExtraParams(params);
114 },
115
116 setUser: function(user) {
117 let view = this.getView();
118 let params = view.getStore().getProxy().getExtraParams();
119 if (user === null) {
120 delete params.pmail;
121 } else {
122 params.pmail = user;
123 }
124 view.getStore().getProxy().setExtraParams(params);
125 view.user = user;
126 },
127
128 changeTime: function(field, value) {
129 let me = this;
130
131 me.allowPositionSave = false;
132 me.savedPosition = undefined;
133
134 if (!value) {
135 return;
136 }
137
138 let val = value.getTime() / 1000;
139 let combobox = me.lookupReference('email');
140 let params = combobox.getStore().getProxy().getExtraParams();
141
142 let to = me.lookupReference('to');
143 let from = me.lookupReference('from');
144
145 if (field.name === 'from') {
146 me.setFrom(val);
147 params.starttime = val;
148 to.setMinValue(value);
149 } else if (field.name === 'to') {
150 me.setTo(val);
151 params.endtime = val + 24*60*60;
152 from.setMaxValue(value);
153 } else {
154 return;
155 }
156
157 combobox.getStore().getProxy().setExtraParams(params);
158 combobox.getStore().load();
159
160 me.load();
161 },
162
163 resetEmail: function() {
164 let me = this;
165 let view = me.getView();
166 if (view.emailSelection) {
167 me.setUser(undefined);
168 }
169 },
170
171 changeEmail: function(tb, value) {
172 let me = this;
173 me.savedPosition = undefined;
174 me.allowPositionSave = false;
175 if (value === 'all') {
176 me.setUser(null);
177 } else {
178 me.setUser(value);
179 }
180 me.load();
181 },
182
183 savePosition: function(grid, selected, eopts) {
184 let me = this;
185 if (!me.allowPositionSave) {
186 return;
187 }
188 if (selected.length <= 0) {
189 me.savedPosition = undefined;
190 return;
191 }
192
193 let view = me.getView();
194 let id = view.getStore().indexOf(selected[0]);
195
196 me.savedPosition = id;
197 },
198
199 doFilter: function(searchValue, store, sm) {
200 const selected = sm.getSelection();
201 const selectedRecordId = selected.length === 1 ? selected[0].id : null;
202 let clearSelectedMail = true;
203 let toDeselect = [];
204 store.filterBy(function(record) {
205 let match = false;
206
207 Ext.each(['subject', 'from'], property => {
208 if (record.data[property] === null) {
209 return;
210 }
211
212 let v = record.data[property].toString();
213 if (v !== undefined) {
214 v = v.toLowerCase();
215 if (v.includes(searchValue)) {
216 match = true;
217 if (record.id === selectedRecordId) {
218 clearSelectedMail = false;
219 }
220 }
221 }
222 });
223 if (!match && sm.isSelected(record)) {
224 toDeselect.push(record);
225 }
226 return match;
227 });
228 if (toDeselect.length > 0) {
229 sm.deselect(toDeselect, true);
230 sm.maybeFireSelectionChange(true);
231 }
232 return selectedRecordId !== null && clearSelectedMail;
233 },
234
235 updateFilter: async function(field) {
236 let me = this;
237 let view = me.getView();
238 let store = view.getStore();
239 let sm = view.getSelectionModel();
240
241 let searchValue = field.getValue().toLowerCase();
242
243 // supress store event if not empty, let filterBy below trigger it to avoid glitches
244 store.clearFilter(searchValue.length > 0);
245 field.triggers.clear.setVisible(searchValue.length > 0);
246
247 if (searchValue.length === 0) {
248 me.setEmptyText();
249 return;
250 }
251 me.setEmptyText(gettext('No match found'));
252
253 let clearSelection = me.doFilter(searchValue, store, sm);
254
255 if (clearSelection) {
256 view.setSelection();
257 }
258 },
259
260 control: {
261 '#': {
262 beforedestroy: 'resetEmail',
263 selectionchange: 'savePosition',
264 },
265 'combobox[reference=email]': {
266 change: 'changeEmail',
267 },
268 datefield: {
269 change: {
270 fn: 'changeTime',
271 },
272 },
273
274 },
275 },
276
277 features: [
278 {
279 ftype: 'grouping',
280 groupHeaderTpl: '{columnName}: {name} ({children.length})',
281 },
282 ],
283
284 tbar: {
285 layout: {
286 type: 'vbox',
287 align: 'stretch',
288 },
289 defaults: {
290 margin: 2,
291 },
292 items: [
293 {
294 xtype: 'datefield',
295 name: 'from',
296 fieldLabel: gettext('Since'),
297 reference: 'from',
298 format: 'Y-m-d',
299 },
300 {
301 xtype: 'datefield',
302 name: 'to',
303 fieldLabel: gettext('Until'),
304 reference: 'to',
305 format: 'Y-m-d',
306 },
307 {
308 xtype: 'combobox',
309 hidden: true,
310 displayField: 'mail',
311 valueField: 'mail',
312 listConfig: {
313 emptyText:
314 '<div class="x-grid-empty">' +
315 gettext('No data in database') +
316 '</div>',
317 },
318 store: {
319 proxy: {
320 type: 'proxmox',
321 url: '/api2/json/quarantine/spamusers',
322 },
323 fields: [
324 {
325 name: 'mail',
326 renderer: Ext.htmlEncode,
327 },
328 ],
329 listeners: {
330 load: function(store, records, successfull) {
331 if (successfull && records.length > 1) {
332 store.insert(0, { mail: 'all' });
333 }
334 },
335 },
336 },
337 queryMode: 'local',
338 editable: true,
339 typeAhead: true,
340 forceSelection: true,
341 autoSelect: true,
342 anyMatch: true,
343 selectOnFocus: true,
344 reference: 'email',
345 fieldLabel: 'E-Mail',
346 },
347 {
348 xtype: 'textfield',
349 name: 'filter',
350 fieldLabel: gettext('Search'),
351 emptyText: gettext('Subject, Sender'),
352 enableKeyEvents: true,
353 triggers: {
354 clear: {
355 cls: 'pmx-clear-trigger',
356 weight: -1,
357 hidden: true,
358 handler: function() {
359 let me = this;
360 me.setValue('');
361 // setValue does not results in a keyup event, so trigger manually
362 me.up('grid').getController().updateFilter(me);
363 },
364 },
365 },
366 listeners: {
367 buffer: 500,
368 keyup: 'updateFilter',
369 },
370 },
371 ],
372 },
373 });