app/javascript/avo.base.js in avo-3.2.3 vs app/javascript/avo.base.js in avo-3.3.0

- old
+ new

@@ -1,24 +1,23 @@ // eslint-disable-next-line import/no-extraneous-dependencies import 'core-js/stable' // eslint-disable-next-line import/no-extraneous-dependencies +import 'chartkick/chart.js/chart.esm' +import 'mapkick/bundle' import 'regenerator-runtime/runtime' import * as ActiveStorage from '@rails/activestorage' import * as Mousetrap from 'mousetrap' import { Turbo } from '@hotwired/turbo-rails' import tippy from 'tippy.js' import { LocalStorageService } from './js/local-storage-service' -import 'chartkick/chart.js/chart.esm' - -window.Avo.localStorage = new LocalStorageService() - import './js/active-storage' import './js/controllers' import './js/custom-stream-actions' +window.Avo.localStorage = new LocalStorageService() window.Turbolinks = Turbo let scrollTop = null Mousetrap.bind('r r r', () => { @@ -49,18 +48,56 @@ return title }, }) } + +// Detect whether an element is in view inside a parent element. +// Original here: https://gist.github.com/jjmu15/8646226 +function isInViewport(element, parentElement) { + const rect = element.getBoundingClientRect() + const html = document.documentElement + const parent = parentElement.getBoundingClientRect() + + return ( + rect.top >= 0 + && rect.left >= 0 + && rect.bottom <= (parent.height || window.innerHeight || html.clientHeight) + && rect.right <= (parent.width || window.innerWidth || html.clientWidth) + ) +} + +// Used on initial page load to scroll to the first active sidebar item if it's not in view. +function scrollSidebarMenuItemIntoView() { + const activeSidebarItem = document.querySelector('.avo-sidebar .mac-styled-scrollbar a.active') + const sidebarScrollingArea = document.querySelector('.avo-sidebar .mac-styled-scrollbar') + if (!isInViewport(activeSidebarItem, sidebarScrollingArea)) { + activeSidebarItem.scrollIntoView({ block: 'end', inline: 'nearest' }) + } +} + window.initTippy = initTippy ActiveStorage.start() +let sidebarScrollPosition = null + document.addEventListener('turbo:load', () => { initTippy() isMac() + if (window.Avo.configuration.focus_sidebar_menu_item) { + scrollSidebarMenuItemIntoView() + } + // Restore sidebar scroll position + if (sidebarScrollPosition && window.Avo.configuration.preserve_sidebar_scroll) { + document.querySelector('.avo-sidebar .mac-styled-scrollbar').scrollTo({ + top: sidebarScrollPosition, + behavior: 'instant', + }) + } + // Restore scroll position after r r r turbo reload if (scrollTop) { setTimeout(() => { document.scrollingElement.scrollTo(0, scrollTop) scrollTop = 0 @@ -84,10 +121,15 @@ e.target.src = `${window.Avo.configuration.root_path}/failed_to_load?turbo_frame=${id}&src=${src}` } } }) -document.addEventListener('turbo:visit', () => document.body.classList.add('turbo-loading')) +document.addEventListener('turbo:visit', () => { + // Remeber sidebar scroll position before changing pages. + sidebarScrollPosition = document.querySelector('.avo-sidebar .mac-styled-scrollbar').scrollTop + + document.body.classList.add('turbo-loading') +}) document.addEventListener('turbo:submit-start', () => document.body.classList.add('turbo-loading')) document.addEventListener('turbo:submit-end', () => document.body.classList.remove('turbo-loading')) document.addEventListener('turbo:before-cache', () => { document.querySelectorAll('[data-turbo-remove-before-cache]').forEach((element) => element.remove()) })