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 %}
+
+
+
+ {% print_folders folders selected withunseen %}
+
+
+{% 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 += "" % (fd["path"], ul_state) \
- + print_folders(fd["sub"], selected, withunseen, withmenu) + "
\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;
}