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

[BC Break] Add support mounting admin inside a sub path #7100

Merged
merged 39 commits into from
Jan 19, 2022
Merged

[BC Break] Add support mounting admin inside a sub path #7100

merged 39 commits into from
Jan 19, 2022

Conversation

fzaninotto
Copy link
Member

@fzaninotto fzaninotto commented Jan 17, 2022

Problems

React-router v6 doesn't support nesting routers. So it will break for users who use react-router to mount the admin in a sub path (e.g. "admin").

The way react-admin v3 used to support sub path relied on passing the basePath everywhere, which is not very good DX.

We need to reintroduce the ability to mount react-admin in a sub path, without using basePath.

Use case

const App = () => (
    <BrowserRouter>
        <Routes>
            <Route
                path="/admin/*"
                element={
                    <Admin dataProvider={dataProvider} basename="/admin">
                        <Resource name="posts" {...posts} />
                        <Resource name="comments" {...comments} />
                    </Admin>
                }
            />
        </Routes>
    </BrowserRouter>,
);

Solution

  • Do not add a Router if the app mounts inside an existing router
  • Add a BasenameContext to support passing a custom basename
  • Update link generation to take into account the basename context
  • Fix useRedirect
  • Fix Buttons (Show, Edit, Create, List, Clone)
  • Fix Tab routing (TabbedForm, TabbedShowLayout)
  • Fix Menu routing (MenuItemLink, Menu, DashboardMenu
  • Fix List iterator routing (Datagrid, SingleFieldList, SimpleList)
  • Fix Reference routing (ReferenceField, ReferenceOneField)
  • Fix custom links in simple demo (not in other demos, which aren't supposed to be mounted inside another router)
  • Add tests & stories
  • Fix tests
  • Add routing doc chapter
  • [BC Break] Remove basePath prop everywhere
  • Write upgrade guide

@fzaninotto fzaninotto added the WIP Work In Progress label Jan 17, 2022
@fzaninotto fzaninotto added this to the 4.0.0-alpha.2 milestone Jan 17, 2022
@fzaninotto fzaninotto mentioned this pull request Jan 17, 2022
@fzaninotto fzaninotto changed the title Add support mounting admin unside a sub path [BC Break] Add support mounting admin unside a sub path Jan 17, 2022
@vercel vercel bot temporarily deployed to Preview – react-admin January 17, 2022 16:55 Inactive
@vercel vercel bot temporarily deployed to Preview – react-admin January 17, 2022 17:00 Inactive
import { useInRouterContext } from 'react-router-dom';
import { History } from 'history';

import { HistoryRouter } from './HistoryRouter';
Copy link
Member Author

Choose a reason for hiding this comment

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

I upgraded react-router to 6.1 to get their new HistoryRouter, but they've made in "unstable" in v6.1.1, so we still need to use our own.

@@ -38,8 +38,8 @@
"react-dom": "^17.0.0",
"react-final-form": "^6.5.7",
"react-redux": "^7.1.0",
"react-router": "^6.0.2",
Copy link
Member Author

Choose a reason for hiding this comment

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

This change is not necessary - I wanted their HistoryRouter but the've hidden it behind an "unstable" flag.

Copy link
Collaborator

Choose a reason for hiding this comment

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

As previously mentionned, there's v6.2.1 now: https://github.com/remix-run/react-router/releases

@@ -476,16 +476,16 @@ And now you can use a regular Field component, and the label displays correctly

### Linking To Other Records

A custom Field component might need to display a link to another record. React Admin provides a `linkToRecord(basePath, id[, linkType])` method for this purpose.
A custom Field component might need to display a link to another record. Build the URL to the distant record using the resource name and the id, as follows:
Copy link
Member Author

@fzaninotto fzaninotto Jan 17, 2022

Choose a reason for hiding this comment

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

Probably a good time to introduce useCreateInternalLink

packages/ra-core/src/routing/useCreateInternalLink.ts Outdated Show resolved Hide resolved
examples/crm/src/companies/CompanyCard.tsx Outdated Show resolved Hide resolved
@@ -3,11 +3,9 @@ import FieldTitle, { FieldTitleProps } from './FieldTitle';
import getFetchedAt from './getFetchedAt';
import getFieldLabelTranslationArgs from './getFieldLabelTranslationArgs';
import ComponentPropType from './ComponentPropType';
import linkToRecord from './linkToRecord';
Copy link
Member Author

Choose a reason for hiding this comment

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

moved to the routing directory

packages/ra-core/src/routing/useCreateInternalLink.ts Outdated Show resolved Hide resolved
@@ -1,11 +0,0 @@
import * as React from 'react';
Copy link
Member Author

Choose a reason for hiding this comment

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

useless component: LoadingPage is already set as default prop in AdminUI

@vercel vercel bot temporarily deployed to Preview – react-admin January 17, 2022 17:34 Inactive
@fzaninotto fzaninotto changed the title [BC Break] Add support mounting admin unside a sub path [BC Break] Add support mounting admin inside a sub path Jan 17, 2022
@wattroll
Copy link
Contributor

wattroll commented Jan 17, 2022

Looks great. I was setting up my own AdminContext to use BrowserRouter (passing history: createBrowserHistory() wasn't working for some reason). So apart from subpath mounting, this will bring a smooth way of changing the default router. Thanks.


Is history and HistoryRouter still needed per-se? From what I understood the main need for it came from using react-connected-router which isn't used anymore. Of course it's a question of BC breakage (as history is a prop of Admin), but it won't be big breakage if the fix is to just wrap Admin with HistoryRouter { history } or straight up with the preferred Router implementation.


Should the docs provide advice to switch away from HashRouter? I totally understand it being the default to facilitate getting started quickly, but e.g. react-router docs say "We strongly recommend you do not use HashRouter unless you absolutely have to.".

@vercel vercel bot temporarily deployed to Preview – react-admin January 17, 2022 19:53 Inactive
Copy link
Collaborator

@djhi djhi left a comment

Choose a reason for hiding this comment

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

Neat! This is so much better 💪

UPGRADE.md Outdated Show resolved Hide resolved
Comment on lines +21 to +22
"react-router": "^6.1.0",
"react-router-dom": "^6.1.0",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Comment on lines +37 to +38
"react-router": "^6.1.0",
"react-router-dom": "^6.1.0",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Comment on lines +31 to +32
"react-router": "^6.1.0",
"react-router-dom": "^6.1.0"
Copy link
Collaborator

Choose a reason for hiding this comment

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

@@ -38,8 +38,8 @@
"react-dom": "^17.0.0",
"react-final-form": "^6.5.7",
"react-redux": "^7.1.0",
"react-router": "^6.0.2",
Copy link
Collaborator

Choose a reason for hiding this comment

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

As previously mentionned, there's v6.2.1 now: https://github.com/remix-run/react-router/releases

Comment on lines +1 to +12
/**
* @deprecated use useCreatePath instead
*/
export const linkToRecord = (resource, id, linkType = 'edit') => {
const link = `${resource}/${encodeURIComponent(id)}`;

if (linkType === 'show') {
return `${link}/show`;
}

return link;
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should be deprecated in next v3 and removed here

Copy link
Member Author

Choose a reason for hiding this comment

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

We don't need to remove it here - it would force an even longer upgrade.

It's just not used anymore, and doesn't do any harm until v5.

import { To } from 'react-router-dom';

/**
* @deprecated use useCreatePath instead
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same

Copy link
Member Author

Choose a reason for hiding this comment

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

Same answer: we don't remove it to avoid a more painful upgrade.

Comment on lines +33 to +34
"react-router": "^6.1.0",
"react-router-dom": "^6.1.0",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same, more recent version available

Comment on lines +40 to +41
"react-router": "^6.1.0",
"react-router-dom": "^6.1.0",
Copy link
Collaborator

Choose a reason for hiding this comment

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

There too

Comment on lines +46 to +47
"react-router": "^6.1.0",
"react-router-dom": "^6.1.0",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Again

UPGRADE.md Outdated Show resolved Hide resolved
Copy link
Contributor

@WiXSL WiXSL left a comment

Choose a reason for hiding this comment

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

Impressive work!
I couldn't been able to find problems 💪

@fzaninotto
Copy link
Member Author

@djhi Let's upgrade the packages to their latest version in another PR (and rather at the end of the 4.0 roadmap), to avoid multiple rebases due to yarn.lock conflicts.

@fzaninotto
Copy link
Member Author

@wattroll

Is history and HistoryRouter still needed per-se? From what I understood the main need for it came from using react-connected-router which isn't used anymore. Of course it's a question of BC breakage (as history is a prop of Admin), but it won't be big breakage if the fix is to just wrap Admin with HistoryRouter { history } or straight up with the preferred Router implementation.

No, <Admin history> is no longer necessary, but we don't need to remove it. I've marked it as deprecated.

Should the docs provide advice to switch away from HashRouter? I totally understand it being the default to facilitate getting started quickly, but e.g. react-router docs say "We strongly recommend you do not use HashRouter unless you absolutely have to.".

I added a section about it, see Routing.md

@djhi djhi merged commit 6814f34 into next Jan 19, 2022
@djhi djhi deleted the basename branch January 19, 2022 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFR Ready For Review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants