restructure spam quarantine

this patch restructures the spam quarantine tab

notable changes:
* no daily overview any more, instead you have to select the range and
  email address
* an email selector in the admin view, which gets its data from
  the backend
* preview window has a show raw/html button

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
Dominik Csapak 2017-08-23 12:26:56 +02:00 committed by Dietmar Maurer
parent 9bdd2de318
commit c96a22cb0b

View File

@ -12,58 +12,23 @@ Ext.define('pmg-spam-archive', {
idProperty: 'day' idProperty: 'day'
}); });
Ext.define('PMG.SpamArchive', {
extend: 'Ext.grid.GridPanel',
xtype: 'pmgSpamArchive',
controller: {
xclass: 'Ext.app.ViewController',
init: function(view) {
view.store.load({
callback: function() {
view.getSelectionModel().select(0);
}
});
}
},
store: {
model: 'pmg-spam-archive'
},
columns: [
{
xtype: 'datecolumn',
header: gettext('Date'),
format: 'Y-m-d',
dataIndex: 'day',
flex: 1
},
{
header: gettext('Count'),
dataIndex: 'count',
flex: 1
},
{
header: gettext('Spam level'),
dataIndex: 'spamavg',
flex: 1
}
]
});
Ext.define('pmg-spam-list', { Ext.define('pmg-spam-list', {
extend: 'Ext.data.Model', extend: 'Ext.data.Model',
fields: [ 'id', 'envelope_sender', 'from', 'sender', 'receiver', 'subject', fields: [ 'id', 'envelope_sender', 'from', 'sender', 'receiver', 'subject',
{ type: 'number', name: 'spamlevel' }, { type: 'number', name: 'spamlevel' },
{ type: 'integer', name: 'bytes' }, { type: 'integer', name: 'bytes' },
{ type: 'date', dateFormat: 'timestamp', name: 'time' } { type: 'date', dateFormat: 'timestamp', name: 'time' },
{
type: 'string',
name: 'day',
convert: function(v, rec) {
return Ext.Date.format(rec.get('time'), 'Y-m-d');
}, depends: ['time']
}
], ],
proxy: { proxy: {
type: 'proxmox', type: 'proxmox',
url: "/api2/json/quarantine/spam",
}, },
idProperty: 'id' idProperty: 'id'
}); });
@ -72,31 +37,61 @@ Ext.define('PMG.SpamList', {
extend: 'Ext.grid.GridPanel', extend: 'Ext.grid.GridPanel',
xtype: 'pmgSpamList', xtype: 'pmgSpamList',
setDay: function(day) { title: gettext('Spam List'),
var me = this;
me.setTitle(Ext.Date.format(day, "F j Y")); emptyText: gettext('No E-Mail address selected'),
me.store.load({ viewConfig: {
url: "/api2/json/quarantine/spam/" + (day.getTime() / 1000) deferEmptyText: false
}); },
setUser: function(user) {
var me = this;
var params = me.getStore().getProxy().getExtraParams();
params.pmail = user;
me.getStore().getProxy().setExtraParams(params);
me.user = user;
},
setFrom: function(from) {
var me = this;
var params = me.getStore().getProxy().getExtraParams();
params.starttime = from;
me.getStore().getProxy().setExtraParams(params);
},
setTo: function(to) {
var me = this;
var params = me.getStore().getProxy().getExtraParams();
params.endtime = to;
me.getStore().getProxy().setExtraParams(params);
},
load: function() {
var me = this;
if (me.user || PMG.view === 'quarantine') {
// extjs has no method to dynamically change the emptytext on
// grids, so we have to do it this way
var view = me.getView();
view.emptyText = '<div class="x-grid-empty">'+ gettext('No Spam E-Mails found') + '</div>';
view.refresh();
}
me.getStore().load();
}, },
store: { store: {
model: 'pmg-spam-list', model: 'pmg-spam-list',
groupField: 'day',
groupDir: 'DESC',
sorters: [{
property: 'time',
direction: 'DESC'
}]
}, },
tbar: [ features: [
{ {
text: gettext('Whitelist') ftype: 'grouping',
}, groupHeaderTpl: '{columnName}: {name} ({children.length})'
{
text: gettext('Blacklist')
},
{
text: gettext('Deliver')
},
{
text: gettext('Delete')
} }
], ],
@ -125,12 +120,17 @@ Ext.define('PMG.SpamList', {
renderer: function(v) { return Ext.Number.toFixed(v/1024, 0); }, renderer: function(v) { return Ext.Number.toFixed(v/1024, 0); },
dataIndex: 'bytes' dataIndex: 'bytes'
}, },
{
header: gettext('Arrival Day'),
dataIndex: 'day',
hidden: true
},
{ {
xtype: 'datecolumn', xtype: 'datecolumn',
header: gettext('Arrival Time'), header: gettext('Arrival Time'),
dataIndex: 'time', dataIndex: 'time',
format: 'H:m:s' format: 'H:m:s'
} },
] ]
}); });
@ -148,21 +148,32 @@ Ext.define('PMG.SpamQuarantine', {
xclass: 'Ext.app.ViewController', xclass: 'Ext.app.ViewController',
init: function(view) { init: function(view) {
var me = this;
var spamlist = me.lookupReference('spamlist');
if (PMG.view === 'quarantine') {
spamlist.down('combobox[name=email]').setVisible(false);
spamlist.load();
}
// we to this to trigger the change event of those fields
var today = new Date();
spamlist.down('datefield[name=from]').setValue(today);
spamlist.down('datefield[name=to]').setValue(today);
}, },
onSelectDay: function() { changeEmail: function(tb, value) {
var view = this.getView();
var grid = this.lookupReference('archive');
var rec = grid.selModel.getSelection()[0];
if (!rec || !rec.data || !rec.data.day) return;
var spamlist = this.lookupReference('spamlist'); var spamlist = this.lookupReference('spamlist');
spamlist.setDay(rec.data.day); spamlist.setUser(value);
spamlist.load();
},
resetEmail: function() {
var spamlist = this.lookupReference('spamlist');
spamlist.setUser(undefined);
}, },
onSelectMail: function() { onSelectMail: function() {
var me = this;
var spamlist = this.lookupReference('spamlist'); var spamlist = this.lookupReference('spamlist');
var rec = spamlist.selModel.getSelection()[0]; var rec = spamlist.selModel.getSelection()[0];
@ -170,47 +181,171 @@ Ext.define('PMG.SpamQuarantine', {
if (!rec || !rec.data || !rec.data.id) { if (!rec || !rec.data || !rec.data.id) {
preview.update(''); preview.update('');
me.lookupReference('preview').setDisabled(true);
return; return;
} }
var url = '/api2/htmlmail/quarantine/content?id=' + rec.data.id; me.lookupReference('preview').setDisabled(false);
preview.update("<iframe frameborder=0 width=100% height=100% src='" + url +"'></iframe>");
var raw = me.raw || false;
var url = '/api2/htmlmail/quarantine/content?id=' + rec.data.id + ((raw)?'&raw=1':'');
preview.update("<iframe frameborder=0 width=100% height=100% sandbox='allow-same-origin' src='" + url +"'></iframe>");
}, },
rawMail: function(button) {
var me = this;
me.lookupReference('html').setVisible(true);
button.setVisible(false);
me.raw = true;
me.onSelectMail();
},
htmlMail: function(button) {
var me = this;
me.lookupReference('raw').setVisible(true);
button.setVisible(false);
me.raw = false;
me.onSelectMail();
},
changeTime: function(field, value) {
var me = this;
if (!value) {
return;
}
var val = value.getTime()/1000;
var spamlist = me.lookupReference('spamlist');
var combobox = me.lookupReference('email');
var params = combobox.getStore().getProxy().getExtraParams();
var to = me.lookupReference('to');
var from = me.lookupReference('from');
if (field.name === 'from') {
spamlist.setFrom(val);
params.starttime = val;
to.setMinValue(value);
} else if (field.name === 'to') {
spamlist.setTo(val + 24*60*60);
params.endtime = val + 24*60*60;
from.setMaxValue(value);
} else {
return;
}
// the combobox does not know anything about the extraparams
// so we disable queryCaching until we expand (and query) again
combobox.queryCaching = false;
combobox.getStore().getProxy().setExtraParams(params);
// we are reloading when we already have an email selected,
// or are in the user quarantine view
if (combobox.getValue() || PMG.view === 'quarantine') {
spamlist.load();
}
},
setQueryCaching: function() {
this.lookupReference('email').queryCaching = true;
},
control: {
'#':{
beforedestroy: 'resetEmail'
},
'button[reference=raw]': {
click: 'rawMail'
},
'button[reference=html]': {
click: 'htmlMail'
},
'combobox[name=email]': {
change: {
fn: 'changeEmail',
buffer: 500
},
expand: 'setQueryCaching'
},
'datefield': {
change: 'changeTime'
},
'pmgSpamList':{
selectionChange: 'onSelectMail'
},
}
}, },
items: [ items: [
{ {
xtype: 'pmgSpamArchive', tbar: {
reference: 'archive', layout: {
type: 'vbox',
align: 'stretch'
},
defaults: {
margin: 2,
},
items: [
{
fieldLabel: gettext('From'),
reference: 'from',
xtype: 'datefield',
format: 'Y-m-d',
name: 'from'
},
{
fieldLabel: gettext('To'),
reference: 'to',
xtype: 'datefield',
format: 'Y-m-d',
name: 'to'
},
{
xtype: 'combobox',
displayField: 'mail',
valueField: 'mail',
store: {
proxy: {
type: 'proxmox',
url: '/api2/json/quarantine/spamusers'
}
},
queryParam: false,
queryCaching: false,
editable: false,
reference: 'email',
name: 'email',
fieldLabel: 'E-Mail',
}]
},
xtype: 'pmgSpamList',
reference: 'spamlist',
region: 'west', region: 'west',
width: 320, width: 500,
split: true, split: true,
collapsible: false,
listeners: {
selectionChange: 'onSelectDay'
}
}, },
{ {
xtype: 'panel', title: gettext('Selected Mail'),
border: 0,
region: 'center', region: 'center',
layout: { type: 'vbox', align: 'stretch' }, split: true,
items: [ reference: 'preview',
{ disabled: true,
xtype: 'pmgSpamList', tbar: [{
reference: 'spamlist', xtype: 'button',
height: 300, reference: 'raw',
listeners: { text: gettext('Show Raw'),
selectionChange: 'onSelectMail' iconCls: 'fa fa-file-code-o'
} },{
}, xtype: 'button',
{ reference: 'html',
xtype: 'splitter' hidden: true,
}, text: gettext('Show HTML'),
{ iconCls: 'fa fa-file-text-o'
flex: 1, }]
reference: 'preview',
}
]
} }
] ]
}); });