add view views.upcoming
- Legacy-Id: 10860
This commit is contained in:
parent
8b87125716
commit
bc8e744388
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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),
|
||||
]
|
||||
|
||||
|
|
|
@ -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,
|
||||
})
|
77
ietf/static/ietf/js/toggle-visibility.js
Normal file
77
ietf/static/ietf/js/toggle-visibility.js
Normal 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();
|
||||
});
|
||||
|
129
ietf/templates/meeting/upcoming.html
Normal file
129
ietf/templates/meeting/upcoming.html
Normal 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 %}
|
Loading…
Reference in a new issue