And more agenda fixes.
- Legacy-Id: 19678
This commit is contained in:
parent
a114ad9ecc
commit
5772701781
110
ietf/static/js/doc-search.js
Normal file
110
ietf/static/js/doc-search.js
Normal file
|
@ -0,0 +1,110 @@
|
|||
$(document)
|
||||
.ready(function () {
|
||||
// search form
|
||||
var form = $("#search_form");
|
||||
|
||||
function anyAdvancedActive() {
|
||||
var advanced = false;
|
||||
var by = form.find("input[name=by]:checked");
|
||||
|
||||
if (by.length > 0) {
|
||||
by.closest(".search_field")
|
||||
.find("input,select")
|
||||
.not("input[name=by]")
|
||||
.each(function () {
|
||||
if (String.prototype.trim(this.value)) {
|
||||
advanced = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var additional_doctypes = form.find("input.advdoctype:checked");
|
||||
if (additional_doctypes.length > 0) {
|
||||
advanced = true;
|
||||
}
|
||||
return advanced;
|
||||
}
|
||||
|
||||
function toggleSubmit() {
|
||||
var nameSearch = $("#id_name")
|
||||
.val()
|
||||
.trim();
|
||||
form.find("button[type=submit]")
|
||||
.get(0)
|
||||
.disabled = !nameSearch && !anyAdvancedActive();
|
||||
}
|
||||
|
||||
function updateAdvanced() {
|
||||
form.find("input[name=by]:checked")
|
||||
.closest(".search_field")
|
||||
.find("input,select")
|
||||
.not("input[name=by]")
|
||||
.each(function () {
|
||||
this.disabled = false;
|
||||
this.focus();
|
||||
});
|
||||
|
||||
form.find("input[name=by]")
|
||||
.not(":checked")
|
||||
.closest(".search_field")
|
||||
.find("input,select")
|
||||
.not("input[name=by]")
|
||||
.each(function () {
|
||||
this.disabled = true;
|
||||
});
|
||||
|
||||
toggleSubmit();
|
||||
}
|
||||
|
||||
if (form.length > 0) {
|
||||
form.find(".search_field input[name=by]")
|
||||
.closest(".search_field")
|
||||
.find("label,input")
|
||||
.on("click", updateAdvanced);
|
||||
|
||||
form.find(".search_field input,select")
|
||||
.on("change click keyup", toggleSubmit);
|
||||
|
||||
form.find(".toggle_advanced")
|
||||
.on("click", function () {
|
||||
var advanced = $(this)
|
||||
.next();
|
||||
advanced.find('.search_field input[type="radio"]')
|
||||
.attr("checked", false);
|
||||
updateAdvanced();
|
||||
});
|
||||
|
||||
updateAdvanced();
|
||||
}
|
||||
|
||||
$(".review-wish-add-remove-doc.ajax, .track-untrack-doc")
|
||||
.on("click", function (e) {
|
||||
e.preventDefault();
|
||||
var trigger = $(this);
|
||||
$.ajax({
|
||||
url: trigger.attr("href"),
|
||||
type: "POST",
|
||||
cache: false,
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
if (response.success) {
|
||||
trigger.parent()
|
||||
.find(".tooltip")
|
||||
.remove();
|
||||
trigger.attr("hidden", true);
|
||||
|
||||
var target_unhide = null;
|
||||
if (trigger.hasClass("review-wish-add-remove-doc")) {
|
||||
target_unhide = ".review-wish-add-remove-doc";
|
||||
} else if (trigger.hasClass("track-untrack-doc")) {
|
||||
target_unhide = ".track-untrack-doc";
|
||||
}
|
||||
trigger.parent()
|
||||
.find(target_unhide)
|
||||
.not(trigger)
|
||||
.removeAttr("hidden");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
|
@ -14,12 +14,12 @@ import "bootstrap/js/dist/tab";
|
|||
// import "bootstrap/js/dist/toast";
|
||||
import "bootstrap/js/dist/tooltip";
|
||||
|
||||
import jquery from "jquery"
|
||||
import jquery from "jquery";
|
||||
|
||||
window.$ = window.jQuery = jquery;
|
||||
if (!process.env.BUILD_DEPLOY) {
|
||||
// get warnings for using deprecated jquery features
|
||||
require("jquery-migrate")
|
||||
require("jquery-migrate");
|
||||
}
|
||||
|
||||
import Cookies from "js-cookie";
|
||||
|
@ -104,116 +104,4 @@ $(document)
|
|||
$("ul.nav li.dropdown, ul.nav li.dropend")
|
||||
.on("mouseenter mouseleave", dropdown_hover);
|
||||
}
|
||||
});
|
||||
|
||||
// This used to be in doc-search.js; consolidate all JS in one file.
|
||||
$(document)
|
||||
.ready(function () {
|
||||
// search form
|
||||
var form = $("#search_form");
|
||||
|
||||
function anyAdvancedActive() {
|
||||
var advanced = false;
|
||||
var by = form.find("input[name=by]:checked");
|
||||
|
||||
if (by.length > 0) {
|
||||
by.closest(".search_field")
|
||||
.find("input,select")
|
||||
.not("input[name=by]")
|
||||
.each(function () {
|
||||
if (String.prototype.trim(this.value)) {
|
||||
advanced = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var additional_doctypes = form.find("input.advdoctype:checked");
|
||||
if (additional_doctypes.length > 0) {
|
||||
advanced = true;
|
||||
}
|
||||
return advanced;
|
||||
}
|
||||
|
||||
function toggleSubmit() {
|
||||
var nameSearch = $("#id_name")
|
||||
.val()
|
||||
.trim();
|
||||
form.find("button[type=submit]")
|
||||
.get(0)
|
||||
.disabled = !nameSearch && !anyAdvancedActive();
|
||||
}
|
||||
|
||||
function updateAdvanced() {
|
||||
form.find("input[name=by]:checked")
|
||||
.closest(".search_field")
|
||||
.find("input,select")
|
||||
.not("input[name=by]")
|
||||
.each(function () {
|
||||
this.disabled = false;
|
||||
this.focus();
|
||||
});
|
||||
|
||||
form.find("input[name=by]")
|
||||
.not(":checked")
|
||||
.closest(".search_field")
|
||||
.find("input,select")
|
||||
.not("input[name=by]")
|
||||
.each(function () {
|
||||
this.disabled = true;
|
||||
});
|
||||
|
||||
toggleSubmit();
|
||||
}
|
||||
|
||||
if (form.length > 0) {
|
||||
form.find(".search_field input[name=by]")
|
||||
.closest(".search_field")
|
||||
.find("label,input")
|
||||
.on("click", updateAdvanced);
|
||||
|
||||
form.find(".search_field input,select")
|
||||
.on("change click keyup", toggleSubmit);
|
||||
|
||||
form.find(".toggle_advanced")
|
||||
.on("click", function () {
|
||||
var advanced = $(this)
|
||||
.next();
|
||||
advanced.find('.search_field input[type="radio"]')
|
||||
.attr("checked", false);
|
||||
updateAdvanced();
|
||||
});
|
||||
|
||||
updateAdvanced();
|
||||
}
|
||||
|
||||
$(".review-wish-add-remove-doc.ajax, .track-untrack-doc")
|
||||
.on("click", function (e) {
|
||||
e.preventDefault();
|
||||
var trigger = $(this);
|
||||
$.ajax({
|
||||
url: trigger.attr("href"),
|
||||
type: "POST",
|
||||
cache: false,
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
if (response.success) {
|
||||
trigger.parent()
|
||||
.find(".tooltip")
|
||||
.remove();
|
||||
trigger.attr("hidden", true);
|
||||
|
||||
var target_unhide = null;
|
||||
if (trigger.hasClass("review-wish-add-remove-doc")) {
|
||||
target_unhide = ".review-wish-add-remove-doc";
|
||||
} else if (trigger.hasClass("track-untrack-doc")) {
|
||||
target_unhide = ".track-untrack-doc";
|
||||
}
|
||||
trigger.parent()
|
||||
.find(target_unhide)
|
||||
.not(trigger)
|
||||
.removeAttr("hidden");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
600
ietf/static/js/week-view.js
Normal file
600
ietf/static/js/week-view.js
Normal file
|
@ -0,0 +1,600 @@
|
|||
var color = {
|
||||
'app': { fg: "#008", bg: "#eef" },
|
||||
'art': { fg: "#808", bg: "#fef" },
|
||||
'gen': { fg: "#080", bg: "#efe" },
|
||||
'int': { fg: "#088", bg: "#eff" },
|
||||
'ops': { fg: "#800", bg: "#fee" },
|
||||
'rai': { fg: "#808", bg: "#fef" },
|
||||
'rtg': { fg: "#880", bg: "#ffe" },
|
||||
'sec': { fg: "#488", bg: "#dff" },
|
||||
'tsv': { fg: "#484", bg: "#dfd" },
|
||||
'irtf': { fg: "#448", bg: "#ddf" },
|
||||
'break': { fg: "#000", bg: "#fff" },
|
||||
}
|
||||
|
||||
var day = [
|
||||
'Saturday',
|
||||
'Sunday',
|
||||
'Monday',
|
||||
'Tuesday',
|
||||
'Wednesday',
|
||||
'Thursday',
|
||||
'Friday'
|
||||
];
|
||||
|
||||
var padding = 2;
|
||||
var border = 1;
|
||||
|
||||
//===========================================================================
|
||||
function compute_swimlanes(items) {
|
||||
var start_map = items.map(function (el, i) {
|
||||
return { day: parseInt(el.day, 10), start_time: el.start_time, index: i };
|
||||
});
|
||||
|
||||
start_map.sort(function (a, b) {
|
||||
if (a.day != b.day) { return (a.day - b.day); }
|
||||
return (a.start_time - b.start_time);
|
||||
});
|
||||
|
||||
var end_map = items.map(function (el, i) {
|
||||
return { day: parseInt(el.day, 10), end_time: el.end_time, index: i };
|
||||
});
|
||||
|
||||
end_map.sort(function (a, b) {
|
||||
if (a.day != b.day) { return (a.day - b.day); }
|
||||
return (a.end_time - b.end_time);
|
||||
});
|
||||
|
||||
var si = 0; // start index
|
||||
var ei = 0; // end index
|
||||
var overlap = 0;
|
||||
var max_lanes = 0;
|
||||
var next_lane = [];
|
||||
|
||||
var start_overlap = si;
|
||||
while (si < items.length) {
|
||||
var start_day_change = false;
|
||||
while (!start_day_change &&
|
||||
si < items.length &&
|
||||
start_map[si].start_time < end_map[ei].end_time) {
|
||||
overlap++;
|
||||
if (next_lane.length > 0) {
|
||||
items[start_map[si].index].lane = next_lane.shift();
|
||||
} else {
|
||||
items[start_map[si].index].lane = max_lanes;
|
||||
max_lanes++;
|
||||
}
|
||||
start_day_change = (si + 1 == items.length ||
|
||||
start_map[si].day != start_map[si + 1].day);
|
||||
si++;
|
||||
}
|
||||
var end_day_change = false;
|
||||
while (ei < items.length &&
|
||||
!end_day_change &&
|
||||
(start_day_change ||
|
||||
si == items.length ||
|
||||
start_map[si].start_time >= end_map[ei].end_time)) {
|
||||
next_lane.push(items[end_map[ei].index].lane);
|
||||
overlap--;
|
||||
end_day_change = (ei + 1 == items.length ||
|
||||
end_map[ei].day != end_map[ei + 1].day);
|
||||
ei++;
|
||||
}
|
||||
if (overlap == 0) {
|
||||
for (var i = start_overlap; i < si; i++) {
|
||||
items[start_map[i].index].lanes = max_lanes;
|
||||
}
|
||||
max_lanes = 0;
|
||||
next_lane = [];
|
||||
start_overlap = si;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
function is_visible(filter_params) {
|
||||
// Returns a method to filter objects for visibility
|
||||
// Accepts show and hide filters. No longer accepts
|
||||
// '@<state>' to show sessions in a particular state (e.g., @bof).
|
||||
return function (item) {
|
||||
var filter_keywords = item.filter_keywords.split(',');
|
||||
return (!agenda_filter.keyword_match(filter_keywords, filter_params.hide) &&
|
||||
agenda_filter.keyword_match(filter_keywords, filter_params.show));
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
window.draw_calendar = function (items, filter_params) {
|
||||
var width = document.body.clientWidth;
|
||||
var height = document.body.clientHeight;
|
||||
|
||||
var visible_items = items;
|
||||
if (agenda_filter.filtering_is_enabled(filter_params)) {
|
||||
visible_items = visible_items.filter(is_visible(filter_params));
|
||||
}
|
||||
|
||||
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 = items[0].day;
|
||||
day_start = items[0].start_time;
|
||||
}
|
||||
var end_day = start_day;
|
||||
var day_end = 0;
|
||||
|
||||
compute_swimlanes(visible_items);
|
||||
|
||||
/* Find our boundaries */
|
||||
visible_items.forEach(function (item) {
|
||||
day_start = Math.min(day_start, item.start_time);
|
||||
day_end = Math.max(day_end, item.end_time);
|
||||
start_day = Math.min(start_day, item.day)
|
||||
end_day = Math.max(start_day, item.day)
|
||||
});
|
||||
|
||||
var header_height = height * 0.05;
|
||||
|
||||
var num_days = end_day - start_day + 1;
|
||||
var num_minutes = day_end - day_start;
|
||||
var day_width = width / num_days;
|
||||
var minute_height = (height - header_height) / num_minutes;
|
||||
|
||||
while (document.body.firstChild) {
|
||||
document.body.removeChild(document.body.firstChild);
|
||||
}
|
||||
|
||||
var j = start_day;
|
||||
for (var i = 0; i < num_days; i++) {
|
||||
//-----------------------------------------------------------------
|
||||
// Draw weekday name
|
||||
//-----------------------------------------------------------------
|
||||
var e = document.createElement("div");
|
||||
|
||||
e.style.border = "solid";
|
||||
e.style.borderWidth = border;
|
||||
|
||||
e.style.background = "#2647a0";
|
||||
e.style.color = "#fff";
|
||||
e.style.borderColor = "#000 #fff";
|
||||
e.style.borderColor = "#2647a0 #2647a0 #000 #2647a0";
|
||||
|
||||
e.style.display = "block";
|
||||
e.style.overflow = "hidden";
|
||||
e.style.position = "absolute";
|
||||
|
||||
e.style.top = 0;
|
||||
e.style.left = i * day_width;
|
||||
e.style.width = day_width - 2 * (padding + border);
|
||||
e.style.height = header_height;
|
||||
|
||||
e.style.margin = 0;
|
||||
e.style.padding = padding;
|
||||
e.style.fontFamily = "sans-serif";
|
||||
e.style.fontSize = header_height * 0.6;
|
||||
|
||||
e.style.textAlign = "center";
|
||||
|
||||
var div = document.createElement("div");
|
||||
div.appendChild(document.createTextNode(day[((j + 1) % 7 + 7) % 7])); // js % is remainder, not modulus
|
||||
j++;
|
||||
e.appendChild(div);
|
||||
document.body.appendChild(e);
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// Draw weekday column border
|
||||
//-----------------------------------------------------------------
|
||||
e = document.createElement("div");
|
||||
|
||||
e.style.border = "solid";
|
||||
e.style.borderWidth = border;
|
||||
|
||||
e.style.background = "#fff";
|
||||
e.style.color = "#000";
|
||||
e.style.borderColor = "#fff #000";
|
||||
|
||||
e.style.display = "block";
|
||||
e.style.overflow = "hidden";
|
||||
e.style.position = "absolute";
|
||||
|
||||
e.style.top = header_height;
|
||||
e.style.left = i * day_width;
|
||||
e.style.width = day_width - 2 * (padding + border);
|
||||
e.style.height = height -
|
||||
2 * (padding + border) - header_height;
|
||||
|
||||
e.style.margin = 0;
|
||||
e.style.padding = padding;
|
||||
|
||||
document.body.appendChild(e);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// Draw a block for each meeting
|
||||
//-----------------------------------------------------------------
|
||||
visible_items.forEach(function (item) {
|
||||
var sess_width = day_width / item.lanes;
|
||||
var sess_height = ((item.end_time - item.start_time) * minute_height) -
|
||||
2 * (padding + border);
|
||||
var day_left = ((item.day - start_day) * day_width);
|
||||
var sess_left = day_left + sess_width * item.lane;
|
||||
var sess_top = ((item.start_time - day_start) * minute_height) + header_height;
|
||||
|
||||
sess_width = sess_width - 2 * (padding + border);
|
||||
|
||||
var e = document.createElement("div");
|
||||
e.style.border = "solid";
|
||||
e.style.borderWidth = border;
|
||||
|
||||
if (item.area && color[item.area]) {
|
||||
e.style.background = color[item.area].bg;
|
||||
e.style.color = color[item.area].fg;
|
||||
e.style.borderColor = color[item.area].fg;
|
||||
} else {
|
||||
if (item.area) {
|
||||
console.log("No color for " + item.area + ": using default");
|
||||
}
|
||||
e.style.background = "#e0e0e0";
|
||||
e.style.color = "#000000";
|
||||
e.style.borderColor = "#000000";
|
||||
}
|
||||
|
||||
e.style.display = "block";
|
||||
e.style.overflow = "hidden";
|
||||
e.style.position = "absolute";
|
||||
e.style.top = sess_top;
|
||||
e.style.left = sess_left;
|
||||
e.style.width = sess_width;
|
||||
e.style.height = sess_height;
|
||||
e.style.margin = 0;
|
||||
e.style.padding = padding;
|
||||
e.style.fontFamily = "sans-serif";
|
||||
e.style.fontSize = "8pt";
|
||||
e.item = item;
|
||||
|
||||
e.onmouseenter = function () {
|
||||
resize(e, sess_top, day_left,
|
||||
day_width - 2 * (padding + border),
|
||||
sess_height, true)
|
||||
};
|
||||
|
||||
e.onmouseleave = function () { resize(e, sess_top, sess_left, sess_width, sess_height, false) };
|
||||
|
||||
if (item.agenda) {
|
||||
e.onclick = function () { maximize(e) };
|
||||
e.style.cursor = "pointer";
|
||||
}
|
||||
|
||||
var div = document.createElement("div");
|
||||
div.appendChild(document.createTextNode(item.time));
|
||||
div.appendChild(document.createElement("br"));
|
||||
|
||||
var label = item.name;
|
||||
if (label.length === 0) {
|
||||
label = "Free Slot";
|
||||
}
|
||||
if (item.group && color[item.area]) {
|
||||
label = label + " (" + item.group + ")";
|
||||
}
|
||||
|
||||
var bold = document.createElement("span");
|
||||
bold.appendChild(document.createTextNode(label));
|
||||
bold.style.fontWeight = "bold";
|
||||
div.appendChild(bold);
|
||||
|
||||
if (item.room) {
|
||||
div.appendChild(document.createElement("br"));
|
||||
var italics = document.createElement("span");
|
||||
italics.appendChild(document.createTextNode(item.room));
|
||||
italics.style.fontStyle = "oblique";
|
||||
div.appendChild(italics);
|
||||
}
|
||||
|
||||
e.appendChild(div);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Note: if "to_fit" is true and the text won't fit in the dimensions
|
||||
// provided, then the height parameter is ignored, and the item is resized to
|
||||
// be tall enough to contain the entire contents
|
||||
|
||||
var animation_counter = 0;
|
||||
|
||||
function resize(div, top, left, width, height, to_fit) {
|
||||
var from_top = (div.style.top.replace("px", ""));
|
||||
var from_left = (div.style.left.replace("px", ""));
|
||||
var from_width = (div.style.width.replace("px", ""));
|
||||
var from_height = (div.style.height.replace("px", ""));
|
||||
|
||||
// If we're fitting the height to the content, and there is overflow,
|
||||
// calculate the new (larger) height
|
||||
if (to_fit) {
|
||||
div.style.removeProperty("height");
|
||||
div.style.width = width;
|
||||
var clientHeight = div.clientHeight;
|
||||
div.style.height = from_height;
|
||||
div.style.width = from_width;
|
||||
if (clientHeight > height) {
|
||||
height = clientHeight;
|
||||
}
|
||||
}
|
||||
|
||||
var animationId = "animation-" + (animation_counter++);
|
||||
|
||||
// Move the element to the front
|
||||
div.style.zIndex = animation_counter;
|
||||
|
||||
var style = document.createElement('style');
|
||||
style.textContent = "@keyframes " + animationId + " {" +
|
||||
" from {" +
|
||||
" top: " + from_top + ";" +
|
||||
" left: " + from_left + ";" +
|
||||
" width: " + from_width + ";" +
|
||||
" height: " + from_height + ";" +
|
||||
" }" +
|
||||
" to {" +
|
||||
" top: " + top + ";" +
|
||||
" left: " + left + ";" +
|
||||
" width: " + width + ";" +
|
||||
" height: " + height + ";" +
|
||||
" }" +
|
||||
"}";
|
||||
document.head.appendChild(style);
|
||||
|
||||
var callback = function () {
|
||||
div.removeEventListener('animationend', callback);
|
||||
document.head.removeChild(style);
|
||||
|
||||
div.style.top = top;
|
||||
div.style.left = left;
|
||||
div.style.width = width;
|
||||
div.style.height = height;
|
||||
|
||||
if (div.callback) {
|
||||
div.callback();
|
||||
div.callback = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
div.addEventListener('animationend', callback, false);
|
||||
|
||||
div.style.animationName = animationId;
|
||||
div.style.animationDuration = "0.25s";
|
||||
div.style.animationIterationCount = "1";
|
||||
div.style.animationFillMode = "forwards";
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
function finish_maximize(e) {
|
||||
if (!e.item.agenda) {
|
||||
console.log("Element has no agenda: " + JSON.stringify(e.item));
|
||||
return;
|
||||
}
|
||||
|
||||
e.insertBefore(document.createElement("br"), e.firstChild);
|
||||
|
||||
var img = document.createElement("img");
|
||||
img.src = "{% static 'ietf/images/agenda-weekview/close.png' %}";
|
||||
img.style.cssFloat = "right";
|
||||
img.onclick = function () { minimize(e); };
|
||||
img.style.cursor = "pointer";
|
||||
e.insertBefore(img, e.firstChild);
|
||||
|
||||
var h = document.createElement("span");
|
||||
h.appendChild(document.createTextNode(e.item.dayname));
|
||||
h.style.fontWeight = "bold";
|
||||
e.insertBefore(h, e.firstChild);
|
||||
e.style.fontSize = "10pt";
|
||||
|
||||
var tmp = e.style.height;
|
||||
e.style.removeProperty("height");
|
||||
var used_height = e.clientHeight;
|
||||
e.style.height = tmp;
|
||||
|
||||
var frame = document.createElement("iframe");
|
||||
frame.setAttribute("src", e.item.agenda);
|
||||
|
||||
frame.style.position = "absolute";
|
||||
frame.style.left = 8;
|
||||
frame.style.width = e.clientWidth - 16 - 2 * (padding + border);
|
||||
frame.style.top = used_height + 8;
|
||||
frame.style.height = e.clientHeight - used_height - 16 - 2 * (padding + border);
|
||||
|
||||
frame.style.background = "#fff";
|
||||
frame.style.overflow = "auto";
|
||||
frame.id = "agenda";
|
||||
|
||||
frame.style.border = e.style.border;
|
||||
frame.style.borderWidth = border;
|
||||
frame.style.padding = padding;
|
||||
frame.style.borderColor = e.style.borderColor;
|
||||
|
||||
e.appendChild(frame);
|
||||
|
||||
e.keyHandler = function (event) {
|
||||
console.log(event.code);
|
||||
if (event.code === "Escape") {
|
||||
minimize(e);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('keydown', e.keyHandler, false);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
function finish_minimize(e) {
|
||||
e.onmouseenter = e.oldmouseenter;
|
||||
e.onmouseleave = e.oldmouseleave;
|
||||
e.oldmouseenter = undefined;
|
||||
e.oldmouseleave = undefined;
|
||||
e.style.cursor = "pointer";
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
function maximize(e) {
|
||||
if (e.onmouseenter) {
|
||||
e.oldmouseenter = e.onmouseenter;
|
||||
e.oldmouseleave = e.onmouseleave;
|
||||
e.onmouseenter = undefined;
|
||||
e.onmouseleave = undefined;
|
||||
e.style.cursor = "auto";
|
||||
e.callback = function () { finish_maximize(e); }
|
||||
resize(e, 0, 0,
|
||||
document.body.clientWidth - 2 * (padding + border),
|
||||
document.body.clientHeight - 2 * (padding + border), false);
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
function minimize(e) {
|
||||
var agenda = document.getElementById("agenda");
|
||||
if (agenda) {
|
||||
e.removeChild(agenda);
|
||||
}
|
||||
document.removeEventListener('keydown', e.keyHandler, false);
|
||||
e.callback = function () { finish_minimize(e); };
|
||||
e.oldmouseleave();
|
||||
e.removeChild(e.firstChild);
|
||||
e.removeChild(e.firstChild);
|
||||
e.removeChild(e.firstChild);
|
||||
e.style.fontSize = "8pt";
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
function get_first_item(items, type) {
|
||||
var earliest;
|
||||
for (var ii = 0; ii < items.length; ii++) {
|
||||
var this_item = items[ii];
|
||||
if (type && (this_item.type !== type)) {
|
||||
continue;
|
||||
}
|
||||
// Update earliest if we don't have an earliest item yet or this_item is earlier
|
||||
if (!earliest || (items[ii].utc_time < earliest.utc_time)) {
|
||||
earliest = items[ii];
|
||||
}
|
||||
}
|
||||
return earliest;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
window.prepare_items = function (items, timezone_name) {
|
||||
function make_display_item(item) {
|
||||
return {
|
||||
name: item.name,
|
||||
group: item.group,
|
||||
area: item.area,
|
||||
room: item.room,
|
||||
agenda: item.agenda,
|
||||
key: item.key,
|
||||
type: item.type,
|
||||
filter_keywords: item.filter_keywords
|
||||
}
|
||||
};
|
||||
|
||||
/* Ported from Django view, which had the following comment:
|
||||
* Only show assignments from the traditional meeting "week" (Sat-Fri).
|
||||
* We'll determine this using the saturday before the first scheduled regular session. */
|
||||
var first_session = get_first_item(items, 'Regular');
|
||||
if (!first_session) {
|
||||
first_session = get_first_item(items); // any type
|
||||
}
|
||||
var first_session_time = moment(first_session.utc_time)
|
||||
.utc();
|
||||
if (timezone_name) {
|
||||
first_session_time.tz(timezone_name); // mutates the moment
|
||||
}
|
||||
|
||||
// Moment.js day() uses 0 == Sunday, 6 == Saturday
|
||||
days_since_saturday = first_session_time.day() - 6;
|
||||
if (days_since_saturday < 0) {
|
||||
days_since_saturday += 7;
|
||||
}
|
||||
saturday_before = first_session_time.clone()
|
||||
.startOf('day')
|
||||
.subtract(days_since_saturday, 'days');
|
||||
|
||||
var display_items = [];
|
||||
for (var ii = 0; ii < items.length; ii++) {
|
||||
var this_item = items[ii];
|
||||
|
||||
/* It's possible an event overlaps the moment of a daylight savings shift.
|
||||
* Calculate the end_moment in utc() time, which has no DST. Once we switch
|
||||
* to a time zone, end time minus start time may not equal duration. */
|
||||
var start_moment = moment(this_item.utc_time)
|
||||
.utc();
|
||||
var end_moment = start_moment.clone()
|
||||
.add(this_item.duration, 'seconds');
|
||||
if (timezone_name) {
|
||||
start_moment.tz(timezone_name);
|
||||
end_moment.tz(timezone_name);
|
||||
}
|
||||
// Avoid off-by-one day number calculations if a session ends at midnight
|
||||
var just_before_end_moment = end_moment.clone()
|
||||
.subtract(1, 'millisecond');
|
||||
|
||||
var start_day = start_moment.diff(saturday_before, 'days') - 1; // shift so sunday = 0
|
||||
var end_day = just_before_end_moment.diff(saturday_before, 'days') - 1; // shift so sunday = 0
|
||||
|
||||
// Generate display items - create multiple if item ends on different day than starts
|
||||
for (var day = start_day; day <= end_day; day++) {
|
||||
var display_item = make_display_item(this_item);
|
||||
display_item.day = day;
|
||||
if (day === start_day) {
|
||||
// First day of session - compute start time
|
||||
display_item.start_time = start_moment.diff(
|
||||
start_moment.clone()
|
||||
.startOf('day'),
|
||||
'minutes'
|
||||
);
|
||||
} else {
|
||||
// Not first day, start at midnight
|
||||
display_item.start_time = 0;
|
||||
display_item.name += " - continued";
|
||||
}
|
||||
if (day === end_day) {
|
||||
// Last day of session - compute end time
|
||||
display_item.end_time = end_moment.diff(
|
||||
just_before_end_moment.clone()
|
||||
.startOf('day'),
|
||||
'minutes'
|
||||
);
|
||||
} else {
|
||||
/* Not last day, use full day. Calculate this on the fly to account for
|
||||
* daylight savings shifts, when a calendar day is not 24*60 minutes long. */
|
||||
display_item.end_time = just_before_end_moment.clone()
|
||||
.endOf('day')
|
||||
.diff(
|
||||
just_before_end_moment.clone()
|
||||
.startOf('day'),
|
||||
'minutes'
|
||||
);
|
||||
}
|
||||
|
||||
display_item.time = start_moment.format('HHmm') + '-' + end_moment.format('HHmm');
|
||||
display_item.dayname = start_moment.format('dddd, ')
|
||||
.toUpperCase() +
|
||||
start_moment.format('MMMM D, Y');
|
||||
display_items.push(display_item);
|
||||
}
|
||||
}
|
||||
return display_items;
|
||||
}
|
|
@ -147,7 +147,7 @@
|
|||
|
||||
<div class="row mb-3 search_field">
|
||||
<div class="offset-sm-4 col-sm-4 d-grid">
|
||||
<button class="btn btn-primary" type="reset">Clear</button>
|
||||
<button class="btn btn-secondary" type="reset">Clear</button>
|
||||
</div>
|
||||
<div class="col-sm-4 d-grid">
|
||||
<button class="btn btn-primary" type="submit">
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block morecss %}
|
||||
iframe#weekview { height: 25em; }
|
||||
#weekview iframe { height: 25em; }
|
||||
{% endblock %}
|
||||
|
||||
{% block bodyAttrs %}data-bs-spy="scroll" data-bs-target="#affix" data-bs-offset="0" tabindex="0"{% endblock %}
|
||||
|
@ -22,17 +22,15 @@
|
|||
{% block content %}
|
||||
{% origin %}
|
||||
|
||||
<div class="row">
|
||||
{% if "-utc" in request.path %}
|
||||
{% include "meeting/meeting_heading.html" with meeting=schedule.meeting updated=updated selected="agenda-utc" title_extra="(UTC)" %}
|
||||
{% else %}
|
||||
{% include "meeting/meeting_heading.html" with meeting=schedule.meeting updated=updated selected="agenda" title_extra="" %}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-10">
|
||||
|
||||
{% if "-utc" in request.path %}
|
||||
{% include "meeting/meeting_heading.html" with meeting=schedule.meeting updated=updated selected="agenda-utc" title_extra="(UTC)" %}
|
||||
{% else %}
|
||||
{% include "meeting/meeting_heading.html" with meeting=schedule.meeting updated=updated selected="agenda" title_extra="" %}
|
||||
{% endif %}
|
||||
|
||||
{# cache this part -- it takes 3-6 seconds to generate #}
|
||||
{% load cache %}
|
||||
{% cache cache_time ietf_meeting_agenda_utc schedule.meeting.number request.path %}
|
||||
|
@ -43,11 +41,11 @@
|
|||
<div class="col float-end tz-display">
|
||||
<div class="input-group input-group-sm">
|
||||
<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 }}')"/>
|
||||
<input type="radio" name="tzradio" class="btn-check" 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')"/>
|
||||
<input type="radio" name="tzradio" class="btn-check" 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')"/>
|
||||
<input type="radio" name="tzradio" class="btn-check" 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. #}
|
||||
|
@ -102,7 +100,7 @@
|
|||
{% endif %}
|
||||
</h2>
|
||||
|
||||
<iframe class="w-100 overflow-hidden"></iframe>
|
||||
<iframe class="w-100 overflow-hidden border border-dark" scrolling="no"></iframe>
|
||||
</div>
|
||||
|
||||
<h2>Detailed Agenda</h2>
|
||||
|
@ -275,7 +273,7 @@
|
|||
</div>
|
||||
|
||||
<div class="col-md-2 d-print-none" id="affix">
|
||||
<ul class="nav nav-pills flex-column small position-fixed" data-bs-spy="scroll">
|
||||
<ul class="nav nav-pills flex-column small position-fixed">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#now">Now</a>
|
||||
</li>
|
||||
|
@ -288,6 +286,8 @@
|
|||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
{% endcache %}
|
||||
|
@ -372,7 +372,7 @@
|
|||
wv_window.redraw_weekview();
|
||||
} else {
|
||||
// either have not yet loaded the iframe or we do not support history replacement
|
||||
wv_iframe.src = new_url;
|
||||
$(wv_iframe).attr("src", new_url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,50 +31,50 @@
|
|||
{# a tags with the agenda-link filterable classes will be updated with show/hide parameters #}
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "agenda" %}active{% endif %}" href="{% url 'ietf.meeting.views.agenda' num=meeting.number %}"
|
||||
class="agenda-link filterable">
|
||||
<a class="nav-link agenda-link filterable {% if selected == "agenda" %}active{% endif %}" href="{% url 'ietf.meeting.views.agenda' num=meeting.number %}"
|
||||
>
|
||||
Agenda
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "agenda-utc" %}active{% endif %}" href="{% url 'ietf.meeting.views.agenda' num=meeting.number utc='-utc' %}"
|
||||
class="agenda-link filterable">
|
||||
<a class="nav-link agenda-link filterable {% if selected == "agenda-utc" %}active{% endif %}" href="{% url 'ietf.meeting.views.agenda' num=meeting.number utc='-utc' %}"
|
||||
>
|
||||
UTC Agenda
|
||||
</a>
|
||||
</li>
|
||||
{% if user|has_role:"Secretariat,Area Director,IAB" %}
|
||||
{% if schedule != meeting.schedule %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "by-room" %}active{% endif %}"
|
||||
<a class="nav-link agenda-link filterable {% if selected == "by-room" %}active{% endif %}"
|
||||
href="{% url 'ietf.meeting.views.agenda_by_room' num=meeting.number name=schedule.name owner=schedule.owner.email %}">by
|
||||
Room</a></li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "by-type" %}active{% endif %}"
|
||||
<a class="nav-link agenda-link filterable {% if selected == "by-type" %}active{% endif %}"
|
||||
href="{% url 'ietf.meeting.views.agenda_by_type' num=meeting.number name=schedule.name owner=schedule.owner.email %}">by
|
||||
Type</a></li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "room-view" %}active{% endif %}"
|
||||
<a class="nav-link agenda-link filterable {% if selected == "room-view" %}active{% endif %}"
|
||||
href="{% url 'ietf.meeting.views.room_view' num=meeting.number name=schedule.name owner=schedule.owner.email %}">Room
|
||||
grid</a></li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "by-room" %}active{% endif %}" href="{% url 'ietf.meeting.views.agenda_by_room' num=meeting.number %}">by Room</a></li>
|
||||
<a class="nav-link agenda-link filterable {% if selected == "by-room" %}active{% endif %}" href="{% url 'ietf.meeting.views.agenda_by_room' num=meeting.number %}">by Room</a></li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "by-type" %}active{% endif %}" href="{% url 'ietf.meeting.views.agenda_by_type' num=meeting.number %}">by Type</a></li>
|
||||
<a class="nav-link agenda-link filterable {% if selected == "by-type" %}active{% endif %}" href="{% url 'ietf.meeting.views.agenda_by_type' num=meeting.number %}">by Type</a></li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "room-view" %}active{% endif %}" href="{% url 'ietf.meeting.views.room_view' num=meeting.number %}">Room grid</a></li>
|
||||
<a class="nav-link agenda-link filterable {% if selected == "room-view" %}active{% endif %}" href="{% url 'ietf.meeting.views.room_view' num=meeting.number %}">Room grid</a></li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "floor-plan" %}active{% endif %}" href="{% url 'ietf.meeting.views.floor_plan' num=meeting.number %}">Floor plan</a></li>
|
||||
<a class="nav-link agenda-link filterable {% if selected == "floor-plan" %}active{% endif %}" href="{% url 'ietf.meeting.views.floor_plan' num=meeting.number %}">Floor plan</a></li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'ietf.meeting.views.agenda' num=meeting.number ext='.txt' %}">
|
||||
<a class="nav-link"agenda-link filterable href="{% url 'ietf.meeting.views.agenda' num=meeting.number ext='.txt' %}">
|
||||
Plaintext
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if selected == "select-sessions" %}active{% endif %}" href="{% url 'ietf.meeting.views.agenda_personalize' num=meeting.number %}"
|
||||
class="agenda-link filterable">
|
||||
<a class="nav-link agenda-link filterable {% if selected == "select-sessions" %}active{% endif %}" href="{% url 'ietf.meeting.views.agenda_personalize' num=meeting.number %}"
|
||||
>
|
||||
Select Sessions
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -1,601 +1,19 @@
|
|||
{# Copyright The IETF Trust 2015, All Rights Reserved #}
|
||||
{% load origin %}{% origin %}
|
||||
{% load static %}
|
||||
<html> <head>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
|
||||
<script src="{% static 'ietf/js/agenda_filter.js' %}"></script>
|
||||
<script src="{% static 'ietf/js/moment.js' %}"></script>
|
||||
<script src="{% static 'ietf/js/moment-timezone-with-data-10-year-range.js' %}"></script>
|
||||
<script src="{% static 'ietf/js/week-view.js' %}"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
var all_items = {{ items|safe }};
|
||||
|
||||
var color = {
|
||||
'app': { fg: "#008", bg: "#eef"},
|
||||
'art': { fg: "#808", bg: "#fef"},
|
||||
'gen': { fg: "#080", bg: "#efe"},
|
||||
'int': { fg: "#088", bg: "#eff"},
|
||||
'ops': { fg: "#800", bg: "#fee"},
|
||||
'rai': { fg: "#808", bg: "#fef"},
|
||||
'rtg': { fg: "#880", bg: "#ffe"},
|
||||
'sec': { fg: "#488", bg: "#dff"},
|
||||
'tsv': { fg: "#484", bg: "#dfd"},
|
||||
'irtf': { fg: "#448", bg: "#ddf"},
|
||||
'break': { fg: "#000", bg: "#fff"},
|
||||
}
|
||||
|
||||
var day = [
|
||||
'Saturday',
|
||||
'Sunday',
|
||||
'Monday',
|
||||
'Tuesday',
|
||||
'Wednesday',
|
||||
'Thursday',
|
||||
'Friday'
|
||||
];
|
||||
|
||||
var padding = 2;
|
||||
var border = 1;
|
||||
|
||||
//===========================================================================
|
||||
function compute_swimlanes(items) {
|
||||
var start_map = items.map(function(el, i) {
|
||||
return { day: parseInt(el.day,10), start_time: el.start_time, index: i };
|
||||
});
|
||||
|
||||
start_map.sort(function(a,b) {
|
||||
if (a.day != b.day) { return(a.day - b.day); }
|
||||
return (a.start_time - b.start_time);
|
||||
});
|
||||
|
||||
var end_map = items.map(function(el, i) {
|
||||
return { day: parseInt(el.day,10), end_time: el.end_time, index: i };
|
||||
});
|
||||
|
||||
end_map.sort(function(a,b) {
|
||||
if (a.day != b.day) { return(a.day - b.day); }
|
||||
return (a.end_time - b.end_time);
|
||||
});
|
||||
|
||||
var si = 0; // start index
|
||||
var ei = 0; // end index
|
||||
var overlap = 0;
|
||||
var max_lanes = 0;
|
||||
var next_lane = [];
|
||||
|
||||
var start_overlap = si;
|
||||
while (si < items.length) {
|
||||
var start_day_change = false;
|
||||
while ( !start_day_change
|
||||
&& si < items.length
|
||||
&& start_map[si].start_time < end_map[ei].end_time ) {
|
||||
overlap++;
|
||||
if (next_lane.length > 0) {
|
||||
items[start_map[si].index].lane = next_lane.shift();
|
||||
} else {
|
||||
items[start_map[si].index].lane = max_lanes;
|
||||
max_lanes++;
|
||||
}
|
||||
start_day_change = ( si+1 == items.length
|
||||
|| start_map[si].day != start_map[si+1].day );
|
||||
si++;
|
||||
}
|
||||
var end_day_change = false;
|
||||
while ( ei < items.length
|
||||
&& !end_day_change
|
||||
&& ( start_day_change
|
||||
|| si == items.length
|
||||
|| start_map[si].start_time >= end_map[ei].end_time ) ) {
|
||||
next_lane.push(items[end_map[ei].index].lane);
|
||||
overlap--;
|
||||
end_day_change = ( ei+1 == items.length
|
||||
|| end_map[ei].day != end_map[ei+1].day );
|
||||
ei++;
|
||||
}
|
||||
if (overlap == 0)
|
||||
{
|
||||
for (var i=start_overlap; i<si; i++) {
|
||||
items[start_map[i].index].lanes = max_lanes;
|
||||
}
|
||||
max_lanes = 0;
|
||||
next_lane=[];
|
||||
start_overlap = si;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
function is_visible(filter_params) {
|
||||
// Returns a method to filter objects for visibility
|
||||
// Accepts show and hide filters. No longer accepts
|
||||
// '@<state>' to show sessions in a particular state (e.g., @bof).
|
||||
return function (item) {
|
||||
var filter_keywords = item.filter_keywords.split(',');
|
||||
return (!agenda_filter.keyword_match(filter_keywords, filter_params.hide)
|
||||
&& agenda_filter.keyword_match(filter_keywords, filter_params.show));
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
function draw_calendar(items, filter_params) {
|
||||
var width = document.body.clientWidth;
|
||||
var height = document.body.clientHeight;
|
||||
|
||||
var visible_items = items;
|
||||
if (agenda_filter.filtering_is_enabled(filter_params)) {
|
||||
visible_items = visible_items.filter(is_visible(filter_params));
|
||||
}
|
||||
|
||||
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 = items[0].day;
|
||||
day_start = items[0].start_time;
|
||||
}
|
||||
var end_day = start_day;
|
||||
var day_end = 0;
|
||||
|
||||
compute_swimlanes(visible_items);
|
||||
|
||||
/* Find our boundaries */
|
||||
visible_items.forEach(function(item){
|
||||
day_start = Math.min(day_start, item.start_time);
|
||||
day_end = Math.max(day_end, item.end_time);
|
||||
start_day = Math.min(start_day, item.day)
|
||||
end_day = Math.max(start_day, item.day)
|
||||
});
|
||||
|
||||
var header_height = height * 0.05 ;
|
||||
|
||||
var num_days = end_day - start_day + 1;
|
||||
var num_minutes = day_end - day_start;
|
||||
var day_width = width / num_days;
|
||||
var minute_height = (height - header_height)/num_minutes;
|
||||
|
||||
while (document.body.firstChild) {
|
||||
document.body.removeChild(document.body.firstChild);
|
||||
}
|
||||
|
||||
var j = start_day;
|
||||
for (var i = 0; i < num_days; i++) {
|
||||
//-----------------------------------------------------------------
|
||||
// Draw weekday name
|
||||
//-----------------------------------------------------------------
|
||||
var e = document.createElement("div");
|
||||
|
||||
e.style.border="solid";
|
||||
e.style.borderWidth=border;
|
||||
|
||||
e.style.background="#2647a0";
|
||||
e.style.color="#fff";
|
||||
e.style.borderColor="#000 #fff";
|
||||
e.style.borderColor="#2647a0 #2647a0 #000 #2647a0";
|
||||
|
||||
e.style.display="block";
|
||||
e.style.overflow="hidden";
|
||||
e.style.position="absolute";
|
||||
|
||||
e.style.top=0;
|
||||
e.style.left = i*day_width;
|
||||
e.style.width=day_width - 2 * (padding + border);
|
||||
e.style.height=header_height;
|
||||
|
||||
e.style.margin=0;
|
||||
e.style.padding=padding;
|
||||
e.style.fontFamily="sans-serif";
|
||||
e.style.fontSize=header_height * 0.6;
|
||||
|
||||
e.style.textAlign="center";
|
||||
|
||||
var div = document.createElement("div");
|
||||
div.appendChild(document.createTextNode(day[((j+1)%7+7)%7])); // js % is remainder, not modulus
|
||||
j++;
|
||||
e.appendChild(div);
|
||||
document.body.appendChild(e);
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// Draw weekday column border
|
||||
//-----------------------------------------------------------------
|
||||
e = document.createElement("div");
|
||||
|
||||
e.style.border="solid";
|
||||
e.style.borderWidth=border;
|
||||
|
||||
e.style.background="#fff";
|
||||
e.style.color="#000";
|
||||
e.style.borderColor="#fff #000";
|
||||
|
||||
e.style.display="block";
|
||||
e.style.overflow="hidden";
|
||||
e.style.position="absolute";
|
||||
|
||||
e.style.top=header_height;
|
||||
e.style.left=i*day_width;
|
||||
e.style.width=day_width - 2 * (padding + border);
|
||||
e.style.height=height -
|
||||
2 * (padding + border) - header_height;
|
||||
|
||||
e.style.margin=0;
|
||||
e.style.padding=padding;
|
||||
|
||||
document.body.appendChild(e);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// Draw a block for each meeting
|
||||
//-----------------------------------------------------------------
|
||||
visible_items.forEach(function(item) {
|
||||
var sess_width = day_width / item.lanes;
|
||||
var sess_height = ((item.end_time - item.start_time) * minute_height)
|
||||
- 2 * (padding + border);
|
||||
var day_left = ((item.day - start_day) * day_width);
|
||||
var sess_left = day_left + sess_width * item.lane;
|
||||
var sess_top = ((item.start_time - day_start) * minute_height) + header_height;
|
||||
|
||||
sess_width = sess_width - 2 * (padding + border);
|
||||
|
||||
var e = document.createElement("div");
|
||||
e.style.border = "solid";
|
||||
e.style.borderWidth = border;
|
||||
|
||||
if (item.area && color[item.area]) {
|
||||
e.style.background=color[item.area].bg;
|
||||
e.style.color=color[item.area].fg;
|
||||
e.style.borderColor=color[item.area].fg;
|
||||
} else {
|
||||
if (item.area) {
|
||||
console.log("No color for " + item.area + ": using default");
|
||||
}
|
||||
e.style.background="#e0e0e0";
|
||||
e.style.color="#000000";
|
||||
e.style.borderColor="#000000";
|
||||
}
|
||||
|
||||
e.style.display="block";
|
||||
e.style.overflow="hidden";
|
||||
e.style.position="absolute";
|
||||
e.style.top=sess_top;
|
||||
e.style.left=sess_left;
|
||||
e.style.width=sess_width;
|
||||
e.style.height=sess_height;
|
||||
e.style.margin=0;
|
||||
e.style.padding=padding;
|
||||
e.style.fontFamily="sans-serif";
|
||||
e.style.fontSize="8pt";
|
||||
e.item=item;
|
||||
|
||||
e.onmouseenter = function(){resize(e,sess_top,day_left,
|
||||
day_width-2*(padding+border),
|
||||
sess_height, true)};
|
||||
|
||||
e.onmouseleave = function(){resize(e,sess_top,sess_left,sess_width,sess_height,false)};
|
||||
|
||||
if (item.agenda) {
|
||||
e.onclick=function(){maximize(e)};
|
||||
e.style.cursor="pointer";
|
||||
}
|
||||
|
||||
var div = document.createElement("div");
|
||||
div.appendChild(document.createTextNode(item.time));
|
||||
div.appendChild(document.createElement("br"));
|
||||
|
||||
var label = item.name;
|
||||
if (label.length === 0) {
|
||||
label = "Free Slot";
|
||||
}
|
||||
if (item.group && color[item.area]) {
|
||||
label = label + " (" + item.group + ")";
|
||||
}
|
||||
|
||||
var bold = document.createElement("span");
|
||||
bold.appendChild(document.createTextNode(label));
|
||||
bold.style.fontWeight="bold";
|
||||
div.appendChild(bold);
|
||||
|
||||
if (item.room) {
|
||||
div.appendChild(document.createElement("br"));
|
||||
var italics = document.createElement("span");
|
||||
italics.appendChild(document.createTextNode(item.room));
|
||||
italics.style.fontStyle="oblique";
|
||||
div.appendChild(italics);
|
||||
}
|
||||
|
||||
e.appendChild(div);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Note: if "to_fit" is true and the text won't fit in the dimensions
|
||||
// provided, then the height parameter is ignored, and the item is resized to
|
||||
// be tall enough to contain the entire contents
|
||||
|
||||
var animation_counter = 0;
|
||||
function resize(div, top, left, width, height, to_fit) {
|
||||
var from_top = (div.style.top.replace("px",""));
|
||||
var from_left = (div.style.left.replace("px",""));
|
||||
var from_width = (div.style.width.replace("px",""));
|
||||
var from_height = (div.style.height.replace("px",""));
|
||||
|
||||
// If we're fitting the height to the content, and there is overflow,
|
||||
// calculate the new (larger) height
|
||||
if (to_fit) {
|
||||
div.style.removeProperty("height");
|
||||
div.style.width = width;
|
||||
var clientHeight = div.clientHeight;
|
||||
div.style.height = from_height;
|
||||
div.style.width = from_width;
|
||||
if (clientHeight > height) {
|
||||
height = clientHeight;
|
||||
}
|
||||
}
|
||||
|
||||
var animationId = "animation-" + (animation_counter++);
|
||||
|
||||
// Move the element to the front
|
||||
div.style.zIndex = animation_counter;
|
||||
|
||||
var style = document.createElement('style');
|
||||
style.textContent = "@keyframes " + animationId + " {" +
|
||||
" from {" +
|
||||
" top: " + from_top + ";" +
|
||||
" left: " + from_left + ";" +
|
||||
" width: " + from_width + ";" +
|
||||
" height: " + from_height + ";" +
|
||||
" }" +
|
||||
" to {" +
|
||||
" top: " + top + ";" +
|
||||
" left: " + left + ";" +
|
||||
" width: " + width + ";" +
|
||||
" height: " + height + ";" +
|
||||
" }" +
|
||||
"}";
|
||||
document.head.appendChild(style);
|
||||
|
||||
var callback = function() {
|
||||
div.removeEventListener('animationend',callback);
|
||||
document.head.removeChild(style);
|
||||
|
||||
div.style.top = top;
|
||||
div.style.left = left;
|
||||
div.style.width = width;
|
||||
div.style.height = height;
|
||||
|
||||
if (div.callback) {
|
||||
div.callback();
|
||||
div.callback = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
div.addEventListener('animationend', callback, false);
|
||||
|
||||
div.style.animationName = animationId;
|
||||
div.style.animationDuration = "0.25s";
|
||||
div.style.animationIterationCount = "1";
|
||||
div.style.animationFillMode="forwards";
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
function finish_maximize(e) {
|
||||
if (!e.item.agenda) {
|
||||
console.log("Element has no agenda: " + JSON.stringify(e.item));
|
||||
return;
|
||||
}
|
||||
|
||||
e.insertBefore(document.createElement("br"),e.firstChild);
|
||||
|
||||
var img = document.createElement("img");
|
||||
img.src = "{% static 'ietf/images/agenda-weekview/close.png' %}";
|
||||
img.style.cssFloat="right";
|
||||
img.onclick = function() {minimize(e);};
|
||||
img.style.cursor="pointer";
|
||||
e.insertBefore(img,e.firstChild);
|
||||
|
||||
var h = document.createElement("span");
|
||||
h.appendChild(document.createTextNode(e.item.dayname));
|
||||
h.style.fontWeight="bold";
|
||||
e.insertBefore(h,e.firstChild);
|
||||
e.style.fontSize="10pt";
|
||||
|
||||
var tmp = e.style.height;
|
||||
e.style.removeProperty("height");
|
||||
var used_height = e.clientHeight;
|
||||
e.style.height = tmp;
|
||||
|
||||
var frame = document.createElement("iframe");
|
||||
frame.setAttribute("src",e.item.agenda);
|
||||
|
||||
frame.style.position = "absolute";
|
||||
frame.style.left = 8;
|
||||
frame.style.width = e.clientWidth - 16 - 2 * (padding + border);
|
||||
frame.style.top = used_height + 8;
|
||||
frame.style.height = e.clientHeight - used_height - 16 - 2*(padding+border);
|
||||
|
||||
frame.style.background = "#fff";
|
||||
frame.style.overflow="auto";
|
||||
frame.id="agenda";
|
||||
|
||||
frame.style.border = e.style.border;
|
||||
frame.style.borderWidth = border;
|
||||
frame.style.padding = padding;
|
||||
frame.style.borderColor = e.style.borderColor;
|
||||
|
||||
e.appendChild(frame);
|
||||
|
||||
e.keyHandler = function(event) {
|
||||
console.log(event.code);
|
||||
if(event.code === "Escape") {
|
||||
minimize(e);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('keydown', e.keyHandler, false);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
function finish_minimize(e) {
|
||||
e.onmouseenter = e.oldmouseenter;
|
||||
e.onmouseleave = e.oldmouseleave;
|
||||
e.oldmouseenter = undefined;
|
||||
e.oldmouseleave = undefined;
|
||||
e.style.cursor="pointer";
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
function maximize(e) {
|
||||
if (e.onmouseenter)
|
||||
{
|
||||
e.oldmouseenter = e.onmouseenter;
|
||||
e.oldmouseleave = e.onmouseleave;
|
||||
e.onmouseenter = undefined;
|
||||
e.onmouseleave = undefined;
|
||||
e.style.cursor="auto";
|
||||
e.callback = function(){finish_maximize(e);}
|
||||
resize(e,0,0,
|
||||
document.body.clientWidth-2*(padding + border),
|
||||
document.body.clientHeight-2*(padding + border), false);
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
function minimize(e) {
|
||||
var agenda = document.getElementById("agenda");
|
||||
if (agenda) {
|
||||
e.removeChild(agenda);
|
||||
}
|
||||
document.removeEventListener('keydown', e.keyHandler, false);
|
||||
e.callback = function(){finish_minimize(e);};
|
||||
e.oldmouseleave();
|
||||
e.removeChild(e.firstChild);
|
||||
e.removeChild(e.firstChild);
|
||||
e.removeChild(e.firstChild);
|
||||
e.style.fontSize="8pt";
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
function get_first_item(items, type) {
|
||||
var earliest;
|
||||
for (var ii=0; ii < items.length; ii++) {
|
||||
var this_item = items[ii];
|
||||
if (type && (this_item.type !== type)) {
|
||||
continue;
|
||||
}
|
||||
// Update earliest if we don't have an earliest item yet or this_item is earlier
|
||||
if (!earliest || (items[ii].utc_time < earliest.utc_time)) {
|
||||
earliest = items[ii];
|
||||
}
|
||||
}
|
||||
return earliest;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
function prepare_items(items, timezone_name) {
|
||||
function make_display_item(item) {
|
||||
return {
|
||||
name: item.name,
|
||||
group: item.group,
|
||||
area: item.area,
|
||||
room: item.room,
|
||||
agenda: item.agenda,
|
||||
key: item.key,
|
||||
type: item.type,
|
||||
filter_keywords: item.filter_keywords
|
||||
}
|
||||
};
|
||||
|
||||
/* Ported from Django view, which had the following comment:
|
||||
* Only show assignments from the traditional meeting "week" (Sat-Fri).
|
||||
* We'll determine this using the saturday before the first scheduled regular session. */
|
||||
var first_session = get_first_item(items, 'Regular');
|
||||
if (!first_session) {
|
||||
first_session = get_first_item(items); // any type
|
||||
}
|
||||
var first_session_time = moment(first_session.utc_time).utc();
|
||||
if (timezone_name) {
|
||||
first_session_time.tz(timezone_name); // mutates the moment
|
||||
}
|
||||
|
||||
// Moment.js day() uses 0 == Sunday, 6 == Saturday
|
||||
days_since_saturday = first_session_time.day() - 6;
|
||||
if (days_since_saturday < 0) {
|
||||
days_since_saturday += 7;
|
||||
}
|
||||
saturday_before = first_session_time.clone().startOf('day').subtract(days_since_saturday, 'days');
|
||||
|
||||
var display_items = [];
|
||||
for (var ii = 0; ii < items.length; ii++) {
|
||||
var this_item = items[ii];
|
||||
|
||||
/* It's possible an event overlaps the moment of a daylight savings shift.
|
||||
* Calculate the end_moment in utc() time, which has no DST. Once we switch
|
||||
* to a time zone, end time minus start time may not equal duration. */
|
||||
var start_moment = moment(this_item.utc_time).utc();
|
||||
var end_moment = start_moment.clone().add(this_item.duration, 'seconds');
|
||||
if (timezone_name) {
|
||||
start_moment.tz(timezone_name);
|
||||
end_moment.tz(timezone_name);
|
||||
}
|
||||
// Avoid off-by-one day number calculations if a session ends at midnight
|
||||
var just_before_end_moment = end_moment.clone().subtract(1, 'millisecond');
|
||||
|
||||
var start_day = start_moment.diff(saturday_before, 'days') - 1; // shift so sunday = 0
|
||||
var end_day = just_before_end_moment.diff(saturday_before, 'days') - 1; // shift so sunday = 0
|
||||
|
||||
// Generate display items - create multiple if item ends on different day than starts
|
||||
for (var day = start_day; day <= end_day; day++) {
|
||||
var display_item = make_display_item(this_item);
|
||||
display_item.day = day;
|
||||
if (day === start_day) {
|
||||
// First day of session - compute start time
|
||||
display_item.start_time = start_moment.diff(
|
||||
start_moment.clone().startOf('day'),
|
||||
'minutes'
|
||||
);
|
||||
} else {
|
||||
// Not first day, start at midnight
|
||||
display_item.start_time = 0;
|
||||
display_item.name += " - continued";
|
||||
}
|
||||
if (day === end_day) {
|
||||
// Last day of session - compute end time
|
||||
display_item.end_time = end_moment.diff(
|
||||
just_before_end_moment.clone().startOf('day'),
|
||||
'minutes'
|
||||
);
|
||||
} else {
|
||||
/* Not last day, use full day. Calculate this on the fly to account for
|
||||
* daylight savings shifts, when a calendar day is not 24*60 minutes long. */
|
||||
display_item.end_time = just_before_end_moment.clone().endOf('day').diff(
|
||||
just_before_end_moment.clone().startOf('day'),
|
||||
'minutes'
|
||||
);
|
||||
}
|
||||
|
||||
display_item.time = start_moment.format('HHmm') + '-' + end_moment.format('HHmm');
|
||||
display_item.dayname = start_moment.format('dddd, ').toUpperCase() +
|
||||
start_moment.format('MMMM D, Y');
|
||||
display_items.push(display_item);
|
||||
}
|
||||
}
|
||||
return display_items;
|
||||
}
|
||||
var all_items = {{ items | safe }};
|
||||
|
||||
//===========================================================================
|
||||
// Set up events for drawing the calendar
|
||||
|
@ -613,6 +31,8 @@
|
|||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="cal"><span>Error loading calendar</span></div>
|
||||
</body></html>
|
||||
|
||||
<body>
|
||||
<p>Error loading calendar</p>
|
||||
</body>
|
||||
</html>
|
|
@ -28,6 +28,8 @@
|
|||
"ietf/static/js/agenda_timezone.js",
|
||||
"ietf/static/js/timezone.js",
|
||||
"ietf/static/js/room_params.js",
|
||||
"ietf/static/js/week-view.js",
|
||||
"ietf/static/js/doc-search.js",
|
||||
"ietf/static/js/moment-timezone-with-data-10-year-range.js",
|
||||
"ietf/static/css/ietf.scss",
|
||||
"ietf/static/css/datatables.scss",
|
||||
|
|
Loading…
Reference in a new issue