From 8b273acacab8293e5a2a70cc4b6a0e1b66db66a6 Mon Sep 17 00:00:00 2001 From: aignatov-bio Date: Fri, 28 Feb 2020 14:03:08 +0100 Subject: [PATCH] Update all sidebars --- app/assets/javascripts/application.js.erb | 1 + app/assets/javascripts/projects/index.js | 4 +- app/assets/javascripts/sidebar.js | 335 ++---------------- .../users/settings/list_toggle.js.erb | 18 - .../stylesheets/partials/_tree_view.scss | 171 ++++----- app/assets/stylesheets/repositories.scss | 1 + app/controllers/experiments_controller.rb | 2 +- app/views/repositories/_sidebar.html.erb | 6 +- app/views/shared/_sidebar.html.erb | 18 +- .../shared/sidebar/_experiments.html.erb | 5 +- app/views/shared/sidebar/_my_modules.html.erb | 3 + app/views/shared/sidebar/_projects.html.erb | 2 +- app/views/users/settings/_sidebar.html.erb | 86 ++--- 13 files changed, 152 insertions(+), 500 deletions(-) delete mode 100644 app/assets/javascripts/users/settings/list_toggle.js.erb diff --git a/app/assets/javascripts/application.js.erb b/app/assets/javascripts/application.js.erb index 909940fb5..2ef43493c 100644 --- a/app/assets/javascripts/application.js.erb +++ b/app/assets/javascripts/application.js.erb @@ -46,6 +46,7 @@ //= require_tree ./repositories/renderers //= require_directory ./repositories/validators //= require_directory ./sitewide +//= require sidebar //= require turbolinks diff --git a/app/assets/javascripts/projects/index.js b/app/assets/javascripts/projects/index.js index 76bed9eef..c7e027c5c 100644 --- a/app/assets/javascripts/projects/index.js +++ b/app/assets/javascripts/projects/index.js @@ -453,8 +453,8 @@ type: 'GET', dataType: 'json', success: function(data) { - $('#slide-panel .tree').html(''); - setupSidebarTree(); + $('#slide-panel .tree').html(data.html); + Sidebar.loadLastState(); } }); } diff --git a/app/assets/javascripts/sidebar.js b/app/assets/javascripts/sidebar.js index 7bb33cae6..9479efd6b 100644 --- a/app/assets/javascripts/sidebar.js +++ b/app/assets/javascripts/sidebar.js @@ -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(''); - } 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 - 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("
"); - } - - // 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)); } + 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: (mode) => { + init: () => { if ($(SIDEBAR_ID).length) { - initSideBar() + initSideBar(); } + }, + + loadLastState: () => { + loadLastState(); } }; }()); diff --git a/app/assets/javascripts/users/settings/list_toggle.js.erb b/app/assets/javascripts/users/settings/list_toggle.js.erb deleted file mode 100644 index a006dde1b..000000000 --- a/app/assets/javascripts/users/settings/list_toggle.js.erb +++ /dev/null @@ -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(); - } - }); -})(); diff --git a/app/assets/stylesheets/partials/_tree_view.scss b/app/assets/stylesheets/partials/_tree_view.scss index 9850415c6..53fdf3156 100644 --- a/app/assets/stylesheets/partials/_tree_view.scss +++ b/app/assets/stylesheets/partials/_tree_view.scss @@ -1,135 +1,103 @@ +// 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; + .tree-link { + align-items: center; + display: flex; + height: 50px; + position: relative; - &.my-module-group-element { - border: 0; - padding: 0; + .tree-toggle { + cursor: pointer; + display: inline-block; + line-height: 30px; + position: absolute; + text-align: center; + top: 10px; + width: 30px; + z-index: 2; } - &.fa-map-marker-alt { - border: 0; - display: inline-block; - padding: 0; + .line-wrap { + animation-timing-function: $timing-function-sharp; + color: $color-volcano; + flex-grow: 1; + height: 100%; + line-height: 50px; + padding: 0 10px 0 30px; + transition: .2s; + + &.disabled { + color: $brand-primary; + pointer-events: none; + } + } + + .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; + } + + &:hover { + .line-wrap { + background-color: $color-alto; + text-decoration: none; + } + + .canvas-center-on { + background-color: $color-alto; + } } } - &.active > span { + &.active > .tree-link { 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%; + .line-wrap { + background-color: $color-white; + color: $brand-primary; + text-decoration: none; } - } - 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 { + .canvas-center-on { + background-color: $color-white; color: $brand-primary; } + } + } - &:hover { - color: $color-volcano; + .leaf { + .tree-link { + .line-wrap { + padding-left: 10px; } } } - - .tree-link { - align-items: center; - display: flex; - padding-left: 0; - position: relative; - - .tree-toggle { - display: inline-block; - line-height: 30px; - position: absolute; - text-align: center; - top: 10px; - width: 30px; - z-index: 2; - } - - .line-wrap { - padding-left: 30px; - } - - a:not(.canvas-center-on) { - width: 100%; - } - - a:not(.canvas-center-on)::after { - height: 48px; - left: -3px; - position: absolute; - top: -18px; - width: 100%; - } - } - - #settings { - .fa-caret-right { - margin-left: -15px; - } - - .no-indent { - padding-left: 30px; - } - - .first-indent { - padding-left: 15px; - } - } } #repo-tree { @@ -137,6 +105,7 @@ .fas-custom { float: right; + margin-right: 5px; top: 2px; } diff --git a/app/assets/stylesheets/repositories.scss b/app/assets/stylesheets/repositories.scss index bf1c52086..b9c797564 100644 --- a/app/assets/stylesheets/repositories.scss +++ b/app/assets/stylesheets/repositories.scss @@ -381,6 +381,7 @@ .sidebar-button { color: $brand-primary !important; + margin-left: 30px; span { display: inline-block !important; diff --git a/app/controllers/experiments_controller.rb b/app/controllers/experiments_controller.rb index 0addb3e1b..d228f4b9e 100644 --- a/app/controllers/experiments_controller.rb +++ b/app/controllers/experiments_controller.rb @@ -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 diff --git a/app/views/repositories/_sidebar.html.erb b/app/views/repositories/_sidebar.html.erb index 1e065e59b..8984cd71f 100644 --- a/app/views/repositories/_sidebar.html.erb +++ b/app/views/repositories/_sidebar.html.erb @@ -1,9 +1,9 @@ <%= content_for :sidebar do %>
<% end %> - -<%= javascript_include_tag("sidebar") %> diff --git a/app/views/shared/sidebar/_experiments.html.erb b/app/views/shared/sidebar/_experiments.html.erb index 5f08439fe..a856fdc5d 100644 --- a/app/views/shared/sidebar/_experiments.html.erb +++ b/app/views/shared/sidebar/_experiments.html.erb @@ -3,7 +3,7 @@ <% project.active_experiments.each do |experiment| %> <% cache [action_name, current_user, experiment] do %>
  • - + <% if experiment.active_my_modules.any? %> <% 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' %> - - <% end %> <%= render partial: 'shared/sidebar/my_modules', locals: { experiment: experiment, diff --git a/app/views/shared/sidebar/_my_modules.html.erb b/app/views/shared/sidebar/_my_modules.html.erb index 2dcfff2b2..33ec28b83 100644 --- a/app/views/shared/sidebar/_my_modules.html.erb +++ b/app/views/shared/sidebar/_my_modules.html.erb @@ -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' %> + + <% end %>
  • <% end %> diff --git a/app/views/shared/sidebar/_projects.html.erb b/app/views/shared/sidebar/_projects.html.erb index 8ebe7d749..c74d55a0a 100644 --- a/app/views/shared/sidebar/_projects.html.erb +++ b/app/views/shared/sidebar/_projects.html.erb @@ -1,4 +1,4 @@ -
      +