mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-19 05:58:34 +02:00
All listing pages (domains and identities) are now more responsive. No full reload anymore.
see #315
This commit is contained in:
+12
-12
@@ -1,13 +1,13 @@
|
||||
# coding: utf-8
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||
from modoboa.lib.webutils import _render
|
||||
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, tplname="admin/listing.html",
|
||||
**kwargs):
|
||||
def render_listing(request, objtype, **kwargs):
|
||||
"""Common function to render a listing
|
||||
|
||||
All listing pages available into the admin application use the
|
||||
@@ -15,7 +15,6 @@ def render_listing(request, objtype, tplname="admin/listing.html",
|
||||
|
||||
:param request: a ``Request`` object
|
||||
:param objtype: the object type's name (lowercase)
|
||||
:param tplname: the template used to render the HTML
|
||||
"""
|
||||
tblclass = "%sTable" % objtype.capitalize()
|
||||
if not globals().has_key(tblclass):
|
||||
@@ -26,18 +25,19 @@ def render_listing(request, objtype, tplname="admin/listing.html",
|
||||
kwargs["domid"] = request.GET["domid"]
|
||||
else:
|
||||
kwargs["domid"] = ""
|
||||
kwargs["selection"] = objtype
|
||||
paginator = Paginator(kwargs["objects"],
|
||||
int(parameters.get_admin("ITEMS_PER_PAGE")))
|
||||
try:
|
||||
page = request.GET.get("page", "1")
|
||||
pagenum = request.GET.get("page", "1")
|
||||
except ValueError:
|
||||
page = 1
|
||||
pagenum = 1
|
||||
try:
|
||||
kwargs["page"] = paginator.page(page)
|
||||
page = paginator.page(pagenum)
|
||||
except (EmptyPage, PageNotAnInteger):
|
||||
kwargs["page"] = paginator.page(paginator.num_pages)
|
||||
kwargs["table"] = tblclass(request, kwargs["page"].object_list)
|
||||
kwargs["selection"] = objtype
|
||||
page = paginator.page(paginator.num_pages)
|
||||
|
||||
return _render(request, tplname, kwargs)
|
||||
return ajax_simple_response({
|
||||
"table" : tblclass(request, page.object_list).render(),
|
||||
"page" : page.number,
|
||||
"paginbar" : pagination_bar(page)
|
||||
})
|
||||
|
||||
@@ -1,147 +1,281 @@
|
||||
function domainform_cb() {
|
||||
$('input:text:visible:first').focus();
|
||||
$("#id_aliases").dynamic_input();
|
||||
$(".submit").one('click', function(e) {
|
||||
simple_ajax_form_post(e, {
|
||||
formid: "domform",
|
||||
error_cb: domainform_cb
|
||||
});
|
||||
});
|
||||
$("a[name=removeperm]").click(function(e) {
|
||||
var $tr = $(this).parent().parent();
|
||||
simple_ajax_request.apply(this, [e, {
|
||||
ok_cb: function(resp) {
|
||||
$tr.remove();
|
||||
if (!$("#domadmins").children("tr").length) {
|
||||
$("#admins").html('<div class="alert alert-info">'
|
||||
+ gettext("No domain administrator defined") + "</div>");
|
||||
var Admin = function(options) {
|
||||
this.initialize(options);
|
||||
};
|
||||
|
||||
Admin.prototype = {
|
||||
constructor: Admin,
|
||||
|
||||
defaults: {
|
||||
deflocation: "list/",
|
||||
squery: null
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
this.options = $.extend({}, this.defaults, options);
|
||||
this.options.defcallback = $.proxy(this.list_cb, this);
|
||||
|
||||
this.navobj = new History(this.options);
|
||||
|
||||
$("#searchquery").focus(function() {
|
||||
$(this).attr("value", "");
|
||||
}).blur($.proxy(function(e) {
|
||||
var $this = $(e.target);
|
||||
if ($this.attr("value") == "") {
|
||||
if (this.options.squery && this.options.squery == "") {
|
||||
$this.attr("value", this.options.squery);
|
||||
} else {
|
||||
$this.attr("value", gettext("Search"));
|
||||
}
|
||||
}
|
||||
}]);
|
||||
});
|
||||
$(document).trigger('domform_init');
|
||||
}
|
||||
}, this));
|
||||
|
||||
function simpleuser_mode() {
|
||||
$("#id_username").autocompleter({
|
||||
from_character: "@",
|
||||
choices: get_domains_list
|
||||
});
|
||||
$("#id_email").addClass("disabled")
|
||||
.attr("readonly", "")
|
||||
.autocompleter("unbind");
|
||||
}
|
||||
this.listen();
|
||||
},
|
||||
|
||||
function normal_mode() {
|
||||
$("#id_email").removeClass("disabled")
|
||||
.attr("readonly", null)
|
||||
.autocompleter("listen");
|
||||
}
|
||||
|
||||
function generalform_init() {
|
||||
$("#id_role").change(function(e) {
|
||||
if ($(this).attr("value") == "SimpleUsers") {
|
||||
simpleuser_mode();
|
||||
} else {
|
||||
normal_mode();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function mailform_init() {
|
||||
$("#id_aliases").autocompleter({
|
||||
from_character: "@",
|
||||
choices: get_domains_list
|
||||
}).dynamic_input();
|
||||
$("#id_email").autocompleter({
|
||||
from_character: "@",
|
||||
choices: get_domains_list
|
||||
});
|
||||
if ($("#id_role").length) {
|
||||
$("#id_role").trigger("change");
|
||||
} else {
|
||||
simpleuser_mode();
|
||||
}
|
||||
$("#id_domains")
|
||||
.autocompleter({
|
||||
choices: get_domains_list
|
||||
})
|
||||
.dynamic_input();
|
||||
|
||||
}
|
||||
|
||||
function accountform_init() {
|
||||
generalform_init();
|
||||
mailform_init();
|
||||
}
|
||||
|
||||
function mailform_prefill() {
|
||||
if (!$("#id_role").length || $("#id_role").attr("value") == "SimpleUsers") {
|
||||
$("#id_email").attr("value", $("#id_username").attr("value"));
|
||||
}
|
||||
}
|
||||
|
||||
function newaccount_cb() {
|
||||
accountform_init();
|
||||
$("#wizard").cwizard({
|
||||
formid: "newaccount_form",
|
||||
transition_callbacks: {
|
||||
1: mailform_prefill
|
||||
},
|
||||
error_callbacks: {
|
||||
1: generalform_init,
|
||||
2: mailform_init
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function editaccount_cb() {
|
||||
accountform_init();
|
||||
$('.submit').one('click', function(e) {
|
||||
simple_ajax_form_post(e, {
|
||||
formid: "accountform",
|
||||
error_cb: editaccount_cb
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function aliasform_cb() {
|
||||
$("#id_email").autocompleter({
|
||||
from_character: "@",
|
||||
choices: get_domains_list
|
||||
});
|
||||
$("#id_recipients").dynamic_input();
|
||||
$("#id_int_recipient").autocompleter({
|
||||
choices: get_mboxes_list
|
||||
});
|
||||
$(".submit").one('click', function(e) {
|
||||
simple_ajax_form_post(e, {
|
||||
formid: "aliasform",
|
||||
error_cb: aliasform_cb
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function importform_cb() {
|
||||
$(".submit").one('click', function(e) {
|
||||
if ($("#id_sourcefile").attr("value") == "") {
|
||||
list_cb: function(data) {
|
||||
$("#listing").html(data.table);
|
||||
$("#bottom-bar-right").html(data.paginbar);
|
||||
$("#pagination_bar").find(".disabled a").click(function(e) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
});
|
||||
if (data.page != this.navobj.getparam("page")) {
|
||||
this.navobj.setparam("page", data.page).update(false, false);
|
||||
}
|
||||
$("#import_status").css("display", "block");
|
||||
$("#import_result").html("").removeClass("alert alert-error");
|
||||
$("#importform").submit();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
function importdone(status, msg) {
|
||||
$("#import_status").css("display", "none");
|
||||
if (status == "ok") {
|
||||
$("#modalbox").modal('hide');
|
||||
window.location.reload();
|
||||
} else {
|
||||
$("#import_result").addClass("alert alert-error");
|
||||
$("#import_result").html(msg);
|
||||
importform_cb();
|
||||
listen: function() {
|
||||
$(document).on("click", "#bottom-bar-right a",
|
||||
$.proxy(this.getpage_loader, this));
|
||||
$("#searchform").submit($.proxy(this.do_search, this));
|
||||
},
|
||||
|
||||
do_search: function(e) {
|
||||
e.preventDefault();
|
||||
this.navobj.setparam("searchquery", $("#searchquery").attr("value")).update();
|
||||
},
|
||||
|
||||
getpage_loader: function(e) {
|
||||
var $link = $(e.target).parent();
|
||||
e.preventDefault();
|
||||
this.navobj.updateparams($link.attr("href")).update();
|
||||
},
|
||||
|
||||
importform_cb: function() {
|
||||
$(".submit").one('click', function(e) {
|
||||
e.preventDefault();
|
||||
if ($("#id_sourcefile").attr("value") == "") {
|
||||
return;
|
||||
}
|
||||
$("#import_status").css("display", "block");
|
||||
$("#import_result").html("").removeClass("alert alert-error");
|
||||
$("#importform").submit();
|
||||
});
|
||||
},
|
||||
|
||||
importdone: function(status, msg) {
|
||||
$("#import_status").css("display", "none");
|
||||
if (status == "ok") {
|
||||
$("#modalbox").modal('hide');
|
||||
this.reload_listing({respmsg: msg});
|
||||
} else {
|
||||
$("#import_result").addClass("alert alert-error");
|
||||
$("#import_result").html(msg);
|
||||
this.importform_cb();
|
||||
}
|
||||
},
|
||||
|
||||
reload_listing: function(data) {
|
||||
this.navobj.update(true);
|
||||
if (data.respmsg) {
|
||||
$("body").notify("success", data.respmsg, 2000);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Domains
|
||||
*/
|
||||
var Domains = function(options) {
|
||||
Admin.call(this, options);
|
||||
};
|
||||
|
||||
Domains.prototype = {
|
||||
list_cb: function(data) {
|
||||
Admin.prototype.list_cb.call(this, data);
|
||||
|
||||
$("a[name=deldomain]").confirm({
|
||||
question: gettext("Delete this domain?"),
|
||||
checkboxes: {keepdir: gettext("Do not delete domain directory")},
|
||||
success_cb: $.proxy(this.reload_listing, this)
|
||||
});
|
||||
},
|
||||
|
||||
domainform_cb: function() {
|
||||
$('input:text:visible:first').focus();
|
||||
$("#id_aliases").dynamic_input();
|
||||
$(".submit").one('click', $.proxy(function(e) {
|
||||
simple_ajax_form_post(e, {
|
||||
formid: "domform",
|
||||
error_cb: this.domainform_cb,
|
||||
reload_on_success: false,
|
||||
success_cb: $.proxy(this.reload_listing, this)
|
||||
});
|
||||
}, this));
|
||||
$("a[name=removeperm]").click(function(e) {
|
||||
var $tr = $(this).parent().parent();
|
||||
simple_ajax_request.apply(this, [e, {
|
||||
ok_cb: function(resp) {
|
||||
$tr.remove();
|
||||
if (!$("#domadmins").children("tr").length) {
|
||||
$("#admins").html('<div class="alert alert-info">'
|
||||
+ gettext("No domain administrator defined") + "</div>");
|
||||
}
|
||||
}
|
||||
}]);
|
||||
});
|
||||
$(document).trigger('domform_init');
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Domains.prototype = $.extend({}, Admin.prototype, Domains.prototype);
|
||||
|
||||
/*
|
||||
* Identities
|
||||
*/
|
||||
var Identities = function(options) {
|
||||
Admin.call(this, options);
|
||||
};
|
||||
|
||||
Identities.prototype = {
|
||||
list_cb: function(data) {
|
||||
Admin.prototype.list_cb.call(this, data);
|
||||
|
||||
$("a[name=delaccount]").confirm({
|
||||
question: gettext("Delete this account?"),
|
||||
checkboxes: {keepdir: gettext("Do not delete mailbox directory")},
|
||||
success_cb: $.proxy(this.reload_listing, this)
|
||||
});
|
||||
$("a[name=deldlist]").confirm({
|
||||
question: gettext("Delete this list?"),
|
||||
success_cb: $.proxy(this.reload_listing, this)
|
||||
});
|
||||
$("a[name=delforward]").confirm({
|
||||
question: gettext("Delete this forward?"),
|
||||
success_cb: $.proxy(this.reload_listing, this)
|
||||
});
|
||||
$("a[name=delalias]").confirm({
|
||||
question: gettext("Delete this alias?"),
|
||||
success_cb: $.proxy(this.reload_listing, this)
|
||||
});
|
||||
},
|
||||
|
||||
simpleuser_mode: function() {
|
||||
$("#id_username").autocompleter({
|
||||
from_character: "@",
|
||||
choices: get_domains_list
|
||||
});
|
||||
$("#id_email").addClass("disabled")
|
||||
.attr("readonly", "")
|
||||
.autocompleter("unbind");
|
||||
},
|
||||
|
||||
normal_mode: function() {
|
||||
$("#id_email").removeClass("disabled")
|
||||
.attr("readonly", null)
|
||||
.autocompleter("listen");
|
||||
},
|
||||
|
||||
generalform_init: function() {
|
||||
$("#id_role").change($.proxy(function(e) {
|
||||
var $this = $(e.target);
|
||||
if ($this.attr("value") == "SimpleUsers") {
|
||||
this.simpleuser_mode();
|
||||
} else {
|
||||
this.normal_mode();
|
||||
}
|
||||
}, this));
|
||||
},
|
||||
|
||||
mailform_init: function() {
|
||||
$("#id_aliases").autocompleter({
|
||||
from_character: "@",
|
||||
choices: get_domains_list
|
||||
}).dynamic_input();
|
||||
$("#id_email").autocompleter({
|
||||
from_character: "@",
|
||||
choices: get_domains_list
|
||||
});
|
||||
if ($("#id_role").length) {
|
||||
$("#id_role").trigger("change");
|
||||
} else {
|
||||
this.simpleuser_mode();
|
||||
}
|
||||
$("#id_domains")
|
||||
.autocompleter({
|
||||
choices: get_domains_list
|
||||
})
|
||||
.dynamic_input();
|
||||
|
||||
},
|
||||
|
||||
accountform_init: function() {
|
||||
this.generalform_init();
|
||||
this.mailform_init();
|
||||
},
|
||||
|
||||
mailform_prefill: function() {
|
||||
if (!$("#id_role").length || $("#id_role").attr("value") == "SimpleUsers") {
|
||||
$("#id_email").attr("value", $("#id_username").attr("value"));
|
||||
}
|
||||
},
|
||||
|
||||
newaccount_cb: function() {
|
||||
this.accountform_init();
|
||||
$("#wizard").cwizard({
|
||||
formid: "newaccount_form",
|
||||
transition_callbacks: {
|
||||
1: this.mailform_prefill
|
||||
},
|
||||
error_callbacks: {
|
||||
1: this.generalform_init,
|
||||
2: this.mailform_init
|
||||
},
|
||||
success_callback: $.proxy(this.reload_listing, this)
|
||||
});
|
||||
},
|
||||
|
||||
editaccount_cb: function() {
|
||||
this.accountform_init();
|
||||
$('.submit').one('click', $.proxy(function(e) {
|
||||
simple_ajax_form_post(e, {
|
||||
formid: "accountform",
|
||||
error_cb: this.editaccount_cb,
|
||||
reload_on_success: false,
|
||||
success_cb: $.proxy(this.reload_listing, this)
|
||||
});
|
||||
}, this));
|
||||
},
|
||||
|
||||
aliasform_cb: function() {
|
||||
$("#id_email").autocompleter({
|
||||
from_character: "@",
|
||||
choices: get_domains_list
|
||||
});
|
||||
$("#id_recipients").dynamic_input();
|
||||
$("#id_int_recipient").autocompleter({
|
||||
choices: get_mboxes_list
|
||||
});
|
||||
$(".submit").one('click', $.proxy(function(e) {
|
||||
simple_ajax_form_post(e, {
|
||||
formid: "aliasform",
|
||||
error_cb: this.aliasform_cb,
|
||||
reload_on_success: false,
|
||||
success_cb: $.proxy(this.reload_listing, this)
|
||||
});
|
||||
}, this));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Identities.prototype = $.extend({}, Admin.prototype, Identities.prototype);
|
||||
|
||||
@@ -11,7 +11,7 @@ class DomainsTable(tables.Table):
|
||||
name = tables.LinkColumn(
|
||||
"name", label=ugettext_lazy("Name"),
|
||||
urlpattern="modoboa.admin.views.editdomain",
|
||||
title=_("Edit domain"), modal=True, modalcb="domainform_cb"
|
||||
title=_("Edit domain"), modal=True, modalcb="admin.domainform_cb"
|
||||
)
|
||||
domaliases = tables.Column("domainalias_set",
|
||||
label=ugettext_lazy("Alias(es)"), safe=True)
|
||||
@@ -55,7 +55,7 @@ class IdentitiesTable(tables.Table):
|
||||
modal=True,
|
||||
urlpattern={"User" : "modoboa.admin.views.editaccount",
|
||||
"Alias" : "modoboa.admin.views.editalias_dispatcher"},
|
||||
modalcb={"User" : "editaccount_cb", "Alias" : "aliasform_cb"}
|
||||
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"),
|
||||
|
||||
@@ -3,27 +3,11 @@
|
||||
{% block html_head %}
|
||||
{{ block.super }}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$("a[name=deldomain]").confirm({
|
||||
question: gettext("Delete this domain?"),
|
||||
checkboxes: {keepdir: gettext("Do not delete domain directory")}
|
||||
});
|
||||
$("#searchquery").focus(function() {
|
||||
$(this).attr("value", "");
|
||||
}).blur(function() {
|
||||
var $this = $(this);
|
||||
if ($this.attr("value") == "") {
|
||||
$this.attr("value", gettext("Search"));
|
||||
}
|
||||
});
|
||||
$(document).ready(function() {
|
||||
admin = new Domains({
|
||||
squery: "{{ squery }}"
|
||||
});
|
||||
</script>
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block leftcol %}<div class="well sidebar-nav">
|
||||
<li class="nav-header">
|
||||
{% trans "Filter" %}
|
||||
</li>{% include "admin/searchform.html" %}
|
||||
<li class="nav-header">
|
||||
{% trans "Actions" %}
|
||||
</li>{% domains_menu "domains" user %}
|
||||
</div>{{ block.super }}{% endblock %}
|
||||
{% block actions %}{% domains_menu "domains" user %}{% endblock %}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{% extends "twocols.html" %}
|
||||
{% block html_head %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/admin.css" />
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}js/history.js"></script>
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/admin.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -24,30 +24,10 @@ function get_mboxes_list(container) {
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$("a[name=delaccount]").confirm({
|
||||
question: gettext("Delete this account?"),
|
||||
checkboxes: {keepdir: gettext("Do not delete mailbox directory")}
|
||||
});
|
||||
$("a[name=deldlist]").confirm({
|
||||
question: gettext("Delete this list?")
|
||||
});
|
||||
$("a[name=delforward]").confirm({
|
||||
question: gettext("Delete this forward?")
|
||||
});
|
||||
$("a[name=delalias]").confirm({
|
||||
question: gettext("Delete this alias?")
|
||||
});
|
||||
$("#pagination_bar").find(".disabled").click(function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
admin = new Identities({
|
||||
squery: "{{ squery }}"
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block leftcol %}<div class="well sidebar-nav">
|
||||
<li class="nav-header">
|
||||
{% trans "Filter" %}
|
||||
</li>{% include "admin/searchform.html" %}
|
||||
<li class="nav-header">
|
||||
{% trans "Actions" %}
|
||||
</li>{% identities_menu user %}
|
||||
</div>{{ block.super }}{% endblock %}
|
||||
{% block actions %}{% identities_menu user %}{% endblock %}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<head profile="http://www.w3.org/2005/10/profile">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<script type="text/javascript">
|
||||
parent.importdone("{{ status }}", "{{ msg|escapejs }}");
|
||||
parent.admin.importdone("{{ status }}", "{{ msg|escapejs }}");
|
||||
</script>
|
||||
</head>
|
||||
<body></body>
|
||||
|
||||
@@ -3,20 +3,18 @@
|
||||
{{ block.super }}
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}js/dynamic_input.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$("#searchquery").focus(function() {
|
||||
$(this).attr("value", "");
|
||||
}).blur(function() {
|
||||
var $this = $(this);
|
||||
if ($this.attr("value") == "") {
|
||||
$this.attr("value", {% if squery %}"{{ squery }}"{% else %}"{% trans 'Search' %}"{% endif %});
|
||||
}
|
||||
});
|
||||
});
|
||||
var admin;
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block leftcol %}{% get_extra_admin_content user "leftcol" selection %}{% endblock %}
|
||||
{% block apparea %}
|
||||
{{ table|safe }}
|
||||
{% block leftcol %}<div class="well sidebar-nav">
|
||||
<ul class="nav nav-list">
|
||||
<li class="nav-header">{% trans "Filter" %}</li>
|
||||
<li>{% include "admin/searchform.html" %}</li>
|
||||
<li class="nav-header">{% trans "Actions" %}</li>
|
||||
{% block actions %}{% endblock %}
|
||||
{% get_extra_admin_content user "leftcol" selection %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block footerright %}{% pagination_bar page %}{% endblock %}
|
||||
{% block apparea %}<div id="listing"></div>{% endblock %}
|
||||
{% block footerright %}{% endblock %}
|
||||
|
||||
@@ -70,19 +70,18 @@ def domains_menu(selection, user):
|
||||
"label" : _("Add domain"),
|
||||
"img" : "icon-plus",
|
||||
"modal" : True,
|
||||
"modalcb" : "domainform_cb",
|
||||
"modalcb" : "admin.domainform_cb",
|
||||
"url" : reverse("modoboa.admin.views.newdomain")},
|
||||
{"name" : "import",
|
||||
"label" : _("Import"),
|
||||
"img" : "icon-folder-open",
|
||||
"url" : reverse(admin.views.import_domains),
|
||||
"modal" : True,
|
||||
"modalcb" : "importform_cb"}
|
||||
"modalcb" : "admin.importform_cb"}
|
||||
]
|
||||
|
||||
return render_to_string('common/menu.html', {
|
||||
return render_to_string('common/menulist.html', {
|
||||
"entries" : entries,
|
||||
"css" : "nav nav-list",
|
||||
"selection" : selection,
|
||||
"user" : user
|
||||
})
|
||||
@@ -94,37 +93,36 @@ def identities_menu(user):
|
||||
"label" : _("Add account"),
|
||||
"img" : "icon-plus",
|
||||
"modal" : True,
|
||||
"modalcb" : "newaccount_cb",
|
||||
"modalcb" : "admin.newaccount_cb",
|
||||
"url" : reverse(admin.views.newaccount)},
|
||||
{"name" : "newalias",
|
||||
"label" : _("Add alias"),
|
||||
"img" : "icon-plus",
|
||||
"modal" : True,
|
||||
"modalcb" : "aliasform_cb",
|
||||
"modalcb" : "admin.aliasform_cb",
|
||||
"url" : reverse(admin.views.newalias)},
|
||||
{"name" : "newforward",
|
||||
"label" : _("Add forward"),
|
||||
"img" : "icon-plus",
|
||||
"modal" : True,
|
||||
"modalcb" : "aliasform_cb",
|
||||
"modalcb" : "admin.aliasform_cb",
|
||||
"url" : reverse(admin.views.newforward)},
|
||||
{"name" : "newdlist",
|
||||
"label" : _("Add distribution list"),
|
||||
"img" : "icon-plus",
|
||||
"modal" : True,
|
||||
"modalcb" : "aliasform_cb",
|
||||
"modalcb" : "admin.aliasform_cb",
|
||||
"url" : reverse(admin.views.newdlist)},
|
||||
{"name" : "import",
|
||||
"label" : _("Import"),
|
||||
"img" : "icon-folder-open",
|
||||
"url" : reverse(admin.views.import_identities),
|
||||
"modal" : True,
|
||||
"modalcb" : "importform_cb"}
|
||||
"modalcb" : "admin.importform_cb"}
|
||||
]
|
||||
|
||||
return render_to_string('common/menu.html', {
|
||||
return render_to_string('common/menulist.html', {
|
||||
"entries" : entries,
|
||||
"css" : "nav nav-list",
|
||||
"user" : user
|
||||
})
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@ urlpatterns = patterns(
|
||||
'modoboa.admin.views',
|
||||
url(r'^$', 'domains', name="index"),
|
||||
url(r'^domains/$', 'domains', name="domains"),
|
||||
(r'^domains/list/$', 'domains_list'),
|
||||
(r'^domains/list/$', '_domains'),
|
||||
(r'^domains/flatlist/$', 'domains_list'),
|
||||
(r'^domains/new/', 'newdomain'),
|
||||
(r'^domains/(?P<dom_id>\d+)/edit/$', 'editdomain'),
|
||||
(r'^domains/delete/$', 'deldomain'),
|
||||
@@ -19,6 +20,7 @@ urlpatterns = patterns(
|
||||
(r'^permissions/remove/$', 'remove_permission'),
|
||||
|
||||
(r'^identities/$', 'identities'),
|
||||
(r'^identities/list/$', '_identities'),
|
||||
(r'^identities/import/$', 'import_identities'),
|
||||
|
||||
(r'^accounts/list/$', 'accounts_list'),
|
||||
|
||||
+40
-36
@@ -5,7 +5,7 @@ from django.core.urlresolvers import reverse
|
||||
from django.contrib.auth.decorators \
|
||||
import login_required, permission_required, user_passes_test
|
||||
from django.db.models import Q
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import render
|
||||
from django.db import transaction, IntegrityError
|
||||
|
||||
from lib import render_listing
|
||||
@@ -21,7 +21,7 @@ from modoboa.lib.models import Parameter
|
||||
from modoboa.lib.permissions import *
|
||||
|
||||
@login_required
|
||||
def domains(request):
|
||||
def _domains(request):
|
||||
if not request.user.has_perm("admin.view_domains"):
|
||||
if request.user.has_perm("admin.view_mailboxes"):
|
||||
return HttpResponseRedirect(reverse(identities))
|
||||
@@ -34,8 +34,13 @@ def domains(request):
|
||||
q = Q(name__contains=squery)
|
||||
q |= Q(domainalias__name__contains=squery)
|
||||
domains = domains.filter(q).distinct()
|
||||
return render_listing(request, "domains", "admin/domains.html",
|
||||
objects=domains, squery=squery)
|
||||
return render_listing(request, "domains", objects=domains, squery=squery)
|
||||
|
||||
@login_required
|
||||
def domains(request, tplname="admin/domains.html"):
|
||||
return render(request, tplname, {
|
||||
"selection" : "domains"
|
||||
})
|
||||
|
||||
@login_required
|
||||
@permission_required("auth.add_user")
|
||||
@@ -60,8 +65,7 @@ def _validate_domain(request, form, successmsg, commonctx, tplname,
|
||||
else:
|
||||
if callback is not None:
|
||||
callback(request.user, domain)
|
||||
messages.info(request, successmsg, fail_silently=True)
|
||||
return ajax_response(request, url=reverse("modoboa.admin.views.domains"))
|
||||
return ajax_simple_response({"status" : "ok", "respmsg" : successmsg})
|
||||
|
||||
commonctx[tpl_form_name] = form
|
||||
commonctx["error"] = error
|
||||
@@ -87,7 +91,7 @@ def newdomain(request, tplname="admin/newdomainform.html"):
|
||||
tplname, callback=newdomain_cb)
|
||||
form = DomainFormGeneral()
|
||||
commonctx["form"] = form
|
||||
return _render(request, tplname, commonctx)
|
||||
return render(request, tplname, commonctx)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.view_domains")
|
||||
@@ -123,7 +127,7 @@ def editdomain(request, dom_id, tplname="admin/editdomainform.html"):
|
||||
|
||||
commonctx["tabs"] = DomainForm(request.user, instances=instances)
|
||||
commonctx["domadmins"] = domadmins
|
||||
return _render(request, tplname, commonctx)
|
||||
return render(request, tplname, commonctx)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.delete_domain")
|
||||
@@ -145,8 +149,7 @@ def deldomain(request):
|
||||
dom.delete(keepdir=keepdir)
|
||||
|
||||
msg = ungettext("Domain deleted", "Domains deleted", len(selection))
|
||||
messages.info(request, msg, fail_silently=True)
|
||||
return ajax_response(request)
|
||||
return ajax_simple_response({"status" : "ok", "respmsg" : msg})
|
||||
|
||||
def _validate_alias(request, form, successmsg, tplname, commonctx, callback=None):
|
||||
"""Alias validation
|
||||
@@ -163,9 +166,7 @@ def _validate_alias(request, form, successmsg, tplname, commonctx, callback=None
|
||||
|
||||
if callback:
|
||||
callback(request.user, alias)
|
||||
|
||||
messages.info(request, successmsg)
|
||||
return ajax_response(request, url=reverse("modoboa.admin.views.identities"))
|
||||
return ajax_simple_response({"status" : "ok", "respmsg" : successmsg})
|
||||
|
||||
if request.POST.has_key("targets"):
|
||||
targets = request.POST.getlist("targets")
|
||||
@@ -191,7 +192,7 @@ def _new_alias(request, tplname, formclass, ctx, successmsg):
|
||||
|
||||
form = formclass(request.user)
|
||||
ctx["form"] = form
|
||||
return _render(request, tplname, ctx)
|
||||
return render(request, tplname, ctx)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.add_alias")
|
||||
@@ -234,7 +235,7 @@ def _edit_alias(request, alias, tplname, formclass, ctx, successmsg):
|
||||
|
||||
form = formclass(request.user, instance=alias)
|
||||
ctx["form"] = form
|
||||
return _render(request, tplname, ctx)
|
||||
return render(request, tplname, ctx)
|
||||
|
||||
def editalias(request, alias, ctx):
|
||||
return _edit_alias(request, alias, "common/generic_modal_form.html",
|
||||
@@ -268,8 +269,7 @@ def _del_alias(request, msg, msgs):
|
||||
alias.delete()
|
||||
|
||||
msg = ungettext(msg, msgs, len(selection))
|
||||
messages.info(request, msg)
|
||||
return ajax_response(request)
|
||||
return ajax_simple_response({"status" : "ok", "respmsg" : msg})
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.delete_alias")
|
||||
@@ -291,7 +291,7 @@ def delforward(request):
|
||||
|
||||
@login_required
|
||||
@user_passes_test(lambda u: u.has_perm("auth.add_user") or u.has_perm("admin.add_alias"))
|
||||
def identities(request, tplname='admin/identities.html'):
|
||||
def _identities(request):
|
||||
idents_list = request.user.get_identities()
|
||||
squery = request.GET.get("searchquery", None)
|
||||
if squery:
|
||||
@@ -314,8 +314,15 @@ def identities(request, tplname='admin/identities.html'):
|
||||
if oa.content_object:
|
||||
objects.append(oa.content_object)
|
||||
objects = sorted(objects, key=lambda o: o.identity)
|
||||
return render_listing(request, "identities", tplname,
|
||||
objects=objects, squery=squery)
|
||||
return render_listing(request, "identities", objects=objects, squery=squery)
|
||||
|
||||
@login_required
|
||||
@user_passes_test(lambda u: u.has_perm("auth.add_user") or u.has_perm("admin.add_alias"))
|
||||
def identities(request, tplname="admin/identities.html"):
|
||||
return render(request, tplname, {
|
||||
"selection" : "identities",
|
||||
"deflocation" : "list/"
|
||||
})
|
||||
|
||||
@login_required
|
||||
@permission_required("auth.add_user")
|
||||
@@ -376,8 +383,7 @@ def newaccount(request, tplname='admin/newaccount.html'):
|
||||
status="ok", title=cwizard.get_title(data + 1), stepid=data
|
||||
))
|
||||
if retcode == 2:
|
||||
messages.info(request, _("Account created"))
|
||||
return ajax_simple_response(dict(status="ok"))
|
||||
return ajax_simple_response(dict(status="ok", respmsg=_("Account created")))
|
||||
|
||||
from modoboa.lib.templatetags.libextras import render_form
|
||||
return ajax_simple_response(dict(
|
||||
@@ -387,7 +393,7 @@ def newaccount(request, tplname='admin/newaccount.html'):
|
||||
cwizard.create_forms()
|
||||
ctx.update(steps=cwizard.steps)
|
||||
ctx.update(subtitle="1. %s" % cwizard.steps[0]['title'])
|
||||
return _render(request, tplname, ctx)
|
||||
return render(request, tplname, ctx)
|
||||
|
||||
@login_required
|
||||
@permission_required("auth.change_user")
|
||||
@@ -421,15 +427,14 @@ def editaccount(request, accountid, tplname="common/tabforms.html"):
|
||||
if form.is_valid(optional_only=True):
|
||||
events.raiseEvent("AccountModified", account, form.account)
|
||||
form.save()
|
||||
messages.info(request, _("Account updated"))
|
||||
return ajax_simple_response(dict(status="ok"))
|
||||
return ajax_simple_response(dict(status="ok", respmsg=_("Account updated")))
|
||||
transaction.rollback()
|
||||
|
||||
ctx["tabs"] = form
|
||||
return ajax_response(request, status="ko", template=tplname, **ctx)
|
||||
|
||||
ctx["tabs"] = AccountForm(request.user, instances=instances)
|
||||
return _render(request, tplname, ctx)
|
||||
return render(request, tplname, ctx)
|
||||
|
||||
@login_required
|
||||
@permission_required("auth.delete_user")
|
||||
@@ -442,8 +447,7 @@ def delaccount(request):
|
||||
account.delete(request.user, keepdir)
|
||||
|
||||
msg = ungettext("Account deleted", "Accounts deleted", len(selection))
|
||||
messages.info(request, msg, fail_silently=True)
|
||||
return ajax_response(request)
|
||||
return ajax_simple_response({"status" : "ok", "respmsg" : msg})
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.add_domain")
|
||||
@@ -482,7 +486,7 @@ def viewparameters(request, tplname='admin/parameters.html'):
|
||||
tmp["params"] += [newdef]
|
||||
gparams += [tmp]
|
||||
|
||||
return _render(request, tplname, {
|
||||
return render(request, tplname, {
|
||||
"selection" : "settings",
|
||||
"left_selection" : "parameters",
|
||||
"gparams" : gparams
|
||||
@@ -516,7 +520,7 @@ def viewextensions(request, tplname='admin/extensions.html'):
|
||||
ext["selection"] = False
|
||||
|
||||
tbl = ExtensionsTable(request, exts)
|
||||
return _render(request, tplname, {
|
||||
return render(request, tplname, {
|
||||
"selection" : "settings",
|
||||
"left_selection" : "extensions",
|
||||
"extensions" : tbl
|
||||
@@ -599,14 +603,14 @@ def importdata(request):
|
||||
continue
|
||||
fct(request.user, row)
|
||||
cpt += 1
|
||||
messages.info(request, _("%d objects imported successfully" % cpt))
|
||||
return _render(request, "admin/import_done.html", {
|
||||
"status" : "ok", "msg" : ""
|
||||
msg = _("%d objects imported successfully" % cpt)
|
||||
return render(request, "admin/import_done.html", {
|
||||
"status" : "ok", "msg" : msg
|
||||
})
|
||||
except (IntegrityError, ModoboaException), e:
|
||||
error = str(e)
|
||||
|
||||
return _render(request, "admin/import_done.html", {
|
||||
return render(request, "admin/import_done.html", {
|
||||
"status" : "ko", "msg" : error
|
||||
})
|
||||
|
||||
@@ -635,7 +639,7 @@ You can use a different character as separator.
|
||||
form=ImportDataForm(),
|
||||
helptext=helptext
|
||||
)
|
||||
return _render(request, "admin/importform.html", ctx)
|
||||
return render(request, "admin/importform.html", ctx)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.add_domain")
|
||||
@@ -661,4 +665,4 @@ You can use a different character as separator.
|
||||
helptext=helptext,
|
||||
form=ImportDataForm()
|
||||
)
|
||||
return _render(request, "admin/importform.html", ctx)
|
||||
return render(request, "admin/importform.html", ctx)
|
||||
|
||||
@@ -67,9 +67,9 @@
|
||||
position: "absolute",
|
||||
top: coords.top + this.$element.outerHeight(),
|
||||
left: coords.left,
|
||||
width: this.$element.outerWidth()
|
||||
width: this.$element.outerWidth(),
|
||||
'z-index': 1051
|
||||
});
|
||||
|
||||
if (this.$menu.children().length) {
|
||||
this.$menu.show();
|
||||
} else {
|
||||
|
||||
@@ -46,11 +46,13 @@
|
||||
var ok_btn = $('<a href="#" class="btn btn-primary">Ok</a>');
|
||||
|
||||
ok_btn.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
box.data('result', true);
|
||||
box.modal('hide');
|
||||
});
|
||||
|
||||
cancel_btn.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
box.modal('hide');
|
||||
});
|
||||
|
||||
@@ -76,7 +78,7 @@
|
||||
cache: false,
|
||||
data: params,
|
||||
url: this.$element.attr('href'),
|
||||
complete: function(XMLHttpRequest, textStatus) {
|
||||
complete: $.proxy(function(XMLHttpRequest, textStatus) {
|
||||
var data;
|
||||
try {
|
||||
data = $.parseJSON(XMLHttpRequest.responseText);
|
||||
@@ -84,11 +86,15 @@
|
||||
data = { status: 'ko', respmsg: gettext('Internal Error') };
|
||||
}
|
||||
if (data.status == "ok") {
|
||||
if (this.options.success_cb != undefined) {
|
||||
this.options.success_cb(data);
|
||||
return;
|
||||
}
|
||||
window.location.reload();
|
||||
} else {
|
||||
$("body").notify("error", data.respmsg);
|
||||
}
|
||||
}
|
||||
}, this)
|
||||
});
|
||||
this.box.remove();
|
||||
}
|
||||
|
||||
@@ -37,7 +37,11 @@
|
||||
this.$element.carousel('next');
|
||||
} else {
|
||||
$("#modalbox").modal('hide').remove();
|
||||
window.location.reload();
|
||||
if (this.options.success_callback != undefined) {
|
||||
this.options.success_callback(resp);
|
||||
} else {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -107,10 +107,11 @@ function simple_ajax_form_post(e, options) {
|
||||
}
|
||||
$.post($form.attr("action"), args, function(data) {
|
||||
if (data.status == "ok") {
|
||||
$("#modalbox").modal('hide');
|
||||
if (opts.success_cb != undefined) {
|
||||
opts.success_cb(data);
|
||||
return;
|
||||
}
|
||||
$("#modalbox").modal('hide');
|
||||
if (opts.reload_on_success) {
|
||||
if (opts.reload_mode == 'full') {
|
||||
window.location.reload();
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
<div id="pagination_bar" class="simplepagination pull-right padded5">
|
||||
<ul>
|
||||
<li class="{% if not page.has_previous %}disabled{% endif %}">
|
||||
<a href="{{ baseurl }}page=1"><i class="icon-white icon-fast-backward"></i></a>
|
||||
<li>
|
||||
{% if page.has_previous %}<a href="{{ baseurl }}page=1">
|
||||
<i class="icon-white icon-fast-backward"></i></a>{% else %}
|
||||
<i class="icon-white icon-fast-backward"></i>{% endif %}
|
||||
</li>
|
||||
<li class="{% if not page.has_previous %}disabled{% endif %}">
|
||||
<a href="{{ baseurl }}page={{ page.previous_page_number }}">
|
||||
<i class="icon-step-backward icon-white"></i></a>
|
||||
<li>
|
||||
{% if page.has_previous %}<a href="{{ baseurl }}page={{ page.previous_page_number }}">
|
||||
<i class="icon-step-backward icon-white"></i></a>{% else %}
|
||||
<i class="icon-step-backward icon-white"></i>{% endif %}
|
||||
</li>
|
||||
<li class="disabled">
|
||||
{{ page.number }}/{{ page.paginator.num_pages }}
|
||||
</li>
|
||||
<li class="{% if not page.has_next %}disabled{% endif %}">
|
||||
<a href="{{ baseurl }}page={{ page.next_page_number }}">
|
||||
<i class="icon-step-forward icon-white"></i></a>
|
||||
<li>
|
||||
{% if page.has_next %}<a href="{{ baseurl }}page={{ page.next_page_number }}">
|
||||
<i class="icon-step-forward icon-white"></i></a>{% else %}
|
||||
<i class="icon-step-forward icon-white"></i>{% endif %}
|
||||
</li>
|
||||
<li class="{% if not page.has_next %}disabled{% endif %}">
|
||||
<a href="{{ baseurl }}page={{ page.paginator.num_pages }}">
|
||||
<i class="icon-fast-forward icon-white"></i></a>
|
||||
<li>
|
||||
{% if page.has_next %}<a href="{{ baseurl }}page={{ page.paginator.num_pages }}">
|
||||
<i class="icon-fast-forward icon-white"></i></a>{% else %}
|
||||
<i class="icon-fast-forward icon-white"></i>{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user