diff --git a/modoboa/core/static/core/js/settings.js b/modoboa/core/static/core/js/settings.js
index 30b0faf4c..ae1b65c95 100644
--- a/modoboa/core/static/core/js/settings.js
+++ b/modoboa/core/static/core/js/settings.js
@@ -19,6 +19,9 @@ Settings.prototype = {
TwocolsNav.prototype.initialize.call(this, this.options);
this.navobj.register_callback(
"logs", $.proxy(this.logs_callback, this));
+ this.navobj.register_callback(
+ "extensions", $.proxy(this.extensions_callback, this));
+ $(document).on("click", "#toggle_extensions_sel", this.toggle_extensions_sel);
},
/**
@@ -31,6 +34,28 @@ Settings.prototype = {
$('#' + this.options.divid).html(data.content);
}
this.update_listing(data);
+ },
+
+ /**
+ * Navigation callback: extensions.
+ */
+ extensions_callback: function(data) {
+ if (data.content) {
+ $('#' + this.options.divid).html(data.content);
+ }
+ this.update_listing(data);
+ if ($("tbody input[type=checkbox]:checked").length) {
+ $("#toggle_extensions_sel").prop("checked", true);
+ }
+ },
+
+ /**
+ * Select or unselect all extensions in on click.
+ */
+ toggle_extensions_sel: function(evt) {
+ var status = $(this).prop("checked");
+
+ $("tbody input[type=checkbox]").prop("checked", status);
}
};
diff --git a/modoboa/core/tables.py b/modoboa/core/tables.py
deleted file mode 100644
index 78a730983..000000000
--- a/modoboa/core/tables.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from django.utils.translation import ugettext_lazy
-from modoboa.lib import tables
-
-
-class ExtensionsTable(tables.Table):
- idkey = "id"
- styles = "table-hover"
- selection = tables.SelectionColumn("selection", width="4%", header=False)
- label = tables.Column("label", label=ugettext_lazy("Name"), width="15%")
- version = tables.Column(
- "version", label=ugettext_lazy("Version"), width="6%"
- )
- descr = tables.Column("description", label=ugettext_lazy("Description"))
-
- cols_order = ["selection", "label", "version", "descr"]
diff --git a/modoboa/core/templates/core/extensions.html b/modoboa/core/templates/core/extensions.html
index acccfbd56..cc51b3ecb 100644
--- a/modoboa/core/templates/core/extensions.html
+++ b/modoboa/core/templates/core/extensions.html
@@ -1,6 +1,26 @@
{% load i18n %}{% load url from future %}
{% trans "Extensions" %} {% trans "Choose the extension(s) to use" %}
-
{% trans 'Save' %}
diff --git a/modoboa/core/views/admin.py b/modoboa/core/views/admin.py
index 911544e8b..6da5a04d2 100644
--- a/modoboa/core/views/admin.py
+++ b/modoboa/core/views/admin.py
@@ -1,17 +1,23 @@
+"""
+Views available to super administrators only.
+"""
+
from django.shortcuts import render
from django.template.loader import render_to_string
from django.utils.translation import ugettext as _
+
from django.contrib.auth.decorators import (
login_required, user_passes_test
)
+
+
+from modoboa.core.models import Extension, Log
+from modoboa.core.utils import new_version_available
from modoboa.lib import events, parameters
+from modoboa.lib.listing import get_sort_order, get_listing_page
from modoboa.lib.webutils import (
_render_to_string, render_to_json_response
)
-from modoboa.lib.listing import get_sort_order, get_listing_page
-from modoboa.core.models import Extension, Log
-from modoboa.core.utils import new_version_available
-from modoboa.core.tables import ExtensionsTable
@login_required
@@ -51,6 +57,7 @@ def saveparameters(request):
@login_required
@user_passes_test(lambda u: u.is_superuser)
def viewextensions(request, tplname='core/extensions.html'):
+ """List available extensions."""
from modoboa.core.extensions import exts_pool
exts = exts_pool.list_all()
@@ -65,15 +72,16 @@ def viewextensions(request, tplname='core/extensions.html'):
dbext.save()
ext["selection"] = False
- tbl = ExtensionsTable(request, exts)
return render_to_json_response({
- "content": _render_to_string(request, tplname, {"extensions": tbl})
+ "callback": "extensions",
+ "content": _render_to_string(request, tplname, {"extensions": exts})
})
@login_required
@user_passes_test(lambda u: u.is_superuser)
def saveextensions(request):
+ """Enable of disable extension(s)."""
actived_exts = Extension.objects.filter(enabled=True)
found = []
for k in request.POST.keys():
diff --git a/modoboa/lib/tables.py b/modoboa/lib/tables.py
deleted file mode 100644
index 356ada43d..000000000
--- a/modoboa/lib/tables.py
+++ /dev/null
@@ -1,256 +0,0 @@
-# coding: utf-8
-"""
-:mod:`tables` --- simple tabular renderer
------------------------------------------
-
-This module offers a simple (I hope so) interface to render tabular
-data. For a given Table class, it generates the corresponding HTML
-output (using standard tags like and co.).
-
-"""
-import inspect
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext as _
-from django.template import Template, RequestContext, Context
-
-from .templatetags.lib_tags import render_link
-
-
-class Column(object):
- """Simple column representation
- """
- def __init__(self, name, **kwargs):
- self.name = name
- self.sortable = True
- for k, v in kwargs.iteritems():
- setattr(self, k, v)
-
- def __unicode__(self):
- try:
- label = getattr(self, "label")
- except AttributeError:
- return u''
- return label
-
- def transform(self, row, col, table):
- if "class" in row.keys():
- col["cssclass"] += col["cssclass"] != "" \
- and ", %s" % row["class"] or row["class"]
- try:
- col["value"] = table.parse(self.name, row[self.name])
- except AttributeError:
- col["value"] = row[self.name]
- try:
- limit = getattr(self, "limit")
- if limit:
- # The value is not necessarily a string, so...
- col["value"] = unicode(col["value"], "utf-8") if isinstance(col["value"], str) else unicode(col["value"])
- if len(col["value"]) > limit:
- col["value"] = col["value"][0:limit] + "..."
- except AttributeError:
- pass
- try:
- col["safe"] = getattr(self, "safe")
- except AttributeError:
- pass
-
-
-class SelectionColumn(Column):
- """Specific column: selection
-
- A 'selection' column contains only checkboxes (one per row). It is
- usefull to select rows for grouped actions (modify, delete, etc.)
- """
- def __unicode__(self):
- if self.header:
- return ""
- return ""
-
- def render(self, value, selection):
- return "" \
- % {'id': self.name, 'value': value,
- "checked": "checked=''" if selection else ""}
-
- def transform(self, row, col, table):
- selection = row[self.name] if self.name in row else False
- col["value"] = self.render(row[table.idkey], selection)
- col["safe"] = True
-
-
-class ImgColumn(Column):
- """Specific column: image
-
- This kind of column only contains images tags (
).
- """
- def __str__(self):
- self.sortable = False
- try:
- return getattr(self, "header")
- except AttributeError:
- return ""
-
- def render(self, value):
- if getattr(self, "bootstrap", False) and value.startswith("icon"):
- return "" % value
- if type(value) in [list, tuple]:
- return "".join(["
" % i for i in value])
- return "
" % value
-
- def transform(self, row, col, table):
- key = "img_%s" % self.name
- if key in row.keys():
- col["value"] = self.render(row[key])
- else:
- try:
- col["value"] = self.render(self.defvalue)
- except Exception:
- pass
- col["safe"] = True
-
-
-class DivColumn(Column):
- def __str__(self):
- return ""
-
- def render(self):
- return "
"
-
- def transform(self, row, col, table):
- col["value"] = self.render()
- col["safe"] = True
-
-
-class ActionColumn(Column):
- def render(self, fct, user, rowid):
- return fct(user, rowid)
-
- def transform(self, row, col, table):
- col["value"] = self.render(self.defvalue, table.request.user, row[table.idkey])
- col["safe"] = True
-
-
-class LinkColumn(Column):
- def render(self, rowid, value):
- linkdef = dict(label=value, modal=self.modal)
- if type(self.urlpattern) is dict:
- t, value = rowid.split(":")
- linkdef.update(url=reverse(self.urlpattern[t], args=[value]),
- modalcb=self.modalcb[t])
- else:
- linkdef.update(url=reverse(self.urlpattern, args=[rowid]),
- modalcb=self.modalcb)
- return render_link(linkdef)
-
- def transform(self, row, col, table):
- col["value"] = self.render(row[table.idkey], row[self.name])
- col["safe"] = True
-
-
-class Table(object):
- tableid = ""
-
- def __init__(self, request, rows=None):
- self.columns = []
- self.request = request
- if rows is None:
- rows = {}
- try:
- order = getattr(self, "cols_order")
- except AttributeError:
- for m in inspect.getmembers(self):
- if isinstance(m[1], Column):
- try:
- if getattr(m[1], "first"):
- self.columns = [m[1]] + self.columns
- except AttributeError:
- self.columns += [m[1]]
- else:
- for colname in order:
- try:
- col = getattr(self, colname)
- except AttributeError:
- continue
- if not isinstance(col, Column):
- continue
- self.columns += [col]
-
- if rows != {}:
- self.populate(rows)
-
- def populate(self, rows):
- self.rows = []
- trcpt = 0
- for row in rows:
- nrow = {"id": row[self.idkey], "cols": [], "trcpt": trcpt}
- for name in ["style", "options"]:
- if name in row:
- nrow[name] = row[name]
-
- for c in self.columns:
- newcol = {"name": c.name}
- for key in ["width", "align", "cssclass"]:
- try:
- newcol[key] = getattr(c, key)
- except AttributeError:
- newcol[key] = ""
- c.transform(row, newcol, self)
- nrow["cols"] += [newcol]
- self.rows += [nrow]
- trcpt += 1
-
- def _rows_from_model(self, objects, include_type_in_id=False):
- rows = []
- for obj in objects:
- nrow = {}
- try:
- idkey = getattr(self, "idkey")
- nrow[idkey] = getattr(obj, idkey)
- if include_type_in_id:
- nrow[idkey] = "%s:%s" % (obj.__class__.__name__, nrow[idkey])
- except AttributeError:
- pass
- for c in self.columns:
- try:
- nrow[c.name] = getattr(obj, c.name)
- except AttributeError:
- pass
- for meth in ["options", "class"]:
- try:
- nrow[meth] = getattr(self, "row_%s" % meth)(self.request, obj)
- except AttributeError:
- pass
- rows += [nrow]
- return rows
-
- def parse(self, header, value):
- try:
- return getattr(self, "parse_%s" % header)(value)
- except AttributeError:
- return value
-
- def __unicode__(self):
- return self.render()
-
- def render(self, withheader=True):
- if len(self.rows):
- try:
- styles = self.styles
- except AttributeError:
- styles = "table-striped table-bordered"
-
- t = Template("""
-
- {% if withheader %}{% include "common/table_head.html" %}{% endif %}
- {% include "common/table_body.html" %}
-
-""")
- return t.render(RequestContext(self.request, {
- "table": self, "tableid": self.tableid, "styles": styles,
- "withheader": withheader
- }))
-
- t = Template("""
-%s
-""" % _("No entries to display"))
- return t.render(Context())