Added the ability to associate documents with sessions from the document main page.

Integrated the group meetings tab with the secretariat meeting request and meeting materials pages.
Made better use of bootstrap styling for the meetings tab and session details view.
Commit ready for merge.
 - Legacy-Id: 10779
This commit is contained in:
Robert Sparks 2016-02-04 21:51:04 +00:00
commit 776b95106f
12 changed files with 143 additions and 60 deletions

View file

@ -307,6 +307,8 @@ def document_main(request, name, rev=None):
status_changes = [ rel.document for rel in status_change_docs if rel.document.get_state_slug() in ('appr-sent','appr-pend')]
proposed_status_changes = [ rel.document for rel in status_change_docs if rel.document.get_state_slug() in ('needshep','adrev','iesgeval','defer','appr-pr')]
presentations = doc.future_presentations()
# remaining actions
actions = []
@ -417,6 +419,7 @@ def document_main(request, name, rev=None):
search_archive=search_archive,
actions=actions,
tracking_document=tracking_document,
presentations=presentations,
),
context_instance=RequestContext(request))
@ -526,13 +529,8 @@ def document_main(request, name, rev=None):
# created and content is made available on disk
if doc.type_id in ("slides", "agenda", "minutes"):
can_manage_material = can_manage_materials(request.user, doc.group)
presentations = None
if doc.type_id=='slides' and doc.get_state_slug('slides')=='active' :
presentations = doc.future_presentations()
presentations = doc.future_presentations()
if doc.meeting_related():
# disallow editing meeting-related stuff through this
# interface for the time being
can_manage_material = False
basename = doc.canonical_name() # meeting materials are unversioned at the moment
if doc.external_url:
# we need to remove the extension for the globbing below to work

View file

@ -250,11 +250,10 @@ def get_upcoming_manageable_sessions(user, doc, acronym=None, date=None, seq=Non
def edit_material_presentations(request, name, acronym=None, date=None, seq=None, week_day=None):
doc = get_object_or_404(Document, name=name)
if not (doc.type_id=='slides' and doc.get_state('slides').slug=='active'):
raise Http404
group = doc.group
if not (group.features.has_materials and can_manage_materials(request.user,group)):
if not can_manage_materials(request.user,group):
raise Http404
sorted_sessions = get_upcoming_manageable_sessions(request.user, doc, acronym, date, seq, week_day)
@ -301,11 +300,11 @@ def edit_material_presentations(request, name, acronym=None, date=None, seq=None
def material_presentations(request, name, acronym=None, date=None, seq=None, week_day=None):
doc = get_object_or_404(Document, name=name)
if not (doc.type_id=='slides' and doc.get_state('slides').slug=='active'):
raise Http404
group = doc.group
if not (group.features.has_materials and can_manage_materials(request.user,group)):
if not can_manage_materials(request.user,group):
raise Http404
sorted_sessions = get_upcoming_manageable_sessions(request.user, doc, acronym, date, seq, week_day)

View file

@ -59,6 +59,7 @@ from ietf.group.utils import can_manage_materials, get_group_or_404
from ietf.utils.pipe import pipe
from ietf.settings import MAILING_LIST_INFO_URL
from ietf.mailtrigger.utils import gather_relevant_expansions
from ietf.ietfauth.utils import has_role
def roles(group, role_name):
return Role.objects.filter(group=group, name=role_name).select_related("email", "person")
@ -732,7 +733,9 @@ def meetings(request, acronym=None, group_type=None):
four_years_ago = datetime.datetime.now()-datetime.timedelta(days=4*365)
sessions = group.session_set.filter(status__in=['sched','schedw','appr','canceled'],meeting__date__gt=four_years_ago)
sessions = group.session_set.filter(status__in=['sched','schedw','appr','canceled'],
meeting__date__gt=four_years_ago,
type__in=['session','plenary','other'])
def sort_key(session):
if session.meeting.type.slug=='ietf':
@ -764,10 +767,13 @@ def meetings(request, acronym=None, group_type=None):
else:
past.append(s)
can_edit = has_role(request.user,["Secretariat","Area Director"]) or group.has_role(request.user,["Chair","Secretary"])
return render(request,'group/meetings.html',
construct_group_menu_context(request, group, "meetings", group_type, {
'group':group,
'future':future,
'in_progress':in_progress,
'past':past,
'can_edit':can_edit,
}))

View file

@ -948,6 +948,9 @@ class Session(models.Model):
def slides(self):
return list(self.get_material("slides", only_one=False))
def drafts(self):
return list(self.materials.filter(type='draft'))
def __unicode__(self):
if self.meeting.type_id == "interim":
return self.meeting.number

View file

@ -6,7 +6,7 @@ import re
import tarfile
import urllib
from tempfile import mkstemp
from collections import OrderedDict
from collections import OrderedDict, Counter
import csv
import json
@ -25,6 +25,7 @@ from django.views.decorators.csrf import ensure_csrf_cookie
from ietf.doc.models import Document, State
from ietf.group.models import Group
from ietf.group.utils import can_manage_materials
from ietf.ietfauth.utils import role_required, has_role
from ietf.meeting.models import Meeting, Session, Schedule, Room
from ietf.meeting.helpers import get_areas, get_person_by_email, get_schedule_by_name
@ -830,7 +831,7 @@ def session_details(request, num, acronym ):
sessions = Session.objects.filter(meeting=meeting,group__acronym=acronym,type__in=['session','plenary','other'])
if not sessions:
sessions = Session.objects.filter(meeting=meeting,short=acronym)
sessions = Session.objects.filter(meeting=meeting,short=acronym,type__in=['session','plenary','other'])
def sort_key(session):
official_sessions = session.timeslotassignments.filter(schedule=session.meeting.agenda)
@ -844,21 +845,32 @@ def session_details(request, num, acronym ):
if not sessions:
raise Http404
type_counter = Counter()
for session in sessions:
ss = session.timeslotassignments.filter(schedule=meeting.agenda).order_by('timeslot__time')
if ss:
session.time = ', '.join(x.timeslot.time.strftime("%A %b-%d-%Y %H%M") for x in ss)
if session.status.slug == 'canceled':
session.time += " CANCELLED"
elif session.meeting.type_id=='interim':
session.time = session.meeting.date.strftime("%A %b-%d-%Y")
if session.status.slug == 'canceled':
session.time += " CANCELLED"
else:
session.time = 'Not yet scheduled'
session.time = session.status.name
# TODO FIXME Deleted materials shouldn't be in the sessionpresentation_set
session.filtered_sessionpresentation_set = [p for p in session.sessionpresentation_set.all() if p.document.get_state_slug(p.document.type_id)!='deleted']
type_counter.update([p.document.type.slug for p in session.filtered_sessionpresentation_set])
can_manage = can_manage_materials(request.user, Group.objects.get(acronym=acronym))
return render(request, "meeting/session_details.html",
{ 'sessions':sessions ,
'meeting' :meeting ,
'acronym' :acronym,
'can_manage_materials' : can_manage,
'type_counter': type_counter,
})

View file

@ -244,6 +244,26 @@
</tr>
{% endif %}
{% if presentations or can_edit_stream_info %}
<tr>
<th></th>
<th>On Agenda</th>
<td class="edit">
{% if not snapshot and can_edit_stream_info %}
{% doc_edit_button "material_presentations" name=doc.name %}
{% endif %}
</td>
<td>
{% if presentations %}
{% for pres in presentations %}{{ pres.session.short_name }} at {{ pres.session.meeting }} {% if pres.rev != doc.rev %}(version -{{ pres.rev }}){% endif %}{% if not forloop.last %}, {% endif %}{% endfor %}
{% else %}
None
{% endif %}
</td>
</tr>
{% endif %}
<tr>
<th></th>
<th>Document shepherd</th>

View file

@ -32,9 +32,9 @@
<tbody class="meta">
<tr>
<th>{% if doc.meeting_related %}Meeting{% endif %} {{ doc.type.name }}</th>
<td class="edit"></td>
<td>
<th class="col-md-1">{% if doc.meeting_related %}Meeting{% endif %} {{ doc.type.name }}</th>
<td class="edit col-md-1"></td>
<td class="col-md-10">
{{ doc.group.name }}
<a href="{{ doc.group.about_url }}">({{ doc.group.acronym }})</a> {{ doc.group.type.name }}

View file

@ -13,15 +13,22 @@
<tr>
<td>{% ifchanged s.meeting %}{% if s.meeting.type.slug == 'ietf' %}IETF{% endif %}{{s.meeting.number}}{% endifchanged %}</td>
<td>
{% if s.name %}{{ s.name }}<br>{% endif %}
{% if s.status.slug == "sched" %}
{% if s.meeting.type.slug == 'ietf' %}{{s.time|date:"D M d, Y Hi"}}{% else %}{{s.time|date:"D M d, Y"}}{% endif %}
{% else %}
{{s.status}}
{% endif %}
{% if show_request and s.meeting.type.slug == 'ietf' %}
{% if can_edit %}
<br>
<a class="btn btn-default btn-xs" href="{% url 'sessions_view' num=s.meeting.number acronym=s.group.acronym %}">Edit Session Request</a>
{% endif %}
{% endif %}
</td>
<td>{% if s.minutes %}<a href="{{ s.minutes.get_absolute_url }}">Minutes</a>{% endif %}</td>
<td>{% if s.agenda %}<a href="{{ s.agenda.get_absolute_url }}">Agenda</a>{% endif %}</td>
<td><a href="{% url 'ietf.meeting.views.session_details' num=s.meeting.number acronym=s.group.acronym %}">Materials</a></td>
<td>{% if s.agenda %}<a class="btn btn-default btn-xs" href="{{ s.agenda.get_absolute_url }}">Agenda</a>{% endif %}</td>
<td>{% if s.minutes %}<a class="btn btn-default btn-xs" href="{{ s.minutes.get_absolute_url }}">Minutes</a>{% endif %}</td>
<td><a class="btn btn-default btn-xs" href="{% url 'ietf.meeting.views.session_details' num=s.meeting.number acronym=s.group.acronym %}">Materials</a></td>
{% endfor %}
</tbody>
</table>

View file

@ -6,13 +6,21 @@
{% block group_content %}
{% origin %}
<div class="buttonlist">
<a class="btn btn-default" href="{% url 'ietf.meeting.views.meeting_requests' %}">Session requests</a>
{% if can_edit %}
<a class="btn btn-default" href="{% url 'ietf.secr.sreq.views.main' %}">Request a session</a>
{% endif %}
</div>
{% if in_progress %}
<div class="panel panel-default" id="inprogressmeets">
<div class="panel-heading">
Meetings in progress
</div>
<div class="panel-body">
{% with in_progress as sessions %}
{% with sessions=in_progress show_request=True %}
{% include "group/meetings-row.html" %}
{% endwith %}
</div>
@ -25,7 +33,7 @@
Future Meetings
</div>
<div class="panel-body">
{% with future as sessions %}
{% with sessions=future show_request=True %}
{% include "group/meetings-row.html" %}
{% endwith %}
</div>

View file

@ -48,6 +48,15 @@
{% endfor %}
{% endwith %}
</td>
<td>
{% with session.drafts as drafts %}
{% for draft in drafts %}
<a href="{% url "doc_view" name=draft.canonical_name %}">{{ draft.canonical_name }}</a><br>
{% empty %}
<span class="label label-warning">No drafts</span>
{% endfor %}
{% endwith %}
</td>
{% endif %}
</tr>

View file

@ -42,10 +42,11 @@
<table class="table table-condensed table-striped tablesorter">
<thead>
<tr>
<th>Group</th>
<th>Agenda</th>
<th>Minutes</th>
<th>Slides</th>
<th class="col-md-1">Group</th>
<th class="col-md-1">Agenda</th>
<th class="col-md-1">Minutes</th>
<th class="col-md-6">Slides</th>
<th class="col-md-3">Drafts</th>
</tr>
</thead>
@ -64,10 +65,11 @@
<table class="table table-condensed table-striped tablesorter">
<thead>
<tr>
<th>Group</th>
<th>Agenda</th>
<th>Minutes</th>
<th>Slides</th>
<th class="col-md-1">Group</th>
<th class="col-md-1">Agenda</th>
<th class="col-md-1">Minutes</th>
<th class="col-md-6">Slides</th>
<th class="col-md-3">Drafts</th>
</tr>
</thead>
@ -88,10 +90,11 @@
<table class="table table-condensed table-striped tablesorter">
<thead>
<tr>
<th>Group</th>
<th>Agenda</th>
<th>Minutes</th>
<th>Slides</th>
<th class="col-md-1">Group</th>
<th class="col-md-1">Agenda</th>
<th class="col-md-1">Minutes</th>
<th class="col-md-6">Slides</th>
<th class="col-md-3">Drafts</th>
</tr>
</thead>
@ -112,10 +115,11 @@
<table class="table table-condensed table-striped tablesorter">
<thead>
<tr>
<th>Group</th>
<th>Agenda</th>
<th>Minutes</th>
<th>Slides</th>
<th class="col-md-1">Group</th>
<th class="col-md-1">Agenda</th>
<th class="col-md-1">Minutes</th>
<th class="col-md-6">Slides</th>
<th class="col-md-3">Drafts</th>
</tr>
</thead>
@ -135,10 +139,11 @@
<table class="table table-condensed table-striped tablesorter">
<thead>
<tr>
<th>Group</th>
<th>Agenda</th>
<th>Minutes</th>
<th>Slides</th>
<th class="col-md-1">Group</th>
<th class="col-md-1">Agenda</th>
<th class="col-md-1">Minutes</th>
<th class="col-md-6">Slides</th>
<th class="col-md-3">Drafts</th>
</tr>
</thead>
@ -182,4 +187,4 @@
{% block js %}
<script src="{% static "jquery.tablesorter/js/jquery.tablesorter.combined.min.js" %}"></script>
{% endblock %}
{% endblock %}

View file

@ -9,23 +9,39 @@
<h1>{{ meeting }} : {{ acronym }}</h1>
{% for session in sessions %}
<h2>{{ session.time }}{% if session.name %} : {{ session.name }}{% endif %}</h2>
<h2>{% if sessions|length > 1 %}Session {{ forloop.counter }} : {% endif %}{{ session.time }}{% if session.name %} : {{ session.name }}{% endif %}</h2>
{% if can_manage_materials %}
{% 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
</a>
{% if not type_counter.agenda %}
<span class="label label-warning">This session does not yet have an agenda</span>
{% endif %}
</div>
{% endif %}
{% endif %}
{% if session.filtered_sessionpresentation_set %}
<p>Materials:</p>
<table class="table table-condensed table-striped">
{% for pres in session.filtered_sessionpresentation_set %}
{% if pres.document.type_id != 'bluesheets' and pres.document.type_id != 'recording' %}
<tr>
<td>
<a href="{% url 'doc_view' name=pres.document.name rev=pres.rev%}">{{pres.document.title}} ({{ pres.document.name }}-{{ pres.rev }})
</a>
</td>
</tr>
{% endif %}
{% endfor %}
</table>
<div class="panel panel-default">
<div class="panel-heading">Materials:</div>
<div class="panel-body">
<table class="table table-condensed table-striped">
{% for pres in session.filtered_sessionpresentation_set %}
{% if pres.document.type_id != 'bluesheets' and pres.document.type_id != 'recording' %}
<tr>
<td>
<a href="{% url 'doc_view' name=pres.document.name rev=pres.rev%}">{{pres.document.title}} ({{ pres.document.name }}-{{ pres.rev }})
</a>
</td>
</tr>
{% endif %}
{% endfor %}
</table>
</div>
</div>
{% endif %}
{% endfor %}