mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
see #55: folders manipulation. Work in progress.
This commit adds the following features: * Folder creation, * Folder modification, * Folder removal. There are still issues with subfolders but they should not be too complicated to fix. I've also done some javascript refactoring.
This commit is contained in:
@@ -16,6 +16,12 @@
|
||||
<script type="text/javascript">
|
||||
window.addEvent("domready", function() {
|
||||
var cal = new Calendar({id_untildate: "Y-m-d"}, {tweak: {x: -100, y:-100}});
|
||||
|
||||
register_error_callback("armform", function() {
|
||||
new Calendar({id_untildate: "Y-m-d"}, {
|
||||
tweak: {x: -100, y:-100}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -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
|
||||
})
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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":
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@@ -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", "<img src='" + picpath + "' /> " + 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();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
{% extends "layout_simple.html" %}
|
||||
{% load i18n %}
|
||||
{% block html_head %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/webmail/folders.css" />
|
||||
<script src="{{ MEDIA_URL }}js/form.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
window.addEvent("domready", function() {
|
||||
$$("li[class*=clickable]").removeEvents();
|
||||
$$("li[class*=clickable]").addEvent("click", function(evt) {
|
||||
$$("ul[name=" + evt.target.get("name") + "]").each(function(item) {
|
||||
if (item.hasClass("hidden")) {
|
||||
evt.target.setStyle("background",
|
||||
"url('{{ MEDIA_URL }}pics/folder-open.png') no-repeat");
|
||||
item.removeClass("hidden").addClass("visible");
|
||||
item.setStyle("background-color", evt.target.getStyle("background-color"));
|
||||
} else {
|
||||
evt.target.setStyle("background",
|
||||
"url('{{ MEDIA_URL }}pics/subfolders.png') no-repeat");
|
||||
item.removeClass("visible").addClass("hidden");
|
||||
}
|
||||
});
|
||||
evt.stop();
|
||||
});
|
||||
$$("a[name=loadfolder]").addEvent("click", function(evt) {
|
||||
evt.stop();
|
||||
$$("a[name=loadfolder]").each(function(item) {
|
||||
item.getParent().removeClass("selected");
|
||||
});
|
||||
this.getParent().addClass("selected");
|
||||
});
|
||||
register_extra_data_callback("newfolder", function() {
|
||||
var result = "";
|
||||
$$("li[class*=selected]").each(function(item) {
|
||||
var atag = item.getFirst("a");
|
||||
result = atag.get("href");
|
||||
});
|
||||
return "parent_folder=" + result;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="title"><h1>{{ title }}</h1></div>
|
||||
<form action="" method="POST" id="{{ fname }}" name="{{ fname }}">
|
||||
{% include "common/genericform.html" %}
|
||||
<div class="row">
|
||||
<label>{% trans "Parent folder" %}</label>
|
||||
</div>
|
||||
<div id="folders2" class="box">
|
||||
{% include "webmail/folders.html" %}
|
||||
</div>
|
||||
<div id="fdcreate">
|
||||
<input type="submit" name="submit" value='{{ submit_label }}'/>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -1,6 +1,13 @@
|
||||
{% load i18n %}
|
||||
{% load webextras %}
|
||||
{% if titlebar %}
|
||||
<a href="{% url extensions.webmail.views.newfolder %}" class="boxed"
|
||||
rel="{handler: 'iframe', size: {x: 350, y: 400}}">
|
||||
<img class="aligned" src="{{MEDIA_URL}}pics/add.png"
|
||||
alt="{% trans 'Add a new folder' %}"/>
|
||||
</a>
|
||||
<h3>{% trans "Folders" %}</h3>
|
||||
{% endif %}
|
||||
<ul>
|
||||
{% print_folders folders selected %}
|
||||
{% print_folders folders selected withunseen withmenu %}
|
||||
</ul>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
{% extends "common/email_listing.html" %}
|
||||
{% load i18n %}
|
||||
{% block css %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/webmail/webmail.css" />
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/webmail/folders.css" />
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
quota_pb = new ProgressBar({
|
||||
@@ -19,9 +19,29 @@
|
||||
updatelisting(resp);
|
||||
if ($defined(resp.folders)) {
|
||||
$("folders").set("html", resp.folders);
|
||||
$$("li[class*=clickable]").removeEvents();
|
||||
SqueezeBox.assign($$('a[class=boxed]'), {
|
||||
parse: 'rel'
|
||||
});
|
||||
|
||||
var fdbuttons = $$("img[class*=footer]");
|
||||
var fdmenu = new FdMenu({
|
||||
media_url: "{{MEDIA_URL}}",
|
||||
modify_url: "{% url extensions.webmail.views.editfolder %}",
|
||||
delete_url: "{% url extensions.webmail.views.delfolder %}"
|
||||
});
|
||||
|
||||
fdbuttons.addEvents({
|
||||
click: function(evt) {
|
||||
var parent = this.getParent();
|
||||
var fdname = parent.getFirst("a[name=loadfolder]").get("href");
|
||||
|
||||
fdmenu.toggle(this, fdname);
|
||||
evt.stop();
|
||||
}
|
||||
});
|
||||
}
|
||||
select($$("a[href=" + current_anchor.getbaseurl() + "]"));
|
||||
$$("li[class*=clickable]").removeEvents();
|
||||
$$("li[class*=clickable]").addEvent("click", function(evt) {
|
||||
$$("ul[name=" + evt.target.get("name") + "]").each(function(item) {
|
||||
if (item.hasClass("hidden")) {
|
||||
|
||||
@@ -116,8 +116,14 @@ def listing_menu(selection, folder, user):
|
||||
return menu + searchbar
|
||||
|
||||
@register.simple_tag
|
||||
def print_folders(folders, selected=None):
|
||||
def print_folders(folders, selected=None, withunseen=False, withmenu=False):
|
||||
result = ""
|
||||
|
||||
import pprint
|
||||
pprint.PrettyPrinter(indent=2).pprint(folders)
|
||||
print "END"
|
||||
|
||||
|
||||
for fd in folders:
|
||||
if fd.has_key("class"):
|
||||
cssclass = fd["class"]
|
||||
@@ -131,14 +137,17 @@ def print_folders(folders, selected=None):
|
||||
if selected == label:
|
||||
cssclass += " selected"
|
||||
result += "<li name='%s' class='droppable %s'>\n" % (name, cssclass)
|
||||
if withmenu:
|
||||
result += "<img src='%spics/go-down.png' class='footer' />" % settings.MEDIA_URL
|
||||
|
||||
cssclass = ""
|
||||
if fd.has_key("unseen"):
|
||||
if withunseen and fd.has_key("unseen"):
|
||||
label += " (%d)" % fd["unseen"]
|
||||
cssclass = "unseen"
|
||||
result += "<a href='%s' class='%s' name='loadfolder'>%s</a>\n" \
|
||||
% (fd.has_key("path") and fd["path"] or fd["name"], cssclass, label)
|
||||
if fd.has_key("sub"):
|
||||
result += "<ul name='%s' class='hidden'>" % (fd["path"]) + print_folders(fd["sub"], selected) + "</ul>\n"
|
||||
result += "<ul name='%s' class='hidden'>" % (fd["path"]) \
|
||||
+ print_folders(fd["sub"], selected, withunseen, withmenu) + "</ul>\n"
|
||||
result += "</li>\n"
|
||||
return result
|
||||
|
||||
@@ -7,6 +7,9 @@ urlpatterns = patterns('modoboa.extensions.webmail.views',
|
||||
(r'^mark/(?P<name>.+)/$', "mark"),
|
||||
(r'^empty/(?P<name>.+)/$', "empty"),
|
||||
(r'^compact/(?P<name>.+)/$', "compact"),
|
||||
(r'^newfolder/$', "newfolder"),
|
||||
(r'^editfolder/$', 'editfolder'),
|
||||
(r'^delfolder/$', 'delfolder'),
|
||||
(r'^(?P<folder>.+)/(?P<mail_id>[\w\-\+]+)/part/$', 'getattachment'),
|
||||
(r'^(?P<fdname>.+)/(?P<mail_id>[\w\-\+]+)/delete/$', 'delete'),
|
||||
(r'^(?P<folder>.+)/(?P<mail_id>[\w\-\+]+)/content/$', 'getmailcontent'),
|
||||
|
||||
@@ -10,7 +10,8 @@ from django.core.urlresolvers import reverse
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from modoboa.admin.models import Mailbox
|
||||
from modoboa.lib import parameters, _render, _render_error, \
|
||||
getctx, is_not_localadmin, _render_to_string, split_mailbox
|
||||
getctx, is_not_localadmin, _render_to_string, split_mailbox, \
|
||||
ajax_response
|
||||
from modoboa.lib.email_listing import parse_search_parameters, Paginator
|
||||
from lib import *
|
||||
from forms import *
|
||||
@@ -63,9 +64,12 @@ def __render_common_components(request, folder_name, lst=None, content=None, men
|
||||
% _("This folder contains no messages")
|
||||
|
||||
ret = {
|
||||
"folders" : render_to_string("webmail/folders.html", {
|
||||
"folders" : _render_to_string(request, "webmail/folders.html", {
|
||||
"titlebar" : True,
|
||||
"selected" : request.session["folder"],
|
||||
"folders" : mbc.getfolders(request.user)
|
||||
"folders" : mbc.getfolders(request.user),
|
||||
"withmenu" : True,
|
||||
"withunseen" : True
|
||||
}),
|
||||
"menu" : menu,
|
||||
"listing" : content,
|
||||
@@ -423,3 +427,68 @@ def forward(request, folder, mail_id):
|
||||
email = ForwardModifier(msg, request.user, form, addrfull=True, links="1")
|
||||
return render_compose(request, form, reverse(forward, args=[folder, mail_id]),
|
||||
email)
|
||||
|
||||
@login_required
|
||||
@is_not_localadmin()
|
||||
def newfolder(request, tplname="webmail/folder.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}
|
||||
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
|
||||
if mbc.create_folder(form.cleaned_data["name"], pf):
|
||||
return ajax_response(request, ajaxnav=True)
|
||||
|
||||
ctx["form"] = form
|
||||
ctx["selected"] = None
|
||||
return ajax_response(request, status="ko", template=tplname, **ctx)
|
||||
|
||||
ctx["form"] = FolderForm()
|
||||
ctx["selected"] = None
|
||||
return _render(request, tplname, ctx)
|
||||
|
||||
@login_required
|
||||
@is_not_localadmin()
|
||||
def editfolder(request, tplname="webmail/folder.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["folders"] = mbc.getfolders(request.user)
|
||||
if not request.GET.has_key("name") or request.GET["name"] == "":
|
||||
return
|
||||
name = request.GET["name"]
|
||||
if name.count("."):
|
||||
parts = name.split(".")
|
||||
name = parts[-1]
|
||||
parent = ".".join(parts[0:len(parts) - 1])
|
||||
else:
|
||||
parent = None
|
||||
print parent
|
||||
ctx["form"] = FolderForm()
|
||||
ctx["form"].fields["name"].initial = name
|
||||
parts = request
|
||||
ctx["selected"] = parent
|
||||
return _render(request, tplname, ctx)
|
||||
|
||||
@login_required
|
||||
@is_not_localadmin()
|
||||
def delfolder(request):
|
||||
if not request.GET.has_key("name") or request.GET["name"] == "":
|
||||
return
|
||||
mbc = IMAPconnector(user=request.user.username,
|
||||
password=request.session["password"])
|
||||
if mbc.delete_folder(request.GET["name"]):
|
||||
return ajax_response(request)
|
||||
return ajax_response(request, status="ko")
|
||||
|
||||
+7
-5
@@ -74,7 +74,7 @@ def getctx(status, level=1, callback=None, **kwargs):
|
||||
ctx[kw] = v
|
||||
return ctx
|
||||
|
||||
def ajax_response(request, status="ok", url=None, template=None, **kwargs):
|
||||
def ajax_response(request, status="ok", url="", ajaxnav=False, template=None, **kwargs):
|
||||
"""Ajax response shortcut
|
||||
|
||||
Simple shortcut that sends an JSON response. If a template is
|
||||
@@ -94,10 +94,12 @@ def ajax_response(request, status="ok", url=None, template=None, **kwargs):
|
||||
content = _render_to_string(request, template, ctx)
|
||||
else:
|
||||
content = ""
|
||||
return HttpResponse(simplejson.dumps({"status" : status,
|
||||
"content" : content,
|
||||
"url" : url}),
|
||||
mimetype="application/json")
|
||||
jsonctx = {"status" : status, "content" : content}
|
||||
if ajaxnav:
|
||||
jsonctx["ajaxnav"] = True
|
||||
else:
|
||||
jsonctx["url"] = url
|
||||
return HttpResponse(simplejson.dumps(jsonctx), mimetype="application/json")
|
||||
|
||||
def decode(s, encodings=('utf8', 'latin1', 'windows-1252', 'ascii'), charset=None):
|
||||
if charset is not None:
|
||||
|
||||
+75
-52
@@ -1,59 +1,82 @@
|
||||
window.addEvent("domready", function() {
|
||||
ajax_submit = function(event, error_callbacks) {
|
||||
var form = event.target;
|
||||
var myid = form.get("id");
|
||||
var error_callbacks = {
|
||||
mbaliasform: function() {
|
||||
if ($("id_domain").value == 0) {
|
||||
$("id_mboxes").set("html", "");
|
||||
}
|
||||
mbaliasform_init();
|
||||
},
|
||||
permform: function() {
|
||||
if ($defined($("id_domain"))) {
|
||||
$("id_domain").options[0].setProperty("selected", "selected");
|
||||
domadminform_init();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
event.stop();
|
||||
form.set('send', {
|
||||
onSuccess: function(responseText) {
|
||||
var response = JSON.decode(responseText);
|
||||
var extra_data_callbacks = {
|
||||
|
||||
if (response.status == "ko") {
|
||||
$(document.body).set("html", response.content);
|
||||
$(document.body).addEvent("submit", default_submit);
|
||||
if ($defined(error_callbacks[myid])) {
|
||||
error_callbacks[myid]();
|
||||
}
|
||||
} else {
|
||||
if (response.url != "") {
|
||||
parent.location.href = response.url;
|
||||
}
|
||||
parent.SqueezeBox.close();
|
||||
};
|
||||
|
||||
function register_callback(hash, name, callback) {
|
||||
if ($defined(hash[name])) {
|
||||
return false;
|
||||
}
|
||||
hash[name] = callback;
|
||||
return true;
|
||||
}
|
||||
|
||||
function register_error_callback(name, callback) {
|
||||
return register_callback(error_callbacks, name, callback);
|
||||
}
|
||||
|
||||
function register_extra_data_callback(name, callback) {
|
||||
return register_callback(extra_data_callbacks, name, callback);
|
||||
}
|
||||
|
||||
function ajax_submit(event) {
|
||||
var form = event.target;
|
||||
var myid = form.get("id");
|
||||
var data = form.toQueryString();
|
||||
|
||||
event.stop();
|
||||
if ($defined(extra_data_callbacks[myid])) {
|
||||
if (data != "") {
|
||||
data += "&";
|
||||
}
|
||||
data += extra_data_callbacks[myid]();
|
||||
}
|
||||
|
||||
new Request({
|
||||
method: form.get("method"),
|
||||
data: data,
|
||||
onSuccess: function(responseText) {
|
||||
var response = JSON.decode(responseText);
|
||||
|
||||
if (response.status == "ko") {
|
||||
$(document.body).set("html", response.content);
|
||||
$(document.body).addEvent("submit", ajax_submit);
|
||||
if ($defined(error_callbacks[myid])) {
|
||||
error_callbacks[myid]();
|
||||
}
|
||||
} else {
|
||||
if ($defined(response.url) && response.url != "") {
|
||||
parent.location.href = response.url;
|
||||
}
|
||||
if ($defined(response.ajaxnav)) {
|
||||
parent.current_anchor.update(1);
|
||||
}
|
||||
},
|
||||
onFailure: function(xhr) {
|
||||
parent.document.getElement('iframe').setStyles({width: 800, height: 600});
|
||||
$(document.body).set("html", xhr.responseText);
|
||||
}
|
||||
});
|
||||
form.send();
|
||||
};
|
||||
parent.SqueezeBox.close();
|
||||
}
|
||||
},
|
||||
onFailure: function(xhr) {
|
||||
parent.document.getElement('iframe').setStyles({width: 800, height: 600});
|
||||
$(document.body).set("html", xhr.responseText);
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
|
||||
default_submit = function(event) {
|
||||
var error_callbacks = {
|
||||
mbaliasform: function() {
|
||||
if ($("id_domain").value == 0) {
|
||||
$("id_mboxes").set("html", "");
|
||||
}
|
||||
mbaliasform_init();
|
||||
},
|
||||
armform: function() {
|
||||
new Calendar({id_untildate: "Y-m-d"}, {
|
||||
tweak: {x: -100, y:-100}
|
||||
});
|
||||
},
|
||||
permform: function() {
|
||||
if ($defined($("id_domain"))) {
|
||||
$("id_domain").options[0].setProperty("selected", "selected");
|
||||
domadminform_init();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ajax_submit(event, error_callbacks);
|
||||
};
|
||||
|
||||
$(document.body).addEvent("submit", default_submit);
|
||||
window.addEvent("domready", function() {
|
||||
$(document.body).addEvent("submit", ajax_submit);
|
||||
|
||||
$$("input[type!=submit]", "select").addEvents({
|
||||
focus: function(evt) {
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 325 B |
@@ -5,6 +5,7 @@
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/searchbar.css" />
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/ProgressBar.js"></script>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/ckeditor/ckeditor.js"></script>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/webmail/fdmenu.js"></script>
|
||||
{% block css %}{% endblock %}
|
||||
<style type="text/css">
|
||||
#navbar {
|
||||
|
||||
Reference in New Issue
Block a user