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
94 changes: 78 additions & 16 deletions packages/twenty-front/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
import { Route, Routes, useLocation } from 'react-router-dom';
import { StrictMode } from 'react';
import {
createBrowserRouter,
createRoutesFromElements,
Outlet,
redirect,
Route,
RouterProvider,
Routes,
useLocation,
} from 'react-router-dom';
import { useRecoilValue } from 'recoil';

import { ApolloProvider } from '@/apollo/components/ApolloProvider';
import { VerifyEffect } from '@/auth/components/VerifyEffect';
import { ClientConfigProvider } from '@/client-config/components/ClientConfigProvider';
import { ClientConfigProviderEffect } from '@/client-config/components/ClientConfigProviderEffect';
import { billingState } from '@/client-config/states/billingState';
import { PromiseRejectionEffect } from '@/error-handler/components/PromiseRejectionEffect';
import { ApolloMetadataClientProvider } from '@/object-metadata/components/ApolloMetadataClientProvider';
import { ObjectMetadataItemsProvider } from '@/object-metadata/components/ObjectMetadataItemsProvider';
import { PrefetchDataProvider } from '@/prefetch/components/PrefetchDataProvider';
import { AppPath } from '@/types/AppPath';
import { SettingsPath } from '@/types/SettingsPath';
import { DialogManager } from '@/ui/feedback/dialog-manager/components/DialogManager';
import { DialogManagerScope } from '@/ui/feedback/dialog-manager/scopes/DialogManagerScope';
import { SnackBarProvider } from '@/ui/feedback/snack-bar-manager/components/SnackBarProvider';
import { BlankLayout } from '@/ui/layout/page/BlankLayout';
import { DefaultLayout } from '@/ui/layout/page/DefaultLayout';
import { AppThemeProvider } from '@/ui/theme/components/AppThemeProvider';
import { PageTitle } from '@/ui/utilities/page-title/PageTitle';
import { UserProvider } from '@/users/components/UserProvider';
import { UserProviderEffect } from '@/users/components/UserProviderEffect';
import { CommandMenuEffect } from '~/effect-components/CommandMenuEffect';
import { GotoHotkeysEffect } from '~/effect-components/GotoHotkeysEffect';
import { PageChangeEffect } from '~/effect-components/PageChangeEffect';
import { Authorize } from '~/pages/auth/Authorize';
import { ChooseYourPlan } from '~/pages/auth/ChooseYourPlan.tsx';
import { CreateProfile } from '~/pages/auth/CreateProfile';
Expand Down Expand Up @@ -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 = () => {
const { pathname } = useLocation();
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

const pageTitle = getPageTitleFromPath(pathname);

Comment on lines 82 to 83
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

return (
<>
<PageTitle title={pageTitle} />
<GotoHotkeysEffect />
<CommandMenuEffect />
<Routes>
<ApolloProvider>
<ClientConfigProviderEffect />
<ClientConfigProvider>
<UserProviderEffect />
<UserProvider>
<ApolloMetadataClientProvider>
<ObjectMetadataItemsProvider>
<PrefetchDataProvider>
<AppThemeProvider>
<SnackBarProvider>
<DialogManagerScope dialogManagerScopeId="dialog-manager">
<DialogManager>
<StrictMode>
<PromiseRejectionEffect />
<CommandMenuEffect />
<GotoHotkeysEffect />
<PageTitle title={pageTitle} />
<Outlet />
</StrictMode>
</DialogManager>
</DialogManagerScope>
</SnackBarProvider>
</AppThemeProvider>
</PrefetchDataProvider>
<PageChangeEffect />
</ObjectMetadataItemsProvider>
</ApolloMetadataClientProvider>
</UserProvider>
</ClientConfigProvider>
</ApolloProvider>
);
};

const createRouter = (isBillingEnabled?: boolean) =>
createBrowserRouter(
createRoutesFromElements(
<Route element={<ProvidersThatNeedRouterContext />}>
<Route element={<DefaultLayout />}>
<Route path={AppPath.Verify} element={<VerifyEffect />} />
<Route path={AppPath.SignInUp} element={<SignInUp />} />
Expand Down Expand Up @@ -117,12 +172,14 @@ export const App = () => {
path={SettingsPath.AccountsEmailsInboxSettings}
element={<SettingsAccountsEmailsInboxSettings />}
/>
{billing?.isBillingEnabled && (
<Route
path={SettingsPath.Billing}
element={<SettingsBilling />}
/>
)}
<Route
path={SettingsPath.Billing}
element={<SettingsBilling />}
loader={() => {
if (!isBillingEnabled) return redirect(AppPath.Index);
return null;
}}
/>
<Route
path={SettingsPath.WorkspaceMembersPage}
element={<SettingsWorkspaceMembers />}
Expand Down Expand Up @@ -210,7 +267,12 @@ export const App = () => {
<Route element={<BlankLayout />}>
<Route path={AppPath.Authorize} element={<Authorize />} />
</Route>
</Routes>
</>
</Route>,
),
);

export const App = () => {
const billing = useRecoilValue(billingState);

return <RouterProvider router={createRouter(billing?.isBillingEnabled)} />;
};
62 changes: 9 additions & 53 deletions packages/twenty-front/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,13 @@
import { StrictMode } from 'react';
import ReactDOM from 'react-dom/client';
import { HelmetProvider } from 'react-helmet-async';
import { BrowserRouter } from 'react-router-dom';
import { RecoilRoot } from 'recoil';
import { IconsProvider } from 'twenty-ui';

import { ApolloProvider } from '@/apollo/components/ApolloProvider';
import { ClientConfigProvider } from '@/client-config/components/ClientConfigProvider';
import { ClientConfigProviderEffect } from '@/client-config/components/ClientConfigProviderEffect';
import { ApolloDevLogEffect } from '@/debug/components/ApolloDevLogEffect';
import { RecoilDebugObserverEffect } from '@/debug/components/RecoilDebugObserver';
import { AppErrorBoundary } from '@/error-handler/components/AppErrorBoundary';
import { ExceptionHandlerProvider } from '@/error-handler/components/ExceptionHandlerProvider';
import { PromiseRejectionEffect } from '@/error-handler/components/PromiseRejectionEffect';
import { ApolloMetadataClientProvider } from '@/object-metadata/components/ApolloMetadataClientProvider';
import { ObjectMetadataItemsProvider } from '@/object-metadata/components/ObjectMetadataItemsProvider';
import { PrefetchDataProvider } from '@/prefetch/components/PrefetchDataProvider';
import { DialogManager } from '@/ui/feedback/dialog-manager/components/DialogManager';
import { DialogManagerScope } from '@/ui/feedback/dialog-manager/scopes/DialogManagerScope';
import { SnackBarProvider } from '@/ui/feedback/snack-bar-manager/components/SnackBarProvider';
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
import { AppThemeProvider } from '@/ui/theme/components/AppThemeProvider';
import { UserProvider } from '@/users/components/UserProvider';
import { UserProviderEffect } from '@/users/components/UserProviderEffect';
import { PageChangeEffect } from '~/effect-components/PageChangeEffect';

import '@emotion/react';

Expand All @@ -41,43 +25,15 @@ root.render(
<AppErrorBoundary>
<RecoilDebugObserverEffect />
<ApolloDevLogEffect />
<BrowserRouter>
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
<IconsProvider>
<ExceptionHandlerProvider>
<ApolloProvider>
<HelmetProvider>
<ClientConfigProviderEffect />
<ClientConfigProvider>
<UserProviderEffect />
<UserProvider>
<ApolloMetadataClientProvider>
<ObjectMetadataItemsProvider>
<PrefetchDataProvider>
<AppThemeProvider>
<SnackBarProvider>
<DialogManagerScope dialogManagerScopeId="dialog-manager">
<DialogManager>
<StrictMode>
<PromiseRejectionEffect />
<App />
</StrictMode>
</DialogManager>
</DialogManagerScope>
</SnackBarProvider>
</AppThemeProvider>
</PrefetchDataProvider>
<PageChangeEffect />
</ObjectMetadataItemsProvider>
</ApolloMetadataClientProvider>
</UserProvider>
</ClientConfigProvider>
</HelmetProvider>
</ApolloProvider>
</ExceptionHandlerProvider>
</IconsProvider>
</SnackBarProviderScope>
</BrowserRouter>
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
<IconsProvider>
<ExceptionHandlerProvider>
<HelmetProvider>
<App />
</HelmetProvider>
</ExceptionHandlerProvider>
</IconsProvider>
</SnackBarProviderScope>
</AppErrorBoundary>
</RecoilRoot>,
);