More agenda fixes.

- Legacy-Id: 19674
This commit is contained in:
Lars Eggert 2021-11-17 12:56:09 +00:00
parent a8764f225f
commit a114ad9ecc
24 changed files with 399 additions and 166 deletions

View file

@ -6,6 +6,7 @@ module.exports = {
"no-multiple-empty-lines": ["error", { max: 2, maxEOF: 0 }],
"quote-props": ["error", "as-needed"],
"brace-style": ["error", "1tbs", { allowSingleLine: true }],
"semi": ["error", "always"],
},
env: {
browser: true,

View file

@ -6,6 +6,8 @@ $enable-negative-margins: true;
// Don't add carets to dropdowns by default.
// $enable-caret: false;
$tooltip-max-width: 100%;
// Only import what we need:
// https://getbootstrap.com/docs/5.1/customize/optimize/

View file

@ -9,85 +9,105 @@
This should be done before calling anything else in the file.
*/
var meeting_timezone;
var local_timezone = moment.tz.guess();
// get_current_tz_cb must be overwritten using set_current_tz_cb
window.get_current_tz_cb = function () {
function get_current_tz_cb() {
throw new Error('Tried to get current timezone before callback registered. Use set_current_tz_cb().')
};
// Initialize moments
window.initialize_moments = function () {
var times=$('span.time')
$.each(times, function(i, item) {
item.start_ts = moment.unix(this.getAttribute("data-start-time")).utc();
item.end_ts = moment.unix(this.getAttribute("data-end-time")).utc();
var times = $('div.time')
$.each(times, function (i, item) {
item.start_ts = moment.unix(this.getAttribute("data-start-time"))
.utc();
item.end_ts = moment.unix(this.getAttribute("data-end-time"))
.utc();
if (this.hasAttribute("weekday")) {
item.format=2;
item.format = 2;
} else {
item.format=1;
item.format = 1;
}
if (this.hasAttribute("format")) {
item.format = +this.getAttribute("format");
}
});
var times=$('[data-slot-start-ts]')
$.each(times, function(i, item) {
item.slot_start_ts = moment.unix(this.getAttribute("data-slot-start-ts")).utc();
item.slot_end_ts = moment.unix(this.getAttribute("data-slot-end-ts")).utc();
var times = $('[data-slot-start-ts]')
$.each(times, function (i, item) {
item.slot_start_ts = moment.unix(this.getAttribute("data-slot-start-ts"))
.utc();
item.slot_end_ts = moment.unix(this.getAttribute("data-slot-end-ts"))
.utc();
});
}
window.format_time = function (t, tz, fmt) {
function format_time(t, tz, fmt) {
var out;
var mtz = meeting_timezone;
var mtz = window.meeting_timezone;
if (mtz == "") {
mtz = "UTC";
}
switch (fmt) {
case 0:
out = t.tz(tz).format('dddd, ') + '<span class="d-none d-sm-block">' +
t.tz(tz).format('MMMM Do YYYY, ') + '</span>' +
t.tz(tz).format('HH:mm') + '<span class="d-none d-sm-block">' +
t.tz(tz).format(' Z z') + '</span>';
out = t.tz(tz)
.format('dddd, ') + '<span class="">' +
t.tz(tz)
.format('MMMM Do YYYY, ') + '</span>' +
t.tz(tz)
.format('HH:mm') + '<span class="">' +
t.tz(tz)
.format(' Z z') + '</span>';
break;
case 1:
// Note, this code does not work if the meeting crosses the
// year boundary.
out = t.tz(tz).format("HH:mm");
if (+t.tz(tz).dayOfYear() < +t.tz(mtz).dayOfYear()) {
out = t.tz(tz)
.format("HH:mm");
if (+t.tz(tz)
.dayOfYear() < +t.tz(mtz)
.dayOfYear()) {
out = out + " (-1)";
} else if (+t.tz(tz).dayOfYear() > +t.tz(mtz).dayOfYear()) {
} else if (+t.tz(tz)
.dayOfYear() > +t.tz(mtz)
.dayOfYear()) {
out = out + " (+1)";
}
break;
case 2:
out = t.tz(mtz).format("dddd, ").toUpperCase() +
t.tz(tz).format("HH:mm");
if (+t.tz(tz).dayOfYear() < +t.tz(mtz).dayOfYear()) {
out = t.tz(mtz)
.format("dddd, ")
.toUpperCase() +
t.tz(tz)
.format("HH:mm");
if (+t.tz(tz)
.dayOfYear() < +t.tz(mtz)
.dayOfYear()) {
out = out + " (-1)";
} else if (+t.tz(tz).dayOfYear() > +t.tz(mtz).dayOfYear()) {
} else if (+t.tz(tz)
.dayOfYear() > +t.tz(mtz)
.dayOfYear()) {
out = out + " (+1)";
}
break;
case 3:
out = t.utc().format("YYYY-MM-DD");
out = t.utc()
.format("YYYY-MM-DD");
break;
case 4:
out = t.tz(tz).format("YYYY-MM-DD HH:mm");
out = t.tz(tz)
.format("YYYY-MM-DD HH:mm");
break;
case 5:
out = t.tz(tz).format("HH:mm");
out = t.tz(tz)
.format("HH:mm");
break;
}
return out;
}
// Format tooltip notice
window.format_tooltip_notice = function (start, end) {
function format_tooltip_notice(start, end) {
var notice = "";
if (end.isBefore()) {
@ -102,31 +122,31 @@ window.format_tooltip_notice = function (start, end) {
}
// Format tooltip table
window.format_tooltip_table = function (start, end) {
function format_tooltip_table(start, end) {
var current_timezone = get_current_tz_cb();
var out = '<table><tr><th>Timezone</th><th>Start</th><th>End</th></tr>';
if (meeting_timezone !== "") {
out += '<tr><td class="timehead">Meeting timezone:</td><td>' +
format_time(start, meeting_timezone, 0) + '</td><td>' +
format_time(end, meeting_timezone, 0) + '</td></tr>';
var out = '<div class="text-start"><table class="table text-light table-sm"><tr><th></th><th>Session start</th><th>Session end</th></tr>';
if (window.meeting_timezone !== "") {
out += '<tr><th class="timehead">Meeting timezone</th><td>' +
format_time(start, window.meeting_timezone, 0) + '</td><td>' +
format_time(end, window.meeting_timezone, 0) + '</td></tr>';
}
out += '<tr><td class="timehead">Local timezone:</td><td>' +
out += '<tr><th class="timehead">Local timezone</th><td>' +
format_time(start, local_timezone, 0) + '</td><td>' +
format_time(end, local_timezone, 0) + '</td></tr>';
if (current_timezone !== 'UTC') {
out += '<tr><td class="timehead">Selected Timezone:</td><td>' +
out += '<tr><th class="timehead">Selected Timezone</th><td>' +
format_time(start, current_timezone, 0) + '</td><td>' +
format_time(end, current_timezone, 0) + '</td></tr>';
}
out += '<tr><td class="timehead">UTC:</td><td>' +
out += '<tr><th class="timehead">UTC</th><td>' +
format_time(start, 'UTC', 0) + '</td><td>' +
format_time(end, 'UTC', 0) + '</td></tr>';
out += '</table>' + format_tooltip_notice(start, end);
out += '</table>' + format_tooltip_notice(start, end) + '</div>';
return out;
}
// Format tooltip for item
window.format_tooltip = function (start, end) {
function format_tooltip(start, end) {
return '<div class="timetooltiptext">' +
format_tooltip_table(start, end) +
'</div>';
@ -134,78 +154,108 @@ window.format_tooltip = function (start, end) {
// Add tooltips
window.add_tooltips = function () {
$('span.time').each(function () {
var tooltip = $(format_tooltip(this.start_ts, this.end_ts));
tooltip[0].start_ts = this.start_ts;
tooltip[0].end_ts = this.end_ts;
tooltip[0].ustart_ts = moment(this.start_ts).add(-2, 'hours');
tooltip[0].uend_ts = moment(this.end_ts).add(2, 'hours');
$(this).parent().append(tooltip);
});
$('div.time')
.each(function () {
var tooltip = $(format_tooltip(this.start_ts, this.end_ts));
tooltip[0].start_ts = this.start_ts;
tooltip[0].end_ts = this.end_ts;
tooltip[0].ustart_ts = moment(this.start_ts)
.add(-2, 'hours');
tooltip[0].uend_ts = moment(this.end_ts)
.add(2, 'hours');
$(this)
.closest("th, td")
.attr("data-bs-toggle", "tooltip")
.attr("title", $(tooltip)
.html())
.tooltip({
html: true,
sanitize: false
});
});
}
// Update times on the agenda based on the selected timezone
window.update_times = function (newtz) {
$('span.current-tz').html(newtz);
$('span.time').each(function () {
if (this.format == 4) {
var tz = this.start_ts.tz(newtz).format(" z");
if (this.start_ts.tz(newtz).dayOfYear() ==
this.end_ts.tz(newtz).dayOfYear()) {
$(this).html(format_time(this.start_ts, newtz, this.format) +
'-' + format_time(this.end_ts, newtz, 5) + tz);
$('span.current-tz')
.html(newtz);
$('div.time')
.each(function () {
if (this.format == 4) {
var tz = this.start_ts.tz(newtz)
.format(" z");
if (this.start_ts.tz(newtz)
.dayOfYear() ==
this.end_ts.tz(newtz)
.dayOfYear()) {
$(this)
.html(format_time(this.start_ts, newtz, this.format) +
'-' + format_time(this.end_ts, newtz, 5) + tz);
} else {
$(this)
.html(format_time(this.start_ts, newtz, this.format) +
'-' +
format_time(this.end_ts, newtz, this.format) + tz);
}
} else {
$(this).html(format_time(this.start_ts, newtz, this.format) +
'-' +
format_time(this.end_ts, newtz, this.format) + tz);
$(this)
.html(format_time(this.start_ts, newtz, this.format) + '-' +
format_time(this.end_ts, newtz, this.format));
}
} else {
$(this).html(format_time(this.start_ts, newtz, this.format) + '-' +
format_time(this.end_ts, newtz, this.format));
}
});
});
update_tooltips_all();
update_clock();
}
// Highlight ongoing based on the current time
window.highlight_ongoing = function () {
$("div#now").remove("#now");
$('.ongoing').removeClass("ongoing");
var agenda_rows=$('[data-slot-start-ts]')
agenda_rows = agenda_rows.filter(function() {
return moment().isBetween(this.slot_start_ts, this.slot_end_ts);
$("div#now")
.remove("#now");
$('.table-warning')
.removeClass("table-warning");
var agenda_rows = $('[data-slot-start-ts]')
agenda_rows = agenda_rows.filter(function () {
return moment()
.isBetween(this.slot_start_ts, this.slot_end_ts);
});
agenda_rows.addClass("ongoing");
agenda_rows.first().children("th, td").
agenda_rows.addClass("table-warning");
agenda_rows.first()
.children("th, td")
.
prepend($('<div id="now" class="anchor-target"></div>'));
}
// Update tooltips
window.update_tooltips = function () {
var tooltips=$('.timetooltiptext');
tooltips.filter(function() {
return moment().isBetween(this.ustart_ts, this.uend_ts);
}).each(function () {
$(this).html(format_tooltip_table(this.start_ts, this.end_ts));
});
var tooltips = $('.timetooltiptext');
tooltips.filter(function () {
return moment()
.isBetween(this.ustart_ts, this.uend_ts);
})
.each(function () {
$(this)
.html(format_tooltip_table(this.start_ts, this.end_ts));
});
}
// Update all tooltips
window.update_tooltips_all = function () {
var tooltips=$('.timetooltiptext');
var tooltips = $('.timetooltiptext');
tooltips.each(function () {
$(this).html(format_tooltip_table(this.start_ts, this.end_ts));
$(this)
.html(format_tooltip_table(this.start_ts, this.end_ts));
});
}
// Update clock
window.update_clock = function () {
$('#current-time').html(format_time(moment(), get_current_tz_cb(), 0));
$('#current-time')
.html(format_time(moment(), get_current_tz_cb(), 0));
}
$.urlParam = function(name) {
var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
$.urlParam = function (name) {
var results = new RegExp('[\?&]' + name + '=([^&#]*)')
.exec(window.location.href);
if (results == null) {
return null;
} else {
@ -217,10 +267,10 @@ window.init_timers = function () {
var fast_timer = 60000 / (speedup > 600 ? 600 : speedup);
update_clock();
highlight_ongoing();
setInterval(function() { update_clock(); }, fast_timer);
setInterval(function() { highlight_ongoing(); }, fast_timer);
setInterval(function() { update_tooltips(); }, fast_timer);
setInterval(function() { update_tooltips_all(); }, 3600000 / speedup);
setInterval(function () { update_clock(); }, fast_timer);
setInterval(function () { highlight_ongoing(); }, fast_timer);
setInterval(function () { update_tooltips(); }, fast_timer);
setInterval(function () { update_tooltips_all(); }, 3600000 / speedup);
}
// set method used to find current time zone

View file

@ -0,0 +1,184 @@
var verbose = 0;
window.suffixmap = function (nm)
// Given a name like "foo-ab" or "foo-X-and-Y", change it to the "list-of-room-names" format, "foo-a/foo-b".
{
var andsuffix = /^(.*-)([^-]+)-and-(.*)$/;
var andMatch = andsuffix.exec(nm);
if (andMatch && andMatch[0] != '') {
nm = andMatch[1] + andMatch[2] + "-" + andMatch[3];
}
// xyz-a/b/c => xyz-a/xyz-b/xyz-c
var abcsuffix = /^(.*)-([a-h0-9]+)[-\/]([a-h0-9]+)([-\/][a-h0-9]+)?$/;
var suffixMatch = abcsuffix.exec(nm);
if (verbose) alert("nm=" + nm);
if (suffixMatch && suffixMatch[0] != '') {
if (verbose) alert("matched");
nm = suffixMatch[1] + "-" + suffixMatch[2] + "/" +
suffixMatch[1] + "-" + suffixMatch[3];
if (verbose) alert("nm=>" + nm);
if (suffixMatch[4] && suffixMatch[4] != '')
nm += "/" + suffixMatch[1] + "-" + suffixMatch[4];
if (verbose) alert("nm=>" + nm);
}
// xyz-abc => xyz-a/xyz-b/xyz-c
abcsuffix = /^(.*)-([a-h])([a-h]+)([a-h])?$/;
var suffixMatch = abcsuffix.exec(nm);
if (suffixMatch && suffixMatch[0] != '') {
nm = suffixMatch[1] + "-" + suffixMatch[2] + "/" +
suffixMatch[1] + "-" + suffixMatch[3];
if (suffixMatch[4] && suffixMatch[4] != '')
nm += "/" + suffixMatch[1] + "-" + suffixMatch[4];
}
if (verbose) alert("suffixmap returning: " + nm);
return nm;
}
window.roomcoords = function (nm)
// Find the coordinates of a room or list of room names separated by "/".
// Calls the function findroom() to get the coordinates for a specific room.
{
if (!nm) return null;
if (nm.match("/")) {
var nms = nm.split("/");
var nm0 = findroom(nms[0]);
if (!nm0) return null;
for (var i = 1; i < nms.length; i++) {
var nmi = roomcoords(nms[i]);
if (!nmi) return null;
if (nmi[0] < nm0[0]) nm0[0] = nmi[0];
if (nmi[1] < nm0[1]) nm0[1] = nmi[1];
if (nmi[2] > nm0[2]) nm0[2] = nmi[2];
if (nmi[3] > nm0[3]) nm0[3] = nmi[3];
}
return [nm0[0], nm0[1], nm0[2], nm0[3], nm0[4], nm0[5]];
} else {
return findroom(nm);
}
}
window.setarrow = function (nm)
// Place an arrow at the center of a given room name (or list of room names separated by "/").
{
for (var f = 0; f < floorlist.length; f++) {
floor = floorlist[f];
for (var i = 0; i < arrowsuffixlist.length; i++) {
removearrow(arrowsuffixlist[i], floor);
}
}
for (var i = 0; i < arguments.length; i+=2) {
nm = roommap(arguments[i]);
if (verbose) alert("nm=" + nm);
var rooms = nm.split(/[|]/);
for (var j = 0; j < rooms.length; j++) {
var room = rooms[j];
var ret = roomcoords(room);
if (verbose) alert("roomcoords returned: " + ret);
if (!ret) continue;
var left = ret[0], top = ret[1], right = ret[2], bottom = ret[3], floor=ret[4], width=ret[5], offsetleft = -25, offsettop = -25;
if (verbose) alert("left=" + left + ", top=" + top + ", right=" + right + ", bottom=" + bottom + ", floor=" + floor + ", width=" + width);
//alert("left=" + left + ", top=" + top + ", right=" + right + ", bottom=" + bottom);
// calculate arrow position
arrow_left = (left + (right - left) / 2 );
arrow_top = (top + (bottom - top) / 2 );
// scale the coordinates to match image scaling
var img = document.getElementById(floor+"-image");
scale = img.width / width;
arrow_left = arrow_left * scale;
arrow_top = arrow_top * scale;
var arrowdiv = floor+'-arrowdiv'+j;
//if (verbose) alert("arrowdiv: " + arrowdiv);
var adiv = document.getElementById(arrowdiv);
if (adiv) {
adiv.style.left = arrow_left + offsetleft + "px";
adiv.style.top = arrow_top + offsettop + "px";
adiv.style.visibility = "visible";
window.location.hash = floor;
}
}
}
}
window.removearrow = function (which, fl)
{
for (var i = 0; i < arguments.length; i++) {
var which = arguments[i];
var arrowdiv = fl+'-arrowdiv' + (which ? which : "");
var adiv = document.getElementById(arrowdiv);
// if (verbose) alert("looking for '" + arrowdiv + "'");
if (adiv) {
// if (verbose) alert("adiv found");
adiv.style.left = -500;
adiv.style.top = -500;
adiv.style.visibility = "hidden";
}
}
}
window.setarrowlist = function (which, names)
{
for (var i = 1; i < arguments.length; i++) {
setarrow(arguments[i], which);
}
}
window.QueryString = function ()
// Create a QueryString object
{
// get the query string, ignore the ? at the front.
var querystring = location.search.substring(1);
// parse out name/value pairs separated via &
var args = querystring.split('&');
// split out each name = value pair
for (var i = 0; i < args.length; i++) {
var pair = args[i].split('=');
// Fix broken unescaping
var temp = unescape(pair[0]).split('+');
var name_ = temp.join(' ');
var value_ = '';
if (typeof pair[1] == 'string') {
temp = unescape(pair[1]).split('+');
value_ = temp.join(' ');
}
this[name_] = value_;
}
this.get = function(nm, def) {
var value_ = this[nm];
if (value_ == null) return def;
else return value_;
};
}
window.checkParams = function ()
// Check the parameters for one named "room". If found, call setarrow(room).
{
var querystring = new QueryString();
var room = querystring.get("room");
if (room && room != "") setarrow(room);
}
// new functions
window.located = function (loc)
{
if (loc.civic && loc.civic.ROOM) {
// map from "TerminalRoom" to "terminal-room" as necessary.
setarrow(loc.civic.ROOM.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(), "-green");
}
}
// this needs to be called onload
window.automaticarrow = function ()
{
// if (navigator.geolocation) {
// navigator.geolocation.getCurrentPosition(located);
// }
}

View file

@ -54,7 +54,7 @@ window.ietf_timezone; // public interface
}))
}
})
select.on("change", function () {use_timezone(this.value)});
select.on("change", function () { use_timezone(this.value)});
/* When navigating back/forward, the browser may change the select input's
* value after the window load event. It does not fire the change event on
* the input when it does this. The pageshow event occurs after such an update,

View file

@ -362,7 +362,7 @@ payload = jwstoken.payload
</div>
<div class="col-md-1 d-print-none bs-docs-sidebar" id="affix">
<div class="col-md-1 d-print-none" id="affix">
<ul class="nav nav-pills nav-stacked small fixed" data-bs-spy="affix">
<li><a href="#framework">Framework API</a></li>

View file

@ -85,7 +85,7 @@
{% endfor %}
</div>
<div class="col-md-2 d-print-none bs-docs-sidebar" id="affix">
<div class="col-md-2 d-print-none" id="affix">
<ul class="nav nav-pills nav-stacked small" data-bs-spy="affix">
{% for area in areas %}
<li><a href="#{{area.acronym}}">{{ area.name }}</a></li>

View file

@ -55,7 +55,7 @@
{% endfor %}
</div>
<div class="col-md-1 d-print-none bs-docs-sidebar" id="affix">
<div class="col-md-1 d-print-none" id="affix">
<ul class="nav nav-pills nav-stacked small fixed" data-bs-spy="affix">
{% for letter in alphabet_blocks %}
<li><a href="#{{letter.grouper}}">{{letter.grouper}}</a></li>

View file

@ -92,7 +92,7 @@
{% endfor %}
</div>
<div class="col-md-2 d-print-none bs-docs-sidebar" id="navscroller">
<div class="col-md-2 d-print-none" id="navscroller">
<ul class="nav nav-pills nav-stacked small fixed" >
{% for label, groups in sections.items %}
<li>

View file

@ -52,7 +52,7 @@
{% endfor %}
</div>
<div class="col-md-1 d-print-none bs-docs-sidebar" id="affix">
<div class="col-md-1 d-print-none" id="affix">
<ul class="nav nav-pills nav-stacked small fixed" data-bs-spy="affix">
{% for role_name in role_groups %}
<li><a href="#{{role_name.grouper|urlencode}}">{{role_name.grouper}}</a></li>

View file

@ -124,7 +124,7 @@
{% endfor %}
</div>
<div class="col-md-2 d-print-none bs-docs-sidebar" id="affix">
<div class="col-md-2 d-print-none" id="affix">
<ul class="nav nav-pills nav-stacked small" data-bs-spy="affix">
{% for num, section in sections %}
{% if num|sectionlevel <= 1 %}

View file

@ -64,7 +64,7 @@
{% endfor %}
</div>
<div class="col-md-1 d-print-none bs-docs-sidebar" id="affix">
<div class="col-md-1 d-print-none" id="affix">
<ul class="nav nav-pills nav-stacked small fixed" data-bs-spy="affix">
{% for letter in alphabet_blocks %}
<li><a href="#{{letter.grouper}}">{{letter.grouper}}</a></li>

View file

@ -47,7 +47,7 @@
</div>
<div class="col-md-2 d-print-none bs-docs-sidebar" id="affix">
<div class="col-md-2 d-print-none" id="affix">
<ul class="nav nav-pills nav-stacked small" data-bs-spy="affix">
<li><a href="#generic">General IPR disclosures</a></li>
<li><a href="#specific">Specific IPR disclosures</a></li>

View file

@ -32,6 +32,7 @@
</div>
<div class="row">
<div class="col-md-10">
{# cache this part -- it takes 3-6 seconds to generate #}
{% load cache %}
{% cache cache_time ietf_meeting_agenda_utc schedule.meeting.number request.path %}
@ -39,19 +40,20 @@
<div class="col-5">
<h2>Agenda</h2>
</div>
<div class="col float-end">
<div class="col float-end tz-display">
<div class="input-group input-group-sm">
<label class="input-group-text border-secondary">Time zone:</label>
<button class="btn btn-outline-secondary" type="button" id="meeting-timezone" onclick="ietf_timezone.use('{{ timezone }}')">Meeting</button>
<button class="btn btn-outline-secondary" type="button" id="local-timezone" onclick="ietf_timezone.use('local')">Local</button>
<button class="btn btn-outline-secondary" type="button" id="utc-timezone" onclick="ietf_timezone.use('UTC')">UTC</button>
<select id="timezone-select" class="tz-select form-select border-secondary">
<label class="input-group-text border-primary">Time zone:</label>
<input type="radio" name="tzradio" class="btn-check" autocomplete="off" id="meeting-timezone" onclick="ietf_timezone.use('{{ timezone }}')"/>
<label class="btn btn-outline-primary" for="meeting-timezone">Meeting</label>
<input type="radio" name="tzradio" class="btn-check" autocomplete="off" id="local-timezone" onclick="ietf_timezone.use('local')"/>
<label class="btn btn-outline-primary" for="local-timezone">Local</label>
<input type="radio" name="tzradio" class="btn-check" autocomplete="off" id="utc-timezone" onclick="ietf_timezone.use('UTC')"/>
<label class="btn btn-outline-primary" for="utc-timezone">UTC</label>
<select id="timezone-select" class="tz-select form-select border-primary">
{# Avoid blank while loading. JavaScript replaces the option list after init. #}
<option selected>{{ timezone }}</option>
</select>
</div>
</div>
</div>
@ -70,42 +72,50 @@
<p>
{% include "meeting/agenda_filter.html" with filter_categories=filter_categories customize_button_text="Customize the agenda view..." %}
</p>
<h2>Download as .ics</h2>
<p>
{% for fc in filter_categories %}
{% if not forloop.last %} {# skip the last group, it's the office hours/misc #}
{% for p in fc|dictsort:"label" %}
<a class="btn btn-primary btn-sm mb-3" href="{% url "ietf.meeting.views.agenda_ical" num=schedule.meeting.number %}?show={{p.keyword}}">{{p.label}}</a>
<div class="d-inline mb-3">Download agenda as .ics:</div>
<div class="d-inline">
<a id="ical-link" class="visually-hidden btn btn-sm btn-primary agenda-link filterable" href="{% url "ietf.meeting.views.agenda_ical" num=schedule.meeting.number %}">Customized schedule above</a>
</div>
<div class="input-group input-group-sm mb-3 d-inline">
<button class="btn btn-outline-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">By area</button><ul class="dropdown-menu">
{% for fc in filter_categories %}
{% if not forloop.last %} {# skip the last group, it's the office hours/misc #}
{% for p in fc|dictsort:"label" %}
<li><a class="dropdown-item" href="{% url "ietf.meeting.views.agenda_ical" num=schedule.meeting.number %}?show={{p.keyword}}">{{p.label}}</a></li>
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
<a class="btn btn-primary btn-sm mb-3" href="{% url "ietf.meeting.views.agenda_ical" num=schedule.meeting.number %}?show={{ non_area_keywords|join:',' }}">Non-area events</a>
<a id="ical-link" class="hidden btn btn-primary btn-sm mb-3 agenda-link filterable" href="{% url "ietf.meeting.views.agenda_ical" num=schedule.meeting.number %}">Customized schedule</a>
</ul><a class="btn btn-outline-primary" href="{% url "ietf.meeting.views.agenda_ical" num=schedule.meeting.number %}?show={{ non_area_keywords|join:',' }}">Non-area events</a>
</div>
</p>
<h2>
Schedule
{% if schedule.meeting.agenda_warning_note %}
<span class="badge bg-danger">{{ schedule.meeting.agenda_warning_note|removetags:"h1"
|safe }}</span>
{% endif %}
</h2>
<div id="weekview" class="visually-hidden mt-3">
<h2>
Schedule
{% if schedule.meeting.agenda_warning_note %}
<span class="badge bg-danger">{{ schedule.meeting.agenda_warning_note|removetags:"h1"
|safe }}</span>
{% endif %}
</h2>
<iframe class="hidden w-100" scrolling="no" id="weekview"></iframe>
<iframe class="w-100 overflow-hidden"></iframe>
</div>
<h2>Detailed Agenda</h2>
<table class="table table-sm table-striped">
<table class="table table-sm">
{% for item in filtered_assignments %}
{% ifchanged item.timeslot.time|date:"Y-m-d" %}
<tr class="table-warning">
<tr class="table-primary">
<th colspan="5">
{# The anchor here needs to be in a div, not in the th, in order for the anchor-target margin hack to work #}
<div class="anchor-target" id="{{item.timeslot.time|slugify}}"></div>
<h6 class="mt-2">{{ item.timeslot.time|date:"l, F j, Y" }}</h6>
<div class="anchor-target" id="slot-{{item.timeslot.time|slugify}}"></div>
<div class="h6 mt-2">{{ item.timeslot.time|date:"l, F j, Y" }}</div>
</th>
</tr>
{% endifchanged %}
@ -115,14 +125,9 @@
data-slot-start-ts="{{item.start_timestamp}}"
data-slot-end-ts="{{item.end_timestamp}}">
<td class="text-nowrap text-right">
<div class="d-none d-sm-block">
{% include "meeting/timeslot_start_end.html" %}
</div>
{% include "meeting/timeslot_start_end.html" %}
</td>
<td colspan="3">
<div class="d-none d-md-block d-lg-block d-xl-block d-xxl-block">
{% include "meeting/timeslot_start_end.html" %}
</div>
{% location_anchor item.timeslot %}
{{ item.timeslot.get_html_location }}
{% end_location_anchor %}
@ -165,18 +170,13 @@
{% if item|is_regular_agenda_item %}
{% ifchanged %}
<tr class="info session-label-row"
<tr class="table-secondary session-label-row"
data-slot-start-ts="{{item.start_timestamp}}"
data-slot-end-ts="{{item.end_timestamp}}">
<th class="text-nowrap text-right">
<div class="d-none d-sm-block">
{% include "meeting/timeslot_start_end.html" %}
</div>
{% include "meeting/timeslot_start_end.html" %}
</th>
<th colspan="4">
<div class="d-none d-md-block d-lg-block d-xl-block d-xxl-block">
{% include "meeting/timeslot_start_end.html" %}
</div>
{{ item.timeslot.time|date:"l"}}
{{item.timeslot.name|capfirst_allcaps}}
</th>
@ -192,14 +192,9 @@
data-slot-end-ts="{{item.end_timestamp}}">
{% if item.slot_type.slug == 'plenary' %}
<th class="text-nowrap text-right">
<div class="d-none d-sm-block">
{% include "meeting/timeslot_start_end.html" %}
</div>
{% include "meeting/timeslot_start_end.html" %}
</th>
<td colspan="3">
<div class="d-none d-md-block d-lg-block d-xl-block d-xxl-block">
{% include "meeting/timeslot_start_end.html" %}
</div>
{% location_anchor item.timeslot %}
{{item.timeslot.get_html_location}}
{% end_location_anchor %}
@ -279,15 +274,15 @@
</table>
</div>
<div class="col-md-2 d-print-none bs-docs-sidebar" id="affix">
<ul class="nav nav-pills flex-column small" data-bs-spy="affix">
<div class="col-md-2 d-print-none" id="affix">
<ul class="nav nav-pills flex-column small position-fixed" data-bs-spy="scroll">
<li class="nav-item">
<a class="nav-link" href="#now">Now</a>
</li>
{% for item in filtered_assignments %}
{% ifchanged item.timeslot.time|date:"Y-m-d" %}
<li class="nav-item">
<a class="nav-link" href="#{{item.timeslot.time|slugify}}">{{ item.timeslot.time|date:"l, F j, Y" }}</a>
<a class="nav-link" href="#slot-{{item.timeslot.time|slugify}}">{{ item.timeslot.time|date:"l, F j, Y" }}</a>
</li>
{% endifchanged %}
{% endfor %}
@ -347,22 +342,22 @@
function update_ical_links(filter_params) {
var ical_link = $("#ical-link");
ical_link.toggleClass("hidden", !agenda_filter.filtering_is_enabled(filter_params));
ical_link.toggleClass("visually-hidden", !agenda_filter.filtering_is_enabled(filter_params));
}
function update_weekview(filter_params) {
var weekview = $("#weekview");
if (agenda_filter.filtering_is_enabled(filter_params)) {
weekview.removeClass("hidden");
weekview.removeClass("visually-hidden");
} else {
weekview.addClass("hidden");
weekview.addClass("visually-hidden");
}
update_weekview_display();
}
function update_weekview_display() {
var weekview = $("#weekview");
if (!weekview.hasClass('hidden')) {
if (!weekview.hasClass('visually-hidden')) {
var queryparams = window.location.search;
if (queryparams) {
queryparams += '&tz=' + ietf_timezone.get_current_tz().toLowerCase();
@ -370,7 +365,7 @@
queryparams = '?tz=' + ietf_timezone.get_current_tz().toLowerCase();
}
var new_url = 'week-view.html' + queryparams;
var wv_iframe = document.getElementById('weekview');
var wv_iframe = $(weekview).children('iframe');
var wv_window = wv_iframe.contentWindow;
if (wv_iframe.src && wv_window.history && wv_window.history.replaceState) {
wv_window.history.replaceState({}, '', new_url);

View file

@ -103,7 +103,7 @@
<tr class="table-warning">
<th colspan="7">
{# The anchor here needs to be in a div, not in the th, in order for the anchor-target margin hack to work #}
<div class="anchor-target" id="{{ item.timeslot.time|slugify }}"></div>
<div class="anchor-target" id="slot-{{ item.timeslot.time|slugify }}"></div>
{{ item.timeslot.time|date:"l, F j, Y" }}
</th>
</tr>
@ -340,12 +340,12 @@
{% include "meeting/agenda_personalize_buttonlist.html" with meeting=schedule.meeting only %}
</div>
<div class="col-md-2 d-print-none bs-docs-sidebar" id="affix">
<div class="col-md-2 d-print-none" id="affix">
<ul class="nav nav-pills nav-stacked small" data-bs-spy="affix">
<li><a href="#now">Now</a></li>
{% for item in filtered_assignments %}
{% ifchanged item.timeslot.time|date:"Y-m-d" %}
<li><a href="#{{ item.timeslot.time|slugify }}">{{ item.timeslot.time|date:"l, F j, Y" }}</a></li>
<li><a href="#slot-{{ item.timeslot.time|slugify }}">{{ item.timeslot.time|date:"l, F j, Y" }}</a></li>
{% endifchanged %}
{% endfor %}
<li>

View file

@ -254,7 +254,7 @@
{% endwith %}
</div>
<div class="col-md-2 d-print-none bs-docs-sidebar" id="affix">
<div class="col-md-2 d-print-none" id="affix">
<ul class="nav nav-pills nav-stacked small" data-bs-spy="affix">
{% if plenaries %}
<li><a href="#plenaries">Plenaries</a></li>

View file

@ -225,7 +225,7 @@
{% endcache %}
</div>
<div class="col-md-2 d-print-none bs-docs-sidebar" id="affix">
<div class="col-md-2 d-print-none" id="affix">
<ul class="nav nav-pills nav-stacked small" data-bs-spy="affix">
<li><a href="#introduction">Introduction</a></li>
{% if plenaries %}

View file

@ -129,7 +129,7 @@
</table>
{% endfor %}
</div>
<div class="col-md-2 d-print-none bs-docs-sidebar" id="affix">
<div class="col-md-2 d-print-none" id="affix">
<ul class="nav nav-pills nav-stacked small" data-bs-spy="affix">
{% for area in area_sessions %}
<li><a href="#{{area.grouper.acronym}}">{{ area.grouper.acronym|upper }}</a></li>

View file

@ -4,4 +4,4 @@
{% else %}
{{item.timeslot.time|date:"H:i"}}-{{item.timeslot.end_time|date:"H:i"}}
{% endif %}
</div></div>
</div></div>

View file

@ -69,7 +69,7 @@
</div>
<div class="col-md-2 d-print-none bs-docs-sidebar" id="affix">
<div class="col-md-2 d-print-none" id="affix">
<ul class="nav nav-pills nav-stacked small" data-bs-spy="affix">
{% for regime in regimes %}
<li><a href="#{{ regime.group.start_year }}">{{ regime.group.start_year }}/{{ regime.group.end_year }}</a></li>

View file

@ -12,7 +12,7 @@
{% block nomcom_content %}
{% origin %}
<div class="col-sm-2 col-sm-offset-10 d-none d-sm-block d-print-none bs-docs-sidebar" id="nav-instructions">
<div class="col-sm-2 col-sm-offset-10 d-none d-sm-block d-print-none" id="nav-instructions">
<ul class="nav nav-pills nav-stacked small" data-bs-spy="affix">
<li><a href="#keys">Keypair</a></li>
<li><a href="#configure">Configuration</a></li>

View file

@ -775,7 +775,7 @@
</div>
<div class="col-md-2 d-print-none bs-docs-sidebar" id="affix">
<div class="col-md-2 d-print-none" id="affix">
<ul class="nav nav-pills nav-stacked small" data-bs-spy="affix">
{% for regime in regimes %}
<li><a href="#{{ regime.year }}">{{ regime.label }}</a></li>

View file

@ -126,7 +126,7 @@
{% endif %}
</div>
<div class="col-md-2 d-print-none bs-docs-sidebar" id="affix">
<div class="col-md-2 d-print-none" id="affix">
<ul class="nav nav-pills nav-stacked small" data-bs-spy="affix">
<li><a href="#accepted">Accepted</a></li>
<li><a href="#pending">Pending</a></li>

View file

@ -27,6 +27,7 @@
"ietf/static/js/agenda_materials.js",
"ietf/static/js/agenda_timezone.js",
"ietf/static/js/timezone.js",
"ietf/static/js/room_params.js",
"ietf/static/js/moment-timezone-with-data-10-year-range.js",
"ietf/static/css/ietf.scss",
"ietf/static/css/datatables.scss",