Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement <ScrollRestoration /> #5086

Merged
merged 12 commits into from May 17, 2024
Merged

Implement <ScrollRestoration /> #5086

merged 12 commits into from May 17, 2024

Conversation

gitstart-app[bot]
Copy link
Contributor

@gitstart-app gitstart-app bot commented Apr 22, 2024

Description

Implement <ScrollRestoration />

Refs

https://github.com/twentyhq/twenty/issues/4357

Demo

scroll.restoration.mp4

Fixes #4357

@gitstart-twenty
Copy link
Contributor

gitstart-twenty commented Apr 22, 2024

Hey @FelixMalfait

In order to use ScrollRestoration we'd need to switch to createBrowserRouter. This means components outside the routes do not have access to react-router-dom hooks. These components include the various providers in App.tsx, some of which use useNavigate or useLocation. I've created custom versions of these hooks that use history to be used outside the router, please check if these initial changes make sense

@FelixMalfait
Copy link
Member

FelixMalfait commented Apr 22, 2024

Hey @gitstart-twenty ; switching to createBrowserRouter is the right path.

But are you sure the hooks don't work any more?
https://reactrouter.com/en/main/upgrading/v6-data
Screenshot 2024-04-22 at 13 58 31

It seems that they should work (they introduce other hooks like useNavigation, useMatches but don't deprecate others)

You should not directly access history imo, this feels like a bad direction

I would try to stay as close to the upgrade-guide as possible

@gitstart-twenty
Copy link
Contributor

Hey @FelixMalfait,

I think there has been a misunderstanding, allow me clarify on some things.

The hooks still function as expected for components nested within the routes. However, the providers located outside the routes lack access to the react-router-dom context. Previously, we addressed this by wrapping them in BrowserRouter. However, with createBrowserRouter, we have to make a switch to RouterProvider, which does not accept children. Consequently, the previous solution is no longer viable.

For providers situated outside the routes, we'll need to find an alternative method for accessing router-related functionality, as the hooks from react-router won't be available(which is what this PR does).

To sum up, both the old and new hooks(introduced in v6.4) still function inside the routes as usual. The changes outlined in this PR address the necessary modifications to ensure that the providers continue to function correctly, even without the react-router context.

Comment on lines 80 to 81
const { pathname } = useLocation();
const pageTitle = getPageTitleFromPath(pathname);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs react-router context, put under pathless route

@@ -52,17 +76,48 @@ import { SettingsWorkspaceMembers } from '~/pages/settings/SettingsWorkspaceMemb
import { Tasks } from '~/pages/tasks/Tasks';
import { getPageTitleFromPath } from '~/utils/title-utils';

export const App = () => {
const billing = useRecoilValue(billingState);
const ProvidersThatNeedRouterContext = () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need react-router context, put under pathless route with Outlet

@lucasbordeau
Copy link
Contributor

@gitstart-twenty Seems ok for me, do you anything else to move forward ?

@gitstart-twenty
Copy link
Contributor

@gitstart-twenty Seems ok for me, do you anything else to move forward ?

Just needed that green light 🚦

@lucasbordeau lucasbordeau self-assigned this May 1, 2024
@gitstart-twenty
Copy link
Contributor

Hey @lucasbordeau,

Using createBrowserRouter won't suffice because it relies on the scroll position of the page, whereas our focus is on the scroll position of the table(s). Would it be more practical if we stored the table scroll positions, perhaps in state (maybe using recoil), and retrieved them from there upon returning to the page(s)?

cc @FelixMalfait

@FelixMalfait
Copy link
Member

@gitstart-twenty It's nice that you did the migration to data BrowserRouter since we'll have to do it at some point any way so let's get it to the end.

For scrollRestoration on tables (which is what matters most) we'll have to do something custom indeed :(
See remix-run/react-router#10468 (comment)

It will be nicer once we have this implemented #4914

cc @lucasbordeau

@gitstart-twenty
Copy link
Contributor

@gitstart-twenty It's nice that you did the migration to data BrowserRouter since we'll have to do it at some point any way so let's get it to the end.

For scrollRestoration on tables (which is what matters most) we'll have to do something custom indeed :( See remix-run/react-router#10468 (comment)

It will be nicer once we have this implemented #4914

cc @lucasbordeau

@FelixMalfait This is interesting! Looking into it

@FelixMalfait
Copy link
Member

@gitstart-twenty not much interesting in the code itself because it's a basic poc we need to adapt it to our codebase (@lucasbordeau would know best) the most interesting part is that they also came to the conclusion that it wasn't possible... Thanks!

@gitstart-twenty
Copy link
Contributor

@gitstart-twenty not much interesting in the code itself because it's a basic poc we need to adapt it to our codebase (@lucasbordeau would know best) the most interesting part is that they also came to the conclusion that it wasn't possible... Thanks!

Of course! Thanks for the update

@lucasbordeau
Copy link
Contributor

Seems like a custom implementation with session storage is the way to go !

@lucasbordeau
Copy link
Contributor

lucasbordeau commented May 15, 2024

@gitstart-twenty We talked about the implementation, here's the guidelines :

  • We don't want to restore scrolling if someone refreshes the page, so maybe session storage is overkill and recoil is enough.
  • We have to know if we can actually restore the scroll, due to lazy loading. If the scroll is located on edges page 10, at node 290, and we change page but the table resets its pagination state and we only have 30 nodes, we don't want to scroll to node 290, nor load more 10 times to have the 290th node.

@gitstart-twenty
Copy link
Contributor

gitstart-twenty commented May 15, 2024

Hey @lucasbordeau

We have to know if we can actually restore the scroll, due to lazy loading. If the scroll is located on edges page 10, at node 290, and we change page but the table resets its pagination state and we only have 30 nodes, we don't want to scroll to node 290, nor load more 10 times to have the 290th node.
We're having a challenge, the scroll needs to be triggered after the rows are visible (scrollable). What do you think is the best approach here?

How do we plan on achieving this? Should we limit the amount of scroll possible (maybe not bigger than the screen height)?

gitstart-twenty and others added 2 commits May 15, 2024 14:32
Co-authored-by: v1b3m <vibenjamin6@gmail.com>
Co-authored-by: RubensRafael <rubensrafael2@live.com>
@lucasbordeau
Copy link
Contributor

We shouldn't scroll if scroll item index > number of items in the table.

gitstart-twenty and others added 2 commits May 16, 2024 11:02
Co-authored-by: v1b3m <vibenjamin6@gmail.com>
Co-authored-by: RubensRafael <rubensrafael2@live.com>
@gitstart-twenty gitstart-twenty marked this pull request as ready for review May 16, 2024 11:31
@gitstart-twenty
Copy link
Contributor

We shouldn't scroll if scroll item index > number of items in the table.

Alright!

Copy link
Contributor

@lucasbordeau lucasbordeau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works fine and covers the use case we have we show page / table navigation !

} else if (state === 'idle' && isDefined(scrollWrapper) && !skip) {
scrollWrapper.scrollTo({ top: scrollPosition });
}
// eslint-disable-next-line react-hooks/exhaustive-deps
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't deactivate this rule, this is a code smell.

gitstart-twenty and others added 2 commits May 17, 2024 14:19
Co-authored-by: v1b3m <vibenjamin6@gmail.com>
Co-authored-by: RubensRafael <rubensrafael2@live.com>
@lucasbordeau lucasbordeau merged commit 0e525ca into main May 17, 2024
11 of 12 checks passed
@lucasbordeau lucasbordeau deleted the TWNTY-4357 branch May 17, 2024 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement <ScrollRestoration />
3 participants