talk list, with filtering capabilities
This commit is contained in:
parent
1d8d03b2f5
commit
9bc2ed1c92
|
@ -0,0 +1,3 @@
|
|||
tr.clickable-row {
|
||||
cursor: pointer;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
from django.forms import CheckboxSelectMultiple, ModelForm
|
||||
from django import forms
|
||||
from django.forms.models import modelform_factory
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
@ -8,7 +8,19 @@ from django_select2.forms import Select2TagWidget
|
|||
from proposals.models import Talk, Topic, Event, Conference
|
||||
|
||||
|
||||
class TalkForm(ModelForm):
|
||||
STATUS_CHOICES = [
|
||||
('pending', 'Pending decision'),
|
||||
('accepted', 'Accepted'),
|
||||
('declined', 'Declined'),
|
||||
]
|
||||
STATUS_VALUES = [
|
||||
('pending', None),
|
||||
('accepted', True),
|
||||
('declined', False),
|
||||
]
|
||||
|
||||
|
||||
class TalkForm(forms.ModelForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
site = kwargs.pop('site')
|
||||
super(TalkForm, self).__init__(*args, **kwargs)
|
||||
|
@ -18,14 +30,39 @@ class TalkForm(ModelForm):
|
|||
class Meta:
|
||||
model = Talk
|
||||
fields = ['title', 'abstract', 'description', 'topics', 'notes', 'event', 'speakers']
|
||||
widgets = {'topics': CheckboxSelectMultiple(), 'speakers': Select2TagWidget()}
|
||||
widgets = {'topics': forms.CheckboxSelectMultiple(), 'speakers': Select2TagWidget()}
|
||||
help_texts = {
|
||||
'abstract': _('Should be less than 255 characters'),
|
||||
'notes': _('If you want to add some precisions for the organizers.'),
|
||||
}
|
||||
|
||||
|
||||
class TopicCreateForm(ModelForm):
|
||||
class FilterForm(forms.Form):
|
||||
kind = forms.MultipleChoiceField(
|
||||
required=False,
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
choices=[],
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
required=False,
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
choices=STATUS_CHOICES,
|
||||
)
|
||||
topic = forms.MultipleChoiceField(
|
||||
required=False,
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
choices=[],
|
||||
)
|
||||
def __init__(self, *args, **kwargs):
|
||||
site = kwargs.pop('site')
|
||||
super().__init__(*args, **kwargs)
|
||||
events = Event.objects.filter(site=site)
|
||||
self.fields['kind'].choices = events.values_list('pk', 'name')
|
||||
topics = Topic.objects.filter(site=site)
|
||||
self.fields['topic'].choices = topics.values_list('slug', 'name')
|
||||
|
||||
|
||||
class TopicCreateForm(forms.ModelForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.site_id = kwargs.pop('site_id')
|
||||
super(TopicCreateForm, self).__init__(*args, **kwargs)
|
||||
|
|
|
@ -42,7 +42,7 @@ class Topic(PonyConfModel):
|
|||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('list-talks-by-topic', kwargs={'topic': self.slug})
|
||||
return reverse('list-talks') + '?filter=topic:%s' % self.slug
|
||||
|
||||
|
||||
class Event(models.Model):
|
||||
|
@ -52,6 +52,7 @@ class Event(models.Model):
|
|||
|
||||
class Meta:
|
||||
unique_together = ('site', 'name')
|
||||
ordering = ('pk',)
|
||||
|
||||
def __str__(self):
|
||||
return ugettext(self.name)
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
{% if talk.topics.exists %}
|
||||
<i>{% trans "in" %}</i>
|
||||
{% for topic in talk.topics.all %}
|
||||
<a href="{% url 'list-talks-by-topic' topic.slug %}">{{ topic }}</a>
|
||||
<a href="{{ topic.get_full_url }}">{{ topic }}</a>
|
||||
{% if forloop.revcounter == 2 %} {% trans "and" %} {% elif not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
{% for topic in talk.topics.all %}
|
||||
{% if forloop.first %}<ul>{% endif %}
|
||||
<li><a href="{% url 'list-talks-by-topic' topic.slug %}">{{ topic }}</a></li>
|
||||
<li><a href="{{ topic.get_full_url }}">{{ topic }}</a></li>
|
||||
{% if forloop.last %}</ul>{% endif %}
|
||||
{% empty %}
|
||||
<i>{% trans "No topics." %}</i>
|
||||
|
|
|
@ -1,11 +1,101 @@
|
|||
{% extends 'base.html' %}
|
||||
|
||||
{% load bootstrap3 i18n %}
|
||||
|
||||
{% block talktab %} class="active"{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ title }}</h1>
|
||||
<h1>{% trans "Talks" %}</h1>
|
||||
|
||||
{% include "proposals/_talk_list.html" %}
|
||||
<a class="btn btn-primary" role="button" data-toggle="collapse" href="#filter" aria-expanded="{{ show_filters|yesno:"true,false" }}" aria-controls="filter">Show filtering options…</a>
|
||||
|
||||
<br /><br />
|
||||
|
||||
<div class="collapse{{ show_filters|yesno:" in," }}" id="filter">
|
||||
<div class="well">
|
||||
<form class="form-horizontal" method="get">
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-xs-6">
|
||||
{% bootstrap_field filter_form.kind layout="horizontal" %}
|
||||
</div>
|
||||
<div class="col-md-4 col-xs-6">
|
||||
{% bootstrap_field filter_form.status layout="horizontal" %}
|
||||
</div>
|
||||
<div class="col-md-4 col-xs-6">
|
||||
{% bootstrap_field filter_form.topic layout="horizontal" %}
|
||||
</div>
|
||||
</div>
|
||||
<input type="submit" class="btn btn-success" value="Filter">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">{% trans "Title" %} <a href="#"><span class="glyphicon glyphicon-sort pull-right"></span></a></th>
|
||||
<th class="text-center">{% trans "Intervention kind" %} <a href="#"><span class="glyphicon glyphicon-sort pull-right"></span></a></th>
|
||||
<th class="text-center">{% trans "Speakers" %} <a href="#"><span class="glyphicon glyphicon-sort pull-right"></span></a></th>
|
||||
<th class="text-center">{% trans "Topics" %} <a href="#"><span class="glyphicon glyphicon-sort pull-right"></span></a></th>
|
||||
<th class="text-center">{% trans "Status" %} <a href="#"><span class="glyphicon glyphicon-sort pull-right"></span></a></th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for talk in talk_list %}
|
||||
{% if forloop.first %}
|
||||
<tbody>
|
||||
{% endif %}
|
||||
<tr class="clickable-row" data-href="{% url 'show-talk' talk.slug %}">
|
||||
<td class="{{ talk.accepted|yesno:"success,danger,warning" }}">{{ talk.title }}</td>
|
||||
<td class="{{ talk.accepted|yesno:"success,danger,warning" }}">{{ talk.event }}</td>
|
||||
<td class="{{ talk.accepted|yesno:"success,danger,warning" }}">
|
||||
{% for speaker in talk.speakers.all %}
|
||||
{{ speaker }}
|
||||
{% if forloop.revcounter == 2 %} {% trans "and" %} {% elif not forloop.last %}, {% endif %}
|
||||
{% empty %}–
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="{{ talk.accepted|yesno:"success,danger,warning" }}">
|
||||
{% for topic in talk.topics.all %}
|
||||
{{ topic }}
|
||||
{% if forloop.revcounter == 2 %} {% trans "and" %} {% elif not forloop.last %}, {% endif %}
|
||||
{% empty %}–
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="{{ talk.accepted|yesno:"success,danger,warning" }}">
|
||||
{% if talk.accepted == True %}
|
||||
{% trans "Accepted" %}
|
||||
{% elif talk.accepted == False %}
|
||||
{% trans "Declined" %}
|
||||
{% else %}
|
||||
{% blocktrans with score=talk.score %}Pending, score: {{ score }}{% endblocktrans %}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% if forloop.last%}
|
||||
</tbody>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="5">{% trans "Total:" %} {{ talk_list|length }} {% trans "talk" %}{{ talk_list|length|pluralize }}</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_end %}
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function($) {
|
||||
$(".clickable-row").click(function() {
|
||||
window.location = $(this).data("href");
|
||||
});
|
||||
|
||||
var anchor = window.location.hash.replace("#", "");
|
||||
if (anchor == "filter") {
|
||||
$("#filter").collapse('show');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% block talktab %} class="active"{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{% trans "Talks" %}</h1>
|
||||
|
||||
<a class="btn btn-success" href="{% url 'add-talk' %}">{% trans "Propose a talk" %}</a>
|
||||
|
||||
{% if my_talks %}
|
||||
<h2>{% trans "My participing talks" %}</h2>
|
||||
{% include "proposals/_talk_list.html" with talk_list=my_talks %}
|
||||
{% endif %}
|
||||
|
||||
{% if other_talks %}
|
||||
<h2>{% trans "Others talks" %}</h2>
|
||||
{% include "proposals/_talk_list.html" with talk_list=other_talks %}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
|
@ -12,7 +12,7 @@ urlpatterns = [
|
|||
url(r'^talk/edit/(?P<talk>[-\w]+)$', views.talk_edit, name='edit-talk'),
|
||||
url(r'^talk/vote/(?P<talk>[-\w]+)/(?P<score>[-0-2]+)$', views.vote, name='vote'),
|
||||
url(r'^talk/details/(?P<slug>[-\w]+)$', views.TalkDetail.as_view(), name='show-talk'),
|
||||
url(r'^talk/by-topic/(?P<topic>[-\w]+)$', views.talk_list_by_topic, name='list-talks-by-topic'),
|
||||
#url(r'^talk/by-topic/(?P<topic>[-\w]+)$', views.talk_list_by_topic, name='list-talks-by-topic'),
|
||||
url(r'^talk/accept/(?P<talk>[-\w]+)/$', views.talk_decide, {'accepted': True}, name='accept-talk'),
|
||||
url(r'^talk/decline/(?P<talk>[-\w]+)/$', views.talk_decide, {'accepted': False}, name='decline-talk'),
|
||||
url(r'^topic/$', views.TopicList.as_view(), name='list-topics'),
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from functools import reduce
|
||||
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
|
@ -18,7 +20,7 @@ from accounts.decorators import orga_required, staff_required
|
|||
|
||||
from conversations.models import ConversationWithParticipant, ConversationAboutTalk, Message
|
||||
|
||||
from .forms import TalkForm, TopicCreateForm, TopicUpdateForm, ConferenceForm
|
||||
from .forms import TalkForm, TopicCreateForm, TopicUpdateForm, ConferenceForm, FilterForm, STATUS_VALUES
|
||||
from .models import Talk, Topic, Vote, Conference
|
||||
from .signals import talk_added, talk_edited
|
||||
from .utils import allowed_talks, markdown_to_html
|
||||
|
@ -50,7 +52,7 @@ def conference(request):
|
|||
|
||||
@login_required
|
||||
def participate(request):
|
||||
talks = Talk.objects.filter(site=get_current_site(request))#.filter(Q(speakers=request.user) | Q(proposer=request.user)).distinct()
|
||||
talks = Talk.objects.filter(site=get_current_site(request))
|
||||
my_talks = talks.filter(speakers=request.user)
|
||||
proposed_talks = talks.exclude(speakers=request.user).filter(proposer=request.user)
|
||||
return render(request, 'proposals/participate.html', {
|
||||
|
@ -60,20 +62,24 @@ def participate(request):
|
|||
|
||||
@staff_required
|
||||
def talk_list(request):
|
||||
talks = allowed_talks(Talk.objects.filter(site=get_current_site(request)), request)
|
||||
show_filters = False
|
||||
talks = Talk.objects.filter(site=get_current_site(request))
|
||||
filter_form = FilterForm(request.GET or None, site=get_current_site(request))
|
||||
if filter_form.is_valid():
|
||||
data = filter_form.cleaned_data
|
||||
if len(data['kind']):
|
||||
talks = talks.filter(reduce(lambda x, y: x | y, [Q(event__pk=pk) for pk in data['kind']]))
|
||||
if len(data['status']):
|
||||
talks = talks.filter(reduce(lambda x, y: x | y, [Q(accepted=dict(STATUS_VALUES)[status]) for status in data['status']]))
|
||||
if len(data['topic']):
|
||||
talks = talks.filter(reduce(lambda x, y: x | y, [Q(topics__slug=topic) for topic in data['topic']]))
|
||||
show_filters = True
|
||||
return render(request, 'proposals/talk_list.html', {
|
||||
'title': _('Talks') + ' (%d)' % len(talks),
|
||||
'show_filters': show_filters,
|
||||
'talk_list': talks,
|
||||
'filter_form': filter_form,
|
||||
})
|
||||
|
||||
|
||||
@login_required
|
||||
def talk_list_by_topic(request, topic):
|
||||
topic = get_object_or_404(Topic, slug=topic)
|
||||
talks = allowed_talks(Talk.objects.filter(site=topic.site, topics=topic), request)
|
||||
return render(request, 'proposals/talk_list.html', {'title': _('Talks related to %s:') % topic, 'talk_list': talks})
|
||||
|
||||
|
||||
@login_required
|
||||
def talk_edit(request, talk=None):
|
||||
if talk:
|
||||
|
|
Loading…
Reference in New Issue