diff --git a/modoboa/extensions/amavis/sql_listing.py b/modoboa/extensions/amavis/sql_listing.py
index af503c83a..71c2cd5aa 100644
--- a/modoboa/extensions/amavis/sql_listing.py
+++ b/modoboa/extensions/amavis/sql_listing.py
@@ -18,20 +18,38 @@ class Qtable(tables.Table):
styles = "table-condensed"
idkey = "mailid"
+ selection = tables.SelectionColumn(
+ "selection", safe=True, width='5px', header=None, sortable=False
+ )
type = tables.Column(
"type", align="center", width="30px", sort_order="type", safe=True
)
- score = tables.Column("score", label=ugettext_lazy("Score"), limit=6,
- sort_order="score")
- rstatus = tables.ImgColumn("rstatus", width='25px', sortable=False)
- from_ = tables.Column("from", label=ugettext_lazy("From"), limit=30,
- sort_order="from")
- subject = tables.Column("subject", label=ugettext_lazy("Subject"), limit=40,
- sort_order="subject")
- time = tables.Column("date", label=ugettext_lazy("Date"), sort_order="date")
- to = tables.Column("to", label=ugettext_lazy("To"), sort_order="to")
-
- cols_order = []
+ rstatus = tables.ImgColumn(
+ "rstatus", width='25px', sortable=False
+ )
+ score = tables.Column(
+ "score", label=ugettext_lazy("Score"), limit=6,
+ sort_order="score", cssclass="openable"
+ )
+ to = tables.Column(
+ "to", label=ugettext_lazy("To"), sort_order="to", cssclass="openable"
+ )
+ from_ = tables.Column(
+ "from", label=ugettext_lazy("From"), limit=30,
+ sort_order="from", cssclass="openable"
+ )
+ subject = tables.Column(
+ "subject", label=ugettext_lazy("Subject"), limit=40,
+ sort_order="subject", cssclass="openable"
+ )
+ time = tables.Column(
+ "date", label=ugettext_lazy("Date"), sort_order="date",
+ cssclass="openable"
+ )
+
+ cols_order = [
+ 'selection', 'type', 'rstatus', 'score', 'to', 'from_', 'subject', 'time'
+ ]
def parse_type(self, value):
color = 'important' if value in ['S', 'V'] else 'warning'
@@ -254,8 +272,6 @@ class SQLlisting(EmailListing):
reset_wm_url = True
def __init__(self, user, msgs, filter, **kwargs):
- Qtable.cols_order = ['type', 'score', 'rstatus', 'to', 'from_',
- 'subject', 'time']
self.mbc = SQLconnector(msgs, filter)
super(SQLlisting, self).__init__(**kwargs)
self.show_listing_headers = True
diff --git a/modoboa/extensions/amavis/static/amavis/css/quarantine.css b/modoboa/extensions/amavis/static/amavis/css/quarantine.css
index 2f7575752..2ee4aeab5 100644
--- a/modoboa/extensions/amavis/static/amavis/css/quarantine.css
+++ b/modoboa/extensions/amavis/static/amavis/css/quarantine.css
@@ -41,6 +41,10 @@ thead tr {
z-index: 1;
}
+td > input[type=checkbox] {
+ margin: 0;
+}
+
td[name=type] span {
cursor: pointer;
}
@@ -49,6 +53,10 @@ td.unseen {
font-weight: bold;
}
-td.pending {
+td[class*=pending] {
font-style: italic;
+}
+
+td[class*=openable] {
+ cursor: pointer;
}
\ No newline at end of file
diff --git a/modoboa/extensions/amavis/static/amavis/js/quarantine.js b/modoboa/extensions/amavis/static/amavis/js/quarantine.js
index cda5304a9..bcb871eb1 100644
--- a/modoboa/extensions/amavis/static/amavis/js/quarantine.js
+++ b/modoboa/extensions/amavis/static/amavis/js/quarantine.js
@@ -56,7 +56,7 @@ Quarantine.prototype = {
},
listen: function() {
- $(document).on("dblclick", "tbody>tr", $.proxy(this.viewmail_loader, this));
+ $(document).on("click", "td[class*=openable]", $.proxy(this.viewmail_loader, this));
$(document).on("click", "a[name=selectmsgs]", $.proxy(this.selectmsgs, this));
$(document).on("click", "a[name=release-multi]",
$.proxy(this.release_selection, this));
@@ -105,9 +105,10 @@ Quarantine.prototype = {
$("#emails").htmltable("clear_selection");
return;
}
- $("td[name=type]").each(function() {
- var $this = $(this);
- $("#emails").htmltable("select_row", $this.parent());
+ $("td[name*=selection]").each(function() {
+ var $input = $(this).children('input');
+ $input.prop('checked', true);
+ $('#emails').htmltable('select_row', $(this).parent());
});
},
@@ -122,7 +123,9 @@ Quarantine.prototype = {
$("td[name=type]").each(function() {
var $this = $(this);
if ($this.find('span').html().trim() == type) {
- $("#emails").htmltable("select_row", $this.parent());
+ var $input = $this.parent().children('td[name=selection]').children('input');
+ $input.prop('checked', true);
+ $('#emails').htmltable('select_row', $this.parent());
counter++;
}
});
@@ -253,12 +256,14 @@ Quarantine.prototype = {
activate_buttons: function($tr) {
$("a[name=release-multi]").removeClass('disabled');
$("a[name=delete-multi]").removeClass('disabled');
+ $("#selectall").prop('checked', true);
},
deactivate_buttons: function($tr) {
if (!this.htmltable.current_selection().length) {
$("a[name=release-multi]").addClass('disabled');
$("a[name=delete-multi]").addClass('disabled');
+ $("#selectall").prop('checked', false);
}
},
diff --git a/modoboa/extensions/amavis/views.py b/modoboa/extensions/amavis/views.py
index 07be93a5c..1f46ad929 100644
--- a/modoboa/extensions/amavis/views.py
+++ b/modoboa/extensions/amavis/views.py
@@ -25,7 +25,7 @@ from .models import Msgrcpt
def empty_quarantine(request):
content = "
%s
" % _("Empty quarantine")
- ctx = getctx("ok", level=2, listing=content, navbar="")
+ ctx = getctx("ok", level=2, listing=content)
return render_to_json_response(ctx)
@@ -75,19 +75,13 @@ def _listing(request):
return empty_quarantine(request)
content = lst.fetch(request, page.id_start, page.id_stop)
-<<<<<<< HEAD
- paginbar = pagination_bar(page)
- ctx = getctx("ok", listing=content, paginbar=paginbar, page=page.number)
+ ctx = getctx(
+ "ok", listing=content, paginbar=pagination_bar(page), page=page.number
+ )
if request.session.get('location', 'listing') != 'listing':
ctx['menu'] = quar_menu()
request.session['location'] = 'listing'
- return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
-=======
- navbar = lst.render_navbar(page, "listing/?")
- ctx = getctx("ok", listing=content, navbar=navbar,
- menu=quar_menu(request.user))
return render_to_json_response(ctx)
->>>>>>> master
@login_required
@@ -155,12 +149,8 @@ def viewmail(request, mail_id):
""").render(Context({"url": reverse(getmailcontent, args=[mail_id])}))
menu = viewm_menu(mail_id, rcpt)
ctx = getctx("ok", menu=menu, listing=content)
-<<<<<<< HEAD
request.session['location'] = 'viewmail'
- return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
-=======
return render_to_json_response(ctx)
->>>>>>> master
@login_required
diff --git a/modoboa/extensions/webmail/lib.py b/modoboa/extensions/webmail/lib.py
index b910dc546..d662d4fc9 100644
--- a/modoboa/extensions/webmail/lib.py
+++ b/modoboa/extensions/webmail/lib.py
@@ -26,22 +26,29 @@ class WMtable(tables.Table):
tableid = "emails"
styles = "table-condensed"
idkey = "imapid"
- select = tables.ImgColumn(
- "select", cssclass="draggable left", width="2%",
+ drag = tables.ImgColumn(
+ "drag", cssclass="draggable left", width="1%",
defvalue="%spics/grippy.png" % settings.STATIC_URL,
header=""
)
- flags = tables.ImgColumn("flags", width="4%")
+ selection = tables.SelectionColumn(
+ "selection", safe=True, width='1%', header=None, sortable=False
+ )
+ flags = tables.ImgColumn("flags", width="2%")
withatts = tables.ImgColumn("withatts", width="2%")
subject = tables.Column(
- "subject", label=ugettext_lazy("Subject"), width="50%", limit=60
+ "subject", label=ugettext_lazy("Subject"), width="50%", limit=60,
+ cssclass="openable"
)
from_ = tables.Column(
- "from", width="20%", label=ugettext_lazy("From"), limit=30
+ "from", width="20%", label=ugettext_lazy("From"), limit=30,
+ cssclass="openable"
+ )
+ date = tables.Column(
+ "date", width="15%", label=ugettext_lazy("Date"), cssclass="openable"
)
- date = tables.Column("date", width="15%", label=ugettext_lazy("Date"))
- cols_order = ["select", "withatts", "flags", "subject", "from_", "date"]
+ cols_order = ["drag", "selection", "withatts", "flags", "subject", "from_", "date"]
def parse(self, header, value):
if value is None:
diff --git a/modoboa/extensions/webmail/static/webmail/css/webmail.css b/modoboa/extensions/webmail/static/webmail/css/webmail.css
index 82adf1cef..a33f6ec01 100644
--- a/modoboa/extensions/webmail/static/webmail/css/webmail.css
+++ b/modoboa/extensions/webmail/static/webmail/css/webmail.css
@@ -202,4 +202,15 @@ div.expanded {
#folders2 li {
position: relative;
+}
+
+/*
+ * Table
+ */
+td > input[type=checkbox] {
+ margin: 0;
+}
+
+td[class*=openable] {
+ cursor: pointer;
}
\ No newline at end of file
diff --git a/modoboa/extensions/webmail/static/webmail/js/webmail.js b/modoboa/extensions/webmail/static/webmail/js/webmail.js
index d3440efd7..17659db0f 100644
--- a/modoboa/extensions/webmail/static/webmail/js/webmail.js
+++ b/modoboa/extensions/webmail/static/webmail/js/webmail.js
@@ -76,7 +76,7 @@ Webmail.prototype = {
$(document).on("click", "a[name=editmbox]", $.proxy(this.edit_mbox, this));
$(document).on("click", "a[name=removembox]", $.proxy(this.remove_mbox, this));
- $(document).on("dblclick", "tbody>tr", $.proxy(this.viewmail_loader, this));
+ $(document).on("click", "td[class*=openable]", $.proxy(this.viewmail_loader, this));
$(document).on("click", "a[name=reply]", $.proxy(this.reply_loader, this));
$(document).on("click", "a[name=replyall]", $.proxy(this.reply_loader, this));
@@ -989,7 +989,7 @@ Webmail.prototype = {
init_draggables: function() {
var plug = this;
- $("td[name=select]").draggable({
+ $("td[name=drag]").draggable({
opacity: 0.8,
helper: function(e) {
var $this = $(this);
diff --git a/modoboa/static/js/jquery.htmltable.js b/modoboa/static/js/jquery.htmltable.js
index 6ee6daf2e..1a185552d 100644
--- a/modoboa/static/js/jquery.htmltable.js
+++ b/modoboa/static/js/jquery.htmltable.js
@@ -10,6 +10,7 @@
this.$element = $(element);
this.options = $.extend({}, $.fn.htmltable.defaults, options);
this.shift_pressed = false;
+ this.ctrl_pressed = false;
this.last_selection = null;
this.prev_dir = null;
this.listen();
@@ -26,8 +27,8 @@
listen: function() {
$(document)
- .off("click", "tbody>tr")
- .on("click", "tbody>tr",
+ .off("change", "tbody input[type=checkbox]")
+ .on("change", "tbody input[type=checkbox]",
$.proxy(this.toggle_select, this));
$(document).on("keydown", "body", $.proxy(this.keydown, this));
$(document).on("keyup", "body", $.proxy(this.keyup, this));
@@ -36,11 +37,13 @@
_toggle_select: function($tr) {
this.last_selection = $tr;
if ($tr.hasClass(this.options.tr_selected_class)) {
+ $tr.children('td[name=selection]').children('input').prop('checked', false);
$tr.removeClass(this.options.tr_selected_class);
if (this.options.tr_unselected_event != undefined) {
this.options.tr_unselected_event($tr);
}
} else {
+ $tr.children('td[name=selection]').children('input').prop('checked', true);
$tr.addClass(this.options.tr_selected_class);
if (this.options.tr_selected_event != undefined) {
this.options.tr_selected_event($tr);
@@ -49,10 +52,13 @@
},
toggle_select: function(e) {
- e.preventDefault();
- var $tr = $(e.target).parent();
+ var $tr = $(e.target).parents('tr');
if (this.shift_pressed && this.last_selection) {
+ if ($tr.is(this.last_selection)) {
+ $tr.children('td[name=selection]').children('input').prop('checked', true);
+ return;
+ }
var itfunc = ($tr.index() >= this.last_selection.index())
? "next" : "prev";
var $curtr = null;
@@ -70,6 +76,8 @@
}
this.prev_dir = itfunc;
return;
+ } else if (!this.ctrl_pressed && (!this.last_selection || !this.last_selection.is($tr))) {
+ this.clear_selection();
}
this._toggle_select($tr);
},
@@ -86,7 +94,9 @@
* Cancel the current selection
*/
clear_selection: function() {
+ this.last_selection = null;
this.current_selection().removeClass(this.options.tr_selected_class);
+ $("tbody input[type=checkbox]").prop('checked', false);
},
/*
@@ -94,6 +104,7 @@
*/
select_row: function($row) {
$row.addClass(this.options.tr_selected_class);
+
},
keydown: function(e) {
@@ -102,6 +113,9 @@
e.preventDefault();
this.shift_pressed = true;
break;
+ case 17:
+ this.ctrl_pressed = true;
+ break;
}
},
@@ -111,6 +125,9 @@
e.preventDefault();
this.shift_pressed = false;
break;
+ case 17:
+ this.ctrl_pressed = false;
+ break;
}
}
};