2016-02-12 23:52:43 +08:00
|
|
|
/**
|
|
|
|
* The functions here are global because they need to be
|
|
|
|
* accesed from outside (in reports view).
|
|
|
|
*/
|
|
|
|
|
|
|
|
var STORAGE_TREE_KEY = "scinote-sidebar-tree-collapsed-ids";
|
|
|
|
var STORAGE_TOGGLE_KEY = "scinote-sidebar-toggled";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get all collapsed sidebar elements.
|
|
|
|
* @return An array of sidebar element IDs.
|
|
|
|
*/
|
|
|
|
function sessionGetCollapsedSidebarElements() {
|
|
|
|
var val = sessionStorage.getItem(STORAGE_TREE_KEY);
|
|
|
|
if (val === null) {
|
|
|
|
val = "[]";
|
|
|
|
sessionStorage.setItem(STORAGE_TREE_KEY, val);
|
|
|
|
}
|
2016-09-01 16:38:20 +08:00
|
|
|
return JSON.parse(val);
|
2016-02-12 23:52:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Collapse a specified element in the sidebar.
|
|
|
|
* @param id - The collapsed element's ID.
|
|
|
|
*/
|
2016-08-31 21:13:17 +08:00
|
|
|
function sessionCollapseSidebarElement(project, id) {
|
2016-02-12 23:52:43 +08:00
|
|
|
var ids = sessionGetCollapsedSidebarElements();
|
2016-09-01 16:38:20 +08:00
|
|
|
var item = _.findWhere(ids, { prid: project });
|
|
|
|
var collapsed = { prid: project, ids: [] };
|
|
|
|
var stored_projects = _.pluck(ids, 'prid');
|
2016-08-31 22:34:08 +08:00
|
|
|
|
2016-09-01 16:38:20 +08:00
|
|
|
if ( _.contains(stored_projects, project ) ){
|
|
|
|
if ( item && _.indexOf(item.ids, id) === -1 ) {
|
|
|
|
_.findWhere(ids, { prid: project }).ids.push(id);
|
2016-08-31 21:13:17 +08:00
|
|
|
}
|
2016-08-31 22:34:08 +08:00
|
|
|
} else {
|
|
|
|
collapsed.ids.push(id);
|
|
|
|
ids.push(collapsed);
|
2016-02-12 23:52:43 +08:00
|
|
|
}
|
2016-08-31 22:34:08 +08:00
|
|
|
sessionStorage.setItem(STORAGE_TREE_KEY, JSON.stringify(ids));
|
2016-02-12 23:52:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Expand a specified element in the sidebar.
|
|
|
|
* @param id - The expanded element's ID.
|
|
|
|
*/
|
2016-09-13 19:09:57 +08:00
|
|
|
function sessionExpandSidebarElement(project, id, elements) {
|
2016-02-12 23:52:43 +08:00
|
|
|
var ids = sessionGetCollapsedSidebarElements();
|
2016-09-01 16:38:20 +08:00
|
|
|
var item = _.findWhere(ids, { prid: project});
|
2016-08-31 22:34:08 +08:00
|
|
|
var index = -1;
|
2016-09-13 19:09:57 +08:00
|
|
|
|
2016-08-31 22:34:08 +08:00
|
|
|
if ( item ) {
|
2016-09-13 19:09:57 +08:00
|
|
|
index = _.indexOf(item.ids, id);
|
|
|
|
recalculateElementsPositions(ids, item, elements);
|
2016-08-31 22:34:08 +08:00
|
|
|
}
|
2016-08-31 21:13:17 +08:00
|
|
|
|
2016-09-01 16:38:20 +08:00
|
|
|
if ( index !== -1 ) {
|
2016-08-31 22:34:08 +08:00
|
|
|
item.ids.splice(index, 1);
|
|
|
|
sessionStorage.setItem(STORAGE_TREE_KEY, JSON.stringify(ids));
|
2016-02-12 23:52:43 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-13 19:09:57 +08:00
|
|
|
/**
|
|
|
|
* Recalculate the position of the elements after an experiment
|
|
|
|
* is added or archived.
|
|
|
|
*/
|
|
|
|
function recalculateElementsPositions(ids, item, elements) {
|
|
|
|
var diff;
|
|
|
|
|
|
|
|
if ( item.eleNum > elements ){
|
|
|
|
diff = item.eleNum - elements;
|
|
|
|
_.map(item.ids, function(element, index){
|
|
|
|
item.ids[index] = element - diff;
|
|
|
|
});
|
|
|
|
} else if ( item.eleNum < elements ) {
|
|
|
|
diff = elements - item.eleNum ;
|
|
|
|
_.map(item.ids, function(element, index){
|
|
|
|
item.ids[index] = element + diff;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( item.eleNum !== elements) {
|
|
|
|
item.eleNum = elements;
|
|
|
|
sessionStorage.setItem(STORAGE_TREE_KEY, JSON.stringify(ids));
|
|
|
|
}
|
|
|
|
}
|
2016-02-12 23:52:43 +08:00
|
|
|
/**
|
|
|
|
* Get the session stored toggled boolean or null value if
|
|
|
|
* sidebar toggle state was not changed by user. It allow for
|
|
|
|
* automatic toggling for small devices.
|
|
|
|
*
|
|
|
|
* @return True if sidebar is toggled; false otherwise.
|
|
|
|
*/
|
|
|
|
function sessionIsSidebarToggled() {
|
|
|
|
var val = sessionStorage.getItem(STORAGE_TOGGLE_KEY);
|
|
|
|
|
|
|
|
if (val === null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return val === "toggled";
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Store the sidebar toggled boolean to session storage.
|
|
|
|
*/
|
|
|
|
function sessionToggleSidebar() {
|
|
|
|
if (sessionIsSidebarToggled()) {
|
|
|
|
sessionStorage.setItem(STORAGE_TOGGLE_KEY, "not_toggled");
|
|
|
|
} else {
|
|
|
|
sessionStorage.setItem(STORAGE_TOGGLE_KEY, "toggled");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Setup the sidebar collapsing & expanding functionality.
|
|
|
|
*/
|
|
|
|
function setupSidebarTree() {
|
|
|
|
function toggleLi(el, collapse, animate) {
|
|
|
|
var children = el
|
|
|
|
.find(" > ul > li");
|
|
|
|
|
|
|
|
if (collapse) {
|
|
|
|
if (animate) {
|
|
|
|
children.hide("fast");
|
|
|
|
} else {
|
|
|
|
children.hide();
|
|
|
|
}
|
|
|
|
el
|
|
|
|
.find(" > span i")
|
|
|
|
.attr("title", "Expand this branch")
|
|
|
|
.removeClass("expanded");
|
|
|
|
} else {
|
|
|
|
if (animate) {
|
|
|
|
children.show("fast");
|
|
|
|
} else {
|
|
|
|
children.show();
|
|
|
|
}
|
|
|
|
el
|
|
|
|
.find(" > span i")
|
|
|
|
.attr("title", "Collapse this branch")
|
|
|
|
.addClass("expanded");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add triangle icons and titles to every parent node
|
|
|
|
$(".tree li:has(ul)")
|
|
|
|
.addClass("parent_li")
|
|
|
|
.find(" > span i")
|
|
|
|
.attr("title", "Collapse this branch");
|
|
|
|
$(".tree li.parent_li ")
|
|
|
|
.find("> span i")
|
|
|
|
.addClass("glyphicon glyphicon-triangle-right expanded");
|
|
|
|
|
|
|
|
// Add IDs to all parent <lis>
|
2016-09-01 16:38:20 +08:00
|
|
|
var i = 0;
|
2016-08-31 16:25:40 +08:00
|
|
|
_.each($('[data-parent="candidate"]'), function(el) {
|
2016-02-12 23:52:43 +08:00
|
|
|
$(el).attr("data-toggle-id", i++);
|
|
|
|
});
|
|
|
|
|
2016-09-13 19:09:57 +08:00
|
|
|
// Get the current project
|
2016-09-01 16:38:20 +08:00
|
|
|
var project = $('[data-project-id]').data('projectId');
|
2016-09-13 19:09:57 +08:00
|
|
|
|
|
|
|
// Set number of elements
|
|
|
|
sessionExpandSidebarElement(project,
|
|
|
|
null,
|
|
|
|
$('[data-parent="candidate"]').length );
|
|
|
|
|
|
|
|
// Get the session-stored elements
|
2016-02-12 23:52:43 +08:00
|
|
|
var collapsedIds = sessionGetCollapsedSidebarElements();
|
2016-09-01 16:38:20 +08:00
|
|
|
|
|
|
|
// Get the current project stered elements
|
|
|
|
var currentProjectIds = _.findWhere(collapsedIds, { prid: project });
|
|
|
|
if ( currentProjectIds ){
|
|
|
|
currentProjectIds.ids = _.filter(currentProjectIds.ids,
|
|
|
|
function(val) {
|
|
|
|
return val !== null;
|
|
|
|
}).join(", ");
|
|
|
|
|
|
|
|
// Collapse session-stored elements
|
|
|
|
_.each($('li.parent_li[data-parent="candidate"]'), function(el) {
|
|
|
|
var id = $(el).data("toggle-id");
|
|
|
|
var li = $(".tree li.parent_li[data-toggle-id='" + id + "']");
|
2016-09-13 19:09:57 +08:00
|
|
|
|
2016-09-01 16:38:20 +08:00
|
|
|
if( li.hasClass("active") || li.find(".active").length > 0){
|
|
|
|
// Always expand the active element
|
|
|
|
toggleLi(li,
|
|
|
|
false,
|
|
|
|
false);
|
2016-09-13 19:09:57 +08:00
|
|
|
} else if ( $.inArray( id.toString(),
|
|
|
|
currentProjectIds.ids.split(", ")) !== -1 ) {
|
2016-09-01 16:38:20 +08:00
|
|
|
// Expande element
|
|
|
|
toggleLi(li,
|
|
|
|
false,
|
|
|
|
false);
|
|
|
|
} else {
|
|
|
|
// Collapse the session-stored element
|
|
|
|
toggleLi(li,
|
|
|
|
true,
|
|
|
|
false);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
// Collapse all
|
|
|
|
_.each($('li.parent_li[data-parent="candidate"]'), function(el) {
|
|
|
|
var id = $(el).data("toggle-id");
|
|
|
|
var li = $(".tree li.parent_li[data-toggle-id='" + id + "']");
|
|
|
|
|
|
|
|
if( li.hasClass("active") ){
|
|
|
|
// Always expand the active element
|
|
|
|
toggleLi(li,
|
|
|
|
false,
|
|
|
|
false);
|
2016-08-31 21:13:17 +08:00
|
|
|
sessionCollapseSidebarElement(project, id);
|
2016-09-01 16:38:20 +08:00
|
|
|
} else {
|
|
|
|
// Element collapsed by default
|
|
|
|
toggleLi(li,
|
|
|
|
true,
|
|
|
|
false);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2016-02-12 23:52:43 +08:00
|
|
|
|
|
|
|
// Add onclick callback to every triangle icon
|
|
|
|
$(".tree li.parent_li ")
|
|
|
|
.find("> span i")
|
|
|
|
.on("click", function (e) {
|
|
|
|
var el = $(this)
|
|
|
|
.parent("span")
|
|
|
|
.parent("li.parent_li");
|
|
|
|
|
|
|
|
if (el.find(" > ul > li").is(":visible")) {
|
|
|
|
toggleLi(el, true, true);
|
2016-09-13 19:09:57 +08:00
|
|
|
sessionExpandSidebarElement(project,
|
|
|
|
el.data("toggle-id"),
|
|
|
|
$('[data-parent="candidate"]').length );
|
2016-02-12 23:52:43 +08:00
|
|
|
} else {
|
|
|
|
toggleLi(el, false, true);
|
2016-09-01 16:38:20 +08:00
|
|
|
sessionCollapseSidebarElement(project, el.data("toggle-id"));
|
2016-02-12 23:52:43 +08:00
|
|
|
}
|
|
|
|
e.stopPropagation();
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize the show/hide toggling of sidebar.
|
|
|
|
*/
|
|
|
|
function initializeSidebarToggle() {
|
|
|
|
var wrapper = $("#wrapper");
|
|
|
|
var toggled = sessionIsSidebarToggled();
|
|
|
|
|
2016-10-13 16:00:36 +08:00
|
|
|
if (toggled || toggled === null && $(window).width() <
|
|
|
|
<%= Constants::SCREEN_WIDTH_LARGE %>) {
|
2016-02-12 23:52:43 +08:00
|
|
|
wrapper.addClass("no-animation");
|
|
|
|
wrapper.addClass("toggled");
|
|
|
|
// Cause reflow of the wrapper element
|
|
|
|
wrapper[0].offsetHeight;
|
|
|
|
wrapper.removeClass("no-animation");
|
|
|
|
$(".navbar-secondary").addClass("navbar-without-sidebar");
|
|
|
|
}
|
|
|
|
|
|
|
|
$("#toggle-sidebar-link").on("click", function() {
|
|
|
|
$("#wrapper").toggleClass("toggled");
|
|
|
|
sessionToggleSidebar();
|
|
|
|
$(".navbar-secondary").toggleClass("navbar-without-sidebar", sessionIsSidebarToggled());
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// Resize the sidebar to accomodate to the page size
|
|
|
|
function resizeSidebarContents() {
|
|
|
|
var wrapper = $("#wrapper");
|
|
|
|
var tree = $("#sidebar-wrapper .tree");
|
|
|
|
var toggled = sessionIsSidebarToggled();
|
2016-09-08 15:17:58 +08:00
|
|
|
var navbar = $(".navbar-secondary");
|
2016-02-12 23:52:43 +08:00
|
|
|
|
|
|
|
if (tree.length && tree.length == 1) {
|
|
|
|
tree.css(
|
|
|
|
"height",
|
|
|
|
($(window).height() - tree.position().top - 50) + "px"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
// Automatic toggling of sidebar for smaller devices
|
|
|
|
if (toggled === null) {
|
2016-10-13 16:00:36 +08:00
|
|
|
if ($(window).width() < <%= Constants::SCREEN_WIDTH_LARGE %>) {
|
2016-02-12 23:52:43 +08:00
|
|
|
wrapper.addClass("toggled");
|
2016-09-08 15:17:58 +08:00
|
|
|
navbar.addClass("navbar-without-sidebar");
|
2016-02-12 23:52:43 +08:00
|
|
|
} else {
|
|
|
|
wrapper.removeClass("toggled");
|
2016-09-08 15:17:58 +08:00
|
|
|
navbar.removeClass("navbar-without-sidebar");
|
2016-02-12 23:52:43 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
(function () {
|
|
|
|
// Initialize click listeners
|
|
|
|
setupSidebarTree();
|
|
|
|
initializeSidebarToggle();
|
|
|
|
|
|
|
|
// Actually display wrapper, which is, up to now,
|
|
|
|
// hidden
|
|
|
|
$("#wrapper").show();
|
|
|
|
|
|
|
|
// Resize the sidebar automatically
|
|
|
|
resizeSidebarContents();
|
|
|
|
|
|
|
|
// Bind onto window resize function
|
|
|
|
$(window).resize(function() {
|
|
|
|
resizeSidebarContents();
|
|
|
|
});
|
|
|
|
}());
|