Infinite scroll for the calendar list.

see #585
This commit is contained in:
Antoine Nguyen
2014-10-08 16:33:28 +02:00
parent 0ecd163051
commit 3148fee75f
10 changed files with 71 additions and 50 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ from django.conf.urls import include
class ModoExtension(object):
"""Base extension class
"""Base extension class.
Each Modoboa extension must inherit from this class to be
considered as valid.
@@ -39,7 +39,6 @@ Admin.prototype = {
* Children must override this method.
*/
listen: function() {
$(document).on("click", "a.filter", $.proxy(this.filter_by_tag, this));
},
importform_cb: function() {
+1
View File
@@ -33,6 +33,7 @@ class Radicale(ModoExtension):
name = "radicale"
label = ugettext_lazy("Radicale frontend")
version = "1.0"
url = "calendars"
description = ugettext_lazy(
"Management frontend for Radicale, a simple calendar and contact server."
)
@@ -14,13 +14,16 @@ Radicale.prototype = {
constructor: Radicale,
defaults: {
deflocation: "calendars/"
deflocation: "list/",
main_table_id: "calendar_table",
eor_message: gettext("No more calendar to show")
},
initialize: function(options) {
this.options = $.extend({}, this.defaults, options);
this.options.defcallback = $.proxy(this.list_cb, this);
Listing.prototype.initialize.call(this, this.options);
this.options.navigation_params.push("calfilter");
this.register_tag_handler("cal", this.generic_tag_handler);
$(document).on(
"click", "a[name=delcalendar]", $.proxy(this.del_calendar, this)
@@ -28,9 +31,8 @@ Radicale.prototype = {
},
list_cb: function(data) {
$("#listing").html(data.table);
$("#{0} tbody".format(this.options.main_table_id)).html(data.rows);
this.update_listing(data);
$("a.filter").click($.proxy(this.filter_by_tag, this));
},
/**
@@ -1,23 +0,0 @@
{% load i18n lib_tags radicale_tags %}
<table id="{{ tableid }}" class="table {{ styles }}">
<thead>
<tr>
<th id="name" class="sortable" data-sort_order="name" width="">{% trans "Name" %}</th>
{% if with_owner %}<th id="owner" class="sortable" data-sort_order="owner">{% trans "Owner" %}</th>{% endif %}
<th id="tags">{% trans "Tags" %}</th>
<th id="url">{% trans "Address" %}</th>
<th id="actions" width="">{% trans "Actions" %}</th>
</tr>
</thead>
<tbody>
{% for cal in calendars %}
<tr id="{{ cal.id }}" class="" name="{{ forloop.counter }}">
<td name="name">{% calendar_modify_link cal %}</td>
{% if with_owner %}<td name="owner">{{ cal.owner }}</td>{% endif %}
<td name="tags">{% render_tags cal.tags %}</td>
<td name="url">{{ cal.url }}</td>
<td name="actions">{% calendar_actions cal %}</td>
</tr>
{% endfor %}
</tbody>
</table>
@@ -3,6 +3,7 @@
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/jquery.sortable.css" />
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}radicale/css/radicale.css" />
<script type="text/javascript" src="{{ STATIC_URL }}js/jquery.sortable.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/jquery.infinitescroll.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/history.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/creation_wizard.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/listing.js"></script>
@@ -12,7 +13,8 @@
<script type="text/javascript">
$(document).ready(function() {
radicale = new Radicale({
"username_list_url": "{% url 'radicale:username_list' %}"
"username_list_url": "{% url 'radicale:username_list' %}",
"load_page_url": "{% url 'radicale:calendars_page' %}"
});
});
</script>
@@ -31,5 +33,20 @@ $(document).ready(function() {
</div>
</div>
<div id="listing"></div>
<div id="listing">
<table id="calendar_table" class="table">
<thead>
<tr>
<th id="name" class="sortable" data-sort_order="name" width="">{% trans "Name" %}</th>
{% if with_owner %}<th id="owner" class="sortable" data-sort_order="owner">{% trans "Owner" %}</th>{% endif %}
<th id="tags">{% trans "Tags" %}</th>
<th id="url">{% trans "Address" %}</th>
<th id="actions" width="">{% trans "Actions" %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
{% endblock %}
@@ -0,0 +1,10 @@
{% load i18n lib_tags radicale_tags %}
{% for cal in calendars %}
<tr id="{{ cal.id }}" class="" name="{{ forloop.counter }}">
<td name="name">{% calendar_modify_link cal %}</td>
{% if with_owner %}<td name="owner">{{ cal.owner }}</td>{% endif %}
<td name="tags">{% render_tags cal.tags %}</td>
<td name="url">{{ cal.url }}</td>
<td name="actions">{% calendar_actions cal %}</td>
</tr>
{% endfor %}
+5 -5
View File
@@ -4,13 +4,13 @@ urlpatterns = patterns(
'modoboa.extensions.radicale.views',
url(r'^$', 'index', name="index"),
url(r'^calendars/$', 'calendars', name="calendar_list"),
url(r'^usercalendar/$', 'new_user_calendar', name='user_calendar_add'),
url(r'^usercalendar/(?P<pk>\d+)/$', 'user_calendar',
url(r'^list/$', 'calendars_page', name="calendars_page"),
url(r'^user/$', 'new_user_calendar', name='user_calendar_add'),
url(r'^user/(?P<pk>\d+)/$', 'user_calendar',
name='user_calendar'),
url(r'^sharedcalendar/$', 'new_shared_calendar',
url(r'^shared/$', 'new_shared_calendar',
name='shared_calendar_add'),
url(r'^sharedcalendar/(?P<pk>\d+)/$', 'shared_calendar',
url(r'^shared/(?P<pk>\d+)/$', 'shared_calendar',
name='shared_calendar'),
url(r'^usernames/$', 'username_list', name='username_list'),
)
+28 -15
View File
@@ -10,7 +10,7 @@ from django.contrib.auth.decorators import (
)
from django.utils.translation import ugettext as _
from modoboa.lib.listing import get_sort_order
from modoboa.lib.listing import get_sort_order, get_listing_page
from modoboa.lib.webutils import (
_render_to_string, render_to_json_response
)
@@ -24,27 +24,25 @@ from modoboa.extensions.radicale.models import UserCalendar, SharedCalendar
@login_required
def index(request):
"""Calendar list entry point."""
return render(request, "radicale/calendars.html", {
"selection": "radicale"
"selection": "radicale",
"with_owner": request.user.group != "SimpleUsers"
})
@login_required
def calendars(request, tplname="radicale/calendar_list.html"):
"""Display calendars list.
The content depends on current user's role.
"""
def get_calendar_page(request, page_id=None):
"""Return a page containing calendars."""
sort_order, sort_dir = get_sort_order(request.GET, "name")
calfilter = request.GET.get("calfilter", None)
searchquery = request.GET.get("searchquery", None)
page_id = request.GET.get("page", 1)
if request.user.group == "SimpleUsers":
mbox = request.user.mailbox_set.all()[0]
cals = UserCalendar.objects.filter(mailbox=mbox)
if searchquery is not None:
cals = cals.filter(name__icontains=searchquery)
cals = cals.select_related().all()
with_owner = False
else:
ucals = []
if calfilter is None or calfilter == "user":
@@ -57,15 +55,30 @@ def calendars(request, tplname="radicale/calendar_list.html"):
if searchquery is not None:
scals = scals.filter(name__icontains=searchquery)
cals = chain(ucals, scals)
with_owner = True
cals = sorted(
cals, key=lambda c: getattr(c, sort_order), reverse=sort_dir == '-'
)
return render_to_json_response({
"table": _render_to_string(request, tplname, {
"calendars": cals, "with_owner": with_owner
})
})
return get_listing_page(cals, page_id)
@login_required
def calendars_page(request, tplname="radicale/calendars_page.html"):
"""Return a page of calendars.
The content depends on current user's role.
"""
page = get_calendar_page(request)
if page is None:
context = {"length": 0}
else:
context = {
"rows": _render_to_string(request, tplname, {
"calendars": page.object_list,
"with_owner": request.user.group != "SimpleUsers"
}),
"page": page.number
}
return render_to_json_response(context)
@login_required
+2
View File
@@ -31,6 +31,7 @@ Listing.prototype = {
$.proxy(this.load_page, this));
$(document).on("click", this.options.presp_container + " a",
$.proxy(this.load_page, this));
$(document).on("click", "a.filter", $.proxy(this.filter_by_tag, this));
if (this.options.with_searchform) {
this.init_searchform();
}
@@ -131,6 +132,7 @@ Listing.prototype = {
update_listing: function(data, with_infinite_scroll) {
var $this = this;
$(window).scrollTop(0);
if (with_infinite_scroll || with_infinite_scroll === undefined) {
if ($(window).data("infinite-scroll") !== undefined) {
$(window).infinite_scroll("reset_loaded_pages", data.page);