public: add support for badges next to menu items (#11116)

This commit is contained in:
Frédéric Péters 2016-05-28 19:25:19 +02:00
parent ed73a8ef82
commit 291484aee9
10 changed files with 74 additions and 18 deletions

View File

@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
#
# lingo - basket and payment system
# Copyright (C) 2015 Entr'ouvert
#
@ -310,6 +312,17 @@ class LingoBasketCell(CellBase):
).exclude(cancellation_date__isnull=False)
return len(items) > 0
def get_badge(self, context):
if not (getattr(context['request'], 'user', None) and context['request'].user.is_authenticated()):
return
items = BasketItem.objects.filter(
user=context['request'].user, payment_date__isnull=True
).exclude(cancellation_date__isnull=False)
if not items:
return
total = sum([x.amount for x in items])
return {'badge': _(u'%d') % total}
def render(self, context):
basket_template = template.loader.get_template('lingo/combo/basket.html')
context['items'] = BasketItem.objects.filter(

View File

@ -280,6 +280,9 @@ class CellBase(models.Model):
manager_form_template = 'combo/cell_form.html'
template_name = None
# get_badge(self, context); set to None so cell types can be skipped easily
get_badge = None
class Meta:
abstract = True
@ -314,10 +317,12 @@ class CellBase(models.Model):
return cell_types
@classmethod
def get_cells(cls, **kwargs):
def get_cells(cls, cell_filter=None, **kwargs):
"""Returns the list of cells of various classes matching **kwargs"""
cells = []
for klass in get_cell_classes():
if cell_filter and not cell_filter(klass):
continue
cells.extend(klass.objects.filter(**kwargs))
cells.sort(lambda x, y: cmp(x.order, y.order))
return cells

View File

@ -100,4 +100,28 @@ $(function() {
window.location.search = new_qs;
}
});
var menu_page_ids = $.makeArray($('[data-menu-page-id]').map(function() { return $(this).data('menu-page-id'); }));
if (menu_page_ids.length && $('body').data('check-badges') === true) {
$.ajax({url: $('body').data('api-root') + 'menu-badges/',
xhrFields: { withCredentials: true },
async: true,
dataType: 'json',
data: {'page': menu_page_ids},
crossDomain: true,
success: function(data) {
$(document).trigger('combo:menu-badges-loaded', data);
}});
}
$(document).on('combo:menu-badges-loaded', function(ctx, data) {
for (var page_id in data) {
var badge = data[page_id];
if (badge.badge) {
$('[data-menu-page-id=' + page_id + '] > a > span').append(' <span class="badge">' + badge.badge + '</span>');
}
if (badge.klass) {
$('[data-menu-page-id=' + page_id + ']').addClass(badge.klass);
}
}
});
});

View File

@ -3,7 +3,7 @@
<ul>
{% spaceless %}
{% for menuitem in menuitems %}
<li class="menu-{{ menuitem.page.slug }} {% if menuitem.selected %}selected{% endif %}"><a
<li data-menu-page-id="{{ menuitem.page.id }}" class="menu-{{ menuitem.page.slug }} {% if menuitem.selected %}selected{% endif %}"><a
href="{% page_absolute_url menuitem.page %}"><span>{{ menuitem.page.title }}</span></a>
{% if depth > 1 %}
{% show_menu current_page=menuitem.page level=-1 depth=depth reduce_depth=True %}

View File

@ -8,7 +8,9 @@
<script src="{{ STATIC_URL }}js/combo.public.js"></script>
{{ media }}
</head>
<body class="page-{{ page.slug }}">
<body class="page-{{ page.slug }}"
{% if check_badges %}data-check-badges="true"{% endif %}
data-api-root="{{ site_base }}/api/">
<div id="title"><h1>{{ page.title }}</h1></div>
<div id="menu">{% block menu %}{% show_menu %}{% endblock %}</div>
<div id="content">

View File

@ -19,6 +19,7 @@ from django.conf.urls import patterns, url
from . import views
urlpatterns = patterns('combo.publicviews',
url(r'^api/menu-badges/', views.menu_badges),
url(r'^ajax/cell/(?P<page_pk>\w+)/(?P<cell_reference>[\w_-]+)/$',
views.ajax_page_cell, name='combo-public-ajax-page-cell'),
(r'__style__/$', views.style),

View File

@ -14,6 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import json
import urllib
import urlparse
@ -191,12 +192,14 @@ def skeleton(request):
combo_template = settings.COMBO_PUBLIC_TEMPLATES[selected_page.template_name]
cell_with_badges = CellBase.get_cells(cell_filter=lambda x: bool(x.get_badge))
ctx = {
'page': selected_page,
'page_cells': cells,
'pages': pages,
'request': request,
'render_skeleton': True,
'check_badges': bool(cell_with_badges),
'site_base': request.build_absolute_uri('/')[:-1],
}
@ -261,8 +264,10 @@ def publish_page(request, page, status=200, template_name=None):
cells = CellBase.get_cells(page_id=page.id)
extend_with_locked_placeholders_cells(cells, page, pages)
cells = [x for x in cells if x.is_visible(user=request.user)]
cell_with_badges = CellBase.get_cells(cell_filter=lambda x: bool(x.get_badge))
ctx = {
'check_badges': bool(cell_with_badges),
'page': page,
'page_cells': cells,
'pages': pages,
@ -288,3 +293,19 @@ def error404(request, *args, **kwargs):
page = Page()
page.template_name = 'standard'
return publish_page(request, page, status=404, template_name='combo/404.html')
def menu_badges(request):
context = RequestContext(request, {'request': request})
page_ids = request.GET.getlist('page[]')
cells = CellBase.get_cells(
cell_filter=lambda x: bool(x.get_badge),
page_id__in=page_ids)
badges = {}
for cell in cells:
if cell.page_id in badges:
continue
badge = cell.get_badge(context)
if badge:
badges[cell.page_id] = badge
return HttpResponse(json.dumps(badges))

View File

@ -1,14 +0,0 @@
{% load combo %}
{% if menuitems %}
<ul>
{% for menuitem in menuitems %}
<li class="menu-{{ menuitem.page.slug }} {% if menuitem.selected %}selected{% endif %}"><a
href="{{ menuitem.page.get_online_url }}">{{ menuitem.page.title }}</a>
{% if depth > 1 %}
{% show_menu current_page=menuitem.page level=-1 depth=depth reduce_depth=True %}
{% endif %}
</li>
</li>
{% endfor %}
</ul>
{% endif %}

View File

@ -16,6 +16,10 @@
{% block site-title %}{% firstof site_title "Publik" %}{% endblock %}
{% block footer %}Combo — Copyright © Entr'ouvert{% endblock %}
{% block logout-url %}{% url 'auth_logout' %}{% endblock %}
{% block bodyargs %}
data-api-root="{{ site_base }}/api/"
{% if check_badges %}data-check-badges="true"{% endif %}
<{% endblock %}
{% block content %}
<div id="portal-agent-content">

View File

@ -1,7 +1,7 @@
{% extends "combo/page_template.html" %}
{% load combo %}
{% block bodyargs %}class="with-sidebar"{% endblock %}
{% block bodyargs %}{{ block.super }} class="with-sidebar"{% endblock %}
{% block combo-content %}
<div id="page-content">