Commit 71b8a11e authored by Ash_Crow's avatar Ash_Crow Committed by Nicolas Joyard

Separate representative details into tabs

This commit repeats changes from commit 5bc7f3 onto v3
Signed-off-by: default avatarNicolas Joyard <joyard.nicolas@gmail.com>
parent 885ac063
......@@ -8,9 +8,12 @@ from views.dossier_detail import DossierDetail
from views.dossier_list import DossierList
from views.group_ac import GroupAutocomplete
from views.group_list import GroupList
from views.representative_detail import RepresentativeDetail
from views.representative_detail_votes import RepresentativeDetailVotes
from views.representative_detail_mandates import RepresentativeDetailMandates
from views.representative_detail_positions import RepresentativeDetailPositions
from views.representative_list import RepresentativeList
from views.redirects import RedirectGroupList, RedirectGroupRepresentativeList
from views.redirects import (RedirectGroupList, RedirectRepresentativeDetail,
RedirectGroupRepresentativeList)
from views.theme_detail import ThemeDetail
from views.theme_list import ThemeList
......@@ -37,9 +40,25 @@ urlpatterns = [
),
url(
r'^legislature/representative/(?P<slug>[-\w]+)/$',
RepresentativeDetail.as_view(),
RedirectRepresentativeDetail.as_view(),
name='representative-detail'
),
url(
r'^legislature/representative/(?P<slug>[-\w]+)/votes/$',
RepresentativeDetailVotes.as_view(),
name='representative-votes'
),
url(
r'^legislature/representative/(?P<slug>[-\w]+)/mandates/$',
RepresentativeDetailMandates.as_view(),
name='representative-mandates'
),
url(
r'^legislature/representative/(?P<slug>[-\w]+)/positions/$',
RepresentativeDetailPositions.as_view(),
name='representative-positions'
),
url(
r'^legislature/group/$',
GroupList.as_view(),
......
......@@ -28,3 +28,8 @@ class RedirectGroupRepresentativeList(RedirectView):
group = Group.objects.get(kind=kwargs['group_kind'],
name=kwargs['group'])
return '%s?group=%s' % (reverse('representative-list'), group.pk)
class RedirectRepresentativeDetail(RedirectView):
permanent = True
pattern_name = 'representative-votes'
......@@ -5,19 +5,16 @@ from django.views import generic
from representatives.models import Chamber, Representative, Address, Phone, \
WebSite
from representatives_positions.forms import PositionForm
from representatives_recommendations.models import VoteScore
from representatives_votes.models import Proposal
from .representative_mixin import RepresentativeViewMixin
class RepresentativeDetail(RepresentativeViewMixin, generic.DetailView):
class RepresentativeDetailBase(RepresentativeViewMixin, generic.DetailView):
queryset = Representative.objects.select_related('score')
def get_queryset(self):
qs = super(RepresentativeDetail, self).get_queryset()
qs = super(RepresentativeDetailBase, self).get_queryset()
qs = self.prefetch_for_representative_country_and_main_mandate(qs)
......@@ -50,30 +47,14 @@ class RepresentativeDetail(RepresentativeViewMixin, generic.DetailView):
models.Prefetch(
'phone_set',
queryset=Phone.objects.select_related('address__country')
),
models.Prefetch(
'votes',
queryset=VoteScore.objects.filter(
proposal__in=Proposal.objects.exclude(recommendation=None),
).select_related('proposal__recommendation').order_by(
'-proposal__datetime')
)
)
return qs
def get_context_data(self, **kwargs):
c = super(RepresentativeDetail, self).get_context_data(**kwargs)
self.add_representative_country_and_main_mandate(c['object'])
c['votes'] = c['object'].votes.all()
c['mandates'] = c['object'].mandates.all()
c['positions'] = c['object'].positions.filter(published=True) \
.order_by('-datetime', 'pk')
c = super(RepresentativeDetailBase, self).get_context_data(**kwargs)
c['position_form'] = PositionForm(
initial={'representative': self.object.pk})
self.add_representative_country_and_main_mandate(c['object'])
return c
# coding: utf-8
from django.views import generic
from representatives.models import Representative
from .representative_detail_base import RepresentativeDetailBase
class RepresentativeDetailMandates(RepresentativeDetailBase):
template_name = 'representatives/representative_detail_mandates.html'
def get_context_data(self, **kwargs):
c = super(RepresentativeDetailMandates,
self).get_context_data(**kwargs)
c['tab'] = 'mandates'
c['mandates'] = c['object'].mandates.all()
return c
# coding: utf-8
from django.db import models
from django.views import generic
from representatives.models import Representative
from representatives_positions.forms import PositionForm
from representatives_positions.models import Position
from .representative_detail_base import RepresentativeDetailBase
class RepresentativeDetailPositions(RepresentativeDetailBase):
template_name = 'representatives/representative_detail_positions.html'
def get_queryset(self):
qs = super(RepresentativeDetailPositions, self).get_queryset()
qs = qs.prefetch_related(
models.Prefetch(
'positions',
queryset=Position.objects.filter(published=True)
.order_by('-datetime', 'pk')
)
)
return qs
def get_context_data(self, **kwargs):
c = super(RepresentativeDetailPositions,
self).get_context_data(**kwargs)
c['tab'] = 'positions'
c['positions'] = c['object'].positions.all()
return c
# coding: utf-8
from django.db import models
from django.views import generic
from representatives.models import Representative
from representatives_recommendations.models import VoteScore
from representatives_votes.models import Proposal
from .representative_detail_base import RepresentativeDetailBase
class RepresentativeDetailVotes(RepresentativeDetailBase):
template_name = 'representatives/representative_detail_votes.html'
def get_queryset(self):
qs = super(RepresentativeDetailVotes, self).get_queryset()
qs = qs.prefetch_related(
models.Prefetch(
'votes',
queryset=VoteScore.objects.filter(
proposal__in=Proposal.objects.exclude(recommendation=None),
).select_related('proposal__recommendation').order_by(
'-proposal__datetime')
)
)
return qs
def get_context_data(self, **kwargs):
c = super(RepresentativeDetailVotes, self).get_context_data(**kwargs)
c['tab'] = 'votes'
c['votes'] = c['object'].votes.all()
return c
{% load memopol_tags %}
<br/>
<div class="row">
{% for mandate in mandates %}
<div class="col-sm-6 col-md-4">
<div class="thumbnail">
<div class="caption">
<h3 class="text-center">
<a href="{{ mandate.group.get_absolute_url }}">{{ mandate.group.name }}
{% if mandate.group.abreviation %}{{ mandate.group.abreviation }}{% endif %}
</a>
</h3>
<hr>
{# mandate.constituency.name - #}
<p><span class="lead">{{ mandate.role }}</span> from {{ mandate.begin_date|mandate_date:'d/m/Y' }} to {{ mandate.end_date|mandate_date:'d/m/Y' }}</p>
</div>
</div>
</div>
{% if forloop.counter|divisibleby:3 %}</div><div class="row">{% endif %}
{% endfor %}
</div>
{% load humanize %}
{% load i18n %}
{% load representatives_positions_tags %}
{% if not positions %}
{# TODO: link #}
<p>No public position has been recorded. You can always <a>add a public position</a>.</p>
{% else %}
<table class="table table-responsive custom-timeline text-center">
<thead>
<tr>
<th class="text-center">{% trans "Before" %}</th>
<th class="text-center">{% trans "Last year" %}</th>
<th class="text-center">{% trans "Last 6 months" %}</th>
<th class="text-center">{% trans "This month" %}</th>
</tr>
</thead>
<tbody>
<tr>
{% for timeframe in positions|regroup_by_age %}
<td>
{% for position in timeframe %}
<button class="btn btn-default" type="button" data-toggle="collapse" data-target="#collapsePosition-{{ position.pk }}" aria-expanded="false" aria-controls="collapsePosition-{{ position.pk }}">
{{ position.datetime|naturalday }}
</button>
{% endfor %}
</td>
{% endfor %}
</tr>
</tbody>
</table>
{% for position in positions %}
<div class="collapse" id="collapsePosition-{{ position.pk }}">
<div class="panel panel-default">
<div class="panel-body text-justify">
<blockquote>
<p>{{ position.text }}</p>
</blockquote>
{% if position.link %}
<p class="text-right"><a class="btn btn-primary" href="{{ position.link }}" target="blank">Check the source &raquo;</a></p>
{% endif %}
</div>
</div>
</div>
{% endfor %}
{% endif %}
{% load i18n %}
{% load humanize %}
{% load memopol_tags %}
{% load representatives_recommendations_tags %}
<div class="col-sm-9">
<h1 class="text-left">{{ representative.full_name }}</h1>
<div class="col-sm-9">
<dl class="dl-horizontal">
<dt>{% trans "Score" %}</dt>
<dd>
<span class="badge" data-toggle="tooltip" data-placement="right" title="{% trans "Le score est une somme de points attribués suivant si le MEP vote dans notre sens (positif) ou non (négatif) multiplié par le poids (importance) de ce vote." %}">{{ representative.score.score }}</span>&nbsp;&nbsp;{{ representative.score.score|score_arrow }}
</dd>
<dt>{% trans "Country" %}</dt>
<dd>
{{ representative.country|country_flag }}
</dd>
<dt>{% trans "Party" %}</dt>
<dd>
{% with mandate=representative.main_mandate %}
<a href="{{ mandate.group.get_absolute_url }}">
{% blocktrans with role=representative.main_mandate.role group_name=mandate.group.name %}
{{ role }} of {{ group_name }}{% endblocktrans %}</a>
{% if mandate.group.abbreviation %}&nbsp;({{ mandate.group.abbreviation }}){% endif %}
{% endwith %}
</dd>
<dt>{% trans "Biography" %}</dt>
<dd>{% blocktrans with birth_place=representative.birth_place birth_date=representative.birth_date|naturalday:'d/m/Y' %}Born in {{ birth_place }} the {{ birth_date }}{% endblocktrans %} ({{ representative.get_gender_display }})
</dd>
{# <dt>More infos</dt><dd><a><span class="label label-primary"><span class="glyphicon glyphicon-grain"></span> Facebook</span></a> <a><span class="label label-primary"><span class="glyphicon glyphicon-plane"></span> Twitter</span></a> <a><span class="label label-primary"><span class="glyphicon glyphicon-tree-conifer"></span> Parliement</span></a></dd> #}
</dl>
</div>
</div>
{% load i18n %}
{% load representatives_recommendations_tags %}
<div class="panel-group" id="accordion-Dossiers" role="tablist" aria-multiselectable="true">
{% regroup votes by proposal.dossier as groups %}
{% for group in groups %}
{% with dossier=group.grouper %}
{% with votes=group.list %}
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="Dossiers-heading-{{ dossier.pk }}">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion-Dossiers" href="#Dossiers-{{ dossier.pk }}" aria-expanded="false" aria-controls="Dossiers-{{ dossier.pk }}">
{{ dossier.title }}
</a>
</h4>
</div>
<div id="Dossiers-{{ dossier.pk }}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="Dossiers-heading-{{ dossier.pk }}">
<div class="panel-body">
{% if dossier.text %}<p>{{ dossier.text }}</p>{% endif %}
{% if dossier.link %}<a class="btn btn-default" target="blank" href="{{ dossier.link }}">{% trans "En savoir plus" %} &raquo;</a>{% endif %}
<br/><br/>
<table class="table table-striped table-hover text-center">
<thead>
<tr>
<th class="text-center">{% trans "Vote name" %}</th>
<th class="text-center">{% trans "MEP's vote" %}</th>
{% comment %}
<!-- we don't have this information yet -->
<th class="text-center">{% trans "Party's vote" %}</th>
{% endcomment %}
<th class="text-center">{% trans "Lqdn's recommendation" %}</th>
<th class="text-center">Points <a data-toggle="tooltip" data-placement="top" title="{% trans "Le score est une somme de points attribués suivant si le MEP vote dans notre sens (positif) ou non (négatif) multiplié par le poids (importance) de ce vote." %}"><span class="glyphicon glyphicon-info-sign"></span></a></th>
</tr>
</thead>
<tbody>
{% for vote in votes %}
<tr>
<th>{{ vote.proposal.title }}</th>
<td><span class="glyphicon {{ vote.position|vote_glyphicon}} {{ vote.position|vote_icon_color:vote.proposal.recommendation.recommendation }}"></span></td>
<td><span class="glyphicon {{ vote.proposal.recommendation.recommendation|vote_glyphicon }}"></span></td>
<td>{{ vote.absolute_score }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endwith %}
{% endwith %}
{% endfor %}
</div>
{% extends 'base.html' %}
{% load i18n memopol_tags %}
{% block title %}{{ representative.full_name }}{% endblock %}
{% load i18n %}
{% load humanize %}
{% load memopol_tags %}
{% load representatives_recommendations_tags %}
{% block title %}{{ object.full_name }}{% endblock %}
{% block content %}
<div class="row">
<div class="col-sm-3">
<img src="{{ representative.photo }}">
<img src="{{ object.photo }}">
</div>
{% include "representatives/_representative_block.html" %}
{% comment %}
<!-- Design for future feature is ready, leaving it here until we develop the Piphone campaign system -->
<div class="col-sm-3 text-center">
<p>
There is an ungoing &pi;Phone campaign, call this MEP for free to help La Quadrature!</p>
<div class="btn-group" role="group">
<button class="btn btn-large btn-primary" data-toggle="tooltip" data-placement="bottom" title="Call this MEP with the &pi;Phone"><span class="glyphicon glyphicon-phone-alt"></span></button>
<a class="btn btn-large btn-default"><span class="glyphicon glyphicon-plus"></span> info</a>
</div>
<div class="col-sm-9">
<h1 class="text-left">{{ object.full_name }}</h1>
<div class="col-sm-9">
<dl class="dl-horizontal">
<dt>{% trans "Score" %}</dt>
<dd>
<span class="badge" data-toggle="tooltip" data-placement="right" title="{% trans "Le score est une somme de points attribués suivant si le MEP vote dans notre sens (positif) ou non (négatif) multiplié par le poids (importance) de ce vote." %}">{{ object.score.score }}</span>&nbsp;&nbsp;{{ object.score.score|score_arrow }}
</dd>
<dt>{% trans "Country" %}</dt>
<dd>
{{ object.country|country_flag }}
</dd>
<dt>{% trans "Party" %}</dt>
<dd>
{% with mandate=object.main_mandate %}
<a href="{{ mandate.group.get_absolute_url }}">
{% blocktrans with role=object.main_mandate.role group_name=mandate.group.name %}
{{ role }} of {{ group_name }}{% endblocktrans %}</a>
{% if mandate.group.abbreviation %}&nbsp;({{ mandate.group.abbreviation }}){% endif %}
{% endwith %}
</dd>
<dt>{% trans "Biography" %}</dt>
<dd>{% blocktrans with birth_place=object.birth_place birth_date=object.birth_date|naturalday:'d/m/Y' %}Born in {{ birth_place }} the {{ birth_date }}{% endblocktrans %} ({{ object.get_gender_display }})
</dd>
{# <dt>More infos</dt><dd><a><span class="label label-primary"><span class="glyphicon glyphicon-grain"></span> Facebook</span></a> <a><span class="label label-primary"><span class="glyphicon glyphicon-plane"></span> Twitter</span></a> <a><span class="label label-primary"><span class="glyphicon glyphicon-tree-conifer"></span> Parliement</span></a></dd> #}
</dl>
</div>
</div>
{% endcomment %}
</div>
<div class="row">
<div class="col-xs-12">
<ul class="nav nav-tabs nav-justified" role="tablist">
<li role="presentation" class="active">
<a href="#votes" aria-controls="votes" role="tab" data-toggle="tab">
<li role="presentation" {% if tab == 'votes' %}class="active"{% endif %}>
<a href="{% url 'representative-votes' slug=object.slug %}" role="tab">
<h3>{% trans "Votes" %}</h3>
</a>
</li>
<li role="presentation">
<a href="#mandates" aria-controls="mandates" role="tab" data-toggle="tab">
<li role="presentation" {% if tab == 'mandates' %}class="active"{% endif %}>
<a href="{% url 'representative-mandates' slug=object.slug %}" role="tab">
<h3>{% trans "Mandates" %}</h3>
</a>
</li>
<li role="presentation">
<a href="#positions" aria-controls="positions" role="tab" data-toggle="tab">
<li role="presentation" {% if tab == 'positions' %}class="active"{% endif %}>
<a href="{% url 'representative-positions' slug=object.slug %}" role="tab">
<h3>{% trans "Public positions" %}</h3>
</a>
</li>
</ul>
<div class="tab-content">
<div id="votes" role="tabpanel" class="tab-pane active">
{% include "representatives/_votes.html" %}
</div>
<div id="mandates" role="tabpanel" class="tab-pane">
{% include "representatives/_mandates.html" %}
</div>
<div id="positions" role="tabpanel" class="tab-pane">
{% include "representatives/_positions.html" %}
</div>
{% block representative_content %}{% endblock %}
</div>
</div>
</div>
{% endblock %}
{% extends 'representatives/representative_detail.html' %}
{% load i18n %}
{% load memopol_tags %}
{% block representative_content %}
<div class="row">
{% for mandate in mandates %}
<div class="col-sm-6 col-md-4">
<div class="thumbnail">
<div class="caption">
<h3 class="text-center">
<a href="{{ mandate.group.get_absolute_url }}">{{ mandate.group.name }}
{% if mandate.group.abreviation %}{{ mandate.group.abreviation }}{% endif %}
</a>
</h3>
<hr>
<p><span class="lead">{{ mandate.role }}</span> from {{ mandate.begin_date|mandate_date:'d/m/Y' }} to {{ mandate.end_date|mandate_date:'d/m/Y' }}</p>
</div>
</div>
</div>
{% if forloop.counter|divisibleby:3 %}</div><div class="row">{% endif %}
{% endfor %}
</div>
{% endblock %}
{% extends 'representatives/representative_detail.html' %}
{% load i18n %}
{% load humanize %}
{% load representatives_positions_tags %}
{% block representative_content %}
{% if not positions %}
{# TODO: link #}
<p>No public position has been recorded. You can always <a>add a public position</a>.</p>
{% else %}
<table class="table table-responsive custom-timeline text-center">
<thead>
<tr>
<th class="text-center">{% trans "Before" %}</th>
<th class="text-center">{% trans "Last year" %}</th>
<th class="text-center">{% trans "Last 6 months" %}</th>
<th class="text-center">{% trans "This month" %}</th>
</tr>
</thead>
<tbody>
<tr>
{% for timeframe in positions|regroup_by_age %}
<td>
{% for position in timeframe %}
<button class="btn btn-default" type="button" data-toggle="collapse" data-target="#collapsePosition-{{ position.pk }}" aria-expanded="false" aria-controls="collapsePosition-{{ position.pk }}">
{{ position.datetime|naturalday }}
</button>
{% endfor %}
</td>
{% endfor %}
</tr>
</tbody>
</table>
{% for position in positions %}
<div class="collapse" id="collapsePosition-{{ position.pk }}">
<div class="panel panel-default">
<div class="panel-body text-justify">
<blockquote>
<p>{{ position.text }}</p>
</blockquote>
{% if position.link %}
<p class="text-right"><a class="btn btn-primary" href="{{ position.link }}" target="blank">Check the source &raquo;</a></p>
{% endif %}
</div>
</div>
</div>
{% endfor %}
{% endif %}
{% endblock %}
{% extends 'representatives/representative_detail.html' %}
{% load i18n %}
{% load representatives_recommendations_tags %}
{% block representative_content %}
<div class="panel-group" id="accordion-dossier" role="tablist" aria-multiselectable="true">
{% regroup votes by proposal.dossier as groups %}
{% for group in groups %}
{% with dossier=group.grouper %}
{% with votes=group.list %}
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="dossier-heading-{{ dossier.pk }}">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion-dossier" href="#dossier-{{ dossier.pk }}" aria-expanded="false" aria-controls="dossier-{{ dossier.pk }}">
{{ dossier.title }}
</a>
</h4>
</div>
<div id="dossier-{{ dossier.pk }}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="dossier-heading-{{ dossier.pk }}">
<div class="panel-body">
{% if dossier.text %}<p>{{ dossier.text }}</p>{% endif %}
{% if dossier.link %}<a class="btn btn-default" target="blank" href="{{ dossier.link }}">{% trans "En savoir plus" %} &raquo;</a>{% endif %}
<br/><br/>
<table class="table table-striped table-hover text-center">
<thead>
<tr>
<th class="text-center">{% trans "Vote name" %}</th>
<th class="text-center">{% trans "MEP's vote" %}</th>
{% comment %}
<!-- we don't have this information yet -->
<th class="text-center">{% trans "Party's vote" %}</th>
{% endcomment %}
<th class="text-center">{% trans "Lqdn's recommendation" %}</th>
<th class="text-center">Points <a data-toggle="tooltip" data-placement="top" title="{% trans "Le score est une somme de points attribués suivant si le MEP vote dans notre sens (positif) ou non (négatif) multiplié par le poids (importance) de ce vote." %}"><span class="glyphicon glyphicon-info-sign"></span></a></th>
</tr>
</thead>
<tbody>
{% for vote in votes %}
<tr>
<th>{{ vote.proposal.title }}</th>
<td><span class="glyphicon {{ vote.position|vote_glyphicon}} {{ vote.position|vote_icon_color:vote.proposal.recommendation.recommendation }}"></span></td>