diff --git a/modoboa/core/templatetags/core_tags.py b/modoboa/core/templatetags/core_tags.py index 91238b489..b424c1f9f 100644 --- a/modoboa/core/templatetags/core_tags.py +++ b/modoboa/core/templatetags/core_tags.py @@ -230,18 +230,6 @@ def get_modoboa_logo(): return logo -@register.simple_tag -def extra_head_content(user): - tpl = template.Template( - "{% for sc in static_content %}{{ sc|safe }}{% endfor %}" - ) - return tpl.render( - template.Context({ - 'static_content': events.raiseQueryEvent("GetStaticContent", user) - }) - ) - - @register.simple_tag def load_optionalmenu(user): menu = events.raiseQueryEvent("UserMenuDisplay", "top_menu_middle", user) diff --git a/modoboa/demo/__init__.py b/modoboa/demo/__init__.py index 76f5c05b4..ca8931b96 100755 --- a/modoboa/demo/__init__.py +++ b/modoboa/demo/__init__.py @@ -43,12 +43,13 @@ def password_change(user): @events.observe("GetStaticContent") -def get_static_content(user): - if not user.mailbox_set.count(): +def get_static_content(caller, user): + if caller != 'top' and not user.mailbox_set.count(): return [] - return """""" +"""] diff --git a/modoboa/extensions/admin/__init__.py b/modoboa/extensions/admin/__init__.py index 79c8fad5d..c567fc059 100644 --- a/modoboa/extensions/admin/__init__.py +++ b/modoboa/extensions/admin/__init__.py @@ -15,6 +15,11 @@ admin_events = [ "CreateDomain", "DomainModified", "DeleteDomain", + "ExtraDomainEntries", + "ExtraDomainMenuEntries", + "ExtraDomainFilters", + "GetDomainActions", + "GetDomainModifyLink", "DomainAliasCreated", "DomainAliasDeleted", diff --git a/modoboa/extensions/admin/lib.py b/modoboa/extensions/admin/lib.py index 758371f13..bf142a297 100644 --- a/modoboa/extensions/admin/lib.py +++ b/modoboa/extensions/admin/lib.py @@ -1,13 +1,16 @@ # coding: utf-8 from functools import wraps +from itertools import chain from django.db.models import Q from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.contrib.contenttypes.models import ContentType from modoboa.core.models import User -from modoboa.lib import parameters +from modoboa.lib import parameters, events from modoboa.lib.exceptions import ModoboaException from modoboa.lib.emailutils import split_mailbox -from modoboa.extensions.admin.models import Alias +from modoboa.extensions.admin.models import ( + Domain, Alias +) def needs_mailbox(): @@ -65,8 +68,6 @@ def get_identities(user, searchquery=None, idtfilter=None, grpfilter=None): :param list grpfilter: group names filters :return: a queryset """ - from itertools import chain - accounts = [] if idtfilter is None or not idtfilter or idtfilter == "account": ids = user.objectaccess_set \ @@ -104,3 +105,24 @@ def get_identities(user, searchquery=None, idtfilter=None, grpfilter=None): if idtfilter is not None and idtfilter: aliases = [al for al in aliases if al.type == idtfilter] return chain(accounts, aliases) + + +def get_domains(user, domfilter=None, searchquery=None, **extrafilters): + """Return all the domains the user can access. + + :param ``User`` user: user object + :param str searchquery: filter + :rtype: list + :return: a list of domains and/or relay domains + """ + domains = [] + if domfilter is None or not domfilter or domfilter == 'domain': + domains = Domain.objects.get_for_admin(user) + if searchquery is not None: + q = Q(name__contains=searchquery) + q |= Q(domainalias__name__contains=searchquery) + domains = domains.filter(q).distinct() + extra_domain_entries = events.raiseQueryEvent( + 'ExtraDomainEntries', user, domfilter, searchquery, **extrafilters + ) + return chain(domains, extra_domain_entries) diff --git a/modoboa/extensions/admin/migrations/0037_rename_tables.py b/modoboa/extensions/admin/migrations/0037_rename_tables.py index 077918c22..6b08aabd7 100644 --- a/modoboa/extensions/admin/migrations/0037_rename_tables.py +++ b/modoboa/extensions/admin/migrations/0037_rename_tables.py @@ -75,6 +75,13 @@ class Migration(SchemaMigration): 'use_domain_quota': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.User']"}) }, + u'admin.mailboxoperation': { + 'Meta': {'object_name': 'MailboxOperation'}, + 'argument': ('django.db.models.fields.TextField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['admin.Mailbox']", 'null': 'True', 'blank': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '20'}) + }, 'admin.objectdates': { 'Meta': {'object_name': 'ObjectDates'}, 'creation': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), diff --git a/modoboa/extensions/admin/models/__init__.py b/modoboa/extensions/admin/models/__init__.py index 8edb89898..2a34185d3 100644 --- a/modoboa/extensions/admin/models/__init__.py +++ b/modoboa/extensions/admin/models/__init__.py @@ -1,8 +1,10 @@ +from .base import DatesAware from .domain import Domain from .domain_alias import DomainAlias from .mailbox import Mailbox, Quota, MailboxOperation from .alias import Alias __all__ = [ - 'Domain', 'DomainAlias', 'Mailbox', 'Quota', 'Alias', 'MailboxOperation' + 'Domain', 'DomainAlias', 'Mailbox', 'Quota', 'Alias', + 'MailboxOperation', 'DatesAware' ] diff --git a/modoboa/extensions/admin/models/domain.py b/modoboa/extensions/admin/models/domain.py index c4d7d5a36..d497d8260 100644 --- a/modoboa/extensions/admin/models/domain.py +++ b/modoboa/extensions/admin/models/domain.py @@ -56,6 +56,10 @@ class Domain(DatesAware): def mbalias_count(self): return self.alias_set.count() + @property + def tags(self): + return [{"name": "domain", "label": _("Domain"), "type": "dom"}] + @property def admins(self): """Return the domain administrators of this domain diff --git a/modoboa/extensions/admin/static/admin/js/admin.js b/modoboa/extensions/admin/static/admin/js/admin.js index 0e7c225be..f811d322b 100644 --- a/modoboa/extensions/admin/static/admin/js/admin.js +++ b/modoboa/extensions/admin/static/admin/js/admin.js @@ -1,3 +1,8 @@ +/** + * @module admin + * @desc Utility classes for the admin application + */ + var Admin = function(options) { Listing.call(this, options); }; @@ -12,6 +17,7 @@ Admin.prototype = { Listing.prototype.initialize.call(this, options); this.options = $.extend({}, this.defaults, this.options); this.options.defcallback = $.proxy(this.list_cb, this); + this.tag_handlers = {}; this.navobj = new History(this.options); @@ -37,12 +43,61 @@ Admin.prototype = { list_cb: function(data) { $("#listing").html(data.table); this.update_listing(data); + $("a.filter").click($.proxy(this.filter_by_tag, this)); }, listen: function() { $("#searchform").submit($.proxy(this.do_search, this)); }, + register_tag_handler: function(name, handler) { + this.tag_handlers[name] = handler; + if (this.navobj.getparam(name + "filter") != undefined) { + var text = this.navobj.getparam(name + "filter"); + $("#searchform").parent().after(this.make_tag(text, name)); + } + }, + + generic_tag_handler: function(tag, $link) { + if (this.navobj.getparam(tag + "filter") == undefined && $link.hasClass(tag)) { + var text = $link.attr("name"); + this.navobj.setparam(tag + "filter", text).update(); + $("#searchform").parent().after(this.make_tag(text, tag)); + return true; + } + return false; + }, + + make_tag: function(text, type) { + var $tag = $("", {"name": type, "class" : "btn btn-mini", "html": text}); + var $i = $("", {"class" : "icon-remove"}).prependTo($tag); + + $tag.click($.proxy(this.remove_tag, this)); + return $tag; + }, + + remove_tag: function(e) { + var $tag = $(e.target); + + if ($tag.is("i")) { + $tag = $tag.parent(); + } + e.preventDefault(); + this.navobj.delparam($tag.attr("name") + "filter").update(); + $tag.remove(); + }, + + filter_by_tag: function(e) { + var $link = $(e.target); + e.preventDefault(); + + for (var name in this.tag_handlers) { + if (this.tag_handlers[name].apply(this, [name, $link])) { + break; + } + } + }, + do_search: function(e) { e.preventDefault(); var squery = $("#searchquery").val(); @@ -104,6 +159,11 @@ var Domains = function(options) { }; Domains.prototype = { + initialize: function(options) { + Admin.prototype.initialize.call(this, options); + this.register_tag_handler("dom", this.generic_tag_handler); + }, + list_cb: function(data) { Admin.prototype.list_cb.call(this, data); var deloptions = (data.handle_mailboxes) @@ -120,6 +180,11 @@ Domains.prototype = { checkboxes: deloptions, success_cb: $.proxy(this.reload_listing, this) }); + $("a[name=delrelaydomain]").confirm({ + question: function() { return this.$element.attr('title'); }, + method: "DELETE", + success_cb: $.proxy(this.reload_listing, this) + }); }, change_inputs_state: function(value) { @@ -193,6 +258,17 @@ Domains.prototype = { }); }, this)); $(document).trigger('domform_init'); + }, + + rdomainform_cb: function() { + $(".submit").one('click', $.proxy(function(e) { + simple_ajax_form_post2(e, { + formid: "rdomform", + error_cb: $.proxy(this.rdomainform_cb, this), + reload_on_success: false, + success_cb: $.proxy(this.reload_listing, this) + }); + }, this)); } }; @@ -209,14 +285,8 @@ var Identities = function(options) { Identities.prototype = { initialize: function(options) { Admin.prototype.initialize.call(this, options); - if (this.navobj.getparam("idtfilter") != undefined) { - var text = this.navobj.getparam("idtfilter"); - $("#searchform").parent().after(this.make_tag(text, "idt")); - } - if (this.navobj.getparam("grpfilter") != undefined) { - var text = this.navobj.getparam("grpfilter"); - $("#searchform").parent().after(this.make_tag(text, "grp")); - } + this.register_tag_handler("idt", this.generic_tag_handler); + this.register_tag_handler("grp", this.grp_tag_handler); }, listen: function() { @@ -237,7 +307,6 @@ Identities.prototype = { if (data.handle_mailboxes == "yes") { deloptions = {keepdir: gettext("Do not delete mailbox directory")}; } - $("a.filter").click($.proxy(this.filter_by_tag, this)); $("a[name=delaccount]").confirm({ question: function() { return this.$element.attr('title'); }, @@ -252,46 +321,20 @@ Identities.prototype = { }); }, - make_tag: function(text, type) { - var $tag = $("", {"name": type, "class" : "btn btn-mini", "html": text}); - var $i = $("", {"class" : "icon-remove"}).prependTo($tag); - - $tag.click($.proxy(this.remove_tag, this)); - return $tag; - }, - - remove_tag: function(e) { - var $tag = $(e.target); - - if ($tag.is("i")) { - $tag = $tag.parent(); - } - e.preventDefault(); - this.navobj.delparam($tag.attr("name") + "filter").update(); - $tag.remove(); - }, - - filter_by_tag: function(e) { - var $link = $(e.target); - e.preventDefault(); - - if (this.navobj.getparam("idtfilter") == undefined && $link.hasClass("idt")) { - var text = $link.attr("name"); - this.navobj.setparam("idtfilter", text).update(); - $("#searchform").parent().after(this.make_tag(text, "idt")); - return; - } - if (this.navobj.getparam("grpfilter") == undefined && $link.hasClass("grp")) { + grp_tag_handler: function(tag, $link) { + if (this.navobj.getparam(tag + "filter") == undefined && $link.hasClass(tag)) { var text = $link.attr("name"); this.navobj .setparam("idtfilter", "account") - .setparam("grpfilter", text) + .setparam(tag + "filter", text) .update(); if ($("a[name=idt]").length == 0) { $("#searchform").parent().after(this.make_tag("account", "idt")); } - $("#searchform").parent().after(this.make_tag(text, "grp")); + $("#searchform").parent().after(this.make_tag(text, tag)); + return true; } + return false; }, simpleuser_mode: function() { diff --git a/modoboa/extensions/admin/templates/admin/domains.html b/modoboa/extensions/admin/templates/admin/domains.html index 65163e602..d32690232 100644 --- a/modoboa/extensions/admin/templates/admin/domains.html +++ b/modoboa/extensions/admin/templates/admin/domains.html @@ -7,5 +7,6 @@ $(document).ready(function() { admin = new Domains(); }); +{% extra_static_content "domains" user %} {% endblock %} {% block actions %}{% domains_menu "domains" user %}{% endblock %} diff --git a/modoboa/extensions/admin/templates/admin/domains_table.html b/modoboa/extensions/admin/templates/admin/domains_table.html new file mode 100644 index 000000000..b3f16ba9d --- /dev/null +++ b/modoboa/extensions/admin/templates/admin/domains_table.html @@ -0,0 +1,21 @@ +{% load i18n admin_tags lib_tags %} +
| {% trans "Name" %} | +{% trans "Alias(es)" %} | +{% trans "Tags" %} | +{% trans "Actions" %} | +
|---|---|---|---|
| {% domain_modify_link domain %} | +{% domain_aliases domain %} | +{% render_tags domain.tags %} | +{% domain_actions user domain %} | +