diff --git a/ietf/meeting/tests_js.py b/ietf/meeting/tests_js.py
index c66beace9..60384b6aa 100644
--- a/ietf/meeting/tests_js.py
+++ b/ietf/meeting/tests_js.py
@@ -285,10 +285,6 @@ class SlideReorderTests(MeetingTestCase):
@skipIf(skip_selenium, skip_message)
class AgendaTests(MeetingTestCase):
- # Groups whose display logic is inverted in agenda.html. These have
- # toggles with class 'pickviewneg' in the template.
- PICKVIEWNEG = ['iepg', 'tools', 'edu', 'ietf', 'iesg', 'iab']
-
def setUp(self):
super(AgendaTests, self).setUp()
self.meeting = make_meeting_test_data()
@@ -377,40 +373,75 @@ class AgendaTests(MeetingTestCase):
self.assertEqual(result[4], ['item1', 'item3'], 'Removing middle item from list failed')
self.assertEqual(result[5], ['item1', 'item2'], 'Removing last item from list failed')
+ def do_agenda_view_filter_test(self, querystring, visible_groups=()):
+ self.login()
+ self.driver.get(self.absreverse('ietf.meeting.views.agenda') + querystring)
+ self.assert_agenda_item_visibility(visible_groups)
+ weekview_iframe = self.driver.find_element_by_id('weekview')
+ if len(querystring) == 0:
+ self.assertFalse(weekview_iframe.is_displayed(), 'Weekview should be hidden when filters off')
+ else:
+ self.assertTrue(weekview_iframe.is_displayed(), 'Weekview should be visible when filters on')
+ self.driver.switch_to.frame(weekview_iframe)
+ self.assert_weekview_item_visibility(visible_groups)
+ self.driver.switch_to.default_content()
+
def test_agenda_view_filter_show_one(self):
"""Filtered agenda view should display only matching rows (one group selected)"""
- self.login()
- self.driver.get(self.absreverse('ietf.meeting.views.agenda') + '?show=mars')
- self.assert_agenda_item_visibility(['mars'] + self.PICKVIEWNEG) # ames and secretariat not selected
+ self.do_agenda_view_filter_test('?show=mars', ['mars'])
def test_agenda_view_filter_show_two(self):
"""Filtered agenda view should display only matching rows (two groups selected)"""
- self.login()
- self.driver.get(self.absreverse('ietf.meeting.views.agenda') + '?show=mars,ames')
- self.assert_agenda_item_visibility(['mars', 'ames'] + self.PICKVIEWNEG) # secretariat not selected
+ self.do_agenda_view_filter_test('?show=mars,ames', ['mars', 'ames'])
def test_agenda_view_filter_all(self):
"""Filtered agenda view should display only matching rows (all groups selected)"""
- self.login()
- self.driver.get(self.absreverse('ietf.meeting.views.agenda'))
- self.assert_agenda_item_visibility()
+ self.do_agenda_view_filter_test('', None) # None means all should be visible
def test_agenda_view_filter_hide(self):
- self.login()
- self.driver.get(self.absreverse('ietf.meeting.views.agenda') + '?hide=ietf')
- self.assert_agenda_item_visibility([g for g in self.PICKVIEWNEG if g != 'ietf'])
+ self.do_agenda_view_filter_test('?hide=ietf', [])
def test_agenda_view_filter_show_and_hide(self):
- self.login()
- self.driver.get(self.absreverse('ietf.meeting.views.agenda') + '?show=mars&hide=ietf')
- self.assert_agenda_item_visibility(
- ['mars'] + [g for g in self.PICKVIEWNEG if g != 'ietf']
- )
+ self.do_agenda_view_filter_test('?show=mars&hide=ietf', ['mars'])
- def assert_agenda_item_visibility(self, visible_groups=()):
+ def test_agenda_view_filter_show_and_hide_same_group(self):
+ self.do_agenda_view_filter_test('?show=mars&hide=mars', [])
+
+ def test_agenda_view_filter_showtypes(self):
+ self.do_agenda_view_filter_test('?showtypes=plenary', ['ietf']) # ietf has a plenary session
+
+ def test_agenda_view_filter_hidetypes(self):
+ self.do_agenda_view_filter_test('?hidetypes=plenary', [])
+
+ def test_agenda_view_filter_showtypes_and_hidetypes(self):
+ self.do_agenda_view_filter_test('?showtypes=plenary&hidetypes=regular', ['ietf']) # ietf has a plenary session
+
+ def test_agenda_view_filter_showtypes_and_hidetypes_same_type(self):
+ self.do_agenda_view_filter_test('?showtypes=plenary&hidetypes=plenary', [])
+
+ def test_agenda_view_filter_show_and_showtypes(self):
+ self.do_agenda_view_filter_test('?show=mars&showtypes=plenary', ['mars', 'ietf']) # ietf has a plenary session
+
+ def test_agenda_view_filter_show_and_hidetypes(self):
+ self.do_agenda_view_filter_test('?show=ietf,mars&hidetypes=plenary', ['mars']) # ietf has a plenary session
+
+ def test_agenda_view_filter_hide_and_hidetypes(self):
+ self.do_agenda_view_filter_test('?hide=ietf,mars&hidetypes=plenary', [])
+
+ def test_agenda_view_filter_show_hide_and_showtypes(self):
+ self.do_agenda_view_filter_test('?show=mars&hide=ames&showtypes=plenary,regular', ['mars', 'ietf']) # ietf has plenary session
+
+ def test_agenda_view_filter_show_hide_and_hidetypes(self):
+ self.do_agenda_view_filter_test('?show=mars,ietf&hide=ames&hidetypes=plenary', ['mars']) # ietf has plenary session
+
+ def test_agenda_view_filter_all_params(self):
+ self.do_agenda_view_filter_test('?show=secretariat,ietf&hide=ames&showtypes=regular&hidetypes=plenary',
+ ['secretariat', 'mars'])
+
+ def assert_agenda_item_visibility(self, visible_groups=None):
"""Assert that correct items are visible in current browser window
- If visible_groups is empty (the default), expects all items to be visible.
+ If visible_groups is None (the default), expects all items to be visible.
"""
for item in self.get_expected_items():
row_id = self.row_id_for_item(item)
@@ -419,11 +450,33 @@ class AgendaTests(MeetingTestCase):
except NoSuchElementException:
item_row = None
self.assertIsNotNone(item_row, 'No row for schedule item "%s"' % row_id)
- if len(visible_groups) == 0 or item.session.group.acronym in visible_groups:
+ if visible_groups is None or item.session.group.acronym in visible_groups:
self.assertTrue(item_row.is_displayed(), 'Row for schedule item "%s" is not displayed but should be' % row_id)
else:
self.assertFalse(item_row.is_displayed(), 'Row for schedule item "%s" is displayed but should not be' % row_id)
+ def assert_weekview_item_visibility(self, visible_groups=None):
+ for item in self.get_expected_items():
+ if item.session.name:
+ label = item.session.name
+ elif item.timeslot.type_id == 'break':
+ label = item.timeslot.name
+ elif item.session.group:
+ label = item.session.group.name
+ else:
+ label = 'Free Slot'
+
+ try:
+ item_div = self.driver.find_element_by_xpath('//div/span[contains(text(),"%s")]/..' % label)
+ except NoSuchElementException:
+ item_div = None
+
+ if visible_groups is None or item.session.group.acronym in visible_groups:
+ self.assertIsNotNone(item_div, 'No weekview entry for "%s" (%s)' % (label, item.slug()))
+ self.assertTrue(item_div.is_displayed(), 'Entry for "%s (%s)" is not displayed but should be' % (label, item.slug()))
+ else:
+ self.assertIsNone(item_div, 'Unexpected weekview entry for "%s" (%s)' % (label, item.slug()))
+
def test_agenda_view_group_filter_toggle(self):
"""Clicking a group toggle enables/disables agenda filtering"""
group_acronym = 'mars'
@@ -449,7 +502,7 @@ class AgendaTests(MeetingTestCase):
group_button.click()
# Check visibility
- self.assert_agenda_item_visibility([group_acronym] + self.PICKVIEWNEG)
+ self.assert_agenda_item_visibility([group_acronym])
# Click the group button again
group_button = WebDriverWait(self.driver, 2).until(
diff --git a/ietf/meeting/tests_views.py b/ietf/meeting/tests_views.py
index 31ed45ed3..78a6e4436 100644
--- a/ietf/meeting/tests_views.py
+++ b/ietf/meeting/tests_views.py
@@ -801,7 +801,7 @@ class MeetingTests(TestCase):
# ames regular session should be suppressed
self.do_ical_filter_test(
meeting,
- querystring='?show=mars&hide=ames&showtypes=plenary,regular',
+ querystring='?show=ietf&hide=ames&showtypes=regular',
expected_session_summaries=[
'IETF Plenary',
'mars - Martian Special Interest Group',
diff --git a/ietf/templates/meeting/agenda.html b/ietf/templates/meeting/agenda.html
index 4f753ce5b..91b077bec 100644
--- a/ietf/templates/meeting/agenda.html
+++ b/ietf/templates/meeting/agenda.html
@@ -120,12 +120,12 @@
{% endif %}
Also show special sessions of these groups:
-
-
-
-
-
-
+
+
+
+
+
+
@@ -362,10 +362,13 @@
function parse_query_params(qs) {
var params = {};
qs = qs.replace(/^\?/, '');
- $.each(qs.split('&'), function(i, v) {
- var toks = v.split('=', 2)
- params[toks[0]] = toks[1].toLowerCase();
- });
+ if (qs) {
+ var param_strs = qs.split('&');
+ for (var ii = 0; ii < param_strs.length; ii++) {
+ var toks = param_strs[ii].split('=', 2)
+ params[toks[0]] = toks[1] || true;
+ }
+ }
return params;
}
@@ -374,43 +377,56 @@
return qparams[filt] ? qparams[filt].split(',') : [];
}
- function toggle_visibility() {
- var qparams = parse_query_params(window.location.search);
- var show_groups = get_filter_from_qparams(qparams, 'show');
- var hide_groups = get_filter_from_qparams(qparams, 'hide');
+ function get_filter_params(qparams) {
+ return {
+ show_groups: get_filter_from_qparams(qparams, 'show'),
+ hide_groups: get_filter_from_qparams(qparams, 'hide'),
+ show_types: get_filter_from_qparams(qparams, 'showtypes'),
+ hide_types: get_filter_from_qparams(qparams, 'hidetypes'),
+ };
+ }
+ function toggle_visibility(filter_params) {
// reset UI elements to default state
$(".pickview").removeClass("active disabled");
$(".pickviewneg").addClass("active");
- if (show_groups.length || hide_groups.length) {
- // if groups were selected for filtering, hide all rows that are
- // hidden by default, show all rows that are shown by default
+ if (filter_params['show_groups'].length ||
+ filter_params['hide_groups'].length ||
+ filter_params['show_types'].length ||
+ filter_params['hide_types'].length
+ ) {
+ // if groups were selected for filtering, hide all rows 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(hide_groups, function (i, v) {
- // this is a "negative" item: when present, hide these rows
- $('[id^="row-"]').filter('[id*="-' + v + '"]').hide();
- $(".view." + v).find("button").removeClass("active disabled");
- $("button.pickviewneg." + v).removeClass("active");
- });
- $.each(show_groups, function (i, v) {
- // this is a regular item: when present, show these rows
+ $.each(filter_params['show_groups'], function (i, v) {
+ // this is a regular item by wg: when present, show these rows
$('[id^="row-"]').filter('[id*="-' + v + '"]').show();
$(".view." + v).find("button").addClass("active disabled");
$("button.pickview." + v).addClass("active");
});
+ $.each(filter_params['show_types'], function (i, v) {
+ // this is a regular item by type: when present, show these rows
+ $('[id^="row-"]').filter('[timeslot-type*="' + v + '"]').show();
+ });
+ $.each(filter_params['hide_groups'], function (i, v) {
+ // this is a "negative" item by wg: when present, hide these rows
+ $('[id^="row-"]').filter('[id*="-' + v + '"]').hide();
+ $(".view." + v).find("button").removeClass("active disabled");
+ $("button.pickviewneg." + v).removeClass("active");
+ });
+ $.each(filter_params['hide_types'], function (i, v) {
+ // this is a "negative" item by type: when present, hide these rows
+ $('[id^="row-"]').filter('[timeslot-type*="' + v + '"]').hide();
+ });
// show the week view
- $("#weekview").attr("src", "week-view.html" + window.location.search).removeClass("hidden");
+ update_weekview();
+ $("#weekview").removeClass("hidden");
// show the custom .ics link
$("#ical-link").attr("href",$("#ical-link").attr("href").split("?")[0]+window.location.search);
@@ -426,16 +442,14 @@
$(".pickview, .pickviewneg").click(function () {
// Get clicked item label
var item = $(this).text().trim().toLowerCase();
- var qparams = parse_query_params(window.location.search);
- var show_groups = get_filter_from_qparams(qparams, 'show');
- var hide_groups = get_filter_from_qparams(qparams, 'hide');
+ var fp = get_filter_params(parse_query_params(window.location.search));
if ($(this).hasClass("pickviewneg")) {
- toggle_list_item(hide_groups, item);
+ toggle_list_item(fp['hide_groups'], item);
} else {
- toggle_list_item(show_groups, item);
+ toggle_list_item(fp['show_groups'], item);
}
- update_filters(show_groups, hide_groups);
+ update_filters(fp);
});
/* Add to list if not present, remove if present */
@@ -448,14 +462,20 @@
}
}
- function update_filters(show, hide) {
+ function update_filters(filter_params) {
var qparams = [];
var search = '';
- if (show.length > 0) {
- qparams.push('show=' + show.join());
+ if (filter_params['show_groups'].length > 0) {
+ qparams.push('show=' + filter_params['show_groups'].join());
}
- if (hide.length > 0) {
- qparams.push('hide=' + hide.join());
+ if (filter_params['hide_groups'].length > 0) {
+ qparams.push('hide=' + filter_params['hide_groups'].join());
+ }
+ if (filter_params['show_types'].length > 0) {
+ qparams.push('showtypes=' + filter_params['show_types'].join());
+ }
+ if (filter_params['hide_types'].length > 0) {
+ qparams.push('hidetypes=' + filter_params['hide_types'].join());
}
if (qparams.length > 0) {
search = '?' + qparams.join('&');
@@ -466,15 +486,32 @@
if (window.history && window.history.replaceState) {
// Keep current origin, replace search string, no page reload
history.replaceState({}, document.title, new_url);
- toggle_visibility();
+ toggle_visibility(filter_params);
} else {
// No window.history.replaceState support, page reload required
window.location = new_url;
}
}
+ function update_weekview() {
+ var wv_iframe = document.getElementById('weekview');
+ var wv_window = wv_iframe.contentWindow;
+ var new_url = 'week-view.html' + window.location.search;
+ if (wv_iframe.src && wv_window.history && wv_window.history.replaceState) {
+ wv_window.history.replaceState({}, '', new_url);
+ wv_window.draw_calendar()
+ } else {
+ // ho history.replaceState, page reload required
+ wv_iframe.src = new_url;
+ }
+ }
+
$(document).ready(function () {
- toggle_visibility();
+ toggle_visibility(
+ get_filter_params(
+ parse_query_params(window.location.search)
+ )
+ );
});
$(".modal").on("show.bs.modal", function () {
diff --git a/ietf/templates/meeting/week-view.html b/ietf/templates/meeting/week-view.html
index e73d18f5c..e97da16f2 100644
--- a/ietf/templates/meeting/week-view.html
+++ b/ietf/templates/meeting/week-view.html
@@ -107,33 +107,60 @@
}
}
+
//===========================================================================
- function is_visible(include) {
+ function parse_query_params(qs) {
+ var params = {};
+ qs = qs.replace(/^\?/, '').toLowerCase();
+ if (qs) {
+ var param_strs = qs.split('&');
+ for (var ii = 0; ii < param_strs.length; ii++) {
+ var toks = param_strs[ii].split('=', 2)
+ params[toks[0]] = toks[1] || true;
+ }
+ }
+ return params;
+ }
+
+ //===========================================================================
+
+ function get_filter_from_qparams(qparams, filt) {
+ return qparams[filt] ? qparams[filt].split(',') : [];
+ }
+
+ function get_filter_params(qparams) {
+ return {
+ show_groups: get_filter_from_qparams(qparams, 'show'),
+ hide_groups: get_filter_from_qparams(qparams, 'hide'),
+ show_types: get_filter_from_qparams(qparams, 'showtypes'),
+ hide_types: get_filter_from_qparams(qparams, 'hidetypes'),
+ };
+ }
+ //===========================================================================
+
+ function is_visible(query_params) {
+ // Returns a method to filter objects for visibility
+ // Accepts show, hide, showtypes, and hidetypes filters. Also accepts
+ // '@' to show sessions in a particular state (e.g., @bof).
+ // Current types are:
+ // Session, Other, Break, Plenary
+ var fp = get_filter_params(query_params);
+
return function (item) {
- // "-wgname" will remove a working group from the output.
- // "~Type" will add that type to the output.
- // "-~Type" will remove that type from the output
- // "@bof" will include all BOFs
- // Current types are:
- // Session, Other, Break, Plenary
+ var item_group = (item.group || '').toLowerCase();
+ var item_type = (item.type || '').toLowerCase();
+ var item_area = (item.area || '').toLowerCase();
+ var item_state = (item.state || '').toLowerCase();
- if ("group" in item) {
- if (include[(item.group).toLowerCase()]) { return true; }
- if (include["-"+(item.group).toLowerCase()]) { return false; }
+ if ((fp['hide_groups'].indexOf(item_group) >= 0) ||
+ (fp['hide_types'].indexOf(item_type) >= 0)) {
+ return false;
}
- if ("state" in item) {
- if (include["@"+(item.state).toLowerCase()]) { return true; }
- }
- if (include["~"+(item.type).toLowerCase()]) { return true; }
- if (include["-~"+(item.type).toLowerCase()]) { return false; }
- if ("area" in item) {
- if (include[(item.area).toLowerCase()]) { return true; }
- }
- if (item.type === "Plenary") { return true; }
- if (item.type === "Other") { return true; }
-
- return false;
+ return ((fp['show_groups'].indexOf(item_group) >= 0) ||
+ (fp['show_groups'].indexOf(item_area) >= 0) ||
+ (fp['show_types'].indexOf(item_type) >= 0) ||
+ query_params['@'+item_state]);
}
}
@@ -143,16 +170,23 @@
var width = document.body.clientWidth;
var height = document.body.clientHeight;
- var include = {};
- window.location.hash.replace("#",'').split(',').forEach(function(key){
- include[(key + "").toLowerCase()] = true;
- });
+ var visible_items = all_items;
+ var qs = window.location.search;
+ if (qs.length > 1) {
+ visible_items = visible_items.filter(is_visible(parse_query_params(qs)));
+ }
- var visible_items = all_items.filter(is_visible(include));
-
- var start_day = visible_items[0].day;
+ var start_day;
+ var day_start;
+ if (visible_items.length > 0) {
+ start_day = visible_items[0].day;
+ day_start = visible_items[0].start_time;
+ } else {
+ // fallback in case all items were filtered
+ start_day = all_items[0].day;
+ day_start = all_items[0].start_time;
+ }
var end_day = start_day;
- var day_start = visible_items[0].start_time;
var day_end = 0;
compute_swimlanes(visible_items);
@@ -324,6 +358,11 @@
document.body.appendChild(e);
});
+
+ // Div to indicate rendering has occurred, for testing purposes.
+ var elt = document.createElement('div');
+ elt.id = 'wv-end';
+ document.body.appendChild(elt);
}
//===========================================================================