batch talks decision & assignement to room / track
This commit is contained in:
parent
5a97705cc9
commit
848aef170a
|
@ -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'))
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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,
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue
Block a user