diff --git a/modoboa/core/static/core/js/settings.js b/modoboa/core/static/core/js/settings.js
index f43499cba..30b0faf4c 100644
--- a/modoboa/core/static/core/js/settings.js
+++ b/modoboa/core/static/core/js/settings.js
@@ -10,7 +10,8 @@ var Settings = function(options) {
Settings.prototype = {
defaults: {
- main_table_id: "logs_table"
+ main_table_id: "logs_table",
+ eor_message: gettext("No more log entry to show")
},
initialize: function(options) {
diff --git a/modoboa/core/views/admin.py b/modoboa/core/views/admin.py
index eb9ac8e41..8b22b4923 100644
--- a/modoboa/core/views/admin.py
+++ b/modoboa/core/views/admin.py
@@ -101,15 +101,19 @@ def information(request, tplname="core/information.html"):
})
-def get_logs_page(request):
+def get_logs_page(request, page_id=None):
"""Return a page of logs."""
sort_order, sort_dir = get_sort_order(
request.GET, "date_created",
allowed_values=['date_created', 'level', 'logger', 'message']
)
+ if page_id is None:
+ page_id = request.GET.get("page", None)
+ if page_id is None:
+ return None
return get_listing_page(
Log.objects.all().order_by("%s%s" % (sort_dir, sort_order)),
- request.GET.get("page", 1)
+ page_id
)
@@ -121,7 +125,7 @@ def logs(request, tplname="core/logs.html"):
This view is only called the first time the page is displayed.
"""
- page = get_logs_page(request)
+ page = get_logs_page(request, 1)
return render_to_json_response({
"callback": "logs",
"content": render_to_string(tplname, {"logs": page.object_list}),
@@ -134,10 +138,14 @@ def logs(request, tplname="core/logs.html"):
def logs_page(request, tplname="core/logs_page.html"):
"""Return a page containing logs."""
page = get_logs_page(request)
- return render_to_json_response({
- "rows": render_to_string(tplname, {"logs": page.object_list}),
- "page": page.number
- })
+ if page is None:
+ context = {"length": 0}
+ else:
+ context = {
+ "rows": render_to_string(tplname, {"logs": page.object_list}),
+ "page": page.number
+ }
+ return render_to_json_response(context)
@login_required
diff --git a/modoboa/extensions/admin/static/admin/js/admin.js b/modoboa/extensions/admin/static/admin/js/admin.js
index 317549165..a3c245b82 100644
--- a/modoboa/extensions/admin/static/admin/js/admin.js
+++ b/modoboa/extensions/admin/static/admin/js/admin.js
@@ -100,22 +100,18 @@ Domains.prototype = {
initialize: function(options) {
Admin.prototype.initialize.call(this, options);
this.options.navigation_params.push("domfilter", "srvfilter");
+ this.options.eor_message = gettext("No more domain to show");
this.register_tag_handler("dom");
},
- end_of_list_reached: function(element) {
- $("#objects_table").after(
- $("
{0}
".format(
- gettext("No more domain to show")
- ))
- );
- },
-
- list_cb: function(data) {
- Admin.prototype.list_cb.call(this, data);
- var deloptions = (data.handle_mailboxes)
- ? {keepdir: gettext("Do not delete domain directory")}
- : {};
+ /**
+ * Initialize the domain links embedded within a page.
+ *
+ * @param {Object} data - options
+ */
+ init_domain_links: function(data) {
+ var deloptions = (data.handle_mailboxes) ?
+ {keepdir: gettext("Do not delete domain directory")} : {};
var warnmsg = (data.auto_account_removal && data.auto_account_removal == "yes")
? gettext("This operation will remove ALL data associated to this domain.")
: gettext("This operation will remove all data associated to this domain, excepting accounts.");
@@ -130,6 +126,27 @@ Domains.prototype = {
$(document).trigger('domain_listing_refresh');
},
+ /**
+ * Navigation callback: default.
+ *
+ * @param {Object} data - response of the ajax call (JSON)
+ */
+ list_cb: function(data) {
+ Admin.prototype.list_cb.call(this, data);
+ this.init_domain_links(data);
+ },
+
+ /**
+ * A new page has been received, inject it.
+ *
+ * @param {Object} data - page content
+ * @param {string} direction -
+ */
+ add_new_page: function(data, direction) {
+ Admin.prototype.add_new_page.call(this, data, direction);
+ this.init_domain_links(data);
+ },
+
change_inputs_state: function(value) {
$("#id_dom_admin_username").attr("disabled", value);
$("input[name=create_aliases]").attr("disabled", value);
@@ -234,6 +251,7 @@ Identities.prototype = {
initialize: function(options) {
Admin.prototype.initialize.call(this, options);
this.options.navigation_params.push("idtfilter", "grpfilter");
+ this.options.eor_message = gettext("No more identity to show");
this.domain_list = [];
this.register_tag_handler("idt");
this.register_tag_handler("grp", this.grp_tag_handler);
@@ -254,16 +272,12 @@ Identities.prototype = {
this.navobj.baseurl($link.attr("href")).update();
},
- end_of_list_reached: function(element) {
- $("#objects_table").after(
- $("{0}
".format(
- gettext("No more identity to show")
- ))
- );
- },
-
- list_cb: function(data) {
- Admin.prototype.list_cb.call(this, data);
+ /**
+ * Initialize the links embedded within a page.
+ *
+ * @param {Object} data - options
+ */
+ init_identity_links: function(data) {
var deloptions = {};
if (data.handle_mailboxes == "yes") {
@@ -283,6 +297,27 @@ Identities.prototype = {
});
},
+ /**
+ * A new page has been received, inject it.
+ *
+ * @param {Object} data - page content
+ * @param {string} direction -
+ */
+ add_new_page: function(data, direction) {
+ Admin.prototype.add_new_page.call(this, data, direction);
+ this.init_identity_links(data);
+ },
+
+ /**
+ * Navigation callback: default.
+ *
+ * @param {Object} data - response of the ajax call (JSON)
+ */
+ list_cb: function(data) {
+ Admin.prototype.list_cb.call(this, data);
+ this.init_identity_links(data);
+ },
+
grp_tag_handler: function(tag, $link) {
if (this.navobj.getparam(tag + "filter") === undefined &&
$link.hasClass(tag)) {
diff --git a/modoboa/static/js/listing.js b/modoboa/static/js/listing.js
index e2bba6185..d887028bc 100644
--- a/modoboa/static/js/listing.js
+++ b/modoboa/static/js/listing.js
@@ -19,7 +19,8 @@ Listing.prototype = {
with_searchform: true,
load_page_url: null,
navigation_params: ["sort_order", "searchquery"],
- main_table_id: "objects_table"
+ main_table_id: "objects_table",
+ eor_message: gettext("No more entry to show")
},
initialize: function(options) {
@@ -102,14 +103,25 @@ Listing.prototype = {
* @param {string} direction -
*/
add_new_page: function(data, direction) {
- console.log("new page");
- console.log(this.options.main_table_id);
$("#{0} tbody".format(this.options.main_table_id))
.html(function(pos, oldhtml) {
return oldhtml + data.rows;
});
},
+ /**
+ * Callback called when no more page can be loaded.
+ *
+ * @this Listing
+ */
+ end_of_list_reached: function(element) {
+ $("#" + this.options.main_table_id).after(
+ $("{0}
".format(
+ this.options.eor_message
+ ))
+ );
+ },
+
/**
* Update the listing with the received data.
*
@@ -122,6 +134,7 @@ Listing.prototype = {
if (with_infinite_scroll || with_infinite_scroll === undefined) {
if ($(window).data("infinite-scroll") !== undefined) {
$(window).infinite_scroll("reset_loaded_pages", data.page);
+ $(window).infinite_scroll("resume");
} else {
$(window).infinite_scroll({
url: this.options.load_page_url,
@@ -132,9 +145,11 @@ Listing.prototype = {
return $last_row.offset().top - $element.height();
},
process_results: $.proxy(this.add_new_page, this),
- end_of_list_reached: this.end_of_list_reached
+ end_of_list_reached: $.proxy(this.end_of_list_reached, this)
});
}
+ } else if ($(window).data("infinite-scroll") !== undefined) {
+ $(window).infinite_scroll("pause");
}
var $sortables = $(this.options.sortable_selector);