Add general layout for navigator [SCI-8046

]
This commit is contained in:
Anton 2023-04-19 14:16:22 +02:00
parent e8b952f4fd
commit 7143c3ed5d
16 changed files with 179 additions and 27 deletions

View file

@ -1,7 +1,7 @@
.sci--layout {
--breadcrumbs-navigation: 56px;
--left-navigation: 180px;
--navigator-navigation: 280px;
--left-navigation: 204px;
--navigator-navigation: 288px;
--top-navigation: 52px;
display: grid;
grid-template-areas: "top top top"
@ -18,12 +18,20 @@
transition: .4s $timing-function-sharp;
width: 100%;
.sci--layout--navigator-open {
display: none;
}
&[data-breadcrumbs-collapsed="true"] {
--breadcrumbs-navigation: 0px;
}
&[data-navigator-collapsed="true"] {
--navigator-navigation: 0px;
.sci--layout--navigator-open {
display: inline-block;
}
}
&[data-left-navigation-collapsed="true"] {
@ -54,7 +62,7 @@
left: var(--left-navigation);
position: fixed;
top: calc(var(--top-navigation) + var(--breadcrumbs-navigation));
transition: .4s $timing-function-standard;
transition: .4s $timing-function-sharp;
width: var(--navigator-navigation);
z-index: 550;
}
@ -65,7 +73,7 @@
left: var(--left-navigation);
position: fixed;
top: var(--top-navigation);
transition: .4s $timing-function-standard;
transition: .4s $timing-function-sharp;
width: calc(100% - var(--left-navigation));
z-index: 600;
}

View file

@ -3,11 +3,10 @@
.sci--layout--left-menu-container {
background-color: $color-white;
box-shadow: $flyout-shadow;
display: flex;
flex-direction: column;
height: 100%;
padding: 1em 0;
padding: 1rem 1.5rem 1rem 0;
width: 100%;
.sci--layout--menu-item {
@ -25,6 +24,7 @@
.fas {
display: inline-block;
font-size: 1.125rem;
width: 16px;
}

View file

@ -112,3 +112,7 @@ $color-dd-hover: #f5f5f5;
--sn-background-turqoise: #E3F6F7;
--sn-background-bloo: #E2F0FF;
}
.sn-color-primary {
color: var(--sn-blue);
}

View file

@ -20,6 +20,7 @@ class ExperimentsController < ApplicationController
before_action :check_move_permissions, only: %i(move_modal move)
before_action :set_inline_name_editing, only: %i(canvas table module_archive)
before_action :set_breadcrumbs_items, only: %i(canvas table module_archive)
before_action :set_navigator, only: %i(canvas archive)
layout 'fluid'
@ -660,4 +661,8 @@ class ExperimentsController < ApplicationController
end
end
end
def set_navigator
@navigator = true
end
end

View file

@ -21,6 +21,7 @@ class MyModulesController < ApplicationController
before_action :set_inline_name_editing, only: %i(protocols results activities archive)
before_action :load_experiment_my_modules, only: %i(protocols results activities archive)
before_action :set_breadcrumbs_items, only: %i(results protocols activities)
before_action :set_navigator, only: %i(protocols results activities archive)
layout 'fluid'.freeze
@ -609,4 +610,8 @@ class MyModulesController < ApplicationController
my_module: link_to(@my_module.name, protocols_my_module_url(@my_module)))
)
end
def set_navigator
@navigator = true
end
end

View file

@ -24,6 +24,7 @@ class ProjectsController < ApplicationController
before_action :reset_invalid_view_state, only: %i(index cards show)
before_action :set_folder_inline_name_editing, only: %i(index cards)
before_action :set_breadcrumbs_items, only: %i(index show)
before_action :set_navigator, only: %i(index show)
layout 'fluid'
@ -479,4 +480,8 @@ class ProjectsController < ApplicationController
project: project,
message_items: message_items)
end
def set_navigator
@navigator = true
end
end

View file

@ -14,3 +14,7 @@ $(document).on('click', '.sci--layout--menu-item[data-submenu=true]', (e) => {
submenu.attr('data-collapsed', true);
}
});
$(document).on('click', '.sci--layout--navigator-open', (e) => {
navigatorContainer.$data.navigatorCollapsed = false
});

View file

@ -0,0 +1,35 @@
import Vue from 'vue/dist/vue.esm';
import NavigatorContainer from '../../../vue/navigation/navigator.vue';
import PerfectScrollbar from 'vue2-perfect-scrollbar';
import 'vue2-perfect-scrollbar/dist/vue2-perfect-scrollbar.css';
Vue.use(PerfectScrollbar);
Vue.prototype.i18n = window.I18n;
window.addEventListener('DOMContentLoaded', () => {
const navigator = new Vue({
el: '#sciNavigationNavigatorContainer',
components: {
'navigator-container': NavigatorContainer
},
data() {
return {
navigatorCollapsed: false,
}
},
created() {
this.navigatorCollapsed = $('.sci--layout').attr('data-navigator-collapsed');
},
watch: {
navigatorCollapsed: function () {
let stateUrl = $('#sciNavigationNavigatorContainer').attr('data-navigator-state-url');
$('.sci--layout').attr('data-navigator-collapsed', this.navigatorCollapsed);
$.post(stateUrl, {state: this.navigatorCollapsed ? 'collapsed' : 'open'});
}
}
});
window.navigatorContainer = navigator
});

View file

@ -0,0 +1,52 @@
<template>
<div class="w-72 h-full border rounded bg-white flex flex-col right-0 absolute">
<div class="p-3 flex items-center">
<i class="fas fa-bars p-2 cursor-pointer"></i>
<div class="font-bold text-base">
{{ i18n.t('navigator.title') }}
</div>
<i @click="$emit('navigator:colapse')" class="fas fa-times ml-auto cursor-pointer"></i>
</div>
<div class="grow px-2 py-4">
<NavigatorItem v-for="item in sortedMenuItems" :key="item.id" :item="item" />
</div>
</div>
</template>
<script>
import NavigatorItem from './navigator_item.vue'
export default {
name : 'NavigatorContainer',
components: {
NavigatorItem
},
data() {
return {
menuItems: [],
navigatorCollapsed: false
}
},
computed: {
sortedMenuItems() {
return this.menuItems.sort((a, b) => a.name - b.name)
}
},
created() {
this.menuItems = [
{id: 'p1', name: 'Project 1', url: '/', archive: false, children: [
{id: 'e1', name: 'Experiment 1', url: '/', archive: false}
]},
{id: 'f1', name: 'Folder', url: '/', archive: false, icon: 'fas fa-folder', children: [
{id: 'p2', name: 'Project 2', url: '/', archive: false, children: [
{id: 'e2', name: 'Experiment 2', url: '/', archive: false, children: [
{id: 't1', name: 'Task', url: '/', archive: false}
]}
]}
]}
]
}
}
</script>

View file

@ -0,0 +1,38 @@
<template>
<div class="sn-color-primary pl-7 pt-4 flex items-center flex-wrap">
<div class="w-5 mr-2 flex justify-start">
<i v-if="haveChildren"
class="fas cursor-pointer"
:class="{'fa-chevron-right': !childrenOpen, 'fa-chevron-down': childrenOpen }"
@click="childrenOpen = !childrenOpen"></i>
</div>
<i v-if="item.icon" class="mr-2" :class="item.icon"></i>
{{ item.name }}
<div v-if="childrenOpen" class="basis-full">
<NavigatorItem v-for="item in sortedMenuItems" :key="item.id" :item="item" />
</div>
</div>
</template>
<script>
export default {
name: 'NavigatorItem',
props: {
item: Object
},
data: function() {
return {
childrenOpen: false
}
},
computed: {
haveChildren: function() {
return this.item.children && this.item.children.length > 0
},
sortedMenuItems: function() {
if (!this.haveChildren) return []
return this.item.children.sort((a, b) => a.name - b.name)
}
},
}
</script>

View file

@ -42,6 +42,7 @@
<%= javascript_include_tag 'tui_image_editor' %>
<%= stylesheet_link_tag 'tui_image_editor_styles' %>
<%= javascript_include_tag 'vue_navigation_top_menu' %>
<%= javascript_include_tag 'vue_navigation_navigator' %>
</head>
<body
class="<%= yield :body_class %>"
@ -61,8 +62,7 @@
<div class="sci--layout"
data-breadcrumbs-collapsed="<%= !@breadcrumbs_items.present? %>"
data-navigator-collapsed="<%= !content_for?(:sidebar_title) || session[:navigator_collapsed] %>"
data-navitgator-state-url="<%= navigator_state_navigations_path %>"
data-navigator-collapsed="<%= !@navigator || session[:navigator_collapsed] %>"
data-left-navigation-collapsed=<%= !user_signed_in? %>
>
<div class="sci--layout-navigation-top" >
@ -71,8 +71,7 @@
<div class="sci--layout-navigation-left">
<%= render "shared/navigation/left" if user_signed_in? %>
</div>
<!-- temporary fix for sidebar (#wrapper) -->
<div id="wrapper" class="sci--layout-navigation-navigator">
<div class="sci--layout-navigation-navigator pb-3 overflow-hidden relative">
<%= render "shared/navigation/navigator" %>
</div>
<div class="sci--layout-navigation-breadcrumbs">

View file

@ -1,5 +1,6 @@
<div class="content-header sticky-header">
<div class="title-row">
<i class="fas fa-bars sci--layout--navigator-open p-2 cursor-pointer"></i>
<% if current_folder&.name && @inline_editable_title_config.present? %>
<h1 data-view-mode="active" class="projects-title">
<%= render partial: "shared/inline_editing",

View file

@ -1,17 +1,10 @@
<% if content_for?(:sidebar_title) %>
<div id="sidebar-wrapper" class="sidebar-container <%= yield :sidebar_wrapper_class %>" data-sidebar-url="<%= yield :sidebar_url %>">
<div class="sidebar-header">
<div class="sidebar-title">
<%= yield :sidebar_title %>
</div>
<i class="fas fa-times close-sidebar"></i>
</div>
<div class="fas fa-angle-double-right show-sidebar"></div>
<div class="sidebar-body">
<%= yield :sidebar %>
</div>
<div class="sidebar-footer">
<%= yield :sidebar_footer %>
</div>
<% if @navigator %>
<div id="sciNavigationNavigatorContainer"
class="contents"
data-navigator-state-url="<%= navigator_state_navigations_path %>"
data-turbolinks-permanent data-behaviour="vue">
<navigator-container
@navigator:colapse="navigatorCollapsed = true"
/>
</div>
<% end %>

View file

@ -308,7 +308,8 @@ en:
tutorials: "Video tutorials"
core_version: "SciNote version"
about: "about"
navigator:
title: "Navigator"
sidebar:
title: "Navigation"
branch_expand: "Expand this branch"

View file

@ -5,6 +5,7 @@ module.exports = {
'./public/*.html',
'./app/helpers/**/*.rb',
'./app/javascript/**/*.js',
'./app/javascript/**/*.vue',
'./app/views/**/*.{erb,haml,html,slim}'
],
theme: {

View file

@ -31,7 +31,8 @@ const entryList = {
vue_protocol: './app/javascript/packs/vue/protocol.js',
vue_repository_filter: './app/javascript/packs/vue/repository_filter.js',
vue_repository_print_modal: './app/javascript/packs/vue/repository_print_modal.js',
vue_navigation_top_menu: './app/javascript/packs/vue/navigation/top_menu.js'
vue_navigation_top_menu: './app/javascript/packs/vue/navigation/top_menu.js',
vue_navigation_navigator: './app/javascript/packs/vue/navigation/navigator.js'
}
// Engine pack loading based on https://github.com/rails/webpacker/issues/348#issuecomment-635480949