batch talks decision & assignement to room / track

This commit is contained in:
Élie Bouttier 2016-10-12 00:18:56 +02:00
parent 5a97705cc9
commit 848aef170a
3 changed files with 82 additions and 8 deletions

View File

@ -7,6 +7,7 @@ from django_select2.forms import Select2TagWidget
from accounts.models import User, Participation, Transport from accounts.models import User, Participation, Transport
from proposals.models import Conference, Event, Talk, Topic, Track from proposals.models import Conference, Event, Talk, Topic, Track
from planning.models import Room
STATUS_CHOICES = [ STATUS_CHOICES = [
('pending', 'Pending decision'), ('pending', 'Pending decision'),
@ -74,6 +75,23 @@ class TalkFilterForm(forms.Form):
self.fields['track'].choices = [('none', 'Not assigned')] + list(tracks.values_list('slug', 'name')) self.fields['track'].choices = [('none', 'Not assigned')] + list(tracks.values_list('slug', 'name'))
class TalkActionForm(forms.Form):
talks = forms.MultipleChoiceField(choices=[])
decision = forms.NullBooleanField(label=_('Accept talk?'))
track = forms.ChoiceField(required=False, choices=[], label=_('Assign to a track'))
room = forms.ChoiceField(required=False, choices=[], label=_('Put in a room'))
def __init__(self, *args, **kwargs):
site = kwargs.pop('site')
talks = kwargs.pop('talks')
super().__init__(*args, **kwargs)
self.fields['talks'].choices = [(talk.slug, None) for talk in talks.all()]
tracks = Track.objects.filter(site=site)
self.fields['track'].choices = [(None, "---------")] + list(tracks.values_list('slug', 'name'))
rooms = Room.objects.filter(site=site)
self.fields['room'].choices = [(None, "---------")] + list(rooms.values_list('slug', 'name'))
def get_options(option): def get_options(option):
try: try:
options = list(option.objects.values_list('pk', 'name')) options = list(option.objects.values_list('pk', 'name'))

View File

@ -1,6 +1,6 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load bootstrap3 i18n %} {% load bootstrap3 i18n accounts_tags %}
{% block talktab %} class="active"{% endblock %} {% block talktab %} class="active"{% endblock %}
@ -35,9 +35,12 @@
</div> </div>
</div> </div>
<form action="" method="post">
<table class="table table-bordered table-hover"> <table class="table table-bordered table-hover">
<thead> <thead>
<tr> <tr>
<th></th>
<th class="text-center">{% trans "Title" %} <a href="?{{ sort_urls.title }}"><span class="glyphicon glyphicon-{{ sort_glyphicons.title }} pull-right"></span></a></th> <th class="text-center">{% trans "Title" %} <a href="?{{ sort_urls.title }}"><span class="glyphicon glyphicon-{{ sort_glyphicons.title }} pull-right"></span></a></th>
<th class="text-center">{% trans "Intervention kind" %} <a href="?{{ sort_urls.kind }}"><span class="glyphicon glyphicon-{{ sort_glyphicons.kind }} pull-right"></span></a></th> <th class="text-center">{% trans "Intervention kind" %} <a href="?{{ sort_urls.kind }}"><span class="glyphicon glyphicon-{{ sort_glyphicons.kind }} pull-right"></span></a></th>
<th class="text-center">{% trans "Speakers" %}</th> <th class="text-center">{% trans "Speakers" %}</th>
@ -49,9 +52,13 @@
{% for talk in talk_list %} {% for talk in talk_list %}
{% if forloop.first %} {% if forloop.first %}
<tbody> <tbody>
<tr>
<th colspan="5">{% trans "Total:" %} {{ talk_list|length }} {% trans "talk" %}{{ talk_list|length|pluralize }}</th>
</tr>
{% endif %} {% endif %}
<tr class="clickable-row {{ talk.accepted|yesno:"success,danger,warning" }}" data-href="{% url 'show-talk' talk.slug %}"> <tr class="{{ talk.accepted|yesno:"success,danger,warning" }}">
<td>{{ talk.title }}</td> <td><input type="checkbox" name="talks" value="{{ talk.slug }}"></td>
<td><a href="{% url 'show-talk' talk.slug %}">{{ talk.title }}</a></td>
<td>{{ talk.event }}</td> <td>{{ talk.event }}</td>
<td> <td>
{% for speaker in talk.speakers.all %} {% for speaker in talk.speakers.all %}
@ -87,15 +94,30 @@
</tfoot> </tfoot>
</table> </table>
{% if action_form %}
<div id="filter">
<div class="well">
<h4>For selected talks:</h4>
{% csrf_token %}
{% bootstrap_field action_form.decision %}
{% if request|orga %}
{% bootstrap_field action_form.track %}
{% bootstrap_field action_form.room %}
{% endif %}
{% buttons %}
<button type="submit" class="btn btn-primary">{% trans "Apply" %}</button>
{% endbuttons %}
</div>
</div>
{% endif %}
</form>
{% endblock %} {% endblock %}
{% block js_end %} {% block js_end %}
<script type="text/javascript"> <script type="text/javascript">
jQuery(document).ready(function($) { jQuery(document).ready(function($) {
$(".clickable-row").click(function() {
window.location = $(this).data("href");
});
var anchor = window.location.hash.replace("#", ""); var anchor = window.location.hash.replace("#", "");
if (anchor == "filter") { if (anchor == "filter") {
$("#filter").collapse('show'); $("#filter").collapse('show');

View File

@ -21,7 +21,9 @@ from accounts.utils import is_staff, is_orga
from conversations.models import ConversationWithParticipant, ConversationAboutTalk, Message from conversations.models import ConversationWithParticipant, ConversationAboutTalk, Message
from .forms import TalkForm, TopicForm, TrackForm, ConferenceForm, TalkFilterForm, STATUS_VALUES, SpeakerFilterForm from planning.models import Room
from .forms import TalkForm, TopicForm, TrackForm, ConferenceForm, TalkFilterForm, STATUS_VALUES, SpeakerFilterForm, TalkActionForm
from .models import Talk, Track, Topic, Vote, Conference from .models import Talk, Track, Topic, Vote, Conference
from .signals import talk_added, talk_edited from .signals import talk_added, talk_edited
from .utils import allowed_talks, markdown_to_html from .utils import allowed_talks, markdown_to_html
@ -100,6 +102,37 @@ def talk_list(request):
talks = talks.filter(room__isnull=not data['room']) talks = talks.filter(room__isnull=not data['room'])
if data['scheduled'] != None: if data['scheduled'] != None:
talks = talks.filter(start_date__isnull=not data['scheduled']) talks = talks.filter(start_date__isnull=not data['scheduled'])
# Action
action_form = TalkActionForm(request.POST or None, talks=talks, site=get_current_site(request))
if not is_orga(request, request.user):
action_form.fields.pop('track')
action_form.fields.pop('room')
if request.method == 'POST':
if action_form.is_valid():
data = action_form.cleaned_data
permission_error = False
for talk in data['talks']:
talk = Talk.objects.get(site=get_current_site(request), slug=talk)
if data['decision'] != None:
if not talk.is_moderable_by(request.user):
permission_error = True
continue
# TODO: merge with talk_decide code
conversation = ConversationAboutTalk.objects.get(talk=talk)
if data['decision']:
note = "The talk has been accepted."
else:
note = "The talk has been declined."
Message.objects.create(conversation=conversation, author=request.user, content=note)
talk.accepted = data['decision']
if data['track']:
talk.track = Track.objects.get(site=get_current_site(request), slug=data['track'])
if data['room']:
talk.room = Room.objects.get(site=get_current_site(request), slug=data['room'])
talk.save()
if permission_error:
messages.warning(request, 'Some actions were ignored due to missing permissions.')
return redirect(request.get_full_path())
# Sorting # Sorting
if request.GET.get('order') == 'desc': if request.GET.get('order') == 'desc':
reverse = True reverse = True
@ -137,6 +170,7 @@ def talk_list(request):
'show_filters': show_filters, 'show_filters': show_filters,
'talk_list': talks, 'talk_list': talks,
'filter_form': filter_form, 'filter_form': filter_form,
'action_form': action_form,
'sort_urls': sort_urls, 'sort_urls': sort_urls,
'sort_glyphicons': sort_glyphicons, 'sort_glyphicons': sort_glyphicons,
}) })