Commit b6ea1339 authored by Nicolas Joyard's avatar Nicolas Joyard

Add sorting and CSV download

parent 129ffd04
......@@ -83,11 +83,11 @@ class SortMixin(object):
def get_context_data(self, **kwargs):
c = super(SortMixin, self).get_context_data(**kwargs)
c['queries'] = copy(self.request.GET)
if 'sort_by' in c['queries']:
del c['queries']['sort_by']
if 'sort_dir' in c['queries']:
del c['queries']['sort_dir']
c['sort_querystring'] = copy(self.request.GET)
if 'sort_by' in c['sort_querystring']:
del c['sort_querystring']['sort_by']
if 'sort_dir' in c['sort_querystring']:
del c['sort_querystring']['sort_dir']
c['sort'] = {
'fields': self.sort_fields,
......@@ -138,9 +138,9 @@ class PaginationMixin(object):
c['pagination_limits'] = self.pagination_limits
c['paginate_by'] = self.request.session['paginate_by']
c['page_range'] = self.get_page_range(c['page_obj'])
c['queries'] = copy(self.request.GET)
if 'page' in c['queries']:
del c['queries']['page']
c['pagination_querystring'] = copy(self.request.GET)
if 'page' in c['pagination_querystring']:
del c['pagination_querystring']['page']
return c
......@@ -167,6 +167,12 @@ class GridListMixin(object):
class CSVDownloadMixin(object):
def get_context_data(self, **kwargs):
c = super(CSVDownloadMixin, self).get_context_data(**kwargs)
c['csv'] = True
c['csv_querystring'] = copy(self.request.GET)
return c
def get_paginate_by(self, queryset):
if self.request.GET.get('csv', None) is None:
return super(CSVDownloadMixin, self).get_paginate_by(queryset)
......
......@@ -15,6 +15,9 @@ class BaseTest(ResponseDiffTestMixin, test.TestCase):
"""
left_pane_queries = 5
def request_test(self, url=None):
self.assertResponseDiffEmpty(self.client.get(url or self.url))
def selector_test(self, selector, url=None):
self.assertResponseDiffEmpty(self.client.get(url or self.url),
selector)
Zigmantas BALČYTIS,zigmantas.balcytis@europarl.europa.eu,SD,Lithuania [LT]
Vilija BLINKEVIČIŪTĖ,vilija.blinkeviciute@europarl.europa.eu,SD,Lithuania [LT]
Elmar BROK,elmar.brok@europarl.europa.eu,EPP,Germany [DE]
Cristian-Silviu BUŞOI,cristiansilviu.busoi@europarl.europa.eu,EPP,Romania [RO]
David CASA,david.casa@europarl.europa.eu,EPP,Malta [MT]
Jean-Marie CAVADA,jean-marie.cavada@europarl.europa.eu,ALDE,France [FR]
Nikolaos CHOUNTIS,nikolaos.chountis@europarl.europa.eu,GUE/NGL,Greece [GR]
Michael CRAMER,michael.cramer@europarl.europa.eu,Greens/EFA,Germany [DE]
Viorica DĂNCILĂ,vasilicaviorica.dancila@europarl.europa.eu,SD,Romania [RO]
Michel DANTIN,"michel.dantin@europarl.europa.eu, dantin.michel@sp-eurodepute.eu",EPP,France [FR]
Tamás DEUTSCH,tamas.deutsch@europarl.europa.eu,EPP,Hungary [HU]
Bas EICKHOUT,bas.eickhout@europarl.europa.eu,Greens/EFA,Netherlands [NL]
Ismail ERTUG,ismail.ertug@europarl.europa.eu,SD,Germany [DE]
José Manuel FERNANDES,josemanuel.fernandes@europarl.europa.eu,EPP,Portugal [PT]
Monika FLAŠÍKOVÁ BEŇOVÁ,monika.flasikovabenova@europarl.europa.eu,SD,Slovakia [SK]
Ashley FOX,ashley.fox@europarl.europa.eu,ECR,United Kingdom [GB]
Kinga GÁL,kinga.gal@europarl.europa.eu,EPP,Hungary [HU]
Ildikó GÁLL-PELCZ,ildiko.gall-pelcz@europarl.europa.eu,EPP,Hungary [HU]
Eider GARDIAZABAL RUBIAL,eider.gardiazabalrubial@europarl.europa.eu,SD,Spain [ES]
Marian HARKIN,marian.harkin@europarl.europa.eu,ALDE,Ireland [IE]
Mary HONEYBALL,mary.honeyball@europarl.europa.eu,SD,United Kingdom [GB]
Iliana IOTOVA,"iliana.iotova@europarl.europa.eu, iliana.iotova-office@europarl.europa.eu",SD,Bulgaria [BG]
Liisa JAAKONSAARI,liisa.jaakonsaari@europarl.europa.eu,SD,Finland [FI]
Yannick JADOT,yannick.jadot@europarl.europa.eu,Greens/EFA,France [FR]
Eva JOLY,eva.joly@europarl.europa.eu,Greens/EFA,France [FR]
Jarosław KALINOWSKI,jaroslaw.kalinowski@europarl.europa.eu,EPP,Poland [PL]
Andrey KOVATCHEV,andrey.kovatchev@europarl.europa.eu,EPP,Bulgaria [BG]
Olle LUDVIGSSON,olle.ludvigsson@europarl.europa.eu,SD,Sweden [SE]
Sirpa PIETIKÄINEN,sirpa.pietikainen@europarl.europa.eu,EPP,Finland [FI]
Frédérique RIES,frederique.ries@europarl.europa.eu,ALDE,Belgium [BE]
Birgit SIPPEL,birgit.sippel@europarl.europa.eu,SD,Germany [DE]
Charles TANNOCK,charles.tannock@europarl.europa.eu,ECR,United Kingdom [GB]
Ramon TREMOSA i BALCELLS,ramon.tremosa@europarl.europa.eu,ALDE,Spain [ES]
Vladimir URUTCHEV,vladimir.urutchev@europarl.europa.eu,EPP,Bulgaria [BG]
Ivo VAJGL,ivo.vajgl@europarl.europa.eu,ALDE,Slovenia [SI]
Cecilia WIKSTRÖM,cecilia.wikstrom@europarl.europa.eu,ALDE,Sweden [SE]
{
"status_code": 200
}
\ No newline at end of file
<h4 class="text-center">Zigmantas BALČYTIS</h4>
---
<h4 class="text-center">Vilija BLINKEVIČIŪTĖ</h4>
---
<h4 class="text-center">Elmar BROK</h4>
---
<h4 class="text-center">Cristian-Silviu BUŞOI</h4>
---
<h4 class="text-center">David CASA</h4>
---
<h4 class="text-center">Jean-Marie CAVADA</h4>
---
<h4 class="text-center">Nikolaos CHOUNTIS</h4>
---
<h4 class="text-center">Michael CRAMER</h4>
---
<h4 class="text-center">Viorica DĂNCILĂ</h4>
---
<h4 class="text-center">Michel DANTIN</h4>
---
<h4 class="text-center">Tamás DEUTSCH</h4>
---
<h4 class="text-center">Bas EICKHOUT</h4>
\ No newline at end of file
<h4 class="text-center">Cecilia WIKSTRÖM</h4>
---
<h4 class="text-center">Ivo VAJGL</h4>
---
<h4 class="text-center">Vladimir URUTCHEV</h4>
---
<h4 class="text-center">Ramon TREMOSA i BALCELLS</h4>
---
<h4 class="text-center">Charles TANNOCK</h4>
---
<h4 class="text-center">Birgit SIPPEL</h4>
---
<h4 class="text-center">Frédérique RIES</h4>
---
<h4 class="text-center">Sirpa PIETIKÄINEN</h4>
---
<h4 class="text-center">Olle LUDVIGSSON</h4>
---
<h4 class="text-center">Andrey KOVATCHEV</h4>
---
<h4 class="text-center">Jarosław KALINOWSKI</h4>
---
<h4 class="text-center">Eva JOLY</h4>
\ No newline at end of file
<li>
<a href="?&amp;sort_by=score__score">score</a>
</li>
---
<li class="disabled">
<a href="?&amp;sort_by=last_name">name</a>
</li>
---
<li class="disabled">
<a href="?&amp;sort_dir=asc">ascending</a>
</li>
---
<li>
<a href="?&amp;sort_dir=asc">descending</a>
</li>
\ No newline at end of file
<h4 class="text-center">Andrey KOVATCHEV</h4>
---
<h4 class="text-center">Ashley FOX</h4>
---
<h4 class="text-center">Charles TANNOCK</h4>
---
<h4 class="text-center">Vladimir URUTCHEV</h4>
---
<h4 class="text-center">Tamás DEUTSCH</h4>
---
<h4 class="text-center">Kinga GÁL</h4>
---
<h4 class="text-center">Jean-Marie CAVADA</h4>
---
<h4 class="text-center">José Manuel FERNANDES</h4>
---
<h4 class="text-center">Ildikó GÁLL-PELCZ</h4>
---
<h4 class="text-center">Michel DANTIN</h4>
---
<h4 class="text-center">David CASA</h4>
---
<h4 class="text-center">Jarosław KALINOWSKI</h4>
\ No newline at end of file
<h4 class="text-center">Iliana IOTOVA</h4>
---
<h4 class="text-center">Liisa JAAKONSAARI</h4>
---
<h4 class="text-center">Yannick JADOT</h4>
---
<h4 class="text-center">Birgit SIPPEL</h4>
---
<h4 class="text-center">Eider GARDIAZABAL RUBIAL</h4>
---
<h4 class="text-center">Ramon TREMOSA i BALCELLS</h4>
---
<h4 class="text-center">Eva JOLY</h4>
---
<h4 class="text-center">Nikolaos CHOUNTIS</h4>
---
<h4 class="text-center">Viorica DĂNCILĂ</h4>
---
<h4 class="text-center">Ivo VAJGL</h4>
---
<h4 class="text-center">Zigmantas BALČYTIS</h4>
---
<h4 class="text-center">Vilija BLINKEVIČIŪTĖ</h4>
\ No newline at end of file
Cecilia WIKSTRÖM,cecilia.wikstrom@europarl.europa.eu,ALDE,Sweden [SE]
Ivo VAJGL,ivo.vajgl@europarl.europa.eu,ALDE,Slovenia [SI]
Vladimir URUTCHEV,vladimir.urutchev@europarl.europa.eu,EPP,Bulgaria [BG]
Ramon TREMOSA i BALCELLS,ramon.tremosa@europarl.europa.eu,ALDE,Spain [ES]
Charles TANNOCK,charles.tannock@europarl.europa.eu,ECR,United Kingdom [GB]
Birgit SIPPEL,birgit.sippel@europarl.europa.eu,SD,Germany [DE]
Frédérique RIES,frederique.ries@europarl.europa.eu,ALDE,Belgium [BE]
Sirpa PIETIKÄINEN,sirpa.pietikainen@europarl.europa.eu,EPP,Finland [FI]
Olle LUDVIGSSON,olle.ludvigsson@europarl.europa.eu,SD,Sweden [SE]
Andrey KOVATCHEV,andrey.kovatchev@europarl.europa.eu,EPP,Bulgaria [BG]
Jarosław KALINOWSKI,jaroslaw.kalinowski@europarl.europa.eu,EPP,Poland [PL]
Eva JOLY,eva.joly@europarl.europa.eu,Greens/EFA,France [FR]
Yannick JADOT,yannick.jadot@europarl.europa.eu,Greens/EFA,France [FR]
Liisa JAAKONSAARI,liisa.jaakonsaari@europarl.europa.eu,SD,Finland [FI]
Iliana IOTOVA,"iliana.iotova@europarl.europa.eu, iliana.iotova-office@europarl.europa.eu",SD,Bulgaria [BG]
Mary HONEYBALL,mary.honeyball@europarl.europa.eu,SD,United Kingdom [GB]
Marian HARKIN,marian.harkin@europarl.europa.eu,ALDE,Ireland [IE]
Eider GARDIAZABAL RUBIAL,eider.gardiazabalrubial@europarl.europa.eu,SD,Spain [ES]
Ildikó GÁLL-PELCZ,ildiko.gall-pelcz@europarl.europa.eu,EPP,Hungary [HU]
Kinga GÁL,kinga.gal@europarl.europa.eu,EPP,Hungary [HU]
Ashley FOX,ashley.fox@europarl.europa.eu,ECR,United Kingdom [GB]
Monika FLAŠÍKOVÁ BEŇOVÁ,monika.flasikovabenova@europarl.europa.eu,SD,Slovakia [SK]
José Manuel FERNANDES,josemanuel.fernandes@europarl.europa.eu,EPP,Portugal [PT]
Ismail ERTUG,ismail.ertug@europarl.europa.eu,SD,Germany [DE]
Bas EICKHOUT,bas.eickhout@europarl.europa.eu,Greens/EFA,Netherlands [NL]
Tamás DEUTSCH,tamas.deutsch@europarl.europa.eu,EPP,Hungary [HU]
Michel DANTIN,"michel.dantin@europarl.europa.eu, dantin.michel@sp-eurodepute.eu",EPP,France [FR]
Viorica DĂNCILĂ,vasilicaviorica.dancila@europarl.europa.eu,SD,Romania [RO]
Michael CRAMER,michael.cramer@europarl.europa.eu,Greens/EFA,Germany [DE]
Nikolaos CHOUNTIS,nikolaos.chountis@europarl.europa.eu,GUE/NGL,Greece [GR]
Jean-Marie CAVADA,jean-marie.cavada@europarl.europa.eu,ALDE,France [FR]
David CASA,david.casa@europarl.europa.eu,EPP,Malta [MT]
Cristian-Silviu BUŞOI,cristiansilviu.busoi@europarl.europa.eu,EPP,Romania [RO]
Elmar BROK,elmar.brok@europarl.europa.eu,EPP,Germany [DE]
Vilija BLINKEVIČIŪTĖ,vilija.blinkeviciute@europarl.europa.eu,SD,Lithuania [LT]
Zigmantas BALČYTIS,zigmantas.balcytis@europarl.europa.eu,SD,Lithuania [LT]
Zigmantas BALČYTIS,zigmantas.balcytis@europarl.europa.eu,SD,Lithuania [LT]
Elmar BROK,elmar.brok@europarl.europa.eu,EPP,Germany [DE]
Jean-Marie CAVADA,jean-marie.cavada@europarl.europa.eu,ALDE,France [FR]
Tamás DEUTSCH,tamas.deutsch@europarl.europa.eu,EPP,Hungary [HU]
Ismail ERTUG,ismail.ertug@europarl.europa.eu,SD,Germany [DE]
José Manuel FERNANDES,josemanuel.fernandes@europarl.europa.eu,EPP,Portugal [PT]
Marian HARKIN,marian.harkin@europarl.europa.eu,ALDE,Ireland [IE]
Mary HONEYBALL,mary.honeyball@europarl.europa.eu,SD,United Kingdom [GB]
......@@ -21,6 +21,25 @@ class RepresentativeListTest(BaseTest):
def test_cards(self):
self.selector_test('.representative-card')
def test_navbar_order_options(self):
self.selector_test('#listheader #orderby li, #listheader #orderdir li')
def test_navbar_order_name_asc(self):
self.selector_test('.representative-card h4',
'%s?sort_by=last_name&sort_dir=asc' % self.url)
def test_navbar_order_name_desc(self):
self.selector_test('.representative-card h4',
'%s?sort_by=last_name&sort_dir=desc' % self.url)
def test_navbar_order_score_asc(self):
self.selector_test('.representative-card h4',
'%s?sort_by=score__score&sort_dir=asc' % self.url)
def test_navbar_order_score_desc(self):
self.selector_test('.representative-card h4',
'%s?sort_by=score__score&sort_dir=desc' % self.url)
def test_search_no_results(self):
self.selector_test('.representative-card h4',
'%s?search=non-existing' % self.url)
......@@ -56,3 +75,12 @@ class RepresentativeListTest(BaseTest):
def test_search_by_max_score(self):
self.selector_test('.representative-card h4',
'%s?scoremax=0' % self.url)
def test_csv(self):
self.request_test('%s?csv' % self.url)
def test_search_csv(self):
self.request_test('%s?search=ma&csv' % self.url)
def test_order_csv(self):
self.request_test('%s?sort_by=last_name&sort_dir=desc&csv' % self.url)
{% load i18n %}
<nav class="text-center">
<ul class="pagination">
{% if page_obj.has_previous %}
<li>
<a href="?{{pagination_querystring.urlencode}}&page={{ page_obj.previous_page_number }}" aria-label="{% trans 'Previous' %}">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{% else %}
<li class="disabled">
<span aria-hidden="true">&laquo;</span>
</li>
{% endif %}
{% for page in paginator.page_range %}
{% if page_obj.number|add:"5" > page and page_obj.number|add:"-5" < page %}
<li {% if page == page_obj.number %}class="active"{% endif %}>
<a href="?{{pagination_querystring.urlencode}}&page={{page}}">{{ page }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li>
<a href="?{{pagination_querystring.urlencode}}&page={{ page_obj.next_page_number }}" aria-label="{% trans 'Next' %}">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% else %}
<li class="disabled">
<span aria-hidden="true">&raquo;</span>
</li>
{% endif %}
</ul>
</nav>
{% load i18n %}
{% trans "Order by" %}
<div class="btn-group" id="orderby">
<button class="btn btn-default dropdown-toggle" type="button" id="orderby-button" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="true">
{% for field, label in sort.fields.items %}
{% if sort.field == field %}{% trans label %}{% endif %}
{% endfor %}
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="orderby-button">
{% for field, label in sort.fields.items %}
<li {% if sort.field == field %}class="disabled"{% endif %}>
<a href="?{{ sort_querystring.urlencode }}&sort_by={{ field }}">{% trans label %}</a>
</li>
{% endfor %}
</ul>
</div>
<div class="btn-group" id="orderdir">
<button class="btn btn-default dropdown-toggle" type="button" id="orderdir-button" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="true">
{% if sort.dir == 'asc' %}{% trans "ascending" %}{% else %}{% trans "descending" %}{% endif %}
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="orderdir-button">
<li {% if sort.dir == 'asc' %}class="disabled"{% endif %}>
<a href="?{{ sort_querystring.urlencode }}&sort_dir=asc">{% trans "ascending" %}</a>
</li>
<li {% if sort.dir == 'desc' %}class="disabled"{% endif %}>
<a href="?{{ sort_querystring.urlencode }}&sort_dir=asc">{% trans "descending" %}</a>
</li>
</ul>
</div>
\ No newline at end of file
{% if paginator and paginator.num_pages > 1 %}
<div class="container-fluid">
<div class="row">
{% include "blocks/_pagination.html" %}
</div>
</div>
{% endif %}
{% load bootstrap3 %}
{% load i18n %}
<div class="container-fluid" id="listheader">
<div class="row">
<div class="col-sm-8">
{% if sort.fields|length > 0 %}
{% include "blocks/_sorting.html" %}
{% endif %}
</div>
<div class="col-sm-4 text-right">
{% if csv or 1 %}
<a class="btn btn-default" role="button" href="?{{ csv_querystring.urlencode }}&csv">
{% bootstrap_icon "download-alt" %}
{% trans "Download CSV" %}
</a>
{% endif %}
</div>
</div>
</div>
{% if paginator and paginator.num_pages > 1 %}
<div class="container-fluid">
<div class="row">
{% include "blocks/_pagination.html" %}
</div>
</div>
{% endif %}
{% if paginator and paginator.num_pages > 1 %}
<nav class="text-center">
<ul class="pagination">
{% if page_obj.has_previous %}
<li><a href="?{{searchparameters.urlencode}}&page={{ page_obj.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span></a>
</li>
{% else %}
<li class="disabled"><span aria-hidden="true">&laquo;</span></li>
{% endif %}
{% for page in paginator.page_range %}
{% if page_obj.number|add:"5" > page and page_obj.number|add:"-5" < page %}
<li {% if page == page_obj.number %}class="active"{% endif %}><a href="?{{searchparameters}}&page={{page}}">{{ page }}</a></li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li>
<a href="?{{searchparameters}}&page={{ page_obj.next_page_number }}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a>
</li>
{% else %}
<li class="disabled"><span aria-hidden="true">&raquo;</span></li>
{% endif %}
</ul>
</nav>
{% endif %}
......@@ -6,47 +6,13 @@
{% block container-class %}custom-listMEP{% endblock %}
{% block content %}
<h1 class="text-center">{% trans "Representatives" %}</h1>
<p class="lead text-center">
Found {{ paginator.count }} {% trans "representatives" %}.
</p>
<div class="row">
<a href="?{{ searchparameters }}&csv" class="btn btn-default">
<span class="glyphicon glyphicon-file"> {% trans "Download as CSV." %}</span>
</a>
{% comment %}
<!-- TODO: layout & ordering -->
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default active">
<input type="radio" name="view" id="cards" autocomplete="off" checked>
<span class="glyphicon glyphicon-th"></span>
</label>
<label class="btn btn-default">
<input type="radio" name="view" id="lists" autocomplete="off">
<span class="glyphicon glyphicon-list"></span>
</label>
</div>
<div class="dropdown" style="display:inline-block;">
Order by
<button class="btn btn-default dropdown-toggle" type="button" id="orderby" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Score
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="orderby">
<li class="disabled"><a href="#">Score</a></li>
<li><a href="#">Country</a></li>
<li><a href="#">Party</a></li>
<li><a href="#">Group</a></li>
</ul>
</div>
{% endcomment %}
</div>
{% include "blocks/listheader.html" %}
<div class="row">
{% for representative in object_list %}
......@@ -94,6 +60,6 @@
{% endfor %}
</div>
{% include "pagination.html" %}
{% include "blocks/listfooter.html" %}
{% endblock %}
......@@ -69,6 +69,6 @@
{% endfor %}
</div>
{% include "pagination.html" %}
{% include "blocks/_pagination.html" %}
{% endblock %}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment