diff --git a/modoboa/core/static/core/js/settings.js b/modoboa/core/static/core/js/settings.js
new file mode 100644
index 000000000..f43499cba
--- /dev/null
+++ b/modoboa/core/static/core/js/settings.js
@@ -0,0 +1,36 @@
+/**
+ * Return an instance of Settings.
+ *
+ * @constructor
+ * @param {Object} options - instance options
+ */
+var Settings = function(options) {
+ TwocolsNav.call(this, options);
+};
+
+Settings.prototype = {
+ defaults: {
+ main_table_id: "logs_table"
+ },
+
+ initialize: function(options) {
+ this.options = $.extend({}, this.defaults, options);
+ TwocolsNav.prototype.initialize.call(this, this.options);
+ this.navobj.register_callback(
+ "logs", $.proxy(this.logs_callback, this));
+ },
+
+ /**
+ * Navigation callback: logs.
+ *
+ */
+ logs_callback: function(data) {
+ this.select_left_menu();
+ if (data.content) {
+ $('#' + this.options.divid).html(data.content);
+ }
+ this.update_listing(data);
+ }
+};
+
+Settings.prototype = $.extend({}, TwocolsNav.prototype, Settings.prototype);
diff --git a/modoboa/core/templates/core/logs.html b/modoboa/core/templates/core/logs.html
index 741e9e6eb..fde47e1d9 100644
--- a/modoboa/core/templates/core/logs.html
+++ b/modoboa/core/templates/core/logs.html
@@ -1,6 +1,6 @@
-{% load i18n core_tags %}
+{% load i18n %}
{% trans "Logs" %} {% trans "Previously on Modoboa..." %}
-
+
| {% trans "Date" %} |
@@ -10,11 +10,6 @@
- {% for l in logs %}
- | {{ l.date_created }} |
- {{ l.level|colorize_level|safe }} |
- {{ l.logger }} |
- {{ l.message|tohtml|safe }} |
-
{% endfor %}
+ {% include "core/logs_page.html" %}
diff --git a/modoboa/core/templates/core/logs_page.html b/modoboa/core/templates/core/logs_page.html
new file mode 100644
index 000000000..171a3e9df
--- /dev/null
+++ b/modoboa/core/templates/core/logs_page.html
@@ -0,0 +1,10 @@
+{% load core_tags %}
+
+{% for l in logs %}
+
+ | {{ l.date_created }} |
+ {{ l.level|colorize_level|safe }} |
+ {{ l.logger }} |
+ {{ l.message|tohtml|safe }} |
+
+{% endfor %}
diff --git a/modoboa/core/templates/core/settings_header.html b/modoboa/core/templates/core/settings_header.html
index 743dfce69..3ca5a607d 100644
--- a/modoboa/core/templates/core/settings_header.html
+++ b/modoboa/core/templates/core/settings_header.html
@@ -4,17 +4,20 @@
{% block html_head %}
+
+
diff --git a/modoboa/core/templatetags/core_tags.py b/modoboa/core/templatetags/core_tags.py
index 2e2a6667b..3ba0d65fb 100644
--- a/modoboa/core/templatetags/core_tags.py
+++ b/modoboa/core/templatetags/core_tags.py
@@ -119,10 +119,11 @@ def uprefs_menu(selection, user):
@register.filter
def colorize_level(level):
+ """A simple filter a text using a boostrap color."""
classes = {
"INFO": "text-info",
"WARNING": "text-warning",
- "CRITICAL": "text-error"
+ "CRITICAL": "text-danger"
}
if not level in classes:
return level
@@ -131,7 +132,8 @@ def colorize_level(level):
@register.filter
def tohtml(message):
- return re.sub("'(.*?)'", "\g<1>", message)
+ """Simple tag to format a text using HTML."""
+ return re.sub(r"'(.*?)'", "\g<1>", message)
@register.simple_tag
diff --git a/modoboa/core/urls.py b/modoboa/core/urls.py
index a35fd4242..4402f37d2 100644
--- a/modoboa/core/urls.py
+++ b/modoboa/core/urls.py
@@ -22,6 +22,8 @@ urlpatterns = patterns(
url(r'^core/info/$', 'modoboa.core.views.admin.information',
name="information"),
url(r'^core/logs/$', 'modoboa.core.views.admin.logs', name="log_list"),
+ url(r'^core/logs/page/$', 'modoboa.core.views.admin.logs_page',
+ name="logs_page"),
url(r'^core/top_notifications/check/$',
'modoboa.core.views.admin.check_top_notifications',
name='top_notifications_check'),
diff --git a/modoboa/core/views/admin.py b/modoboa/core/views/admin.py
index e2b12671b..eb9ac8e41 100644
--- a/modoboa/core/views/admin.py
+++ b/modoboa/core/views/admin.py
@@ -101,27 +101,45 @@ def information(request, tplname="core/information.html"):
})
-@login_required
-@user_passes_test(lambda u: u.is_superuser)
-def logs(request, tplname="core/logs.html"):
- from modoboa.lib.templatetags.lib_tags import pagination_bar
-
+def get_logs_page(request):
+ """Return a page of logs."""
sort_order, sort_dir = get_sort_order(
request.GET, "date_created",
allowed_values=['date_created', 'level', 'logger', 'message']
)
- page = get_listing_page(
+ return get_listing_page(
Log.objects.all().order_by("%s%s" % (sort_dir, sort_order)),
request.GET.get("page", 1)
)
+
+
+@login_required
+@user_passes_test(lambda u: u.is_superuser)
+def logs(request, tplname="core/logs.html"):
+ """Return a list of log entries.
+
+ This view is only called the first time the page is displayed.
+
+ """
+ page = get_logs_page(request)
return render_to_json_response({
- "content": render_to_string(tplname, {
- "logs": page.object_list,
- }),
- "page": page.number,
- "paginbar": pagination_bar(page),
+ "callback": "logs",
+ "content": render_to_string(tplname, {"logs": page.object_list}),
+ "page": page.number
})
+
+@login_required
+@user_passes_test(lambda u: u.is_superuser)
+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
+ })
+
+
@login_required
def check_top_notifications(request):
"""
diff --git a/modoboa/extensions/admin/static/admin/js/admin.js b/modoboa/extensions/admin/static/admin/js/admin.js
index 1c18507a5..317549165 100644
--- a/modoboa/extensions/admin/static/admin/js/admin.js
+++ b/modoboa/extensions/admin/static/admin/js/admin.js
@@ -35,18 +35,6 @@ Admin.prototype = {
this.update_listing(data);
},
- /**
- * A new page has been received, inject it.
- *
- * @param {Object} data - page content
- * @param {string} direction -
- */
- add_new_page: function(data, direction) {
- $("#objects_table tbody").html(function(pos, oldhtml) {
- return oldhtml + data.rows;
- });
- },
-
/**
* Children must override this method.
*/
diff --git a/modoboa/static/js/listing.js b/modoboa/static/js/listing.js
index b1c745d7c..e2bba6185 100644
--- a/modoboa/static/js/listing.js
+++ b/modoboa/static/js/listing.js
@@ -18,7 +18,8 @@ Listing.prototype = {
sortable_selector: '.sortable',
with_searchform: true,
load_page_url: null,
- navigation_params: ["sort_order", "searchquery"]
+ navigation_params: ["sort_order", "searchquery"],
+ main_table_id: "objects_table"
},
initialize: function(options) {
@@ -94,26 +95,46 @@ Listing.prototype = {
return args;
},
+ /**
+ * A new page has been received, inject it.
+ *
+ * @param {Object} data - page content
+ * @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;
+ });
+ },
+
/**
* Update the listing with the received data.
*
* @this Listing
* @param {Object} data - new content
*/
- update_listing: function(data) {
- if ($(window).data("infinite-scroll") !== undefined) {
- $(window).infinite_scroll("reset_loaded_pages", data.page);
- } else {
- $(window).infinite_scroll({
- url: this.options.load_page_url,
- get_args: $.proxy(this.get_load_page_args, this),
- calculate_bottom: function($element) {
- var $last_row = $("#objects_table").find("tr").last();
- return $last_row.offset().top - $element.height();
- },
- process_results: this.add_new_page,
- end_of_list_reached: this.end_of_list_reached
- });
+ update_listing: function(data, with_infinite_scroll) {
+ var $this = this;
+
+ if (with_infinite_scroll || with_infinite_scroll === undefined) {
+ if ($(window).data("infinite-scroll") !== undefined) {
+ $(window).infinite_scroll("reset_loaded_pages", data.page);
+ } else {
+ $(window).infinite_scroll({
+ url: this.options.load_page_url,
+ get_args: $.proxy(this.get_load_page_args, this),
+ calculate_bottom: function($element) {
+ var $last_row = $("#" + $this.options.main_table_id)
+ .find("tr").last();
+ return $last_row.offset().top - $element.height();
+ },
+ process_results: $.proxy(this.add_new_page, this),
+ end_of_list_reached: this.end_of_list_reached
+ });
+ }
}
var $sortables = $(this.options.sortable_selector);
diff --git a/modoboa/static/js/twocols_nav.js b/modoboa/static/js/twocols_nav.js
index 5a499b75e..3999e3c99 100644
--- a/modoboa/static/js/twocols_nav.js
+++ b/modoboa/static/js/twocols_nav.js
@@ -1,3 +1,8 @@
+/**
+ * Return an instance of TwocolsNav.
+ *
+ * @constructor
+ */
var TwocolsNav = function(options) {
Listing.call(this, options);
};
@@ -33,7 +38,7 @@ TwocolsNav.prototype = {
if (data.content) {
$('#' + this.options.divid).html(data.content);
}
- this.update_listing(data);
+ this.update_listing(data, false);
if (data.onload_cb) {
eval(data.onload_cb + '()');
}
@@ -121,10 +126,16 @@ TwocolsNav.prototype = {
this.navobj.parse_string($link.attr("href"), true).update();
},
-
- default_cb: function(data) {
+ /**
+ * Select an entry in the left menu based on current url.
+ */
+ select_left_menu: function() {
$("a.ajaxlink").parent().removeClass("active");
$("a[name=" + this.navobj.getbaseurl() + "]").parent().addClass("active");
+ },
+
+ default_cb: function(data) {
+ this.select_left_menu();
this.update_content(data);
}
};