diff --git a/extensions/postfix_autoreply/__init__.py b/extensions/postfix_autoreply/__init__.py index e38c9c8ca..677baed6f 100644 --- a/extensions/postfix_autoreply/__init__.py +++ b/extensions/postfix_autoreply/__init__.py @@ -122,7 +122,10 @@ def get_static_content(target): function arform_cb() { $('#id_untildate').datepicker(); $(".submit").one('click', function(e) { - simple_ajax_form_post(e, arform_cb); + simple_ajax_form_post(e, { + error_cb: arform_cb, + formid: "arform" + }); }); } diff --git a/extensions/postfix_autoreply/views.py b/extensions/postfix_autoreply/views.py index ff924e1ac..d4a98b02a 100644 --- a/extensions/postfix_autoreply/views.py +++ b/extensions/postfix_autoreply/views.py @@ -18,7 +18,8 @@ def autoreply(request, tplname="common/generic_modal_form.html"): title=_("Auto-reply message"), action=reverse(autoreply), formid="arform", - submit_label=_("Update") + action_label=_("Update"), + action_classes="submit" ) mb = Mailbox.objects.get(user=request.user.id) try: diff --git a/extensions/webmail/forms.py b/extensions/webmail/forms.py index b00ae102e..5826d6820 100644 --- a/extensions/webmail/forms.py +++ b/extensions/webmail/forms.py @@ -10,6 +10,7 @@ class ComposeMailForm(forms.Form): origmsgid = forms.CharField(label="", widget=forms.HiddenInput(), required=False) class FolderForm(forms.Form): + oldname = forms.CharField(label="", widget=forms.HiddenInput(), required=False) name = forms.CharField() class AttachmentForm(forms.Form): diff --git a/extensions/webmail/imaputils.py b/extensions/webmail/imaputils.py index dd9839511..1c51df511 100644 --- a/extensions/webmail/imaputils.py +++ b/extensions/webmail/imaputils.py @@ -11,7 +11,7 @@ from imapclient.response_parser import parse_fetch_response from modoboa.lib import parameters from modoboa.lib.connections import * from modoboa.lib.webutils import static_url -from exceptions import ImapError +from exceptions import ImapError, WebmailError from fetch_parser import * #imaplib.Debug = 4 @@ -347,7 +347,7 @@ class IMAPconnector(object): @capability('LIST-EXTENDED', '_listfolders_simple') def _listfolders(self, topmailbox='', md_mailboxes=[]): pattern = ("%s.%%" % topmailbox.encode("imap4-utf-7")) if len(topmailbox) else "%" - resp = self._cmd("LSUB", "", pattern, "RETURN", "(CHILDREN)") + resp = self._cmd("LIST", "", pattern, "RETURN", "(CHILDREN)") result = [] for mb in resp: flags, delimiter, name, childinfo = \ diff --git a/extensions/webmail/templates/webmail/folders.html b/extensions/webmail/templates/webmail/folders.html index eb875d26d..a3a5136b2 100644 --- a/extensions/webmail/templates/webmail/folders.html +++ b/extensions/webmail/templates/webmail/folders.html @@ -1,12 +1,8 @@ -{% load i18n %} -{% load webextras %} - +{% load i18n webextras %} +
+ +
+
{% mboxes_menu %}
diff --git a/extensions/webmail/templatetags/webextras.py b/extensions/webmail/templatetags/webextras.py index 9d162e17c..105dd1d46 100644 --- a/extensions/webmail/templatetags/webextras.py +++ b/extensions/webmail/templatetags/webextras.py @@ -74,7 +74,8 @@ def compose_menu(selection, backurl, user): def listmailbox_menu(selection, folder, user): entries = [ {"name" : "compose", - "url" : "compose", + "url" : "compose", + "img" : "icon-edit", "label" : _("New message"), "class" : "btn"}, {"name" : "mark", @@ -118,7 +119,11 @@ def listmailbox_menu(selection, folder, user): )) @register.simple_tag -def print_folders(folders, selected=None, withunseen=False, withmenu=False): +def print_folders(folders, selected=None, withunseen=False, selectonly=False): + """Display a tree of mailboxes and sub-mailboxes + + + """ result = "" for fd in folders: @@ -136,22 +141,46 @@ def print_folders(folders, selected=None, withunseen=False, withmenu=False): ul_state = "hidden" div_state = "collapsed" result += "
" % div_state - # if withmenu: - # result += "" \ - # % settings.MEDIA_URL cssclass = "block" if withunseen and fd.has_key("unseen"): label += " (%d)" % fd["unseen"] cssclass += " unseen" iclass = fd["class"] if fd.has_key("class") else "icon-folder-close" - result += """ + result += """ %s -""" % (fd.has_key("path") and fd["path"] or fd["name"], cssclass, iclass, label) +""" % (fd.has_key("path") and fd["path"] or fd["name"], cssclass, + 'selectfolder' if selectonly else 'loadfolder', iclass, label) if fd.has_key("sub") and len(fd["sub"]): result += "\n" + + print_folders(fd["sub"], selected, withunseen, selectonly) + "\n" result += "\n" return result + +@register.simple_tag +def mboxes_menu(): + entries = [ + {"name" : "newmbox", + "url" : reverse(webmail.views.newfolder), + "img" : "icon-plus", + "label" : "", + "modal" : True, + "modalcb" : "webmail.mboxform_cb", + "class" : "btn btn-mini"}, + {"name" : "editmbox", + "url" : reverse(webmail.views.editfolder), + "img" : "icon-edit", + "label" : "", + "class" : "btn btn-mini"}, + {"name" : "removembox", + "url" : reverse(webmail.views.delfolder), + "img" : "icon-remove", + "label" : "", + "class" : "btn btn-mini"} + ] + + return render_to_string('common/buttons_list.html', dict( + entries=entries, css="nav" + )) diff --git a/extensions/webmail/views.py b/extensions/webmail/views.py index 2417ea1cc..db5b98354 100644 --- a/extensions/webmail/views.py +++ b/extensions/webmail/views.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# coding: utf-8 import time import sys from django.http import HttpResponse, Http404, HttpResponseRedirect @@ -64,7 +64,6 @@ def __render_common_components(request, folder_name, lst=None, content=None, men "titlebar" : True, "selected" : request.session["folder"], "folders" : mbc.getfolders(request.user), - "withmenu" : True, "withunseen" : True }), "menu" : menu, @@ -229,20 +228,22 @@ def separate_folder(fullname, sep="."): @login_required @needs_mailbox() -def newfolder(request, tplname="webmail/folder.html"): +def newfolder(request, tplname="webmail/folder2.html"): mbc = IMAPconnector(user=request.user.username, password=request.session["password"]) ctx = {"title" : _("Create a new folder"), - "fname" : "newfolder", - "submit_label" : _("Create"), - "withmenu" : False, - "withunseen" : False} + "formid" : "mboxform", + "action" : reverse(newfolder), + "action_label" : _("Create"), + "action_classes" : "submit", + "withunseen" : False, + "selectonly" : True} + ctx["folders"] = mbc.getfolders(request.user) if request.method == "POST": form = FolderForm(request.POST) if form.is_valid(): - pf = request.POST.has_key("parent_folder") \ - and request.POST["parent_folder"] or None + pf = request.POST.get("parent_folder", None) mbc.create_folder(form.cleaned_data["name"], pf) return ajax_response(request, ajaxnav=True, respmsg=_("Folder created")) @@ -256,14 +257,16 @@ def newfolder(request, tplname="webmail/folder.html"): @login_required @needs_mailbox() -def editfolder(request, tplname="webmail/folder.html"): +def editfolder(request, tplname="webmail/folder2.html"): mbc = IMAPconnector(user=request.user.username, password=request.session["password"]) - ctx = {"title" : _("Edit folder"), - "fname" : "editfolder", - "submit_label" : _("Update"), - "withmenu" : False, - "withunseen" : False} + ctx = {"title" : _("Edit mailbox"), + "formid" : "mboxform", + "action" : reverse(editfolder), + "action_label" : _("Update"), + "action_classes" : "submit", + "withunseen" : False, + "selectonly" : True} ctx["folders"] = mbc.getfolders(request.user) if request.method == "POST": form = FolderForm(request.POST) @@ -285,12 +288,12 @@ def editfolder(request, tplname="webmail/folder.html"): ctx["form"] = form return ajax_response(request, status="ko", template=tplname, **ctx) - if not request.GET.has_key("name") or request.GET["name"] == "": - return - name = request.GET["name"] - ctx["oldname"] = name - name, parent = separate_folder(name) + name = request.GET.get("name", None) + if name is None: + raise WebmailError(_("Invalid request")) + shortname, parent = separate_folder(name) ctx["form"] = FolderForm() + ctx["form"].fields["oldname"].initial = shortname ctx["form"].fields["name"].initial = name ctx["selected"] = parent return _render(request, tplname, ctx) @@ -298,16 +301,17 @@ def editfolder(request, tplname="webmail/folder.html"): @login_required @needs_mailbox() def delfolder(request): - if not request.GET.has_key("name") or request.GET["name"] == "": - return + name = request.GET.get("name", None) + if name is None: + raise WebmailError(_("Bad request")) mbc = IMAPconnector(user=request.user.username, password=request.session["password"]) - mbc.delete_folder(request.GET["name"]) + mbc.delete_folder(name) return ajax_response(request) @login_required @needs_mailbox() -def attachments(request, tplname="webmail/attachments2.html"): +def attachments(request, tplname="webmail/attachments.html"): if request.method == "POST": csuploader = AttachmentUploadHandler() request.upload_handlers.insert(0, csuploader) @@ -383,10 +387,8 @@ def render_mboxes_list(request, imapc): """ curmbox = request.session.get("mbox", "INBOX") return _render_to_string(request, "webmail/folders.html", { - "titlebar" : True, "selected" : curmbox, "folders" : imapc.getfolders(request.user), - "withmenu" : True, "withunseen" : True }) diff --git a/lib/templatetags/libextras.py b/lib/templatetags/libextras.py index 5d16a73c1..40995dff6 100644 --- a/lib/templatetags/libextras.py +++ b/lib/templatetags/libextras.py @@ -126,6 +126,5 @@ def render_link(linkdef, mdclass=None): class="{{ mdclass }}{% if link.class %} {{ link.class }}{% endif %}" {% if link.confirm %} onclick="return confirm('{{ link.confirm }}')"{% endif %}> {% if link.img %}{% endif %} -{{ link.label }} -""") +{{ link.label }}""") return t.render(Context(dict(link=linkdef, mdclass=mdclass))) diff --git a/lib/webutils.py b/lib/webutils.py index 8c310f6ce..63ef904ca 100644 --- a/lib/webutils.py +++ b/lib/webutils.py @@ -35,18 +35,10 @@ def _render_error(request, errortpl="error", user_context={}): context_instance=template.RequestContext(request)) def render_actions(actions): - t = template.Template(""" -{% for a in actions %} - - -{% endfor %} + t = template.Template("""{% load libextras %} +{% for a in actions %}{% render_link a %}{% endfor %} """) - return t.render(template.Context({ - "actions" : actions - })) + return t.render(template.Context(dict(actions=actions))) def _ctx_ok(url): return {"status" : "ok", "url" : url} diff --git a/static/css/custom.css b/static/css/custom.css index b98beefc8..01f211571 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -18,7 +18,7 @@ body { margin-bottom: 0; } -#pagination_bar { +.navbar-text { color: #999999 !important; }