Update all sidebars

This commit is contained in:
aignatov-bio 2020-02-28 14:03:08 +01:00
parent 9e15d1ea42
commit 8b273acaca
13 changed files with 152 additions and 500 deletions

View file

@ -46,6 +46,7 @@
//= require_tree ./repositories/renderers
//= require_directory ./repositories/validators
//= require_directory ./sitewide
//= require sidebar
//= require turbolinks

View file

@ -453,8 +453,8 @@
type: 'GET',
dataType: 'json',
success: function(data) {
$('#slide-panel .tree').html('<ul>' + data.html + '</ul>');
setupSidebarTree();
$('#slide-panel .tree').html(data.html);
Sidebar.loadLastState();
}
});
}

View file

@ -3,325 +3,62 @@
* accesed from outside (in reports view).
*/
/* global I18n _ */
(function() {
const SIDEBAR_ID = '#slide-panel';
const STORAGE_TREE_KEY = 'scinote-sidebar-tree-collapsed-ids';
/**
* 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);
}
return JSON.parse(val);
}
/**
* Collapse a specified element in the sidebar.
* @param id - The collapsed element's ID.
*/
function sessionCollapseSidebarElement(project, id) {
var ids = sessionGetCollapsedSidebarElements();
var item = _.findWhere(ids, { prid: project });
var collapsed = { prid: project, ids: [] };
var storedProjects = _.pluck(ids, 'prid');
if (_.contains(storedProjects, project)) {
if (item && _.indexOf(item.ids, id) === -1) {
_.findWhere(ids, { prid: project }).ids.push(id);
}
} else {
collapsed.ids.push(id);
ids.push(collapsed);
}
sessionStorage.setItem(STORAGE_TREE_KEY, JSON.stringify(ids));
}
/**
* Recalculate the position of the elements after an experiment
* is added or archived.
*/
function recalculateElementsPositions(ids, item, elements) {
let 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));
}
}
/**
* Expand a specified element in the sidebar.
* @param id - The expanded element's ID.
*/
function sessionExpandSidebarElement(project, id, elements) {
var ids = sessionGetCollapsedSidebarElements();
var item = _.findWhere(ids, { prid: project });
var index = -1;
if (item) {
index = _.indexOf(item.ids, id);
recalculateElementsPositions(ids, item, elements);
}
if (index !== -1) {
item.ids.splice(index, 1);
sessionStorage.setItem(STORAGE_TREE_KEY, JSON.stringify(ids));
}
}
/**
* Setup the sidebar collapsing & expanding functionality.
*/
function setupSidebarTree() {
$('.tree a').click(function() {
var url = new URL($(this).attr('href'));
url.searchParams.set('scroll', $('.tree').scrollTop());
$(this).attr('href', url.toString());
});
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', I18n.t('sidebar.branch_expand'))
.removeClass('expanded');
} else {
if (animate) {
children.show('fast');
} else {
children.show();
}
el.find(' > span i')
.attr('title', I18n.t('sidebar.branch_collapse'))
.addClass('expanded');
}
}
// Make active current project/experiment/task
function activateCurrent() {
var sidebar = $(SIDEBAR_ID);
var projectId = sidebar.data('current-project');
var experimentId = sidebar.data('current-experiment');
var taskId = sidebar.data('current-task');
var currentPage = sidebar.data('page');
var link;
if (currentPage === 'project') {
link = sidebar.find(`a[data-type="project"][data-id="${projectId}"]`);
} else if (currentPage === 'experiment') {
link = sidebar.find(`a[data-type="experiment"][data-id="${experimentId}"]`);
} else if (currentPage === 'canvas') {
link = sidebar.find(`a[data-type="experiment"][data-id="${experimentId}"]`);
let treeLink = link.closest('li').find('.task-tree-link');
treeLink.find('.canvas-center-on').remove();
treeLink.append('<a href="" class="canvas-center-on"><span class="fas fa-map-marker-alt"></span></a>');
} else if (currentPage === 'task') {
link = sidebar.find(`a[data-type="my_module"][data-id="${taskId}"]`);
}
link.addClass('disabled');
link.closest('li').addClass('active');
}
activateCurrent();
// Add triangle icons and titles to every parent node
$('.tree li:has(ul)')
.addClass('parent_li')
.find(' > span i')
.attr('title', I18n.t('sidebar.branch_collapse'));
$('.tree li.parent_li ')
.find('> span i')
.removeClass('no-arrow')
.addClass('fas fa-caret-right expanded');
// Add IDs to all parent <lis>
let i = 0;
_.each($('[data-parent="candidate"]'), function(el) {
$(el).attr('data-toggle-id', i += 1);
});
// Get the current project
let project = $('[data-current-project]').data('currentProject');
// Set number of elements
sessionExpandSidebarElement(
project, null, $('[data-parent="candidate"]').length
);
// Get the session-stored elements
let collapsedIds = sessionGetCollapsedSidebarElements();
// Get the current project stored elements
let 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 + "']");
if (li.hasClass('active') || li.find('.active').length > 0) {
// Always expand the active element
toggleLi(li,
false,
false);
} else if ($.inArray(id.toString(), currentProjectIds.ids.split(', ')) !== -1) {
// 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') || li.find('.active').length > 0) {
// Always expand the active element
toggleLi(li, false, false);
sessionCollapseSidebarElement(project, id);
} else {
// Element collapsed by default
toggleLi(li, true, false);
}
});
}
// Add onclick callback to every triangle icon
$('.tree li.parent_li ').find('> span i').on('click', function(e) {
let el = $(this).parent('span').parent('li.parent_li');
if (el.find(' > ul > li').is(':visible')) {
toggleLi(el, true, true);
sessionExpandSidebarElement(project, el.data('toggle-id'), $('[data-parent="candidate"]').length);
} else {
toggleLi(el, false, true);
sessionCollapseSidebarElement(project, el.data('toggle-id'));
}
e.stopPropagation();
return false;
});
// Add bold style to all levels of selected element
$('.tree li.active ').parents('.parent_li[data-parent="candidate"]').find('> span a').css('font-weight', 'bold');
// Add custom borders to tree links
$('.tree li span.tree-link ').after("<div class='border-custom'></div>");
}
// Resize the sidebar to accomodate to the page size
function resizeSidebarContents() {
var tree = $('#sidebar-wrapper .tree');
// Set vertical scrollbar on navigation tree
if (tree.length && tree.length === 1) {
tree.css('height', ($(window).height() - tree.position().top - 50) + 'px');
}
}
function scrollToSelectedItem() {
$(`${SIDEBAR_ID} .tree`).scrollTo($('.tree').data('scroll'));
}
// Initialize click listeners
setupSidebarTree();
// 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();
scrollToSelectedItem();
});
scrollToSelectedItem();
});
/* global PerfectSb */
var Sidebar = (function() {
const SIDEBAR_ID = '#slide-panel';
const STORAGE_TREE_KEY = 'scinote-sidebar-tree-state';
const STORAGE_SCROLL_TREE_KEY = 'scinote-sidebar-tree-scroll-state';
function toggleTree($tree_childs) {
$tree_childs.toggleClass('hidden')
$.each($tree_childs, (i, tree_child) => {
$(tree_child).closest('.branch').find('.tree-toggle').first().toggleClass('fa-caret-down').toggleClass('fa-caret-right')
})
function toggleTree($treeChildren) {
$treeChildren.toggleClass('hidden');
$.each($treeChildren, (i, treeChild) => {
$(treeChild).closest('.branch').find('.tree-toggle').first()
.toggleClass('fa-caret-down')
.toggleClass('fa-caret-right');
});
}
function saveCurrentState() {
var config = []
var config = [];
$.each($(SIDEBAR_ID).find('.tree-child:not(:hidden)'), (i, branch) => {
config.push(`[data-branch-id=${branch.dataset.branchId}]`)
})
config.push(`[data-branch-id=${branch.dataset.branchId}]`);
});
sessionStorage.setItem(STORAGE_TREE_KEY, config.join(','));
}
function initSideBar() {
$(SIDEBAR_ID).on('click', '.tree-toggle', function() {
var $tree_child = $(this).closest('.branch').find('.tree-child').first()
toggleTree($tree_child)
saveCurrentState();
PerfectSb().update_all();
})
$(SIDEBAR_ID).find('.tree').scroll(function() {
sessionStorage.setItem(STORAGE_SCROLL_TREE_KEY, $(this).scrollTop());
})
toggleTree($(SIDEBAR_ID).find('.tree-child[data-active="true"]'))
toggleTree($(SIDEBAR_ID).find('.tree-child.hidden').filter(sessionStorage.getItem(STORAGE_TREE_KEY)))
$('#wrapper').show();
function loadLastState() {
toggleTree($(SIDEBAR_ID).find('.tree-child[data-active="true"]'));
toggleTree($(SIDEBAR_ID).find('.tree-child.hidden').filter(sessionStorage.getItem(STORAGE_TREE_KEY)));
PerfectSb().update_all();
$(SIDEBAR_ID).find('.tree').scrollTo(sessionStorage.getItem(STORAGE_SCROLL_TREE_KEY));
}
return {
init: (mode) => {
if ($(SIDEBAR_ID).length) {
initSideBar()
function initSideBar() {
$(SIDEBAR_ID).on('click', '.tree-toggle', function() {
var $treeChild = $(this).closest('.branch').find('.tree-child').first();
toggleTree($treeChild);
saveCurrentState();
PerfectSb().update_all();
});
$(SIDEBAR_ID).find('.tree').scroll(function() {
sessionStorage.setItem(STORAGE_SCROLL_TREE_KEY, $(this).scrollTop());
});
$('#wrapper').show();
loadLastState();
}
return {
init: () => {
if ($(SIDEBAR_ID).length) {
initSideBar();
}
},
loadLastState: () => {
loadLastState();
}
};
}());

View file

@ -1,18 +0,0 @@
(function() {
'use strict';
$(".tree li.parent_li ").find("> span i").on("click", function (e) {
e.stopPropagation();
var el = $(this).closest("li.parent_li");
if (el.find(" > ul.accountNavigation").is(":visible")) {
el.find(" > span > i.triangleDown").hide();
el.find(" > span > i.triangleRight").show();
el.find(" > ul.accountNavigation").hide();
} else {
el.find(" > span > i.triangleDown").show();
el.find(" > span > i.triangleRight").hide();
el.find(" > ul.accountNavigation").show();
}
});
})();

View file

@ -1,96 +1,31 @@
// scss-lint:disable SelectorDepth
// scss-lint:disable NestingDepth
@import "constants";
@import "mixins";
.tree {
height: 100%;
height: calc(100% - 30px);
padding-bottom: 30px;
ul {
.sidebar-root {
padding-left: 0;
}
> ul {
margin-bottom: 0;
}
.first-indent {
margin-left: 30px;
}
.second-indent {
margin-left: 60px;
}
li {
.branch,
.leaf {
list-style-type: none;
margin: 0;
position: relative;
span {
display: block;
padding: 15px;
&.my-module-group-element {
border: 0;
padding: 0;
}
&.fa-map-marker-alt {
border: 0;
display: inline-block;
padding: 0;
}
}
&.active > span {
background-color: $color-white;
color: $brand-primary;
font-weight: bold;
&.first-indent > span,
&.no-indent > span {
border: 0;
display: inline-block;
padding: 0;
width: 100%;
}
}
i.no-arrow {
padding-left: 15px;
}
i.fas {
cursor: pointer;
font-size: 9pt;
&.expanded {
@include rotate(90deg);
}
}
// Links are recolored
a {
color: $color-volcano;
position: relative;
&.disabled {
color: $brand-primary;
}
&:hover {
color: $color-volcano;
}
}
}
.tree-link {
align-items: center;
display: flex;
padding-left: 0;
height: 50px;
position: relative;
.tree-toggle {
cursor: pointer;
display: inline-block;
line-height: 30px;
position: absolute;
@ -101,33 +36,66 @@
}
.line-wrap {
padding-left: 30px;
}
animation-timing-function: $timing-function-sharp;
color: $color-volcano;
flex-grow: 1;
height: 100%;
line-height: 50px;
padding: 0 10px 0 30px;
transition: .2s;
a:not(.canvas-center-on) {
width: 100%;
}
a:not(.canvas-center-on)::after {
height: 48px;
left: -3px;
position: absolute;
top: -18px;
width: 100%;
&.disabled {
color: $brand-primary;
pointer-events: none;
}
}
#settings {
.fa-caret-right {
margin-left: -15px;
.canvas-center-on {
animation-timing-function: $timing-function-sharp;
color: $color-volcano;
flex-basis: 36px;
flex-shrink: 0;
line-height: 50px;
padding-right: 16px;
text-align: center;
transition: .2s;
}
.no-indent {
padding-left: 30px;
&:hover {
.line-wrap {
background-color: $color-alto;
text-decoration: none;
}
.first-indent {
padding-left: 15px;
.canvas-center-on {
background-color: $color-alto;
}
}
}
&.active > .tree-link {
background-color: $color-white;
color: $brand-primary;
font-weight: bold;
.line-wrap {
background-color: $color-white;
color: $brand-primary;
text-decoration: none;
}
.canvas-center-on {
background-color: $color-white;
color: $brand-primary;
}
}
}
.leaf {
.tree-link {
.line-wrap {
padding-left: 10px;
}
}
}
}
@ -137,6 +105,7 @@
.fas-custom {
float: right;
margin-right: 5px;
top: 2px;
}

View file

@ -381,6 +381,7 @@
.sidebar-button {
color: $brand-primary !important;
margin-left: 30px;
span {
display: inline-block !important;

View file

@ -95,7 +95,7 @@ class ExperimentsController < ApplicationController
@experiment.last_modified_by = current_user
if @experiment.save
experiment_annotation_notification(old_text)
experiment_annotation_notification(old_text) if old_text
activity_type = if experiment_params[:archived] == 'false'
:restore_experiment

View file

@ -1,9 +1,9 @@
<%= content_for :sidebar do %>
<div id="slide-panel" class="visible">
<div id="repo-tree" class="tree">
<ul>
<ul class="sidebar-root">
<% if can_create_repositories?(current_team) %>
<li>
<li class="branch">
<span class="tree-link no-indent">
<a class="sidebar-button create-new-repository" data-remote="true"
href="<%= create_modal_team_repositories_path(current_team) %>">
@ -14,7 +14,7 @@
</li>
<% end %>
<% repositories.each do |repository| %>
<li class="<%= 'active parent_li' if current_page?(repository_path(repository)) %>" >
<li class="branch <%= 'active parent_li' if current_page?(repository_path(repository)) %>" >
<span class="tree-link no-indent" title="<%= repository.name %>">
<%= link_to repository.name,
repository_path(repository),

View file

@ -10,7 +10,6 @@
data-current-experiment="<%= current_experiment&.id %>"
data-current-task="<%= current_task&.id %>">
<div class="tree perfect-scrollbar" data-scroll="<%= params[:scroll] %>">
<ul>
<% cache [action_name, current_user, current_team] do %>
<%= render partial: 'shared/sidebar/projects', locals: {
current_project: current_project,
@ -18,9 +17,6 @@
current_task: current_task
} %>
<% end %>
</ul>
</div>
</div>
<% end %>
<%= javascript_include_tag("sidebar") %>

View file

@ -3,7 +3,7 @@
<% project.active_experiments.each do |experiment| %>
<% cache [action_name, current_user, experiment] do %>
<li data-parent="candidate" class="branch <%= 'active' if experiment_page? && current_experiment == experiment %>">
<span class="tree-link line-wrap first-indent" title="<%= experiment.name %>">
<span class="tree-link first-indent" title="<%= experiment.name %>">
<% if experiment.active_my_modules.any? %>
<i class="fas fa-caret-right tree-toggle"></i>
<% end %>
@ -13,9 +13,6 @@
style: (current_experiment == experiment ? 'font-weight: bold' : ''),
data: { type: 'experiment', id: experiment.id }
%>
<% if experiment_page? && current_experiment == experiment && action_name =='canvas' %>
<a href="" class="canvas-center-on"><span class="fas fa-map-marker-alt"></span></a>
<% end %>
</span>
<%= render partial: 'shared/sidebar/my_modules', locals: {
experiment: experiment,

View file

@ -7,6 +7,9 @@
module_action_to_link_to(my_module),
class: 'line-wrap',
data: { type: 'my_module', id: my_module.id } %>
<% if experiment_page? && current_experiment == experiment && action_name =='canvas' %>
<a href="" class="canvas-center-on"><i class="fas fa-map-marker-alt"></i></a>
<% end %>
</span>
</li>
<% end %>

View file

@ -1,4 +1,4 @@
<ul>
<ul class="sidebar-root">
<% @projects_tree.each do |project| %>
<% cache [action_name, current_user, project] do %>
<li data-parent="candidate"

View file

@ -1,93 +1,65 @@
<%= content_for :sidebar do %>
<div id="slide-panel" class="visible">
<div class="tree">
<ul id="settings" data-hook="user-settings-navigation-html">
<ul id="settings" class="sidebar-root" data-hook="user-settings-navigation-html">
<!-- Account -->
<li class="parent_li" >
<li class="parent_li branch" >
<span class="tree-link line-wrap no-indent">
<i title="<%= t('sidebar.branch_expand') %>"
class="fas fa-caret-right triangleRight"
class="fas fa-caret-right tree-toggle"
aria-hidden="true"
style="<%= 'display: none;' if on_settings_account_page? %>"
></i>
<i title="<%= t('sidebar.branch_collapse') %>"
class="fas fa-caret-right expanded triangleDown"
aria-hidden="true"
style="<%= 'display: none;' unless on_settings_account_page? %>"
></i>
<% account_style = 'font-weight: bold;' if on_settings_account_page? %>
<%= link_to t("users.settings.sidebar.account"),
edit_user_registration_path,
style: account_style,
class: "line-wrap",
style: (on_settings_account_page? ? 'font-weight: bold' : ''),
data: { 'no-turbolink' => 'true' } %>
</span>
<ul class="accountNavigation" data-hook="user-settings-account-navigation-html" style="<%= 'display: none;' unless on_settings_account_page? %>">
<li class="<%= 'active' if on_settings_account_profile_page? %>" >
<span class="tree-link line-wrap first-indent">
<% if on_settings_account_profile_page? %>
<span title="<%= t("users.settings.sidebar.account_nav.profile") %>"><%= t("users.settings.sidebar.account_nav.profile") %></span>
<% else %>
<ul class="tree-child hidden accountNavigation" data-active="<%= on_settings_account_page? %>" data-hook="user-settings-account-navigation-html">
<li class="leaf <%= 'active' if on_settings_account_profile_page? %>" >
<span class="tree-link first-indent">
<%= link_to t("users.settings.sidebar.account_nav.profile"),
edit_user_registration_path,
class: "line-wrap #{'disabled' if on_settings_account_profile_page?}",
data: { 'no-turbolink' => 'true' } %>
<% end %>
</span>
</li>
<li class="<%= 'active' if on_settings_account_preferences_page? %>" >
<span class="tree-link line-wrap first-indent">
<% if on_settings_account_preferences_page? %>
<span title="<%= t("users.settings.sidebar.account_nav.preferences") %>"><%= t("users.settings.sidebar.account_nav.preferences") %></span>
<% else %>
<li class="leaf <%= 'active' if on_settings_account_preferences_page? %>" >
<span class="tree-link first-indent">
<%= link_to t("users.settings.sidebar.account_nav.preferences"),
preferences_path,
class: "line-wrap #{'disabled' if on_settings_account_preferences_page?}",
data: { 'no-turbolink' => 'true' } %>
<% end %>
</span>
</li>
<li class="<%= 'active' if on_settings_account_addons_page? %>" >
<span class="tree-link line-wrap first-indent">
<% if on_settings_account_addons_page? %>
<span title="<%= t("users.settings.sidebar.account_nav.addons") %>"><%= t("users.settings.sidebar.account_nav.addons") %></span>
<% else %>
<li class="leaf <%= 'active' if on_settings_account_addons_page? %>" >
<span class="tree-link first-indent">
<%= link_to t("users.settings.sidebar.account_nav.addons"),
addons_path,
class: "line-wrap #{'disabled' if on_settings_account_addons_page?}",
data: { 'no-turbolink' => 'true' } %>
<% end %>
</span>
</li>
<!-- Connected accounts -->
<li class="<%= 'active' if on_settings_account_connected_accounts_page? %>" >
<span class="tree-link line-wrap first-indent">
<% if on_settings_account_connected_accounts_page? %>
<span title="<%= t("users.settings.sidebar.account_nav.connected_accounts") %>">
<%= t("users.settings.sidebar.account_nav.connected_accounts") %>
</span>
<% else %>
<li class="leaf <%= 'active' if on_settings_account_connected_accounts_page? %>" >
<span class="tree-link first-indent">
<%= link_to t("users.settings.sidebar.account_nav.connected_accounts"),
connected_accounts_path,
class: "line-wrap #{'disabled' if on_settings_account_connected_accounts_page?}",
data: { 'no-turbolink' => 'true' } %>
<% end %>
</span>
</li>
</ul>
</li>
<!-- Teams -->
<li class="<%= 'active' if on_settings_team_page? %>" >
<span class="tree-link line-wrap no-indent">
<% if on_settings_team_page? %>
<span title="<%= t("users.settings.sidebar.teams") %>">
<%= link_to t("users.settings.sidebar.teams"),
teams_path,
data: { 'no-turbolink' => 'true' },
class: 'all-teams-navigation-link' %>
</span>
<% else %>
<li class="branch <%= 'active' if on_settings_team_page? %>" >
<span class="tree-link no-indent">
<%= link_to t("users.settings.sidebar.teams"),
teams_path,
class: "line-wrap #{'all-teams-navigation-link' if on_settings_team_page?}",
data: { 'no-turbolink' => 'true' } %>
<% end %>
</span>
</li>
@ -95,9 +67,3 @@
</div>
</div>
<% end %>
<script>
$('#wrapper').show();
</script>
<%= javascript_include_tag("users/settings/list_toggle") %>