From 07ceef447e979015e422afeee902b226de70e6da Mon Sep 17 00:00:00 2001 From: Thomas Hackl <hackl@data-quest.de> Date: Tue, 25 Jul 2023 17:05:02 +0200 Subject: [PATCH] adjust sidebar only on admin/courses page --- .../assets/javascripts/bootstrap/sidebar.js | 15 ++++ resources/assets/javascripts/entry-base.js | 1 + resources/assets/javascripts/lib/sidebar.js | 76 ++++++++++++++++--- .../assets/stylesheets/scss/responsive.scss | 1 + .../assets/stylesheets/scss/sidebar.scss | 60 +++++++++++++++ .../responsive/ResponsiveNavigation.vue | 3 +- 6 files changed, 143 insertions(+), 13 deletions(-) create mode 100644 resources/assets/javascripts/bootstrap/sidebar.js diff --git a/resources/assets/javascripts/bootstrap/sidebar.js b/resources/assets/javascripts/bootstrap/sidebar.js new file mode 100644 index 00000000000..b8ea2d3bd2f --- /dev/null +++ b/resources/assets/javascripts/bootstrap/sidebar.js @@ -0,0 +1,15 @@ +import eventBus from '../lib/event-bus.ts'; + +STUDIP.ready(() => { + // Apply sidebar magic only on admin/courses + if (document.body.id === 'admin-courses-index' && + !document.documentElement.classList.contains('responsive-display')) { + STUDIP.Sidebar.observeFooter(); + STUDIP.Sidebar.observeSidebar(); + + document.defaultView.addEventListener('resize', () => { + STUDIP.Sidebar.reset(); + }); + } + +}); diff --git a/resources/assets/javascripts/entry-base.js b/resources/assets/javascripts/entry-base.js index 9fcb57ba97d..82e5640ee8f 100644 --- a/resources/assets/javascripts/entry-base.js +++ b/resources/assets/javascripts/entry-base.js @@ -86,6 +86,7 @@ import "./bootstrap/contentmodules.js" import "./bootstrap/responsive-navigation.js" import "./bootstrap/treeview.js" import "./bootstrap/stock-images.js" +import "./bootstrap/sidebar.js" import "./mvv_course_wizard.js" import "./mvv.js" diff --git a/resources/assets/javascripts/lib/sidebar.js b/resources/assets/javascripts/lib/sidebar.js index 3cb1c05eba8..13418761fdb 100644 --- a/resources/assets/javascripts/lib/sidebar.js +++ b/resources/assets/javascripts/lib/sidebar.js @@ -1,20 +1,72 @@ -import Scroll from './scroll.js'; - const Sidebar = { - open () { - this.toggle(true); + + observeSidebar() { + const options = { + root: null, + rootMargin: '0px 0px 35px 0px', + threshold: 1 + }; + + /** + * Observe if sidebar fits into viewport. + */ + const sidebar = document.getElementById('sidebar'); + if (sidebar) { + const sObserver = new IntersectionObserver(STUDIP.Sidebar.fits, options); + sObserver.observe(sidebar, options); + } }, - close () { - this.toggle(false); + + observeFooter() { + const options = { + root: null, + rootMargin: '0px', + threshold: 1 + }; + + /** + * Observe if the footer is visible in viewport. + */ + const fObserver = new IntersectionObserver(STUDIP.Sidebar.footerVisible, options); + fObserver.observe(document.getElementById('main-footer'), options); + + }, + + reset() { + const sidebar = document.getElementById('sidebar'); + if (sidebar) { + sidebar.classList.remove('oversized', 'was-oversized', 'fixed'); + sidebar.style.top = ''; + STUDIP.Sidebar.observeSidebar(); + } }, - toggle (visible = null) { - visible = visible ?? !$('#sidebar').hasClass('visible-sidebar'); - // Hide navigation - $('#responsive-toggle').prop('checked', false); - $('#responsive-navigation').removeClass('visible'); + fits(entries, observer) { + const sidebar = document.getElementById('sidebar'); + if (sidebar) { + entries.forEach(entry => { + // Sidebar fits onto current page. + if (entry.isIntersecting) { + sidebar.classList.remove('oversized'); + } else { + sidebar.classList.add('oversized', 'was-oversized'); + } + }); + } + }, - $('#sidebar').toggleClass('visible-sidebar', visible); + footerVisible(entries, observer) { + const sidebar = document.getElementById('sidebar'); + if (sidebar) { + entries.forEach(entry => { + // Footer is visible on current page. + if (entry.isIntersecting) { + sidebar.classList.remove('no-footer'); + } else { + sidebar.classList.add('no-footer'); + } + }); + } } }; diff --git a/resources/assets/stylesheets/scss/responsive.scss b/resources/assets/stylesheets/scss/responsive.scss index cbf2e752059..07df5dd1d2d 100644 --- a/resources/assets/stylesheets/scss/responsive.scss +++ b/resources/assets/stylesheets/scss/responsive.scss @@ -546,6 +546,7 @@ $sidebarOut: -330px; #sidebar { height: 100%; + overflow-y: auto; position: fixed; top: 75px; transform: translateX($sidebarOut); diff --git a/resources/assets/stylesheets/scss/sidebar.scss b/resources/assets/stylesheets/scss/sidebar.scss index b67a49e744d..d2c13351bf2 100644 --- a/resources/assets/stylesheets/scss/sidebar.scss +++ b/resources/assets/stylesheets/scss/sidebar.scss @@ -112,6 +112,66 @@ } } +html { + &:not(.responsive-display) { + #admin-courses-index { + #sidebar { + top: 50px; + transition: all $transition-duration ease-in-out; + + &.was-oversized { + height: calc(100vh - 250px); + overflow-y: auto; + position: fixed; + top: 155px; + + &.no-footer { + height: calc(100vh - 200px); + } + } + + .widget-links { + li.active { + &:before, &:after { + border: 0; + } + } + } + } + + &.fixed { + #sidebar { + height: calc(100vh - 125px); + top: 35px; + + &.no-footer { + height: calc(100vh - 100px); + } + } + } + + &.fullscreen-sidebar-shown { + #sidebar { + top: 110px; + + &.was-oversized { + height: calc(100vh - 200px); + + &.no-footer { + height: calc(100vh - 150px); + } + + &.fixed { + top: 110px; + } + } + } + } + + } + } +} + ul.widget-list { list-style: none; margin: 0; diff --git a/resources/vue/components/responsive/ResponsiveNavigation.vue b/resources/vue/components/responsive/ResponsiveNavigation.vue index eda2bfa86ee..6e56fdaf10a 100644 --- a/resources/vue/components/responsive/ResponsiveNavigation.vue +++ b/resources/vue/components/responsive/ResponsiveNavigation.vue @@ -321,7 +321,8 @@ export default { this.showMenu = false; cache.remove('fullscreen-mode'); document.getElementById('responsive-toggle-focusmode').style.display = 'none'; - document.body.style.display = null; + document.body.classList.remove('fullscreen-sidebar-shown'); + document.body.style.display = ''; const siteTitle = document.getElementById('site-title'); if (siteTitle.dataset.originalTitle) { -- GitLab