diff --git a/modoboa/admin/lib.py b/modoboa/admin/lib.py index 79699730a..215cc4e76 100644 --- a/modoboa/admin/lib.py +++ b/modoboa/admin/lib.py @@ -1,46 +1,31 @@ # coding: utf-8 -from django.utils.translation import ugettext as _ from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger -from modoboa.lib.webutils import ajax_simple_response from modoboa.lib import parameters -from modoboa.lib.templatetags.libextras import pagination_bar -from modoboa.admin.tables import * -from exceptions import * -def render_listing(request, objtype, **kwargs): - """Common function to render a listing - All listing pages available into the admin application use the - same layout, rendered by this function. +def get_sort_order(qdict, default, allowed_values=None): + """Return a sort order from a querydict object - :param request: a ``Request`` object - :param objtype: the object type's name (lowercase) + :param QueryDict qdict: the object to analyse + :param string default: the default sort order if no one is found + :param list allowed_values: an optional list of allowed values + :return: a 2uple of strings """ - tblclass = "%sTable" % objtype.capitalize() - if not globals().has_key(tblclass): - raise AdminError(_("Unknown object type")) - tblclass = globals()[tblclass] - - if request.GET.has_key("domid"): - kwargs["domid"] = request.GET["domid"] + sort_order = qdict.get("sort_order", default) + if sort_order.startswith("-"): + sort_dir = "-" + sort_order = sort_order[1:] else: - kwargs["domid"] = "" - paginator = Paginator(kwargs["objects"], - int(parameters.get_admin("ITEMS_PER_PAGE"))) + sort_dir = "" + if allowed_values is not None and not sort_order in allowed_values: + return (default, "") + return (sort_order, sort_dir) + + +def get_listing_page(objects, pagenum): + paginator = Paginator(objects, int(parameters.get_admin("ITEMS_PER_PAGE"))) try: - pagenum = request.GET.get("page", "1") - except ValueError: - pagenum = 1 - try: - page = paginator.page(pagenum) + page = paginator.page(int(pagenum)) except (EmptyPage, PageNotAnInteger): page = paginator.page(paginator.num_pages) - - return ajax_simple_response({ - "table" : tblclass(request, page.object_list).render(), - "page" : page.number, - "paginbar" : pagination_bar(page), - "handle_mailboxes": parameters.get_admin("HANDLE_MAILBOXES", - raise_error=False), - "auto_account_removal": parameters.get_admin("AUTO_ACCOUNT_REMOVAL") - }) + return page diff --git a/modoboa/admin/tables.py b/modoboa/admin/tables.py index 78be02c01..3be7b989a 100644 --- a/modoboa/admin/tables.py +++ b/modoboa/admin/tables.py @@ -11,10 +11,13 @@ class DomainsTable(tables.Table): name = tables.LinkColumn( "name", label=ugettext_lazy("Name"), urlpattern="modoboa.admin.views.editdomain", - title=_("Edit domain"), modal=True, modalcb="admin.domainform_cb" - ) - domaliases = tables.Column("domainalias_set", - label=ugettext_lazy("Alias(es)"), safe=True) + title=_("Edit domain"), modal=True, modalcb="admin.domainform_cb", + sortable=True, sort_order="name" + ) + domaliases = tables.Column( + "domainalias_set", label=ugettext_lazy("Alias(es)"), safe=True, + sortable=True, sort_order="domainalias__name" + ) actions = tables.ActionColumn("actions", label=ugettext_lazy("Actions"), defvalue=domain_actions) @@ -46,31 +49,3 @@ class ExtensionsTable(tables.Table): descr = tables.Column("description", label=ugettext_lazy("Description")) cols_order = ["selection", "label", "version", "descr"] - -class IdentitiesTable(tables.Table): - idkey = "id" - styles = "table" - tags = tables.Column("tags", label=ugettext_lazy("Tags"), safe=True) - identity = tables.LinkColumn( - "identity", label=ugettext_lazy("Email/Username"), - modal=True, - urlpattern={"User" : "modoboa.admin.views.editaccount", - "Alias" : "modoboa.admin.views.editalias_dispatcher"}, - modalcb={"User" : "admin.editaccount_cb", "Alias" : "admin.aliasform_cb"} - ) - name_or_rcpt = tables.Column("name_or_rcpt", label=ugettext_lazy("Fullname/Recipient")) - actions = tables.ActionColumn("actions", label=ugettext_lazy("Actions"), - defvalue=identity_actions) - - cols_order = ["identity", "name_or_rcpt", "tags", "actions"] - - def __init__(self, request, identities): - super(IdentitiesTable, self).__init__(request) - self.populate(self._rows_from_model(identities, True)) - - def row_class(self, request, obj): - if obj.__class__.__name__ == "User" and not obj.is_active: - return "muted" - if not obj.enabled: - return "muted" - return "" diff --git a/modoboa/admin/templates/admin/identities_table.html b/modoboa/admin/templates/admin/identities_table.html index 1d7024579..af3e32580 100644 --- a/modoboa/admin/templates/admin/identities_table.html +++ b/modoboa/admin/templates/admin/identities_table.html @@ -2,9 +2,9 @@ - - - + + + diff --git a/modoboa/admin/views.py b/modoboa/admin/views.py index 1aa30489c..6e4110eef 100644 --- a/modoboa/admin/views.py +++ b/modoboa/admin/views.py @@ -6,14 +6,15 @@ from django.contrib.auth.decorators \ import login_required, permission_required, user_passes_test from django.db.models import Q from django.shortcuts import render +from django.template.loader import render_to_string from django.db import transaction, IntegrityError import cStringIO import csv -from lib import * +from lib import get_sort_order, get_listing_page from forms import * from models import * -from modoboa.admin.tables import * +from modoboa.admin.tables import DomainsTable from modoboa.lib import events, parameters from modoboa.lib.exceptions import * from modoboa.lib.webutils \ @@ -21,41 +22,53 @@ from modoboa.lib.webutils \ from modoboa.lib.emailutils import split_mailbox from modoboa.lib.models import Parameter from modoboa.lib.formutils import CreationWizard +from modoboa.lib.templatetags.libextras import pagination_bar @login_required def index(request): return HttpResponseRedirect(reverse(domains)) + @login_required @user_passes_test(lambda u: u.has_perm("admin.view_domains") or u.has_perm("admin.view_mailboxes")) def _domains(request): + sort_order, sort_dir = get_sort_order(request.GET, "name") domains = request.user.get_domains() squery = request.GET.get("searchquery", None) if squery is not None: q = Q(name__contains=squery) q |= Q(domainalias__name__contains=squery) domains = domains.filter(q).distinct() - return render_listing(request, "domains", objects=domains) + if sort_order in ["name", "domainalias__name"]: + domains = domains.order_by("%s%s" % (sort_dir, sort_order)) + page = get_listing_page(domains, request.GET.get("page", 1)) + return ajax_simple_response({ + "table": DomainsTable(request, page.object_list).render(), + "page": page.number, + "paginbar": pagination_bar(page), + "handle_mailboxes": parameters.get_admin("HANDLE_MAILBOXES", + raise_error=False), + "auto_account_removal": parameters.get_admin("AUTO_ACCOUNT_REMOVAL") + }) + @login_required def domains(request, tplname="admin/domains.html"): if not request.user.has_perm("admin.view_domains"): if request.user.has_perm("admin.view_mailboxes"): return HttpResponseRedirect(reverse(identities)) - return HttpResponseRedirect(reverse("modoboa.userprefs.views.index")) - - return render(request, tplname, { - "selection" : "domains" - }) + return render(request, tplname, {"selection": "domains"}) + @login_required @permission_required("admin.add_user") def domains_list(request): - doms = map(lambda dom: dom.name, request.user.get_domains()) + doms = [dom.name for dom in request.user.get_domains()] return ajax_simple_response(doms) + def _validate_domain(request, form, successmsg, commonctx, tplname, callback=None, tpl_form_name="form"): """Domain form validation @@ -77,12 +90,13 @@ def _validate_domain(request, form, successmsg, commonctx, tplname, commonctx["error"] = error return ajax_response(request, status="ko", template=tplname, **commonctx) + @login_required @permission_required("admin.add_domain") @transaction.commit_on_success def newdomain(request, tplname="common/wizard_forms.html"): events.raiseEvent("CanCreate", request.user, "domains") - + def newdomain_cb(steps): genform = steps[0]["form"] genform.is_valid() @@ -311,35 +325,39 @@ def delalias(request): def deldlist(request): return _del_alias(request, "Distribution list deleted", "Distribution lists deleted") + @login_required @permission_required("admin.delete_alias") @transaction.commit_on_success def delforward(request): return _del_alias(request, "Forward deleted", "Forwards deleted") + @login_required @user_passes_test(lambda u: u.has_perm("admin.add_user") or u.has_perm("admin.add_alias")) def _identities(request): idents_list = request.user.get_identities(request.GET) - objects = sorted(idents_list, key=lambda o: o.identity) - - paginator = Paginator(objects, int(parameters.get_admin("ITEMS_PER_PAGE"))) - pagenum = int(request.GET.get("page", "1")) - try: - page = paginator.page(pagenum) - except (EmptyPage, PageNotAnInteger): - page = paginator.page(paginator.num_pages) - + sort_order, sort_dir = get_sort_order(request.GET, "identity", + ["identity", "name_or_rcpt", "tags"]) + if sort_order in ["identity", "name_or_rcpt"]: + objects = sorted(idents_list, key=lambda o: getattr(o, sort_order), + reverse=sort_dir == '-') + else: + objects = sorted(idents_list, key=lambda o: o.tags[0], + reverse=sort_dir == '-') + page = get_listing_page(objects, request.GET.get("page", 1)) return ajax_simple_response({ - "table" : _render_to_string(request, "admin/identities_table.html", { - "identities" : page.object_list, - "tableid" : "objects_table" + "table": _render_to_string(request, "admin/identities_table.html", { + "identities": page.object_list, + "tableid": "objects_table" }), - "handle_mailboxes": parameters.get_admin("HANDLE_MAILBOXES", raise_error=False), - "page" : page.number, - "paginbar" : pagination_bar(page) + "handle_mailboxes": parameters.get_admin("HANDLE_MAILBOXES", + raise_error=False), + "page": page.number, + "paginbar": pagination_bar(page) }) + @login_required @user_passes_test(lambda u: u.has_perm("admin.add_user") or u.has_perm("admin.add_alias")) def identities(request, tplname="admin/identities.html"): @@ -365,14 +383,9 @@ def mboxes_list(request): @login_required @permission_required("admin.add_mailbox") def list_quotas(request, tplname="admin/quotas.html"): - sort_order = request.GET.get("sort_order", "address") + sort_order, sort_dir = get_sort_order(request.GET, "address") mboxes = request.user.get_mailboxes(request.GET.get("searchquery", None)) mboxes = mboxes.exclude(quota=0) - if sort_order.startswith("-"): - sort_dir = "-" - sort_order = sort_order[1:] - else: - sort_dir = "" if sort_order in ["address", "quota", "quota_value__bytes"]: mboxes = mboxes.order_by("%s%s" % (sort_dir, sort_order)) elif sort_order == "quota_usage": diff --git a/modoboa/templates/common/table_head.html b/modoboa/templates/common/table_head.html index 5c9323166..42fcf8da1 100644 --- a/modoboa/templates/common/table_head.html +++ b/modoboa/templates/common/table_head.html @@ -2,7 +2,7 @@ {% for c in table.columns %} {% if c.sortable %} -
{% trans "Name" %}{% trans "Fullname/Recipient" %}{% trans "Tags" %}{% trans "Name" %}{% trans "Fullname/Recipient" %}{% trans "Tags" %} {% trans "Actions" %}
+ {% else %} {% endif %}