Skip to content

Commit

Permalink
Merge pull request #6659 from TheThingsNetwork/fix/navigation-scroll-…
Browse files Browse the repository at this point in the history
…restauration

Fix scroll jumps when selecting tabs of a table
  • Loading branch information
kschiffer authored Oct 31, 2023
2 parents b4aa590 + a5704fe commit 997906e
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 52 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ For details about compatibility between different releases, see the **Commitment

### Fixed

- Resolve scroll jumps when selecting different tabs of a table in the Console.

### Security

## [3.28.0] - unreleased
Expand Down
70 changes: 47 additions & 23 deletions pkg/webui/account/views/app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,15 @@

import { useSelector, useDispatch } from 'react-redux'
import React, { useEffect } from 'react'
import { Routes, Route, BrowserRouter } from 'react-router-dom'
import {
Routes,
Route,
BrowserRouter,
ScrollRestoration,
createBrowserRouter,
RouterProvider,
Outlet,
} from 'react-router-dom'
import { Helmet } from 'react-helmet'

import { ToastContainer } from '@ttn-lw/components/toast'
Expand All @@ -27,7 +35,6 @@ import Header from '@account/containers/header'
import Landing from '@account/views/landing'
import Authorize from '@account/views/authorize'

import PropTypes from '@ttn-lw/lib/prop-types'
import {
selectApplicationSiteName,
selectApplicationSiteTitle,
Expand All @@ -44,8 +51,34 @@ const siteTitle = selectApplicationSiteTitle()
const pageData = selectPageData()

const errorRender = error => <FullViewError error={error} header={<Header />} />
const getScrollRestorationKey = location => {
// Preserve scroll position only when necessary.
// E.g. we don't want to scroll to top when changing tabs of a table,
// but we do want to scroll to top when changing pages.
const { pathname, search } = location
const params = new URLSearchParams(search)
const page = params.get('page')

return `${pathname}${page ? `?page=${page}` : ''}`
}

const AccountApp = ({ history }) => {
const Layout = () => (
<>
<ScrollRestoration getKey={getScrollRestorationKey} />
<ToastContainer />
<ErrorView errorRender={errorRender}>
<React.Fragment>
<Helmet
titleTemplate={`%s - ${siteTitle ? `${siteTitle} - ` : ''}${siteName}`}
defaultTitle={`${siteTitle ? `${siteTitle} - ` : ''}${siteName}`}
/>
<Outlet />
</React.Fragment>
</ErrorView>
</>
)

const AccountRoot = () => {
const user = useSelector(selectUser)
const dispatch = useDispatch()

Expand All @@ -72,28 +105,19 @@ const AccountApp = ({ history }) => {
}

return (
<>
<ToastContainer />
<BrowserRouter history={history} basename="/oauth">
<ErrorView errorRender={errorRender}>
<React.Fragment>
<Helmet
titleTemplate={`%s - ${siteTitle ? `${siteTitle} - ` : ''}${siteName}`}
defaultTitle={`${siteTitle ? `${siteTitle} - ` : ''}${siteName}`}
/>
<Routes>
<Route path="/authorize/*" Component={Authorize} />
<Route path="*" Component={Boolean(user) ? Landing : Front} />
</Routes>
</React.Fragment>
</ErrorView>
</BrowserRouter>
</>
<Routes>
<Route element={<Layout />}>
<Route path="/authorize/*" Component={Authorize} />
<Route path="*" Component={Boolean(user) ? Landing : Front} />
</Route>
</Routes>
)
}

AccountApp.propTypes = {
history: PropTypes.history.isRequired,
}
const router = createBrowserRouter([{ path: '*', Component: AccountRoot }], {
basename: '/oauth',
})

const AccountApp = () => <RouterProvider router={router} />

export default AccountApp
22 changes: 19 additions & 3 deletions pkg/webui/console/views/app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@

import React, { useCallback, useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { Route, Routes, Outlet, createBrowserRouter, RouterProvider } from 'react-router-dom'
import {
Route,
Routes,
Outlet,
createBrowserRouter,
RouterProvider,
ScrollRestoration,
} from 'react-router-dom'
import classnames from 'classnames'

import { ToastContainer } from '@ttn-lw/components/toast'
Expand All @@ -25,7 +32,6 @@ import Footer from '@ttn-lw/containers/footer'
import GenericNotFound from '@ttn-lw/lib/components/full-view-error/not-found'
import IntlHelmet from '@ttn-lw/lib/components/intl-helmet'
import ErrorView from '@ttn-lw/lib/components/error-view'
import ScrollToTop from '@ttn-lw/lib/components/scroll-to-top'
import WithAuth from '@ttn-lw/lib/components/with-auth'
import FullViewError, { FullViewErrorInner } from '@ttn-lw/lib/components/full-view-error'

Expand Down Expand Up @@ -58,6 +64,16 @@ import {
import style from './app.styl'

const errorRender = error => <FullViewError error={error} header={<Header />} />
const getScrollRestorationKey = location => {
// Preserve scroll position only when necessary.
// E.g. we don't want to scroll to top when changing tabs of a table,
// but we do want to scroll to top when changing pages.
const { pathname, search } = location
const params = new URLSearchParams(search)
const page = params.get('page')

return `${pathname}${page ? `?page=${page}` : ''}`
}

const Layout = () => {
const user = useSelector(selectUser)
Expand All @@ -70,7 +86,7 @@ const Layout = () => {

return (
<>
<ScrollToTop />
<ScrollRestoration getKey={getScrollRestorationKey} />
<ErrorView errorRender={errorRender}>
<div className={style.app}>
<IntlHelmet
Expand Down
26 changes: 0 additions & 26 deletions pkg/webui/lib/components/scroll-to-top.js

This file was deleted.

0 comments on commit 997906e

Please sign in to comment.