diff --git a/admin/__init__.py b/admin/__init__.py
index 2e5ab907b..fdfff4e76 100644
--- a/admin/__init__.py
+++ b/admin/__init__.py
@@ -17,3 +17,5 @@ parameters.register_admin("MAILDIR_ROOT", type="string", deflt=".maildir",
parameters.register_admin("PASSWORD_SCHEME", type="list", deflt="crypt",
values=[("crypt", "crypt"), ("md5", "md5"), ("clear", "clear")],
help=_("Scheme used to crypt mailbox passwords"))
+parameters.register_admin("ITEMS_PER_PAGE", type="int", deflt=30,
+ help=_("Number of displayed items per page"))
diff --git a/admin/models.py b/admin/models.py
index bed1665e9..3ce6a221b 100644
--- a/admin/models.py
+++ b/admin/models.py
@@ -62,6 +62,15 @@ class DatesAware(models.Model):
ObjectDates.set_for_object(self)
super(DatesAware, self).save(*args, **kwargs)
+ def __creation(self):
+ return self.dates.creation
+
+ def __last_modification(self):
+ return self.dates.last_modification
+
+ creation = property(__creation)
+ last_modification = property(__last_modification)
+
class Domain(DatesAware):
name = models.CharField(_('name'), max_length=100, unique=True,
help_text=_("The domain name"))
@@ -157,6 +166,11 @@ class Mailbox(DatesAware):
full_address = property(__full_address)
+ def __enabled(self):
+ return self.user.is_active
+
+ enabled = property(__enabled)
+
def create_dir(self):
relpath = "%s/%s" % (self.domain.name, self.address)
abspath = os.path.join(parameters.get_admin("STORAGE_PATH"), relpath)
@@ -273,6 +287,16 @@ class Alias(DatesAware):
("view_aliases", "View aliases"),
)
+ def __full_address(self):
+ return "%s@%s" % (self.address, self.domain.name)
+ full_address = property(__full_address)
+
+ def __targets(self):
+ ret = "
".join(map(lambda m: str(m), self.mboxes.all()))
+ ret += "
" + self.repr_extmboxes()
+ return ret
+ targets = property(__targets)
+
def save(self, int_targets, ext_targets, *args, **kwargs):
if len(ext_targets):
self.extmboxes = ",".join(ext_targets)
@@ -320,6 +344,15 @@ class Alias(DatesAware):
"""
return "
".join(self.extmboxes.split(","))
+ def ui_disabled(self, user):
+ if user.is_superuser:
+ return False
+ usermb = Mailbox.objects.get(user=user.id)
+ for mb in self.mboxes.all():
+ if mb.domain.id != usermb.domain.id:
+ return True
+ return False
+
class Extension(models.Model):
name = models.CharField(max_length=150)
enabled = models.BooleanField(_('enabled'),
diff --git a/admin/permissions.py b/admin/permissions.py
index 24cd237be..60c38d821 100644
--- a/admin/permissions.py
+++ b/admin/permissions.py
@@ -73,7 +73,7 @@ class SuperAdminsPerms(Permissions):
"full_name" : "%s %s" % (admin.first_name, admin.last_name),
"date_joined" : admin.date_joined,
"enabled" : admin.is_active}]
- return SuperAdminsTable(admins_list).render(request)
+ return SuperAdminsTable(request, admins_list).render()
class DomainAdminsPerms(Permissions):
@@ -123,7 +123,7 @@ class DomainAdminsPerms(Permissions):
domadmins_list = []
for admin in domadmins:
domadmins_list += [admin.tohash()]
- return DomainAdminsTable(domadmins_list).render(request)
+ return DomainAdminsTable(request, domadmins_list).render()
def get_perms_class(user, role):
"""Retrieves the class associated to a given role
diff --git a/admin/tables.py b/admin/tables.py
new file mode 100644
index 000000000..24fd39d93
--- /dev/null
+++ b/admin/tables.py
@@ -0,0 +1,130 @@
+# coding: utf-8
+from django.utils.translation import ugettext as _
+from modoboa.lib import tables
+from templatetags.admin_extras import *
+
+class DomsTable(tables.Table):
+ tableid = "objects_table"
+ idkey = "id"
+
+ name = tables.Column("name", label=_("Name"))
+ creation = tables.Column("creation", label=_("Created"), width="160px")
+ modified = tables.Column("last_modification", label=_("Last modified"),
+ width="160px")
+ domaliases = tables.Column("domainalias_set", label=_("Domain aliases"),
+ width="100px", align="center")
+ mboxes = tables.Column("mailbox_set", label=_("Mailboxes"),
+ width="100px", align="center")
+ mbaliases = tables.Column("mbalias_counter", label=_("Mailbox aliases"),
+ width="100px", align="center")
+ quota = tables.Column("quota", label=_("Quota"), width="50px", align="center")
+ enabled = tables.Column("enabled", label=_("Enabled"), width="50px",
+ align="center")
+ actions = tables.ActionColumn("actions", label=_("Actions"), width="50px",
+ align="center", defvalue=domain_actions)
+
+ cols_order = ["name", "creation", "modified",
+ "domaliases", "mboxes", "mbaliases",
+ "quota", "enabled", "actions"]
+
+ def __init__(self, request, doms):
+ super(DomsTable, self).__init__(request)
+ self.populate(self._rows_from_model(doms))
+
+ def parse_domainalias_set(self, value):
+ return len(value.all())
+
+ def parse_mailbox_set(self, value):
+ return len(value.all())
+
+ def parse_quota(self, value):
+ return "%s %s" % (value, _("MB"))
+
+ def parse_enabled(self, value):
+ return _("yes") if value else _("no")
+
+class DomAliasesTable(tables.Table):
+ tableid = "objects_table"
+ idkey = "id"
+
+ name = tables.Column("name", label=_("Name"))
+ target = tables.Column("target", label=_("Targeted domain"))
+ creation = tables.Column("creation", label=_("Created"), width="170px")
+ modified = tables.Column("last_modification", label=_("Last modified"),
+ width="170px")
+ enabled = tables.Column("enabled", label=_("Enabled"), width="50px",
+ align="center")
+ actions = tables.ActionColumn("actions", label=_("Actions"), width="50px",
+ align="center", defvalue=domalias_actions)
+
+ cols_order = ["name", "target", "creation",
+ "modified", "enabled", "actions"]
+
+ def __init__(self, request, domaliases):
+ super(DomAliasesTable, self).__init__(request)
+ self.populate(self._rows_from_model(domaliases))
+
+ def parse_enabled(self, value):
+ return _("yes") if value else _("no")
+
+class MailboxesTable(tables.Table):
+ tableid = "objects_table"
+ idkey = "id"
+
+ address = tables.Column("address", label=_("Address"))
+ name = tables.Column("name", label=_("Name"))
+ creation = tables.Column("creation", label=_("Created"), width="160px")
+ modified = tables.Column("last_modification", label=_("Last modified"),
+ width="160px")
+ aliases = tables.Column("alias_set", label=_("Aliases"), width="70px",
+ align="center")
+ quota = tables.Column("quota", label=_("Quota"), width="50px", align="center")
+ enabled = tables.Column("enabled", label=gender("Enabled", "f"), width="50px",
+ align="center")
+ actions = tables.ActionColumn("actions", label=_("Actions"), width="70px",
+ align="center", defvalue=mailbox_actions)
+
+ cols_order = ["address", "name", "creation", "modified", "aliases",
+ "quota", "enabled", "actions"]
+
+ def __init__(self, request, mailboxes):
+ super(MailboxesTable, self).__init__(request)
+ self.populate(self._rows_from_model(mailboxes))
+
+ def parse_alias_set(self, value):
+ return len(value.all())
+
+ def parse_quota(self, value):
+ return "%s %s" % (value, _("MB"))
+
+ def parse_enabled(self, value):
+ return _("yes") if value else _("no")
+
+class MbAliasesTable(tables.Table):
+ tableid = "objects_table"
+ idkey = "id"
+
+ address = tables.Column("full_address", label=_("Address"))
+ targets = tables.Column("targets", label=_("Target(s)"), safe=True)
+ creation = tables.Column("creation", label=_("Created"), width="170px")
+ modified = tables.Column("last_modification", label=_("Last modified"),
+ width="170px")
+ enabled = tables.Column("enabled", label=gender("Enabled", "m"), width="50px",
+ align="center")
+ actions = tables.ActionColumn("actions", label=_("Actions"), width="50px",
+ align="center", defvalue=mbalias_actions)
+
+ cols_order = ["address", "targets", "creation", "modified", "enabled", "actions"]
+
+ def __init__(self, request, aliases):
+ super(MbAliasesTable, self).__init__(request)
+ self.populate(self._rows_from_model(aliases))
+
+ def rowoptions(self, request, alias):
+ return "{ui_disabled : '%s'}" % alias.ui_disabled(request.user)
+
+ def parse_enabled(self, value):
+ return _("yes") if value else _("no")
+
+
+
diff --git a/admin/templatetags/admin_extras.py b/admin/templatetags/admin_extras.py
index feeb1b059..3670d87ae 100644
--- a/admin/templatetags/admin_extras.py
+++ b/admin/templatetags/admin_extras.py
@@ -170,26 +170,31 @@ def domalias_actions(user, aid):
return render_actions(actions)
@register.simple_tag
-def mailbox_actions(user, mbox):
+def mailbox_actions(user, mboxid):
actions = [
{"name" : "editmailbox",
- "url" : reverse(admin.views.editmailbox, args=[mbox.id]),
+ "url" : reverse(admin.views.editmailbox, args=[mboxid]),
"img" : static_url("pics/edit.png"),
"title" : _("Edit mailbox"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:300,y:320}}"},
{"name" : "aliases",
- "url" : reverse(admin.views.mbaliases) + "?mbid=%d" % mbox.id,
+ "url" : reverse(admin.views.mbaliases) + "?mbid=%d" % mboxid,
"img" : static_url("pics/alias.png"),
"title" : _("View this mailbox aliases")},
]
return render_actions(actions)
@register.simple_tag
-def mbalias_actions(user, alias):
+def mbalias_actions(user, aliasid):
+ from admin.models import Alias
+
+ alias = Alias.objects.get(pk=aliasid)
+ if alias.ui_disabled(user):
+ return "--"
actions = [
{"name" : "editmbalias",
- "url" : reverse(admin.views.editmbalias, args=[alias.id]),
+ "url" : reverse(admin.views.editmbalias, args=[aliasid]),
"img" : static_url("pics/edit.png"),
"title" : _("Edit mailbox alias"),
"class" : "boxed",
diff --git a/admin/views.py b/admin/views.py
index b86326fac..7bd4a9cbd 100644
--- a/admin/views.py
+++ b/admin/views.py
@@ -10,11 +10,13 @@ from django.db.models import Q
from django.contrib.auth.models import User, Group
from django.contrib import messages
from django.db import transaction, IntegrityError
+from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from lib import *
from modoboa import admin, userprefs
from models import *
from admin.permissions import *
+from admin.tables import *
from modoboa.lib import crypt_password
from modoboa.lib import _render, ajax_response, ajax_simple_response, \
getctx, events, parameters
@@ -22,14 +24,28 @@ from modoboa.lib.emailutils import split_mailbox
from modoboa.lib.models import Parameter
import copy
-def render_domains_page(request, page, **kwargs):
- template = "admin/%s.html" % page
+def render_domains_page(request, objtype, tblclass, tplname="admin/listing.html",
+ **kwargs):
if request.GET.has_key("domid"):
kwargs["domid"] = request.GET["domid"]
else:
kwargs["domid"] = ""
- kwargs["selection"] = page
- return _render(request, template, kwargs)
+ kwargs["selection"] = objtype
+ paginator = Paginator(kwargs["objects"],
+ int(parameters.get_admin("ITEMS_PER_PAGE")))
+ try:
+ page = request.GET.get("page", "1")
+ except ValueError:
+ page = 1
+ try:
+ kwargs["objects"] = paginator.page(page)
+ except (EmptyPage, PageNotAnInteger):
+ kwargs["objects"] = paginator.page(paginator.num_pages)
+ kwargs["last_page"] = paginator.num_pages
+ kwargs["total"] = paginator.count
+ kwargs["table"] = tblclass(request, kwargs["objects"].object_list).render()
+
+ return _render(request, tplname, kwargs)
@login_required
def domains(request):
@@ -43,8 +59,12 @@ def domains(request):
for dom in domains:
dom.mbalias_counter = len(Alias.objects.filter(domain=dom.id))
deloptions = {"keepdir" : _("Do not delete domain directory")}
- return render_domains_page(request, "domains",
- domains=domains,
+ return render_domains_page(request, "domains", DomsTable,
+ "admin/domains.html",
+ title=_("Available domains"),
+ emptymsg=_("No domain defined."),
+ objects=domains,
+ rel="310 190",
deloptions=deloptions)
def _validate_domain(request, form, successmsg, commonctx,
@@ -137,8 +157,11 @@ def domaliases(request):
else:
domain = None
domaliases = DomainAlias.objects.all()
- return render_domains_page(request, "domaliases",
- domaliases=domaliases, domain=domain)
+ return render_domains_page(request, "domaliases", DomAliasesTable,
+ title=_("Domain aliases"),
+ emptymsg=_("No domain alias defined."),
+ rel="310 190",
+ objects=domaliases)
@login_required
@good_domain
@@ -227,8 +250,11 @@ def mailboxes(request):
mboxes = Mailbox.objects.all()
domain = None
deloptions = {"keepdir" : _("Do not delete mailbox directory")}
- return render_domains_page(request, "mailboxes",
- mailboxes=mboxes, domain=domain, deloptions=deloptions)
+ return render_domains_page(request, "mailboxes", MailboxesTable,
+ title=_("Available mailboxes"),
+ emptymsg=_("No mailbox defined."),
+ rel="310 320",
+ objects=mboxes, domain=domain, deloptions=deloptions)
@login_required
@good_domain
@@ -360,15 +386,12 @@ def mbaliases(request):
aliases = Alias.objects.filter(mboxes__id=request.GET["mbid"]).distinct()
else:
aliases = Alias.objects.all()
- if not request.user.is_superuser:
- usermb = Mailbox.objects.get(user=request.user.id)
- for al in aliases:
- al.ui_disabled = False
- for mb in al.mboxes.all():
- if mb.domain.id != usermb.domain.id:
- al.ui_disabled = True
- break
- return render_domains_page(request, "mbaliases", aliases=aliases)
+
+ return render_domains_page(request, "mbaliases", MbAliasesTable,
+ title=_("Mailbox aliases"),
+ emptymsg=_("No mailbox alias defined."),
+ rel="320 300",
+ objects=aliases)
def _validate_mbalias(request, form, successmsg, tplname, commonctx):
"""Mailbox alias validation
@@ -546,9 +569,11 @@ def viewextensions(request, tplname='admin/extensions.html'):
class ExtensionsTable(tables.Table):
idkey = "id"
selection = tables.SelectionColumn("selection", width="4%", first=True)
- _1_name = tables.Column("name", label=_("Name"), width="15%")
- _2_version = tables.Column("version", label=_("Version"), width="6%")
- _3_descr = tables.Column("description", label=_("Description"))
+ name = tables.Column("name", label=_("Name"), width="15%")
+ version = tables.Column("version", label=_("Version"), width="6%")
+ descr = tables.Column("description", label=_("Description"))
+
+ cols_order = ["selection", "name", "version", "descr"]
exts = list_extensions()
for ext in exts:
@@ -562,9 +587,9 @@ def viewextensions(request, tplname='admin/extensions.html'):
dbext.save()
ext["selection"] = False
- tbl = ExtensionsTable(exts)
+ tbl = ExtensionsTable(request, exts)
return _render(request, tplname, {
- "extensions" : tbl.render(request)
+ "extensions" : tbl.render()
})
@login_required
diff --git a/extensions/amavis_quarantine/sql_listing.py b/extensions/amavis_quarantine/sql_listing.py
index 57edf6619..f05cd4f80 100644
--- a/extensions/amavis_quarantine/sql_listing.py
+++ b/extensions/amavis_quarantine/sql_listing.py
@@ -2,29 +2,27 @@
from datetime import datetime
from django.utils.translation import ugettext as _
-from modoboa.lib import tables, db
+from modoboa.lib import tables, db, static_url
from modoboa.lib.email_listing import MBconnector, EmailListing
from modoboa.lib.emailutils import *
class Qtable(tables.Table):
tableid = "emails"
idkey = "mailid"
- #selection = tables.SelectionColumn("selection", first=True)
- _1_type = tables.Column("type", align="center", width="30px",
- label="")
- _2_from_ = tables.Column("from", label=_("From"))
- _3_subject = tables.Column("subject", label=_("Subject"))
- _4_time = tables.Column("date", label=_("Date"))
+
+ type = tables.Column("type", align="center", width="30px",
+ label="")
+ rstatus = tables.ImgColumn("rstatus", width='25px')
+ from_ = tables.Column("from", label=_("From"), limit=30)
+ subject = tables.Column("subject", label=_("Subject"), limit=40)
+ time = tables.Column("date", label=_("Date"))
+ to = tables.Column("to", label=_("To"), limit=30)
+
+ cols_order = ['type', 'rstatus', 'to', 'from_', 'subject', 'time']
def parse_date(self, value):
return datetime.fromtimestamp(value)
- def parse(self, header, value):
- try:
- return getattr(self, "parse_%s" % header)(value)
- except AttributeError:
- return value
-
class SQLconnector(MBconnector):
def __init__(self, filter=None):
self.conn = db.getconnection("amavis_quarantine")
@@ -77,10 +75,13 @@ LIMIT %d,%d
emails = []
rows = cursor.fetchall()
for row in rows:
- emails.append({"from" : row[0], "to" : row[1],
- "subject" : row[2], "content" : row[3],
- "mailid" : row[4], "date" : row[5],
- "type" : row[6]})
+ m = {"from" : row[0], "to" : row[1],
+ "subject" : row[2], "content" : row[3],
+ "mailid" : row[4], "date" : row[5],
+ "type" : row[6]}
+ if row[7] == "R":
+ m["img_rstatus"] = static_url("pics/release.png");
+ emails.append(m)
return emails
class SQLlisting(EmailListing):
@@ -90,7 +91,9 @@ class SQLlisting(EmailListing):
defcallback = "updatelisting"
reset_wm_url = True
- def __init__(self, filter, **kwargs):
+ def __init__(self, user, filter, **kwargs):
+ if not user.is_superuser:
+ Qtable.cols_order.remove('to')
self.mbc = SQLconnector(filter)
EmailListing.__init__(self, **kwargs)
diff --git a/extensions/amavis_quarantine/views.py b/extensions/amavis_quarantine/views.py
index b60b3359b..ed9abef20 100644
--- a/extensions/amavis_quarantine/views.py
+++ b/extensions/amavis_quarantine/views.py
@@ -52,7 +52,7 @@ def _listing(request, internal=False, filter=None):
pageid = request.GET.has_key("page") and int(request.GET["page"]) or 1
request.session["page"] = pageid # ?? nécessaire
- lst = SQLlisting(filter, baseurl="listing/", empty=internal,
+ lst = SQLlisting(request.user, filter, baseurl="listing/", empty=internal,
elems_per_page=int(parameters.get_user(request.user,
"MESSAGES_PER_PAGE")))
if internal:
@@ -165,6 +165,7 @@ WHERE msgrcpt.mail_id=msgs.mail_id AND msgrcpt.rid=maddr.id AND msgs.mail_id IN
result = amr.sendreq(k, values["secret"], *values["rcpts"])
if result:
count += 1
+ db.execute(conn, "UPDATE msgrcpt SET rs='R' WHERE mail_id='%s'" % k)
else:
error = result
break
diff --git a/extensions/webmail/static/css/webmail.css b/extensions/webmail/static/css/webmail.css
index 31d284971..c8ff5f942 100644
--- a/extensions/webmail/static/css/webmail.css
+++ b/extensions/webmail/static/css/webmail.css
@@ -119,12 +119,6 @@ textarea:hover {
}
/* Progress bar */
-#footer {
- color: white;
- font-weight: bold;
- font-size: 1em;
-}
-
#quotalabel {
float: left;
padding: 7px 2px 0 5px;
diff --git a/lib/email_listing.py b/lib/email_listing.py
index 6cd5bb0cd..3dc4cd532 100644
--- a/lib/email_listing.py
+++ b/lib/email_listing.py
@@ -107,14 +107,15 @@ class EmailListing:
return render_to_string("common/navbar.html", context)
def fetch(self, request, id_start, id_stop):
- table = self.tbltype(self.mbc.fetch(start=id_start, stop=id_stop,
+ table = self.tbltype(request,
+ self.mbc.fetch(start=id_start, stop=id_stop,
folder=self.folder,
nbelems=self.elems_per_page))
tpl = Template("""
""")
- return tpl.render(Context({"table" : table.render(request)}))
+ return tpl.render(Context({"table" : table.render()}))
def render(self, request, pageid=1, **kwargs):
listing = ""
diff --git a/lib/tables.py b/lib/tables.py
index eede7bbef..705b28811 100644
--- a/lib/tables.py
+++ b/lib/tables.py
@@ -48,22 +48,46 @@ class DivColumn(Column):
def render(self):
return "
"
+class ActionColumn(Column):
+ def render(self, fct, user, rowid):
+ return fct(user, rowid)
+
class Table(object):
tableid = ""
- def __init__(self, rows={}):
+ def __init__(self, request, rows={}):
self.columns = []
- for m in inspect.getmembers(self):
- if isinstance(m[1], Column):
+ self.request = request
+ 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:
- if getattr(m[1], "first"):
- self.columns = [m[1]] + self.columns
+ col = getattr(self, colname)
except AttributeError:
- self.columns += [m[1]]
+ 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}
+ if row.has_key("options"):
+ nrow["options"] = row["options"]
for c in self.columns:
newcol = {"name" : c.name}
for key in ["width", "align", "cssclass"]:
@@ -88,6 +112,9 @@ class Table(object):
elif isinstance(c, DivColumn):
newcol["value"] = c.render()
newcol["safe"] = True
+ elif isinstance(c, ActionColumn):
+ newcol["value"] = c.render(c.defvalue, self.request.user, nrow["id"])
+ newcol["safe"] = True
elif row.has_key(c.name):
if "class" in row.keys():
newcol["cssclass"] += newcol["cssclass"] != "" \
@@ -96,11 +123,48 @@ class Table(object):
newcol["value"] = self.parse(c.name, row[c.name])
except AttributeError:
newcol["value"] = row[c.name]
+ try:
+ limit = getattr(c, "limit")
+ if len(newcol["value"]) > limit:
+ newcol["value"] = newcol["value"][0:limit] + "..."
+ except AttributeError:
+ pass
+ try:
+ newcol["safe"] = getattr(c, "safe")
+ except AttributeError:
+ pass
nrow["cols"] += [newcol]
self.rows += [nrow]
trcpt += 1
+
+ def _rows_from_model(self, objects):
+ rows = []
+ for obj in objects:
+ nrow = {}
+ try:
+ idkey = getattr(self, "idkey")
+ nrow[idkey] = getattr(obj, idkey)
+ except AttributeError:
+ pass
+ for c in self.columns:
+ try:
+ nrow[c.name] = getattr(obj, c.name)
+ except AttributeError:
+ pass
+ try:
+ nrow["options"] = getattr(self, "rowoptions")(self.request, obj)
+ except AttributeError:
+ pass
+ rows += [nrow]
+ return rows
- def render(self, request):
+ def parse(self, header, value):
+ try:
+ return getattr(self, "parse_%s" % header)(value)
+ except AttributeError:
+ return value
+
+ def render(self):
if len(self.rows):
t = Template("""
diff --git a/static/css/default.css b/static/css/default.css
index a526c907d..68f7e4719 100644
--- a/static/css/default.css
+++ b/static/css/default.css
@@ -34,6 +34,27 @@ div#footer {
height: 30px;
bottom: 0px;
border-top: 5px solid #333;
+ color: white;
+ font-weight: bold;
+ font-size: 1em;
+}
+
+#navbar {
+ float: right;
+ padding: 0;
+ margin: 0;
+ text-align: right;
+}
+
+#navbar label {
+ color: white;
+ margin-right: 5px;
+ font-weight: bold;
+}
+
+#navbar img {
+ margin-top: 5px;
+ margin-right: 5px;
}
#menubar {
diff --git a/templates/admin/domains.html b/templates/admin/domains.html
index 6b1c29ef0..4f7a01574 100644
--- a/templates/admin/domains.html
+++ b/templates/admin/domains.html
@@ -1,4 +1,4 @@
-{% extends "admin/domains_header.html" %}
+{% extends "admin/listing.html" %}
{% load i18n admin_extras libextras %}
{% block html_head %}
{{ block.super }}
@@ -9,37 +9,3 @@
});
{% endblock %}
-{% block middletitle %}{% trans "Available domains" %}{% endblock %}
-{% block subcontent %}
-
- {% if not domains %}
{% trans "No domain defined." %}
- {% else %}
-
-
- | {% trans "Name" %} |
- {% trans "Created" %} |
- {% trans "Last modified" %} |
- {% trans "Domain aliases" %} |
- {% trans "Mailboxes" %} |
- {% trans "Mailbox aliases" %} |
- {% trans "Quota" %} |
- {% trans "Enabled" %} |
- {% trans "Actions" %} |
-
- {% for dom in domains %}
-
- | {{ dom.name }} |
- {{ dom.dates.creation }} |
- {{ dom.dates.last_modification }} |
- {{ dom.domainalias_set.all|length }} |
- {{ dom.mailbox_set.all|length }} |
- {{ dom.mbalias_counter }} |
- {{ dom.quota }} {% trans "MB" %} |
- {{ dom.enabled|yesno:_("yes,no") }} |
- {% domain_actions user dom.id %} |
-
- {% endfor %}
-
- {% endif %}
-
-{% endblock %}
diff --git a/templates/admin/domaliases.html b/templates/admin/domaliases.html
deleted file mode 100644
index caa280c94..000000000
--- a/templates/admin/domaliases.html
+++ /dev/null
@@ -1,31 +0,0 @@
-{% extends "admin/domains_header.html" %}
-{% load i18n admin_extras libextras %}
-{% block pagetitle %}{% trans "Domain aliases" %}{% endblock %}
-{% block subcontent %}
-
- {% if not domaliases %}
-
{% trans "No domain alias defined." %}
- {% else %}
-
-
- | {% trans "Name" %} |
- {% trans "Targeted domain" %} |
- {% trans "Created" %} |
- {% trans "Last modified" %} |
- {% trans "Enabled" %} |
- {% trans "Actions" %} |
-
- {% for domalias in domaliases %}
-
- | {{ domalias.name }} |
- {{ domalias.target.name }} |
- {{ domalias.dates.creation }} |
- {{ domalias.dates.last_modification }} |
- {{ domalias.enabled|yesno }} |
- {% domalias_actions user domalias.id %} |
-
- {% endfor %}
-
- {% endif %}
-
-{% endblock %}
diff --git a/templates/admin/listing.html b/templates/admin/listing.html
new file mode 100644
index 000000000..f688a097b
--- /dev/null
+++ b/templates/admin/listing.html
@@ -0,0 +1,34 @@
+{% extends "admin/domains_header.html" %}
+{% load i18n %}
+{% block middletitle %}{{ title }}{% endblock %}
+{% block subcontent %}
+
+ {% if not objects %}
{{ emptymsg }}
+ {% else %}
+ {{ table }}
+ {% endif %}
+
+{% endblock %}
+{% block footer %}
+
+ {% if total %}
+
+ {% endif %}
+ {% if objects.has_previous %}
+
+
+
+
+
+
+ {% endif %}
+ {% if objects.has_next %}
+
+
+
+
+
+
+ {% endif %}
+
+{% endblock %}
diff --git a/templates/admin/mailboxes.html b/templates/admin/mailboxes.html
deleted file mode 100644
index f10912a4e..000000000
--- a/templates/admin/mailboxes.html
+++ /dev/null
@@ -1,35 +0,0 @@
-{% extends "admin/domains_header.html" %}
-{% load i18n admin_extras %}
-{% block pagetitle %}{% trans "Available mailboxes" %}{% endblock %}
-{% block subcontent %}
-
- {% if not mailboxes %}
-
{% trans "No mailbox defined." %}
- {% else %}
-
-
- | {% trans "Address" %} |
- {% trans "Name" %} |
- {% trans "Created" %} |
- {% trans "Last modified" %} |
- {% trans "Aliases" %} |
- {% trans "Quota" %} |
- {{ "Enabled"|gender:"f" }} |
- {% trans "Actions" %} |
-
- {% for mb in mailboxes %}
-
- | {{ mb.full_address }} |
- {{ mb.name }} |
- {{ mb.dates.creation }} |
- {{ mb.dates.last_modification }} |
- {{ mb.alias_set.all|length }} |
- {{ mb.quota }} {% trans "MB" %} |
- {{ mb.user.is_active|yesno:_("yes,no") }} |
- {% mailbox_actions user mb %} |
-
- {% endfor %}
-
- {% endif %}
-
-{% endblock %}
diff --git a/templates/admin/mbaliases.html b/templates/admin/mbaliases.html
deleted file mode 100644
index d9b3a3d57..000000000
--- a/templates/admin/mbaliases.html
+++ /dev/null
@@ -1,39 +0,0 @@
-{% extends "admin/domains_header.html" %}
-{% load i18n admin_extras %}
-{% block pagetitle %}{% trans "Mailbox aliases" %}{% endblock %}
-{% block subcontent %}
-
- {% if not aliases %}
-
{% trans "No mailbox alias defined." %}
- {% else %}
-
-
- | {% trans "Address" %} |
- {% trans "Target(s)" %} |
- {% trans "Created" %} |
- {% trans "Last modified" %} |
- {% trans "Enabled" %} |
- {% trans "Actions" %} |
-
- {% for alias in aliases %}
-
- | {{ alias.address }}@{{ alias.domain }} |
-
- {% for mb in alias.mboxes.all %}
- {{ mb.full_address }}
- {% endfor %}
- {{ alias.repr_extmboxes|safe }}
- |
- {{ alias.dates.creation }} |
- {{ alias.dates.last_modification }} |
- {{ alias.enabled|yesno }} |
-
- {% if alias.ui_disabled %}--{% else %}{% mbalias_actions user alias %}{% endif %}
- |
-
- {% endfor %}
-
- {% endif %}
-
-{% endblock %}
diff --git a/templates/common/email_listing.html b/templates/common/email_listing.html
index 2314b20ac..970a55550 100644
--- a/templates/common/email_listing.html
+++ b/templates/common/email_listing.html
@@ -7,26 +7,6 @@
{% block css %}{% endblock %}
-
-