add view views.upcoming

- Legacy-Id: 10860
This commit is contained in:
Ryan Cross 2016-02-26 17:41:09 +00:00
parent 8b87125716
commit bc8e744388
6 changed files with 289 additions and 1 deletions

View file

@ -77,6 +77,32 @@ def make_meeting_test_data():
doc.set_state(State.objects.get(type='reuse_policy',slug='single'))
mars_session.sessionpresentation_set.add(SessionPresentation(session=mars_session,document=doc,rev=doc.rev))
# Future Interim Meetings
date = datetime.date.today() + datetime.timedelta(days=365)
mars_meeting = Meeting.objects.create(
number="interim-%s-mars-1" % date.year,
type_id='interim',
date=date,
city="New York",
country="US",
)
mars_session = Session.objects.create(meeting=mars_meeting, group=mars,
attendees=10, requested_by=system_person,
requested_duration=20, status_id="sched",
scheduled=datetime.datetime.now(),type_id="session")
ames = Group.objects.get(acronym="ames")
ames_meeting = Meeting.objects.create(
number="interim-%s-ames-1" % date.year,
type_id='interim',
date=date,
city="New York",
country="US",
)
ames_session = Session.objects.create(meeting=ames_meeting, group=ames,
attendees=10, requested_by=system_person,
requested_duration=20, status_id="canceled",
scheduled=datetime.datetime.now(),type_id="session")
return meeting

View file

@ -9,7 +9,7 @@ from django.conf import settings
from pyquery import PyQuery
from ietf.doc.models import Document
from ietf.meeting.models import Session, TimeSlot
from ietf.meeting.models import Session, TimeSlot, Meeting
from ietf.meeting.test_data import make_meeting_test_data
from ietf.utils.test_utils import TestCase, login_testing_unauthorized, unicontent
@ -330,3 +330,24 @@ class EditTests(TestCase):
ames_slot_qs.update(time=mars_ends + datetime.timedelta(seconds=10 * 60))
self.assertTrue(mars_slot.slot_to_the_right)
self.assertTrue(mars_scheduled.slot_to_the_right)
class InterimTests(TestCase):
def test_upcoming(self):
make_meeting_test_data()
r = self.client.get("/meeting/upcoming/")
self.assertEqual(r.status_code, 200)
today = datetime.date.today()
mars_interim = Meeting.objects.filter(date__gt=today,type='interim',number__contains='mars').first()
ames_interim = Meeting.objects.filter(date__gt=today,type='interim',number__contains='ames').first()
self.assertTrue(mars_interim.number in r.content)
self.assertTrue(ames_interim.number in r.content)
# cancelled session
q = PyQuery(r.content)
self.assertTrue('CANCELLED' in q('[id*="-ames"]').text())
def test_upcoming_ics(self):
make_meeting_test_data()
r = self.client.get("/meeting/upcoming.ics/")
self.assertEqual(r.status_code, 200)
self.assertEqual(r.get('Content-Type'),"text/calendar")

View file

@ -65,6 +65,8 @@ urlpatterns = [
# The optionals have to go first, otherwise the agenda/(owner)/(name)/ patterns match things they shouldn't
url(r'^(?:(?P<num>\d+)/)?', include(type_ietf_only_patterns_id_optional)),
url(r'^(?P<num>\d+)/', include(type_ietf_only_patterns)),
url(r'^upcoming/$', views.upcoming),
url(r'^upcoming.ics/$', views.ical_upcoming),
url(r'^$', views.current_materials),
]

View file

@ -874,3 +874,36 @@ def session_details(request, num, acronym ):
'can_manage_materials' : can_manage,
'type_counter': type_counter,
})
def ical_upcoming(request):
'''ICAL upcoming meetings'''
return HttpResponse()
def upcoming(request):
'''List of upcoming meetings'''
today = datetime.datetime.today()
meetings = Meeting.objects.filter(date__gt=today)
# extract groups hierarchy
seen = set()
groups = [ m.session_set.first().group for m in meetings.filter(type='interim') ]
group_parents = []
for g in groups:
if g.parent.acronym not in seen:
group_parents.append(g.parent)
seen.add(g.parent.acronym)
seen = set()
for p in group_parents:
p.group_list = []
for g in groups:
if g.acronym not in seen and g.parent == p:
p.group_list.append(g)
seen.add(g.acronym)
p.group_list.sort(key=lambda g: g.acronym)
return render(request, "meeting/upcoming.html",
{ 'meetings':meetings,
'group_parents':group_parents,
})

View file

@ -0,0 +1,77 @@
function toggle_visibility() {
var h = window.location.hash;
h = h.replace(/^#?,?/, '');
// reset UI elements to default state
$(".pickview").removeClass("active disabled");
$(".pickviewneg").addClass("active");
if (h) {
// if there are items in the hash, hide all rows that are
// hidden by default, show all rows that are shown by default
$('[id^="row-"]').hide();
//$.each($(".pickviewneg").text().trim().split(/ +/), function (i, v) {
// v = v.trim().toLowerCase();
// $('[id^="row-"]').filter('[id*="-' + v + '"]').show();
//});
// show the customizer
$("#customize").collapse("show");
// loop through the has items and change the UI element and row visibilities accordingly
$.each(h.split(","), function (i, v) {
if (v.indexOf("-") == 0) {
// this is a "negative" item: when present, hide these rows
v = v.replace(/^-/, '');
$('[id^="row-"]').filter('[id*="-' + v + '"]').hide();
$(".view." + v).find("button").removeClass("active disabled");
$("button.pickviewneg." + v).removeClass("active");
} else {
// this is a regular item: when present, show these rows
$('[id^="row-"]').filter('[id*="-' + v + '"]').show();
$(".view." + v).find("button").addClass("active disabled");
$("button.pickview." + v).addClass("active");
}
});
// show the week view
//$("#weekview").attr("src", "week-view.html" + window.location.hash).removeClass("hidden");
// show the custom .ics link
//$("#ical-link").attr("href",$("#ical-link").attr("href").split("?")[0]+"?"+h);
//$("#ical-link").removeClass("hidden");
} else {
// if the hash is empty, show all and hide weekview
$('[id^="row-"]').show();
//$("#ical-link, #weekview").addClass("hidden");
}
}
$(".pickview, .pickviewneg").click(function () {
var h = window.location.hash;
var item = $(this).text().trim().toLowerCase();
if ($(this).hasClass("pickviewneg")) {
item = "-" + item;
}
re = new RegExp('(^|#|,)' + item + "(,|$)");
if (h.match(re) == null) {
if (h.replace("#", "").length == 0) {
h = item;
} else {
h += "," + item;
}
h = h.replace(/^#?,/, '');
} else {
h = h.replace(re, "$2").replace(/^#?,/, '');
}
window.location.hash = h.replace(/^#$/, '');
toggle_visibility();
});
$(document).ready(function () {
toggle_visibility();
});

View file

@ -0,0 +1,129 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}
{% load ietf_filters staticfiles %}
{% block pagehead %}
<link rel="stylesheet" href="{% static "jquery.tablesorter/css/theme.bootstrap.min.css" %}">
{% endblock %}
{% block bodyAttrs %}data-spy="scroll" data-target="#affix"{% endblock %}
{% block title %}IETF Upcoming Meetings{% endblock %}
{% block content %}
{% origin %}
<div class="row">
<div class="col-md-10">
<h1>IETF Upcoming Meetings</h1>
<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#customize">
<span class="fa fa-caret-down"></span> Customize the meeting list...
</a>
</h4>
</div> <!-- panel-heading -->
<div id="customize" class="panel-collapse collapse">
<div class="panel-body">
<p>
You can customize the list to show only selected groups
by clicking on groups and areas in the table below.
To be able to return to the customized view later, bookmark the resulting URL.
</p>
{% if group_parents|length %}
<p>Groups displayed in <b><i>italics</i></b> are BOFs.</p>
<table class="table table-condensed">
<thead>
<tr>
{% for p in group_parents %}
<th style="width:{% widthratio 1 group_parents|length 100 %}%">
<button class="btn btn-default btn-block pickview {{p.acronym|lower}}">{{p.acronym|upper}}</button>
</th>
{% endfor %}
</tr>
</thead>
<tbody>
<tr>
{% for p in group_parents %}
<td class="view {{p.acronym|lower}}">
<div class="btn-group-vertical btn-block">
{% for group in p.group_list %}
<div class="btn-group btn-group-xs btn-group-justified">
<button class="btn btn-default pickview {{group.acronym}}">
{% if group.is_bof %}
<i>{{group.acronym}}</i>
{% else %}
{{group.acronym}}
{% endif %}
</button>
</div> <!-- button-group -->
{% endfor %}
</div> <!-- button-group-vertical -->
</td>
{% endfor %}
</tr>
</tbody>
</table>
{% else %}
<blockquote><i>No meetings have been scheduled yet.</i></blockquote>
{% endif %}
</div> <!-- panel-body -->
</div> <!-- panel-collapse -->
</div> <!-- panel -->
</div> <!-- panel-group -->
{% if meetings %}
<h3></h3>
<table class="table table-condensed table-striped tablesorter">
<thead>
<tr>
<th>Date</th>
<th>Group</th>
<th>Name</th>
</tr>
</thead>
<tbody>
{% for meeting in meetings %}
{% if meeting.type.slug == 'interim' %}
<tr id="row-{{ forloop.counter }}-{{ meeting.session_set.all.0.group.acronym }}">
{% else %}
<tr id="row-{{ forloop.counter }}-ietf">
{% endif %}
<td>{{ meeting.date }}</td>
{% if meeting.type.slug == 'interim' %}
<td>{{ meeting.session_set.all.0.group.acronym }}</td>
{% else %}
<td>ietf</td>
{% endif %}
<td>
{% if meeting.type.slug == "interim" %}
<a href="{% url 'ietf.meeting.views.session_details' num=meeting.number acronym=meeting.session_set.all.0.group.acronym %}">{{ meeting.number }}{% if meeting.session_set.all.0.status.slug == "canceled" %} -- CANCELLED --{% endif %}</a>
{% else %}
<a href="{% url 'ietf.meeting.views.agenda' num=meeting.number %}">IETF - {{ meeting.number }}</a>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<h3>No upcoming meetings</h3>
{% endif %}
</div>
</div>
{% endblock %}
{% block js %}
<script src="{% static "jquery.tablesorter/js/jquery.tablesorter.combined.min.js" %}"></script>
<script src="{% static 'ietf/js/toggle-visibility.js' %}"></script>
{% endblock %}