]>
git.proxmox.com Git - pmg-gui.git/blob - js/MailTracker.js
1 Ext
.define('pmg-mail-tracker', {
2 extend
: 'Ext.data.Model',
4 'id', 'from', 'to', 'dstatus', 'rstatus', 'qid', 'msgid', 'client',
5 { type
: 'number', name
: 'size' },
6 { type
: 'date', dateFormat
: 'timestamp', name
: 'time' },
11 // do not use field 'id', because "id/to" is the unique Id
12 // this way we display an entry for each receiver
17 Ext
.define('PMG.MailTrackerFilter', {
18 extend
: 'Ext.container.Container',
19 xtype
: 'pmgMailTrackerFilter',
27 xclass
: 'Ext.app.ViewController',
29 onFilterChange: function() {
30 let view
= this.getView();
31 view
.fireEvent('filterChanged');
34 onSpecialKey: function(field
, e
) {
35 if (e
.getKey() === e
.ENTER
) {
36 this.onFilterChange();
41 getFilterParams: function() {
45 let names
= ['from', 'target', 'xfilter', 'starttime', 'endtime', 'ndr', 'greylist'];
46 Ext
.Array
.each(names
, function(name
) {
47 let value
= me
.lookupReference(name
).getSubmitValue();
48 if (value
) { param
[name
] = value
; }
51 // there must always be a start and endtime, otherwise the field was invalid
52 if (!param
.starttime
|| !param
.endtime
) {
69 fieldLabel
: gettext('Sender'),
71 listeners
: { specialkey
: 'onSpecialKey' },
75 fieldLabel
: gettext('Receiver'),
77 listeners
: { specialkey
: 'onSpecialKey' },
81 fieldLabel
: gettext('Filter'),
83 listeners
: { specialkey
: 'onSpecialKey' },
97 fieldLabel
: gettext('Start'),
98 reference
: 'starttime',
101 fn
: 'onFilterChange',
106 let now
= new Date();
107 return new Date(now
.getTime() - 3600000);
109 xtype
: 'promxoxDateTimeField',
112 fieldLabel
: gettext('End'),
113 reference
: 'endtime',
116 fn
: 'onFilterChange',
121 let now
= new Date();
122 let tomorrow
= new Date();
123 tomorrow
.setDate(now
.getDate()+1);
124 tomorrow
.setHours(0);
125 tomorrow
.setMinutes(0);
126 tomorrow
.setSeconds(0);
129 xtype
: 'promxoxDateTimeField',
138 boxLabel
: gettext('Include Empty Senders'),
139 xtype
: 'proxmoxcheckbox',
140 listeners
: { change
: 'onFilterChange' },
145 boxLabel
: gettext('Include Greylist'),
146 xtype
: 'proxmoxcheckbox',
147 listeners
: { change
: 'onFilterChange' },
148 margin
: { left
: 20 },
149 reference
: 'greylist',
159 Ext
.define('PMG.MaiLogWindow', {
160 extend
: 'Ext.window.Window',
161 xtype
: 'pmgMaiLogWindow',
163 title
: gettext('Syslog'),
166 starttime
: undefined,
182 Proxmox
.Utils
.API2Request({
184 params
: { starttime
: me
.starttime
, endtime
: me
.endtime
},
185 url
: '/nodes/' + Proxmox
.NodeName
+ '/tracker/' + me
.logid
,
187 failure: function(response
, opts
) {
188 me
.update(gettext('Error') + " " + response
.htmlStatus
);
190 success: function(response
, opts
) {
191 let data
= response
.result
.data
;
193 let logs
= "<pre style='margin: 0;'>";
194 Ext
.Array
.each(data
.logs
, function(line
) {
195 logs
+= Ext
.htmlEncode(line
) + "\n";
203 initComponent: function() {
207 throw "no logid specified";
211 throw "no starttime specified";
214 throw "no endtime specified";
219 me
.setHtml('Loading...');
224 Ext
.define('PMG.MailTracker', {
225 extend
: 'Ext.grid.GridPanel',
226 xtype
: 'pmgMailTracker',
228 title
: gettext('Tracking Center'),
232 emptyText
: gettext("Please enter your search parameters and press 'Search'."),
233 disableSelection
: true,
236 deferEmptyText
: false,
237 enableTextSelection
: true,
238 getRowClass: function(record
, index
) {
239 let status
= record
.data
.rstatus
|| record
.data
.dstatus
;
240 return PMG
.Utils
.mail_status_map
[status
];
246 ptype
: 'rowexpander',
247 expandOnDblClick
: false,
248 rowBodyTpl
: '<p class="logs">{logs}</p>',
254 model
: 'pmg-mail-tracker',
260 xclass
: 'Ext.app.ViewController',
262 onSearch: function() {
263 let view
= this.getView();
264 view
.setEmptyText(gettext('No data in database'));
265 let filter
= this.lookupReference('filter');
266 let status
= this.lookupReference('status');
267 let params
= filter
.getFilterParams();
268 if (params
=== undefined) {
269 return; // something went wrong with the filters bail out
271 status
.update(''); // clear status before load
272 view
.store
.proxy
.setExtraParams(params
);
273 view
.store
.proxy
.setUrl('/api2/json/nodes/' + Proxmox
.NodeName
+ '/tracker');
274 view
.store
.load(function(records
, operation
, success
) {
275 let response
= operation
.getResponse();
277 // fixme: howto avoid duplicate Ext.decode ?
278 let result
= Ext
.decode(response
.responseText
);
279 if (result
.changes
) {
280 status
.update(result
.changes
);
286 showDetails: function(rowNode
, record
) {
287 let view
= this.getView();
289 let params
= view
.store
.proxy
.getExtraParams();
291 Proxmox
.Utils
.API2Request({
293 params
: { starttime
: params
.starttime
, endtime
: params
.endtime
},
294 url
: '/nodes/' + Proxmox
.NodeName
+ '/tracker/' + record
.data
.id
,
296 failure: function(response
, opts
) {
297 record
.set('logs', gettext('Error') + " " + response
.htmlStatus
);
299 success: function(response
, opts
) {
300 let data
= response
.result
.data
;
303 Ext
.Array
.each(data
.logs
, function(line
) {
304 logs
+= Ext
.htmlEncode(line
) + "<br>";
307 record
.set('logs', logs
);
312 // only expand row on dblclick, but do not collapse
313 expand: function(view
, record
, row
, rowIdx
, e
) {
314 // inspired by RowExpander.js
315 let rowNode
= view
.getNode(rowIdx
);
316 let normalRow
= Ext
.fly(rowNode
);
318 let collapsedCls
= view
.rowBodyFeature
.rowCollapsedCls
;
320 if (normalRow
.hasCls(collapsedCls
)) {
321 view
.rowBodyFeature
.rowExpander
.toggleRow(rowIdx
, record
);
327 expandbody
: 'showDetails',
328 itemdblclick
: 'expand',
333 // extjs has no method to dynamically change the emptytext on
334 // grids, so we have to do it this way
335 setEmptyText: function(emptyText
) {
337 let tableview
= me
.getView();
338 tableview
.emptyText
= `<div class="x-grid-empty">${emptyText || ""}</div>`;
343 xtype
: 'pmgMailTrackerFilter',
345 listeners
: { filterChanged
: 'onSearch' },
352 { text
: 'Search', handler
: 'onSearch' },
353 { xtype
: 'component', html
: '', reference
: 'status' },
361 header
: gettext('Time'),
367 header
: gettext('From'),
370 renderer
: Ext
.htmlEncode
,
373 header
: gettext('To'),
376 renderer
: Ext
.htmlEncode
,
379 header
: gettext('Status'),
381 renderer: function(v
, metaData
, rec
) {
382 let returntext
= 'unknown';
383 let icon
= 'question-circle';
384 let rstatus
= rec
.data
.rstatus
;
385 if (v
!== undefined && v
!== '') {
386 let vtext
= PMG
.Utils
.mail_status_map
[v
] || v
;
388 if (v
=== 'Q' || v
=== 'B') {
390 } else if (rstatus
!== undefined && rstatus
!== '') {
391 let rtext
= PMG
.Utils
.mail_status_map
[rstatus
] || rstatus
;
392 returntext
= vtext
+ '/' + rtext
;
394 } else if (rec
.data
.qid
!== undefined) {
395 returntext
= 'queued/' + vtext
;
401 return PMG
.Utils
.format_status_icon(icon
) + returntext
;
403 dataIndex
: 'dstatus',
406 header
: gettext('Size'),
415 renderer
: Ext
.htmlEncode
,
418 header
: gettext('Client'),
422 renderer
: Ext
.htmlEncode
,
426 initComponent: function() {
431 Proxmox
.Utils
.monStoreErrors(me
.getView(), me
.store
);