winding up: added ability to add drafts to a session while looking at the session.
- Legacy-Id: 10853
This commit is contained in:
parent
4a12225742
commit
114ba0ad13
|
@ -3,6 +3,8 @@ import shutil
|
|||
import datetime
|
||||
import urlparse
|
||||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
from django.core.urlresolvers import reverse as urlreverse
|
||||
from django.conf import settings
|
||||
|
||||
|
@ -13,8 +15,10 @@ from ietf.meeting.models import Session, TimeSlot
|
|||
from ietf.meeting.test_data import make_meeting_test_data
|
||||
from ietf.utils.test_utils import TestCase, login_testing_unauthorized, unicontent
|
||||
|
||||
from ietf.person.factories import PersonFactory
|
||||
from ietf.group.factories import GroupFactory
|
||||
from ietf.meeting.factories import SessionFactory, SessionPresentationFactory
|
||||
from ietf.doc.factories import DocumentFactory
|
||||
|
||||
class MeetingTests(TestCase):
|
||||
def setUp(self):
|
||||
|
@ -338,8 +342,51 @@ class SessionDetailsTests(TestCase):
|
|||
SessionPresentationFactory.create(session=session,document__type_id='slides')
|
||||
SessionPresentationFactory.create(session=session,document__type_id='agenda')
|
||||
|
||||
url = urlreverse("ietf.meeting.views.session_details", kwargs=dict(num=session.meeting.number, acronym=group.acronym))
|
||||
url = urlreverse('ietf.meeting.views.session_details', kwargs=dict(num=session.meeting.number, acronym=group.acronym))
|
||||
r = self.client.get(url)
|
||||
self.assertTrue(all([x in unicontent(r) for x in ('slides','agenda','minutes','draft')]))
|
||||
self.assertFalse('deleted' in unicontent(r))
|
||||
|
||||
def test_add_session_drafts(self):
|
||||
group = GroupFactory.create(type_id='wg',state_id='active')
|
||||
group_chair = PersonFactory.create()
|
||||
group.role_set.create(name_id='chair',person = group_chair, email = group_chair.email())
|
||||
session = SessionFactory.create(meeting__type_id='ietf',group=group, meeting__date=datetime.date.today()+datetime.timedelta(days=90))
|
||||
SessionPresentationFactory.create(session=session,document__type_id='draft',rev=None)
|
||||
old_draft = session.sessionpresentation_set.filter(document__type='draft').first().document
|
||||
new_draft = DocumentFactory(type_id='draft')
|
||||
|
||||
url = urlreverse('ietf.meeting.views.add_session_drafts', kwargs=dict(num=session.meeting.number, session_id=session.pk))
|
||||
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 404)
|
||||
|
||||
self.client.login(username="plain",password="plain+password")
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 404)
|
||||
|
||||
self.client.login(username=group_chair.user.username, password='%s+password'%group_chair.user.username)
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue(old_draft.name in unicontent(r))
|
||||
|
||||
r = self.client.post(url,dict(drafts=[new_draft.name,old_draft.name]))
|
||||
self.assertTrue(r.status_code, 200)
|
||||
q=PyQuery(r.content)
|
||||
self.assertTrue(q('form .alert-danger:contains("Already linked:")'))
|
||||
|
||||
self.assertEqual(1,session.sessionpresentation_set.count())
|
||||
r = self.client.post(url,dict(drafts=[new_draft.name,]))
|
||||
self.assertTrue(r.status_code, 302)
|
||||
self.assertEqual(2,session.sessionpresentation_set.count())
|
||||
|
||||
session.meeting.date -= datetime.timedelta(days=180)
|
||||
session.meeting.save()
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code,404)
|
||||
self.client.login(username='secretary',password='secretary+password')
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code,200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEqual(1,len(q(".alert-warning:contains('may affect published proceedings')")))
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ from ietf.meeting import ajax
|
|||
|
||||
safe_for_all_meeting_types = [
|
||||
url(r'^session/(?P<acronym>[A-Za-z0-9_\-\+]+)/$', views.session_details),
|
||||
url(r'^session/(?P<session_id>\d+)/drafts$', views.add_session_drafts),
|
||||
]
|
||||
|
||||
type_ietf_only_patterns = [
|
||||
|
|
|
@ -13,7 +13,7 @@ import json
|
|||
import debug # pyflakes:ignore
|
||||
|
||||
from django import forms
|
||||
from django.shortcuts import render, redirect
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404
|
||||
from django.contrib import messages
|
||||
from django.core.urlresolvers import reverse
|
||||
|
@ -23,7 +23,7 @@ from django.forms.models import modelform_factory
|
|||
from django.forms import ModelForm
|
||||
from django.views.decorators.csrf import ensure_csrf_cookie
|
||||
|
||||
from ietf.doc.models import Document, State
|
||||
from ietf.doc.models import Document, State, DocEvent
|
||||
from ietf.group.models import Group
|
||||
from ietf.group.utils import can_manage_materials
|
||||
from ietf.ietfauth.utils import role_required, has_role
|
||||
|
@ -39,6 +39,8 @@ from ietf.meeting.helpers import convert_draft_to_pdf
|
|||
from ietf.utils.pipe import pipe
|
||||
from ietf.utils.pdf import pdf_pages
|
||||
|
||||
from ietf.doc.fields import SearchableDocumentsField
|
||||
|
||||
def materials(request, meeting_num=None):
|
||||
meeting = get_meeting(meeting_num)
|
||||
|
||||
|
@ -874,3 +876,45 @@ def session_details(request, num, acronym ):
|
|||
'can_manage_materials' : can_manage,
|
||||
'type_counter': type_counter,
|
||||
})
|
||||
|
||||
class SessionDraftsForm(forms.Form):
|
||||
drafts = SearchableDocumentsField(required=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.already_linked = kwargs.pop('already_linked')
|
||||
super(self.__class__, self).__init__(*args, **kwargs)
|
||||
|
||||
def clean(self):
|
||||
selected = self.cleaned_data['drafts']
|
||||
problems = set(selected).intersection(set(self.already_linked))
|
||||
if problems:
|
||||
raise forms.ValidationError("Already linked: %s" % ', '.join([d.name for d in problems]))
|
||||
return self.cleaned_data
|
||||
|
||||
def add_session_drafts(request, session_id, num):
|
||||
# num is redundant, but we're dragging it along an artifact of where we are in the current URL structure
|
||||
session = get_object_or_404(Session,pk=session_id)
|
||||
if not session.can_manage_materials(request.user):
|
||||
raise Http404
|
||||
if session.is_material_submission_cutoff() and not has_role(request.user, "Secretariat"):
|
||||
raise Http404
|
||||
|
||||
already_linked = [sp.document for sp in session.sessionpresentation_set.filter(document__type_id='draft')]
|
||||
|
||||
if request.method == 'POST':
|
||||
form = SessionDraftsForm(request.POST,already_linked=already_linked)
|
||||
if form.is_valid():
|
||||
for draft in form.cleaned_data['drafts']:
|
||||
session.sessionpresentation_set.create(document=draft,rev=None)
|
||||
c = DocEvent(type="added_comment", doc=draft, by=request.user.person)
|
||||
c.desc = "Added to session: %s" % session
|
||||
c.save()
|
||||
return redirect('ietf.meeting.views.session_details', num=session.meeting.number, acronym=session.group.acronym)
|
||||
else:
|
||||
form = SessionDraftsForm(already_linked=already_linked)
|
||||
|
||||
return render(request, "meeting/add_session_drafts.html",
|
||||
{ 'session': session,
|
||||
'already_linked': session.sessionpresentation_set.filter(document__type_id='draft'),
|
||||
'form': form,
|
||||
})
|
||||
|
|
60
ietf/templates/meeting/add_session_drafts.html
Normal file
60
ietf/templates/meeting/add_session_drafts.html
Normal file
|
@ -0,0 +1,60 @@
|
|||
{% extends "base.html" %}
|
||||
{# Copyright The IETF Trust 2015, All Rights Reserved #}
|
||||
{% load origin staticfiles bootstrap3 %}
|
||||
|
||||
{% block title %}Add drafts to {{ session.meeting }} : {{ session.group.acronym }}{% endblock %}
|
||||
|
||||
{% block pagehead %}
|
||||
<link rel="stylesheet" href="{% static 'select2/select2.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'select2-bootstrap-css/select2-bootstrap.min.css' %}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% origin %}
|
||||
|
||||
<h1>Add drafts to {{ session.meeting }} : {{ session.group.acronym }}</h1>
|
||||
{% comment %} TODO: put the session name here or calculate the number at the meeting {% endcomment %}
|
||||
|
||||
{% if session.is_material_submission_cutoff %}
|
||||
<div class="alert alert-warning">The deadline for submission corrections has passed. This may affect published proceedings.</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="alert alert-info">This form will link additional drafts to this session with a revision of "Current at time of presentation". For more fine grained control of versions, or to remove a draft from a session, adjust the sessions associated with a draft from the draft's main page.</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Drafts already linked to this sesssion</div>
|
||||
<div class="panel-body">
|
||||
<table class="table table-contensed table-striped">
|
||||
<tr>
|
||||
<th class="col-md-1">Revision</th>
|
||||
<th>Document</th>
|
||||
</tr>
|
||||
{% for sp in already_linked %}
|
||||
<tr>
|
||||
<td>{% if sp.rev %}-{{sp.rev}}{% else %}(current){% endif %}</td>
|
||||
<td>{{sp.document.title}} ({{sp.document.name}})</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Additional drafts to link to this session</div>
|
||||
<div class="panel-body">
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form form %}
|
||||
{% buttons %}
|
||||
<button class="btn btn-{% if session.is_material_submission_cutoff %}warning{% else %}primary{% endif %}" type="submit">Save</button>
|
||||
<a class="btn btn-default" href="{% url 'ietf.meeting.views.session_details' num=session.meeting.number acronym=session.group.acronym %}">Cancel</a>
|
||||
{% endbuttons %}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
<script src="{% static 'select2/select2.min.js' %}"></script>
|
||||
<script src="{% static 'ietf/js/select2-field.js' %}"></script>
|
||||
{% endblock %}
|
|
@ -15,7 +15,10 @@
|
|||
{% if session.status.slug == 'sched' or session.status.slug == 'schedw' %}
|
||||
<div class="buttonlist">
|
||||
<a class="btn btn-default" href="{% url 'ietf.secr.proceedings.views.upload_unified' meeting_num=session.meeting.number acronym=session.group.acronym %}">
|
||||
Upload/Edit Materials
|
||||
Upload/Edit materials
|
||||
</a>
|
||||
<a class="btn btn-default" href="{% url 'ietf.meeting.views.add_session_drafts' session_id=session.pk num=session.meeting.number %}">
|
||||
Link additional drafts to session
|
||||
</a>
|
||||
{% if not type_counter.agenda %}
|
||||
<span class="label label-warning">This session does not yet have an agenda</span>
|
||||
|
@ -38,7 +41,7 @@
|
|||
{% else %}
|
||||
{% url 'doc_view' name=pres.document.name as url %}
|
||||
{% endif %}
|
||||
<a href="{{url}}">{{pres.document.title}} ({{ pres.document.name }}-{{ pres.rev }})
|
||||
<a href="{{url}}">{{pres.document.title}} ({{ pres.document.name }}{% if pres.rev %}-{{ pres.rev }}{% endif %})
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
Loading…
Reference in a new issue