diff --git a/extensions/postfix_autoreply/templates/postfix_autoreply/autoreply.html b/extensions/postfix_autoreply/templates/postfix_autoreply/autoreply.html
index edfbd2fab..b402bfc34 100644
--- a/extensions/postfix_autoreply/templates/postfix_autoreply/autoreply.html
+++ b/extensions/postfix_autoreply/templates/postfix_autoreply/autoreply.html
@@ -16,6 +16,12 @@
{% endblock %}
diff --git a/extensions/postfix_autoreply/views.py b/extensions/postfix_autoreply/views.py
index 0a176e509..580076fc0 100644
--- a/extensions/postfix_autoreply/views.py
+++ b/extensions/postfix_autoreply/views.py
@@ -7,13 +7,13 @@ from django.contrib.auth.decorators \
from django.contrib import messages
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
-from modoboa.lib import _render, _ctx_ok, _ctx_ko, is_not_localadmin
+from modoboa.lib import _render, ajax_response, is_not_localadmin
from forms import *
from models import *
@login_required
@is_not_localadmin('boxerror')
-def autoreply(request):
+def autoreply(request, tplname="postfix_autoreply/autoreply.html"):
mb = Mailbox.objects.get(user=request.user.id)
try:
arm = ARmessage.objects.get(mbox=mb.id)
@@ -34,17 +34,13 @@ def autoreply(request):
arm.save()
messages.info(request, _("Auto reply message updated successfully."),
fail_silently=True)
- ctx = _ctx_ok(reverse(userprefs.views.index))
- else:
- ctx = _ctx_ko("postfix_autoreply/autoreply.html", {
- "form" : form, "error" : error
- })
- return HttpResponse(simplejson.dumps(ctx),
- mimetype="application/json")
+ return ajax_response(request, url=reverse(userprefs.views.index))
+ return ajax_response(request, status="ko", template=tplname,
+ form=form, error=error)
form = ARmessageForm(instance=arm)
if arm is not None:
form.fields['untildate'].initial = arm.untildate
- return _render(request, "postfix_autoreply/autoreply.html", {
+ return _render(request, tplname, {
"form" : form
})
diff --git a/extensions/webmail/forms.py b/extensions/webmail/forms.py
index 32c5ede87..1de6598e1 100644
--- a/extensions/webmail/forms.py
+++ b/extensions/webmail/forms.py
@@ -7,3 +7,5 @@ class ComposeMailForm(forms.Form):
cc = forms.CharField(label=_("Cc"), widget=forms.Textarea(), required=False)
subject = forms.CharField(label=_("Subject"), max_length=255)
+class FolderForm(forms.Form):
+ name = forms.CharField()
diff --git a/extensions/webmail/lib.py b/extensions/webmail/lib.py
index 949d4795d..8cbb4d495 100644
--- a/extensions/webmail/lib.py
+++ b/extensions/webmail/lib.py
@@ -303,6 +303,20 @@ class IMAPconnector(object):
self.m.select(self._encodefolder(folder))
self.m.expunge()
+ def create_folder(self, name, parent=None):
+ if parent is not None:
+ name = "%s.%s" % (parent, name)
+ typ, data = self.m.create(self._encodefolder(name))
+ if typ == "NO":
+ return False
+ return True
+
+ def delete_folder(self, name):
+ typ, data = self.m.delete(self._encodefolder(name))
+ if typ == "NO":
+ return False
+ return True
+
def getquota(self, folder):
status, data = self.m.getquotaroot(self._encodefolder(folder))
if status == "OK":
diff --git a/extensions/webmail/static/css/folders.css b/extensions/webmail/static/css/folders.css
new file mode 100644
index 000000000..796f50419
--- /dev/null
+++ b/extensions/webmail/static/css/folders.css
@@ -0,0 +1,99 @@
+#folders {
+ float: left;
+ width: 150px;
+}
+
+#folders2 {
+ border: 1px solid #ccc;
+ background-color: #eee;
+ position: absolute;
+ top: 100px;
+ left: 20px;
+ right: 20px;
+ bottom: 40px;
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+
+#fdcreate {
+ position: absolute;
+ top: 370px;
+ left: 20px;
+ right: 20px;
+ text-align: center;
+}
+
+.box h3 {
+ font-size: small;
+ margin: 2px 0px 2px 0px;
+ text-align: center;
+}
+
+.box ul {
+ list-style: none;
+ padding: 5px 5px;
+ margin: 0;
+}
+
+.box li {
+ margin-bottom: 4px;
+ padding-left: 15px;
+}
+
+.box li.selected {
+ background-color: #FFFF77;
+}
+
+.box a:link, .box a:visited {
+ background: transparent;
+ color: black;
+ text-decoration: none;
+ margin-left: 5px;
+}
+
+.box a:hover {
+ color: #6AB0C5;
+ text-decoration: none;
+}
+
+.box img {
+ border: 0;
+}
+
+.box li.dragging {
+ background-color: #6AB0C5;
+}
+
+img.aligned {
+ float: left;
+}
+
+img.footer {
+ float: none;
+ vertical-align: bottom;
+}
+
+li.inbox {
+ background: url("/static/pics/overview.png") no-repeat;
+}
+
+li.trash {
+ background: url("/static/pics/trash.png") no-repeat;
+}
+
+li.folder {
+ background: url("/static/pics/folder.png") no-repeat;
+}
+
+li.subfolders {
+ background: url("/static/pics/subfolders.png") no-repeat;
+}
+
+ul.hidden {
+ display: none;
+}
+
+ul.visible {
+ display: block;
+ padding-bottom: 0;
+}
\ No newline at end of file
diff --git a/extensions/webmail/static/css/webmail.css b/extensions/webmail/static/css/webmail.css
index b87973c89..1928e05ac 100644
--- a/extensions/webmail/static/css/webmail.css
+++ b/extensions/webmail/static/css/webmail.css
@@ -12,11 +12,6 @@ html > body #listing {
bottom: 35px;
}
-#folders {
- float: left;
- width: 150px;
-}
-
/*thead tr {
position: relative;
top: expression(offsetParent.scrollTop);
@@ -50,60 +45,6 @@ html > body #listing {
-khtml-user-select: none; /* Webkit (Safari, Chrome) */
}
-.box h3 {
- font-size: small;
- margin: 2px 0px 2px 0px;
- text-align: center;
-}
-
-.box ul {
- list-style: none;
- padding: 5px 5px;
- margin: 0;
-}
-
-.box li {
- margin-bottom: 4px;
- padding-left: 20px;
-}
-
-.box li.selected {
- background-color: #FFFF77;
-}
-
-.box a:link, .box a:visited {
- background: transparent;
- color: black;
- text-decoration: none;
- margin-left: 5px;
-}
-
-.box a:hover {
- color: #6AB0C5;
- text-decoration: none;
-}
-
-.box img {
- float: left;
- border: 0;
-}
-
-li.inbox {
- background: url("/static/pics/overview.png") no-repeat;
-}
-
-li.trash {
- background: url("/static/pics/trash.png") no-repeat;
-}
-
-li.folder {
- background: url("/static/pics/folder.png") no-repeat;
-}
-
-li.subfolders {
- background: url("/static/pics/subfolders.png") no-repeat;
-}
-
th[class*=sortable] {
cursor: pointer;
/*-moz-box-shadow: 0px -15px 10px -10px rgba(0,0,0,0.6) inset;
@@ -124,16 +65,11 @@ th.selected {
position: static;
}
-.box li.dragging {
- background-color: #6AB0C5;
-}
-
ul.hidden {
display: none;
}
ul.visible {
- background-color: white;
display: block;
padding-bottom: 0;
}
@@ -219,4 +155,27 @@ textarea:hover {
#quotatext {
padding: 2px 0 0 2px;
float: left;
-}
\ No newline at end of file
+}
+
+/* context menu specific */
+#fdmenu { border:1px solid #999; padding:0; background:#eee; width:150px; display:none; }
+#fdmenu .separator { border-top:1px solid #999; }
+#fdmenu ul { list-style-type:none; margin:0; padding:0; }
+#fdmenu li { margin:0; padding:0; }
+#fdmenu li a { display:block; padding:5px 10px 5px 5px; font-size:12px; text-decoration:none; font-family:tahoma,arial,sans-serif; color:#000; }
+#fdmenu li a:hover { background-color:#ddd; }
+#fdmenu img { float:left; margin: 0 5px 0 0; }
+
+.folder_menu {
+ float: right;
+ opacity: 0.8;
+}
+
+.folder_btn {
+ float: right;
+ margin: 3px;
+}
+
+.folder_menubar {
+ clear: both;
+}
diff --git a/extensions/webmail/static/js/fdmenu.js b/extensions/webmail/static/js/fdmenu.js
new file mode 100644
index 000000000..2c540cae9
--- /dev/null
+++ b/extensions/webmail/static/js/fdmenu.js
@@ -0,0 +1,97 @@
+/*
+ * Simple dropdown menu plugin used for folders manipulation.
+ *
+ */
+var FdMenu = new Class({
+ Implements: [Options],
+
+ options: {
+ media_url: "",
+ modify_url: "",
+ delete_url: ""
+ },
+
+ add_entry: function(name, label, pic, url, onclick) {
+ var item = new Element("li");
+ var picpath = this.options.media_url + "pics/" + pic;
+
+ this[name] = new Element("a")
+ .set("html", " " + label)
+ .addEvent("click", onclick)
+ .inject(item);
+ item.inject(this.list);
+ },
+
+ initialize: function(options) {
+ this.setOptions(options);
+
+ this.container = new Element("div", {"id" : "fdmenu"})
+ .addClass("fdmenu");
+ this.list = new Element("ul");
+
+ this.add_entry("modbutton", gettext("Edit folder"),
+ "edit.png", this.options.modify_url, function(evt) {
+ evt.stop();
+ SqueezeBox.initialize({
+ size: {x: 350, y: 400},
+ handler: 'iframe'
+ });
+ SqueezeBox.open(this.get("href"));
+ });
+ this.add_entry("delbutton", gettext("Delete folder"), "remove.png",
+ this.options.delete_url, function(evt) {
+ evt.stop();
+ if (!confirm(gettext("Delete folder?"))) {
+ return;
+ }
+ new Request.JSON({
+ url: this.get("href"),
+ method: "GET",
+ onSuccess: function(resp) {
+ if (resp.status == "ok") {
+ infobox.info(gettext("Folder deleted."));
+ var id = current_anchor.update.delay(500, current_anchor, 1);
+ } else {
+ infobox.error(gettext("Failed to delete folder"));
+ infobox.hide(2);
+ }
+ }
+ }).send();
+ });
+ this.list.inject(this.container);
+ this.shown = false;
+
+ $(document.body).addEvent("click", function() {
+ if (this.shown) {
+ this.hide();
+ }
+ }.bind(this));
+ //this.fx = new Fx.Slide(this.container);
+ },
+
+ show: function(origin, folder) {
+ var position = origin.getPosition();
+
+ this.container.setStyles({
+ position: "absolute",
+ top: position.y + 5,
+ left: position.x + 5,
+ display: "block"
+ });
+ this.container.inject(document.body);
+ this.shown = true;
+ this.modbutton.set("href", this.options.modify_url + "?name=" + folder);
+ },
+
+ hide: function() {
+ this.container.setStyles({
+ display: "none"
+ });
+ this.container.dispose();
+ this.shown = false;
+ },
+
+ toggle: function(origin, folder) {
+ return (!this.shown) ? this.show(origin, folder) : this.hide();
+ }
+});
\ No newline at end of file
diff --git a/extensions/webmail/templates/webmail/folder.html b/extensions/webmail/templates/webmail/folder.html
new file mode 100644
index 000000000..59d0f3492
--- /dev/null
+++ b/extensions/webmail/templates/webmail/folder.html
@@ -0,0 +1,56 @@
+{% extends "layout_simple.html" %}
+{% load i18n %}
+{% block html_head %}
+
+
+
+{% endblock %}
+{% block content %}
+
+
" % settings.MEDIA_URL
cssclass = ""
- if fd.has_key("unseen"):
+ if withunseen and fd.has_key("unseen"):
label += " (%d)" % fd["unseen"]
cssclass = "unseen"
result += "%s\n" \
% (fd.has_key("path") and fd["path"] or fd["name"], cssclass, label)
if fd.has_key("sub"):
- result += "