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