diff --git a/modoboa/extensions/amavis/general_callbacks.py b/modoboa/extensions/amavis/general_callbacks.py index 58add79de..aaf022733 100644 --- a/modoboa/extensions/amavis/general_callbacks.py +++ b/modoboa/extensions/amavis/general_callbacks.py @@ -86,7 +86,7 @@ def check_for_pending_requests(user, include_all): url += "#listing/?viewrequests=1" return [{ "id": "nbrequests", "url": url, "text": _("Pending requests"), - "counter": nbrequests, "level": "important" + "counter": nbrequests, "level": "danger" }] diff --git a/modoboa/extensions/amavis/lib.py b/modoboa/extensions/amavis/lib.py index e66a7bcd4..0fcd1fb18 100644 --- a/modoboa/extensions/amavis/lib.py +++ b/modoboa/extensions/amavis/lib.py @@ -92,6 +92,15 @@ class QuarantineNavigationParameters(NavigationParameters): ('msgtype', None, False), ('viewrequests', None, False) ] + def _store_page(self): + """Specific method to store the current page.""" + if self.request.GET.get("reset_page", None) or "page" not in self: + self["page"] = 1 + else: + page = self.request.GET.get("page", None) + if page is not None: + self["page"] = int(page) + def back_to_listing(self): """Return the current listing URL. diff --git a/modoboa/extensions/amavis/sql_connector.py b/modoboa/extensions/amavis/sql_connector.py index 026483d31..9a27c0a1c 100644 --- a/modoboa/extensions/amavis/sql_connector.py +++ b/modoboa/extensions/amavis/sql_connector.py @@ -1,6 +1,8 @@ """ SQL connector module. """ +import datetime + from django.db.models import Q from modoboa.extensions.admin.models import Domain @@ -124,7 +126,7 @@ class SQLconnector(object): messages = self._apply_extra_select_filters(messages) return messages - def messages_count(self, **kwargs): + def messages_count(self): """Return the total number of messages living in the quarantine. We also store the built queryset for a later use. @@ -148,7 +150,7 @@ class SQLconnector(object): return self._messages_count - def fetch(self, start=None, stop=None, **kwargs): + def fetch(self, start=None, stop=None): """Fetch a range of messages from the internal cache. """ @@ -158,7 +160,7 @@ class SQLconnector(object): "to": qm["rid__email"], "subject": qm["mail__subject"], "mailid": qm["mail__mail_id"], - "date": qm["mail__time_num"], + "date": datetime.datetime.fromtimestamp(qm["mail__time_num"]), "type": qm["content"], "score": qm["bspam_level"]} rs = qm["rs"] diff --git a/modoboa/extensions/amavis/static/amavis/css/quarantine.css b/modoboa/extensions/amavis/static/amavis/css/quarantine.css index c5e08286e..0d0d2e6cb 100644 --- a/modoboa/extensions/amavis/static/amavis/css/quarantine.css +++ b/modoboa/extensions/amavis/static/amavis/css/quarantine.css @@ -40,21 +40,14 @@ margin: 0; } -#listing.fluid-content-quarantine { - position: relative; - padding-top: 30px; - height: 0; - overflow: hidden; - padding-bottom: 56.25%; /* proportion value to aspect ratio 16:9 (9 / 16 = 0.5625 or 56.25%) */ -} - - -#listing.fluid-content-quarantine iframe { +#listing { position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; + top: 125px; + bottom: 0; + margin: 0; + overflow: auto; + padding-left: 15px; + padding-right: 15px; } #mailcontent { diff --git a/modoboa/extensions/amavis/static/amavis/js/quarantine.js b/modoboa/extensions/amavis/static/amavis/js/quarantine.js index 0807a667b..dbb3506e4 100644 --- a/modoboa/extensions/amavis/static/amavis/js/quarantine.js +++ b/modoboa/extensions/amavis/static/amavis/js/quarantine.js @@ -1,3 +1,9 @@ +/** + * Return an instance of Quarantine. + * + * @constructor + * @param {Object} options - instance options + */ var Quarantine = function(options) { Listing.call(this, options); }; @@ -6,7 +12,11 @@ Quarantine.prototype = { constructor: Quarantine, defaults: { - deflocation: "listing" + deflocation: "listing", + main_table_id: "emails", + scroll_container: "#listing", + navigation_params: ["sort_order", "pattern", "criteria", "msgtype"], + eor_message: gettext("No more message to show") }, initialize: function(options) { @@ -18,10 +28,22 @@ Quarantine.prototype = { this.set_msgtype(); $(document).on('click', '#selectall', this.toggle_selection); - $("#searchfield").searchbar({navobj: this.navobj}); + this.initialize_searchfield(); }, - /* + /** + * Search field initialization. + */ + initialize_searchfield: function() { + $("#searchfield").searchbar({ + navobj: this.navobj, + pattern_changed: function(navobj) { + navobj.setparam("reset_page", "true"); + } + }); + }, + + /** * Activate the button corresponding to the current message type * filter. If no message type is found, the 'All' button is * selected. @@ -29,28 +51,40 @@ Quarantine.prototype = { set_msgtype: function() { var msgtype = this.navobj.getparam('msgtype'); - $("button[name*=msgtype]").removeClass('active'); - if (msgtype != undefined) { - $("button[name=msgtype_" + msgtype + "]").addClass('active'); + $("input[name*=msgtype]").attr("checked", false) + .parent().removeClass('active'); + + if (msgtype !== undefined) { + $("input[name=msgtype_" + msgtype + "]").attr("checked", true) + .parent().addClass('active'); } else { - $("button[name=msgtype_all]").addClass('active'); + $("button[name=msgtype_all]").attr("checked", true) + .parent().addClass('active'); } }, + /** + * Update the main page content. + * + * @this Quarantine + * @param {Object} data - new content + */ update_page: function(data) { - if (data.menu != undefined) { + if (data.menu !== undefined) { $("#menubar").html(data.menu); - $("#searchfield").searchbar({navobj: this.navobj}); + this.initialize_searchfield(); } - if (data.listing != undefined) { - - + if (data.listing !== undefined) { $("#listing").html(data.listing); - $("#listing:has(iframe)").addClass("fluid-content-quarantine"); - } - this.update_listing(data); + if (this.navobj.getbaseurl() == "listing") { + this.update_listing(data); + $(this.options.scroll_container).scrollTop(10); + } else { + this.update_listing(data, false); + $(this.options.scroll_container).infinite_scroll("pause"); + } }, listen: function() { @@ -66,7 +100,7 @@ Quarantine.prototype = { $(document).on("click", "a[name=delete]", $.proxy(this.delete, this)); $(document).on("click", "a[name=headers]", $.proxy(this.headers, this)); $(document).on("click", "td[name=type] span", $.proxy(this.filter_by_type, this)); - $(document).on("click", "#filters button", $.proxy(this.filter_by_type, this)); + $(document).on("click", "#filters label", $.proxy(this.filter_by_type, this)); }, load_page: function(e) { @@ -74,6 +108,32 @@ Quarantine.prototype = { this.navobj.delparam("rcpt").update(); }, + /** + * Return extra arguments used to fetch a page. + * + * @this Listing + */ + get_load_page_args: function() { + var args = Listing.prototype.get_load_page_args.call(this); + + args.scroll = true; + return args; + }, + + /** + * Calculate the bottom position of the scroll container. + * + * @param {Object} $element - scroll container object + */ + calculate_bottom: function($element) { + var emails_height = $("#emails").height(); + + if (!emails_height) { + return undefined; + } + return $("#emails").height() - $element.height(); + }, + view_requests: function(e) { e.preventDefault(); this.navobj.setparam("viewrequests", "1").update(); @@ -132,8 +192,10 @@ Quarantine.prototype = { } }, - /* + /** * Filter listing by message type (spam, virus, etc.) + * + * @param {Object} evt - event object */ filter_by_type: function(evt) { var $target = $(evt.target); @@ -142,7 +204,7 @@ Quarantine.prototype = { if ($target.is("span")) { msgtype = $target.html().trim(); } else { - msgtype = $target.attr("name").replace("msgtype_", ""); + msgtype = $target.children("input").attr("name").replace("msgtype_", ""); } if (msgtype != 'all') { @@ -272,6 +334,12 @@ Quarantine.prototype = { } }, + /** + * Navigation callback: listing. + * + * @this Quarantine + * @param {Object} data - ajax call response (JSON) + */ listing_cb: function(data) { this.update_page(data); this.navobj.delparam("rcpt").update(); @@ -282,11 +350,13 @@ Quarantine.prototype = { }); this.htmltable = $("#emails").data("htmltable"); this.deactivate_buttons(); + if (this.navobj.hasparam("reset_page")) { + this.navobj.delparam("reset_page").update(false, true); + } }, viewmail_cb: function(data) { this.update_page(data); - /*$("#listing").css("overflow", "hidden");*/ $("body").css("overflow", "hidden"); }, diff --git a/modoboa/extensions/amavis/templates/amavis/email_list.html b/modoboa/extensions/amavis/templates/amavis/email_list.html new file mode 100644 index 000000000..439d214c0 --- /dev/null +++ b/modoboa/extensions/amavis/templates/amavis/email_list.html @@ -0,0 +1,31 @@ +{% load i18n %} + +
diff --git a/modoboa/extensions/amavis/templates/amavis/emails_page.html b/modoboa/extensions/amavis/templates/amavis/emails_page.html new file mode 100644 index 000000000..0e7b2c3da --- /dev/null +++ b/modoboa/extensions/amavis/templates/amavis/emails_page.html @@ -0,0 +1,26 @@ +{% load amavis_tags %} + +{% for email in email_list %} +