[shared-ux-router] Add Router and Routes components (#159834)

## Summary

Why?

To simplify the process of migration to react-router@6.
https://github.com/remix-run/react-router/discussions/8753

What problems exactly it solves?

- In my previous PR I added `CompatRouter`
https://github.com/elastic/kibana/pull/159173, which caused changes in
~50 files and pinged 15 Teams. And this is just meant to be a temporary
change, so when we're done with the migration I would have to revert
these changes and engage everyone to review the PR again. And it is just
a single step in the migration strategy. So to make our lives easier I
think it would be better to have a common place where we do import our
router components because it will allow us to surface some extra logic
in single place instead of going through the whole source code again.

- `react-router@6` doesn't support a custom `Route` component, so that
means our custom `Route` component that we're using almost everywhere
today, will need to be replaced by a different solution. I have decided
to add `Routes` component, which will be responsible for rendering the
proper component (`react-router@6` renamed `Switch` to `Routes`, so I
have named this component to align with the dictionary of the new
router) and also is going to add the logic that today is done in `Route`
(moving logic to `Routes` will be done in the follow-up PR, here I just
wanted to focus on using the common router components to make the review
process easier)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Patryk Kopyciński 2023-06-23 17:02:06 +02:00 committed by GitHub
parent bb3aa54c86
commit a1d02824f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
274 changed files with 2130 additions and 2506 deletions

View file

@ -245,7 +245,7 @@ const RESTRICTED_IMPORTS = [
},
{
name: 'react-router-dom',
importNames: ['Route'],
importNames: ['Router', 'Switch', 'Route'],
message: 'Please use @kbn/shared-ux-router instead',
},
{

View file

@ -7,9 +7,8 @@
*/
import React from 'react';
import { BrowserRouter as Router, Redirect, Switch } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Route } from '@kbn/shared-ux-router';
import { Redirect } from 'react-router-dom';
import { BrowserRouter as Router, Route, Routes } from '@kbn/shared-ux-router';
import { EuiPage } from '@elastic/eui';
import { useDeps } from '../../hooks/use_deps';
import { Sidebar } from './sidebar';
@ -27,15 +26,13 @@ export const App: React.FC = () => {
return (
<Router basename={appBasePath}>
<CompatRouter>
<EuiPage>
<Sidebar />
<Switch>
{routeElements}
<Redirect to="/count-until" />
</Switch>
</EuiPage>
</CompatRouter>
<EuiPage>
<Sidebar />
<Routes>
{routeElements}
<Redirect to="/count-until" />
</Routes>
</EuiPage>
</Router>
);
};

View file

@ -8,9 +8,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
// eslint-disable-next-line no-restricted-imports
import { Router, Switch, Route, Redirect } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Redirect } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
import { EuiPageTemplate, EuiSideNav } from '@elastic/eui';
import { AppMountParameters, CoreStart } from '@kbn/core/public';
@ -25,52 +24,50 @@ export const renderApp = (
) => {
ReactDOM.render(
<Router history={history}>
<CompatRouter>
<RedirectAppLinks coreStart={core}>
<EuiPageTemplate offset={0}>
<EuiPageTemplate.Sidebar>
<EuiSideNav
items={[
{
id: 'Examples',
name: 'Examples',
items: [
{
id: 'todos',
name: 'Todo app',
'data-test-subj': 'todosExample',
href: '/app/contentManagementExamples/todos',
},
{
id: 'msearch',
name: 'MSearch',
'data-test-subj': 'msearchExample',
href: '/app/contentManagementExamples/msearch',
},
],
},
]}
/>
</EuiPageTemplate.Sidebar>
<RedirectAppLinks coreStart={core}>
<EuiPageTemplate offset={0}>
<EuiPageTemplate.Sidebar>
<EuiSideNav
items={[
{
id: 'Examples',
name: 'Examples',
items: [
{
id: 'todos',
name: 'Todo app',
'data-test-subj': 'todosExample',
href: '/app/contentManagementExamples/todos',
},
{
id: 'msearch',
name: 'MSearch',
'data-test-subj': 'msearchExample',
href: '/app/contentManagementExamples/msearch',
},
],
},
]}
/>
</EuiPageTemplate.Sidebar>
<EuiPageTemplate.Section>
<Switch>
<Redirect from="/" to="/todos" exact />
<Route path="/todos">
<TodoApp contentClient={contentManagement.client} />
</Route>
<Route path="/msearch">
<MSearchApp
contentClient={contentManagement.client}
core={core}
savedObjectsTagging={savedObjectsTaggingOss}
/>
</Route>
</Switch>
</EuiPageTemplate.Section>
</EuiPageTemplate>
</RedirectAppLinks>
</CompatRouter>
<EuiPageTemplate.Section>
<Routes>
<Redirect from="/" to="/todos" exact />
<Route path="/todos">
<TodoApp contentClient={contentManagement.client} />
</Route>
<Route path="/msearch">
<MSearchApp
contentClient={contentManagement.client}
core={core}
savedObjectsTagging={savedObjectsTaggingOss}
/>
</Route>
</Routes>
</EuiPageTemplate.Section>
</EuiPageTemplate>
</RedirectAppLinks>
</Router>,
element
);

View file

@ -28,5 +28,6 @@
"@kbn/core-saved-objects-api-browser",
"@kbn/content-management-table-list-view-table",
"@kbn/content-management-table-list-view",
"@kbn/shared-ux-router",
]
}

View file

@ -9,7 +9,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, withRouter, RouteComponentProps } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Route } from '@kbn/shared-ux-router';
import { EuiPage, EuiPageSideBar_Deprecated as EuiPageSideBar, EuiSideNav } from '@elastic/eui';
@ -127,14 +126,12 @@ const EmbeddableExplorerApp = ({
return (
<Router basename={basename}>
<CompatRouter>
<EuiPage>
<EuiPageSideBar>
<Nav navigateToApp={navigateToApp} pages={pages} />
</EuiPageSideBar>
{routes}
</EuiPage>
</CompatRouter>
<EuiPage>
<EuiPageSideBar>
<Nav navigateToApp={navigateToApp} pages={pages} />
</EuiPageSideBar>
{routes}
</EuiPage>
</Router>
);
};

View file

@ -8,12 +8,8 @@
import React from 'react';
import { FormattedMessage, I18nProvider } from '@kbn/i18n-react';
import { Router, Switch } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Router, Route } from '@kbn/shared-ux-router';
import { EuiPageTemplate } from '@elastic/eui';
import { CoreStart, ScopedHistory } from '@kbn/core/public';
import { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public/types';
@ -46,25 +42,23 @@ export const GuidedOnboardingExampleApp = (props: GuidedOnboardingExampleAppDeps
{guidedOnboarding.guidedOnboardingApi?.isEnabled ? (
<EuiPageTemplate.Section>
<Router history={history}>
<CompatRouter>
<Switch>
<Route exact path="/">
<Main notifications={notifications} guidedOnboarding={guidedOnboarding} />
</Route>
<Route exact path="/stepOne">
<StepOne guidedOnboarding={guidedOnboarding} />
</Route>
<Route exact path="/stepTwo">
<StepTwo />
</Route>
<Route exact path="/stepThree">
<StepThree guidedOnboarding={guidedOnboarding} />
</Route>
<Route path="/stepFour/:indexName?">
<StepFour guidedOnboarding={guidedOnboarding} />
</Route>
</Switch>
</CompatRouter>
<Routes>
<Route exact path="/">
<Main notifications={notifications} guidedOnboarding={guidedOnboarding} />
</Route>
<Route exact path="/stepOne">
<StepOne guidedOnboarding={guidedOnboarding} />
</Route>
<Route exact path="/stepTwo">
<StepTwo />
</Route>
<Route exact path="/stepThree">
<StepThree guidedOnboarding={guidedOnboarding} />
</Route>
<Route path="/stepFour/:indexName?">
<StepFour guidedOnboarding={guidedOnboarding} />
</Route>
</Routes>
</Router>
</EuiPageTemplate.Section>
) : (

View file

@ -12,8 +12,8 @@ import ReactDOM from 'react-dom';
import { EuiPageBody } from '@elastic/eui';
import { EuiPageContent_Deprecated as EuiPageContent } from '@elastic/eui';
import { EuiPageContentBody_Deprecated as EuiPageContentBody } from '@elastic/eui';
import { Switch, Redirect, Router, useLocation } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Redirect, useLocation } from 'react-router-dom';
import { Router, Routes as RouterRoutes, Route } from '@kbn/shared-ux-router';
import { createBrowserHistory } from 'history';
import { EuiText } from '@elastic/eui';
import { AppMountParameters } from '@kbn/core/public';
@ -40,7 +40,7 @@ export const Routes: React.FC<{}> = () => {
<EuiPageBody>
<EuiPageContent>
<EuiPageContentBody>
<Switch>
<RouterRoutes>
<Route path="/hello">
<HelloPage
firstName={query.get('firstName') || ''}
@ -48,7 +48,7 @@ export const Routes: React.FC<{}> = () => {
/>
</Route>
<Redirect from="/" to="/hello" />
</Switch>
</RouterRoutes>
</EuiPageContentBody>
</EuiPageContent>
</EuiPageBody>

View file

@ -9,10 +9,8 @@
import ReactDOM from 'react-dom';
import React, { useMemo } from 'react';
import { useAsync } from 'react-use/lib';
import { Router, Redirect, Switch } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Route } from '@kbn/shared-ux-router';
import { Redirect } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { AppMountParameters } from '@kbn/core/public';
import { EuiButton, EuiCallOut, EuiSpacer } from '@elastic/eui';
import { DashboardListingTable } from '@kbn/dashboard-plugin/public';
@ -50,19 +48,17 @@ const PortableDashboardsDemos = ({
}) => {
return (
<Router history={history}>
<CompatRouter>
<Switch>
<Route exact path="/">
<Redirect to={DASHBOARD_DEMO_PATH} />
</Route>
<Route path={DASHBOARD_LIST_PATH}>
<PortableDashboardListingDemo history={history} />
</Route>
<Route path={DASHBOARD_DEMO_PATH}>
<DashboardsDemo data={data} dashboard={dashboard} history={history} />
</Route>
</Switch>
</CompatRouter>
<Routes>
<Route exact path="/">
<Redirect to={DASHBOARD_DEMO_PATH} />
</Route>
<Route path={DASHBOARD_LIST_PATH}>
<PortableDashboardListingDemo history={history} />
</Route>
<Route path={DASHBOARD_DEMO_PATH}>
<DashboardsDemo data={data} dashboard={dashboard} history={history} />
</Route>
</Routes>
</Router>
);
};

View file

@ -7,9 +7,8 @@
*/
import React from 'react';
import { BrowserRouter as Router, Redirect, Switch } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Route } from '@kbn/shared-ux-router';
import { Redirect } from 'react-router-dom';
import { BrowserRouter as Router, Routes, Route } from '@kbn/shared-ux-router';
import { EuiPage } from '@elastic/eui';
import { useDeps } from '../../hooks/use_deps';
import { Sidebar } from './sidebar';
@ -27,15 +26,13 @@ export const App: React.FC = () => {
return (
<Router basename={appBasePath}>
<CompatRouter>
<EuiPage>
<Sidebar />
<Switch>
{routeElements}
<Redirect to="/simple-string-stream" />
</Switch>
</EuiPage>
</CompatRouter>
<EuiPage>
<Sidebar />
<Routes>
{routeElements}
<Redirect to="/simple-string-stream" />
</Routes>
</EuiPage>
</Router>
);
};

View file

@ -7,8 +7,7 @@
*/
import React, { useEffect } from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { BrowserRouter as Router } from '@kbn/shared-ux-router';
import { FormattedMessage, I18nProvider } from '@kbn/i18n-react';
import {
@ -63,63 +62,61 @@ export const ScreenshotModeExampleApp = ({
}, [isScreenshotMode, notifications, http]);
return (
<Router basename={basename}>
<CompatRouter>
<I18nProvider>
<>
<navigation.ui.TopNavMenu
appName={PLUGIN_NAME}
showSearchBar={true}
useDefaultBehaviors={true}
/>
<EuiPage restrictWidth="1000px">
<EuiPageBody>
<EuiPageHeader>
<EuiTitle size="l">
<h1>
<FormattedMessage
id="screenshotModeExample.helloWorldText"
defaultMessage="{name}"
values={{ name: PLUGIN_NAME }}
/>
</h1>
</EuiTitle>
</EuiPageHeader>
<EuiPageContent>
<EuiPageContentHeader>
<EuiTitle>
<h2>
{isScreenshotMode ? (
<FormattedMessage
id="screenshotModeExample.screenshotModeTitle"
defaultMessage="We are in screenshot mode!"
/>
) : (
<FormattedMessage
id="screenshotModeExample.normalModeTitle"
defaultMessage="We are not in screenshot mode!"
/>
)}
</h2>
</EuiTitle>
</EuiPageContentHeader>
<EuiPageContentBody>
<EuiText>
<I18nProvider>
<>
<navigation.ui.TopNavMenu
appName={PLUGIN_NAME}
showSearchBar={true}
useDefaultBehaviors={true}
/>
<EuiPage restrictWidth="1000px">
<EuiPageBody>
<EuiPageHeader>
<EuiTitle size="l">
<h1>
<FormattedMessage
id="screenshotModeExample.helloWorldText"
defaultMessage="{name}"
values={{ name: PLUGIN_NAME }}
/>
</h1>
</EuiTitle>
</EuiPageHeader>
<EuiPageContent>
<EuiPageContentHeader>
<EuiTitle>
<h2>
{isScreenshotMode ? (
<p>We detected screenshot mode. The chrome navbar should be hidden.</p>
<FormattedMessage
id="screenshotModeExample.screenshotModeTitle"
defaultMessage="We are in screenshot mode!"
/>
) : (
<p>
This is how the app looks in normal mode. The chrome navbar should be
visible.
</p>
<FormattedMessage
id="screenshotModeExample.normalModeTitle"
defaultMessage="We are not in screenshot mode!"
/>
)}
</EuiText>
</EuiPageContentBody>
</EuiPageContent>
</EuiPageBody>
</EuiPage>
</>
</I18nProvider>
</CompatRouter>
</h2>
</EuiTitle>
</EuiPageContentHeader>
<EuiPageContentBody>
<EuiText>
{isScreenshotMode ? (
<p>We detected screenshot mode. The chrome navbar should be hidden.</p>
) : (
<p>
This is how the app looks in normal mode. The chrome navbar should be
visible.
</p>
)}
</EuiText>
</EuiPageContentBody>
</EuiPageContent>
</EuiPageBody>
</EuiPage>
</>
</I18nProvider>
</Router>
);
};

View file

@ -22,5 +22,6 @@
"@kbn/developer-examples-plugin",
"@kbn/analytics",
"@kbn/i18n-react",
"@kbn/shared-ux-router",
]
}

View file

@ -8,9 +8,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Redirect } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Route } from '@kbn/shared-ux-router';
import { Redirect } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { I18nProvider } from '@kbn/i18n-react';
import { AppMountParameters, CoreStart } from '@kbn/core/public';
import { RedirectAppLinks } from '@kbn/kibana-react-plugin/public';
@ -49,7 +48,7 @@ export const renderApp = (
<RedirectAppLinks application={application}>
<SearchExamplePage exampleLinks={LINKS} basePath={http.basePath}>
<Router history={history}>
<CompatRouter>
<Routes>
<Route path={LINKS[0].path}>
<SearchExamplesApp
notifications={notifications}
@ -74,7 +73,7 @@ export const renderApp = (
<Route path="/" exact={true}>
<Redirect to={LINKS[0].path} />
</Route>
</CompatRouter>
</Routes>
</Router>
</SearchExamplePage>
</RedirectAppLinks>

View file

@ -7,9 +7,8 @@
*/
import React, { useEffect, useMemo } from 'react';
import { Link, Router, Switch, useLocation } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Route } from '@kbn/shared-ux-router';
import { Link, useLocation } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { History } from 'history';
import {
EuiButton,
@ -186,59 +185,57 @@ export const TodoAppPage: React.FC<{
return (
<Router history={props.history}>
<CompatRouter>
<EuiPageBody>
<EuiPageHeader>
<EuiPageHeaderSection>
<EuiTitle size="l">
<h1>{props.appTitle}</h1>
</EuiTitle>
<EuiSpacer />
<EuiText>
<p>
This is a simple TODO app that uses state containers and state syncing utils. It
stores state in the URL similar like Discover or Dashboard apps do. <br />
Play with the app and see how the state is persisted in the URL.
<br /> Undo/Redo with browser history also works.
</p>
</EuiText>
</EuiPageHeaderSection>
</EuiPageHeader>
<EuiPageContent>
<EuiPageContentBody>
<Switch>
<Route path={'/completed'}>
<TodoApp filter={'completed'} stateContainer={stateContainer} />
</Route>
<Route path={'/not-completed'}>
<TodoApp filter={'not-completed'} stateContainer={stateContainer} />
</Route>
<Route path={'/'}>
<TodoApp filter={null} stateContainer={stateContainer} />
</Route>
</Switch>
<EuiSpacer size={'xxl'} />
<EuiText size={'s'}>
<p>Most of kibana apps persist state in the URL in two ways:</p>
<ol>
<li>Expanded state in rison format</li>
<li>
Just a state hash. <br />
In the URL only the hash from the state is stored. The state itself is stored in
the sessionStorage. See `state:storeInSessionStorage` advanced option for more
context.
</li>
</ol>
<p>You can switch between these two mods:</p>
</EuiText>
<EuiSpacer />
<EuiButton onClick={() => setUseHashedUrl(!useHashedUrl)}>
{useHashedUrl ? 'Use Expanded State' : 'Use Hashed State'}
</EuiButton>
</EuiPageContentBody>
</EuiPageContent>
</EuiPageBody>
</CompatRouter>
<EuiPageBody>
<EuiPageHeader>
<EuiPageHeaderSection>
<EuiTitle size="l">
<h1>{props.appTitle}</h1>
</EuiTitle>
<EuiSpacer />
<EuiText>
<p>
This is a simple TODO app that uses state containers and state syncing utils. It
stores state in the URL similar like Discover or Dashboard apps do. <br />
Play with the app and see how the state is persisted in the URL.
<br /> Undo/Redo with browser history also works.
</p>
</EuiText>
</EuiPageHeaderSection>
</EuiPageHeader>
<EuiPageContent>
<EuiPageContentBody>
<Routes>
<Route path={'/completed'}>
<TodoApp filter={'completed'} stateContainer={stateContainer} />
</Route>
<Route path={'/not-completed'}>
<TodoApp filter={'not-completed'} stateContainer={stateContainer} />
</Route>
<Route path={'/'}>
<TodoApp filter={null} stateContainer={stateContainer} />
</Route>
</Routes>
<EuiSpacer size={'xxl'} />
<EuiText size={'s'}>
<p>Most of kibana apps persist state in the URL in two ways:</p>
<ol>
<li>Expanded state in rison format</li>
<li>
Just a state hash. <br />
In the URL only the hash from the state is stored. The state itself is stored in
the sessionStorage. See `state:storeInSessionStorage` advanced option for more
context.
</li>
</ol>
<p>You can switch between these two mods:</p>
</EuiText>
<EuiSpacer />
<EuiButton onClick={() => setUseHashedUrl(!useHashedUrl)}>
{useHashedUrl ? 'Use Expanded State' : 'Use Hashed State'}
</EuiButton>
</EuiPageContentBody>
</EuiPageContent>
</EuiPageBody>
</Router>
);
};

View file

@ -8,8 +8,7 @@
import React, { useEffect, useMemo, useState } from 'react';
import { History } from 'history';
import { Router } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Router } from '@kbn/shared-ux-router';
import {
EuiFieldText,
@ -80,42 +79,38 @@ export const App = ({
return (
<StateContainersExamplesPage navigateToApp={navigateToApp} exampleLinks={exampleLinks}>
<Router history={history}>
<CompatRouter>
<EuiPageBody>
<EuiPageHeader>
<EuiTitle size="l">
<h1>Integration with search bar</h1>
</EuiTitle>
</EuiPageHeader>
<EuiText>
<p>
This examples shows how you can use state containers, state syncing utils and
helpers from data plugin to sync your app state and search bar state with the URL.
</p>
</EuiText>
<EuiPageBody>
<EuiPageHeader>
<EuiTitle size="l">
<h1>Integration with search bar</h1>
</EuiTitle>
</EuiPageHeader>
<EuiText>
<p>
This examples shows how you can use state containers, state syncing utils and helpers
from data plugin to sync your app state and search bar state with the URL.
</p>
</EuiText>
<navigation.ui.TopNavMenu
appName={'Example'}
showSearchBar={true}
indexPatterns={[dataView]}
useDefaultBehaviors={true}
showSaveQuery={true}
<navigation.ui.TopNavMenu
appName={'Example'}
showSearchBar={true}
indexPatterns={[dataView]}
useDefaultBehaviors={true}
showSaveQuery={true}
/>
<EuiPageContent>
<EuiText>
<p>In addition to state from query bar also sync your arbitrary application state:</p>
</EuiText>
<EuiFieldText
placeholder="Additional example applications state: My name is..."
value={appState.name}
onChange={(e) => appStateContainer.set({ ...appState, name: e.target.value })}
aria-label="My name"
/>
<EuiPageContent>
<EuiText>
<p>
In addition to state from query bar also sync your arbitrary application state:
</p>
</EuiText>
<EuiFieldText
placeholder="Additional example applications state: My name is..."
value={appState.name}
onChange={(e) => appStateContainer.set({ ...appState, name: e.target.value })}
aria-label="My name"
/>
</EuiPageContent>
</EuiPageBody>
</CompatRouter>
</EuiPageContent>
</EuiPageBody>
</Router>
</StateContainersExamplesPage>
);

View file

@ -7,9 +7,8 @@
*/
import React, { FunctionComponent, useMemo } from 'react';
// eslint-disable-next-line no-restricted-imports
import { RouteComponentProps, Router, Route, Switch } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { RouteComponentProps } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { History } from 'history';
import { EMPTY, Observable } from 'rxjs';
import useObservable from 'react-use/lib/useObservable';
@ -56,62 +55,60 @@ export const AppRouter: FunctionComponent<Props> = ({
return (
<Router history={history}>
<CompatRouter>
<Switch>
{[...mounters].map(([appId, mounter]) => (
<Route
key={mounter.appRoute}
path={mounter.appRoute}
exact={mounter.exactRoute}
render={({ match: { path } }) => (
<AppContainer
appPath={path}
appStatus={appStatuses.get(appId) ?? AppStatus.inaccessible}
createScopedHistory={createScopedHistory}
{...{
appId,
mounter,
setAppLeaveHandler,
setAppActionMenu,
setIsMounting,
theme$,
showPlainSpinner,
}}
/>
)}
/>
))}
{/* handler for legacy apps and used as a catch-all to display 404 page on not existing /app/appId apps*/}
<Routes>
{[...mounters].map(([appId, mounter]) => (
<Route
path="/app/:appId"
render={({
match: {
params: { appId },
url,
},
}: RouteComponentProps<Params>) => {
// the id/mounter retrieval can be removed once #76348 is addressed
const [id, mounter] = mounters.has(appId) ? [appId, mounters.get(appId)] : [];
return (
<AppContainer
appPath={url}
appId={id ?? appId}
appStatus={appStatuses.get(appId) ?? AppStatus.inaccessible}
createScopedHistory={createScopedHistory}
{...{
mounter,
setAppLeaveHandler,
setAppActionMenu,
setIsMounting,
theme$,
showPlainSpinner,
}}
/>
);
}}
key={mounter.appRoute}
path={mounter.appRoute}
exact={mounter.exactRoute}
render={({ match: { path } }) => (
<AppContainer
appPath={path}
appStatus={appStatuses.get(appId) ?? AppStatus.inaccessible}
createScopedHistory={createScopedHistory}
{...{
appId,
mounter,
setAppLeaveHandler,
setAppActionMenu,
setIsMounting,
theme$,
showPlainSpinner,
}}
/>
)}
/>
</Switch>
</CompatRouter>
))}
{/* handler for legacy apps and used as a catch-all to display 404 page on not existing /app/appId apps*/}
<Route
path="/app/:appId"
render={({
match: {
params: { appId },
url,
},
}: RouteComponentProps<Params>) => {
// the id/mounter retrieval can be removed once #76348 is addressed
const [id, mounter] = mounters.has(appId) ? [appId, mounters.get(appId)] : [];
return (
<AppContainer
appPath={url}
appId={id ?? appId}
appStatus={appStatuses.get(appId) ?? AppStatus.inaccessible}
createScopedHistory={createScopedHistory}
{...{
mounter,
setAppLeaveHandler,
setAppActionMenu,
setIsMounting,
theme$,
showPlainSpinner,
}}
/>
);
}}
/>
</Routes>
</Router>
);
};

View file

@ -35,6 +35,7 @@
"@kbn/core-custom-branding-browser-mocks",
"@kbn/core-analytics-browser-mocks",
"@kbn/core-analytics-browser",
"@kbn/shared-ux-router",
],
"exclude": [
"target/**/*",

View file

@ -29,8 +29,7 @@ import type { HttpStart } from '@kbn/core-http-browser';
import { MountPoint } from '@kbn/core-mount-utils-browser';
import { i18n } from '@kbn/i18n';
import React, { createRef, useCallback, useState } from 'react';
import { Router } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Router } from '@kbn/shared-ux-router';
import useLocalStorage from 'react-use/lib/useLocalStorage';
import useObservable from 'react-use/lib/useObservable';
import { Observable, debounceTime } from 'rxjs';
@ -175,32 +174,30 @@ export const ProjectHeader = ({
<EuiHeaderSection grow={false}>
<EuiHeaderSectionItem css={headerCss.nav.toggleNavButton}>
<Router history={application.history}>
<CompatRouter>
<ProjectNavigation
isOpen={isOpen!}
closeNav={() => {
setIsOpen(false);
if (toggleCollapsibleNavRef.current) {
toggleCollapsibleNavRef.current.focus();
}
}}
button={
<EuiHeaderSectionItemButton
data-test-subj="toggleNavButton"
aria-label={headerStrings.nav.closeNavAriaLabel}
onClick={() => setIsOpen(!isOpen)}
aria-expanded={isOpen!}
aria-pressed={isOpen!}
aria-controls={navId}
ref={toggleCollapsibleNavRef}
>
<EuiIcon type={isOpen ? 'menuLeft' : 'menuRight'} size="m" />
</EuiHeaderSectionItemButton>
<ProjectNavigation
isOpen={isOpen!}
closeNav={() => {
setIsOpen(false);
if (toggleCollapsibleNavRef.current) {
toggleCollapsibleNavRef.current.focus();
}
>
{children}
</ProjectNavigation>
</CompatRouter>
}}
button={
<EuiHeaderSectionItemButton
data-test-subj="toggleNavButton"
aria-label={headerStrings.nav.closeNavAriaLabel}
onClick={() => setIsOpen(!isOpen)}
aria-expanded={isOpen!}
aria-pressed={isOpen!}
aria-controls={navId}
ref={toggleCollapsibleNavRef}
>
<EuiIcon type={isOpen ? 'menuLeft' : 'menuRight'} size="m" />
</EuiHeaderSectionItemButton>
}
>
{children}
</ProjectNavigation>
</Router>
</EuiHeaderSectionItem>

View file

@ -41,6 +41,7 @@
"@kbn/core-custom-branding-common",
"@kbn/core-analytics-browser-mocks",
"@kbn/core-analytics-browser",
"@kbn/shared-ux-router",
],
"exclude": [
"target/**/*",

View file

@ -1,8 +1,8 @@
import React, { useState } from 'react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage, I18nProvider } from '@kbn/i18n-react';
import { BrowserRouter as Router } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { BrowserRouter as Router } from '@kbn/shared-ux-router';
import {
EuiButton,
@ -53,64 +53,62 @@ export const <%= upperCamelCase(name) %>App = ({ basename, notifications, http,
// Note that `navigation.ui.TopNavMenu` is a stateful component exported on the `navigation` plugin's start contract.
return (
<Router basename={basename}>
<CompatRouter>
<I18nProvider>
<>
<navigation.ui.TopNavMenu appName={ PLUGIN_ID } showSearchBar={true} useDefaultBehaviors={true}/>
<EuiPage restrictWidth="1000px">
<EuiPageBody>
<EuiPageHeader>
<EuiTitle size="l">
<h1>
<I18nProvider>
<>
<navigation.ui.TopNavMenu appName={ PLUGIN_ID } showSearchBar={true} useDefaultBehaviors={true}/>
<EuiPage restrictWidth="1000px">
<EuiPageBody>
<EuiPageHeader>
<EuiTitle size="l">
<h1>
<FormattedMessage
id="<%= camelCase(name) %>.helloWorldText"
defaultMessage="{name}"
values={{ name: PLUGIN_NAME }}
/>
</h1>
</EuiTitle>
</EuiPageHeader>
<EuiPageContent>
<EuiPageContentHeader>
<EuiTitle>
<h2>
<FormattedMessage
id="<%= camelCase(name) %>.helloWorldText"
defaultMessage="{name}"
values={{ name: PLUGIN_NAME }}
id="<%= camelCase(name) %>.congratulationsTitle"
defaultMessage="Congratulations, you have successfully created a new Kibana Plugin!"
/>
</h1>
</h2>
</EuiTitle>
</EuiPageHeader>
<EuiPageContent>
<EuiPageContentHeader>
<EuiTitle>
<h2>
<FormattedMessage
id="<%= camelCase(name) %>.congratulationsTitle"
defaultMessage="Congratulations, you have successfully created a new Kibana Plugin!"
/>
</h2>
</EuiTitle>
</EuiPageContentHeader>
<EuiPageContentBody>
<EuiText>
<p>
<FormattedMessage
id="<%= camelCase(name) %>.content"
defaultMessage="Look through the generated code and check out the plugin development documentation."
/>
</p>
<EuiHorizontalRule/>
<p>
<FormattedMessage
id="<%= camelCase(name) %>.timestampText"
defaultMessage="Last timestamp: {time}"
values={{ time: timestamp ? timestamp : 'Unknown' }}
/>
</p>
<EuiButton type="primary" size="s" onClick={onClickHandler}>
<FormattedMessage
id="<%= camelCase(name) %>.buttonText"
defaultMessage="<%= hasServer ? 'Get data' : 'Click me' %>"
/>
</EuiButton>
</EuiText>
</EuiPageContentBody>
</EuiPageContent>
</EuiPageBody>
</EuiPage>
</>
</I18nProvider>
</CompatRouter>
</EuiPageContentHeader>
<EuiPageContentBody>
<EuiText>
<p>
<FormattedMessage
id="<%= camelCase(name) %>.content"
defaultMessage="Look through the generated code and check out the plugin development documentation."
/>
</p>
<EuiHorizontalRule/>
<p>
<FormattedMessage
id="<%= camelCase(name) %>.timestampText"
defaultMessage="Last timestamp: {time}"
values={{ time: timestamp ? timestamp : 'Unknown' }}
/>
</p>
<EuiButton type="primary" size="s" onClick={onClickHandler}>
<FormattedMessage
id="<%= camelCase(name) %>.buttonText"
defaultMessage="<%= hasServer ? 'Get data' : 'Click me' %>"
/>
</EuiButton>
</EuiText>
</EuiPageContentBody>
</EuiPageContent>
</EuiPageBody>
</EuiPage>
</>
</I18nProvider>
</Router>
);
};

View file

@ -7,8 +7,8 @@
*/
import { History } from 'history';
import React from 'react';
import { Router as ReactRouter } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Router as ReactRouter } from '@kbn/shared-ux-router';
import { RouteMap, Router } from './types';
import { RouterContextProvider } from './use_router';
@ -23,9 +23,7 @@ export function RouterProvider({
}) {
return (
<ReactRouter history={history}>
<CompatRouter>
<RouterContextProvider router={router}>{children}</RouterContextProvider>
</CompatRouter>
<RouterContextProvider router={router}>{children}</RouterContextProvider>
</ReactRouter>
);
}

View file

@ -13,7 +13,8 @@
"**/*.tsx",
],
"kbn_references": [
"@kbn/io-ts-utils"
"@kbn/io-ts-utils",
"@kbn/shared-ux-router"
],
"exclude": [
"target/**/*",

View file

@ -6,4 +6,6 @@
* Side Public License, v 1.
*/
export { Route } from './router';
export { Route } from './route';
export { HashRouter, BrowserRouter, MemoryRouter, Router } from './router';
export { Routes } from './routes';

View file

@ -8,7 +8,7 @@
import React, { Component, FC } from 'react';
import { shallow } from 'enzyme';
import { Route } from './router';
import { Route } from './route';
import { createMemoryHistory } from 'history';
describe('Route', () => {

View file

@ -14,16 +14,21 @@ import {
RouteProps,
useRouteMatch,
} from 'react-router-dom';
import { useKibana } from '../context';
import { useExecutionContext } from '../use_execution_context';
import { useKibanaSharedUX } from './services';
import { useSharedUXExecutionContext } from './use_execution_context';
/**
* It's a wrapper around the react-router-dom Route component that inserts
* This is a wrapper around the react-router-dom Route component that inserts
* MatchPropagator in every application route. It helps track all route changes
* and send them to the execution context, later used to enrich APM
* 'route-change' transactions.
*/
export const Route = ({ children, component: Component, render, ...rest }: RouteProps) => {
export const Route = <T extends {}>({
children,
component: Component,
render,
...rest
}: RouteProps<string, { [K: string]: string } & T>) => {
const component = useMemo(() => {
if (!Component) {
return undefined;
@ -39,27 +44,16 @@ export const Route = ({ children, component: Component, render, ...rest }: Route
if (component) {
return <ReactRouterRoute {...rest} component={component} />;
}
if (render) {
if (render || typeof children === 'function') {
const renderFunction = typeof children === 'function' ? children : render;
return (
<ReactRouterRoute
{...rest}
render={(props) => (
<>
<MatchPropagator />
{render(props)}
</>
)}
/>
);
}
if (typeof children === 'function') {
return (
<ReactRouterRoute
{...rest}
render={(props) => (
<>
<MatchPropagator />
{children(props)}
{/* @ts-ignore else condition exists if renderFunction is undefined*/}
{renderFunction(props)}
</>
)}
/>
@ -73,11 +67,14 @@ export const Route = ({ children, component: Component, render, ...rest }: Route
);
};
const MatchPropagator = () => {
const { executionContext } = useKibana().services;
/**
* The match propagator that is part of the Route
*/
export const MatchPropagator = () => {
const { executionContext } = useKibanaSharedUX().services;
const match = useRouteMatch();
useExecutionContext(executionContext, {
useSharedUXExecutionContext(executionContext, {
type: 'application',
page: match.path,
id: Object.keys(match.params).length > 0 ? JSON.stringify(match.params) : undefined,

View file

@ -6,79 +6,43 @@
* Side Public License, v 1.
*/
import React, { useMemo } from 'react';
import React from 'react';
import {
// eslint-disable-next-line no-restricted-imports
Route as ReactRouterRoute,
RouteComponentProps,
RouteProps,
useRouteMatch,
Router as ReactRouter,
MemoryRouter as ReactMemoryRouter,
BrowserRouter as ReactBrowserRouter,
HashRouter as ReactHashRouter,
} from 'react-router-dom';
import { useKibanaSharedUX } from './services';
import { useSharedUXExecutionContext } from './use_execution_context';
import type {
RouterProps,
MemoryRouterProps,
BrowserRouterProps,
HashRouterProps,
} from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
/**
* This is a wrapper around the react-router-dom Route component that inserts
* MatchPropagator in every application route. It helps track all route changes
* and send them to the execution context, later used to enrich APM
* 'route-change' transactions.
*/
export const Route = ({
children,
component: Component,
render,
...rest
}: RouteProps<string, { [K: string]: string }>) => {
const component = useMemo(() => {
if (!Component) {
return undefined;
}
return (props: RouteComponentProps) => (
<>
<MatchPropagator />
<Component {...props} />
</>
);
}, [Component]);
export const HashRouter = ({ children, ...props }: HashRouterProps) => (
<ReactHashRouter {...props}>
<CompatRouter>{children}</CompatRouter>
</ReactHashRouter>
);
if (component) {
return <ReactRouterRoute {...rest} component={component} />;
}
if (render || typeof children === 'function') {
const renderFunction = typeof children === 'function' ? children : render;
return (
<ReactRouterRoute
{...rest}
render={(props) => (
<>
<MatchPropagator />
{/* @ts-ignore else condition exists if renderFunction is undefined*/}
{renderFunction(props)}
</>
)}
/>
);
}
return (
<ReactRouterRoute {...rest}>
<MatchPropagator />
{children}
</ReactRouterRoute>
);
};
export const BrowserRouter = ({ children, ...props }: BrowserRouterProps) => (
<ReactBrowserRouter {...props}>
<CompatRouter>{children}</CompatRouter>
</ReactBrowserRouter>
);
/**
* The match propogator that is part of the Route
*/
const MatchPropagator = () => {
const { executionContext } = useKibanaSharedUX().services;
const match = useRouteMatch();
export const MemoryRouter = ({ children, ...props }: MemoryRouterProps) => (
<ReactMemoryRouter {...props}>
<CompatRouter>{children}</CompatRouter>
</ReactMemoryRouter>
);
useSharedUXExecutionContext(executionContext, {
type: 'application',
page: match.path,
id: Object.keys(match.params).length > 0 ? JSON.stringify(match.params) : undefined,
});
return null;
};
export const Router = ({ children, ...props }: RouterProps) => (
<ReactRouter {...props}>
<CompatRouter>{children}</CompatRouter>
</ReactRouter>
);

View file

@ -0,0 +1,56 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { replace } from 'lodash';
import React, { Children } from 'react';
// eslint-disable-next-line no-restricted-imports
import { Switch, useRouteMatch } from 'react-router-dom';
import { Routes as ReactRouterRoutes, Route } from 'react-router-dom-v5-compat';
import { Route as LegacyRoute, MatchPropagator } from './route';
export const Routes = ({
legacySwitch = true,
children,
}: {
legacySwitch?: boolean;
children: React.ReactNode;
}) => {
const match = useRouteMatch();
return legacySwitch ? (
<Switch>{children}</Switch>
) : (
<ReactRouterRoutes>
{Children.map(children, (child) => {
if (React.isValidElement(child) && child.type === LegacyRoute) {
const path = replace(child?.props.path, match.url + '/', '');
const renderFunction =
typeof child?.props.children === 'function'
? child?.props.children
: child?.props.render;
return (
<Route
path={path}
element={
<>
<MatchPropagator />
{(child?.props?.component && <child.props.component />) ||
(renderFunction && renderFunction()) ||
children}
</>
}
/>
);
} else {
return child;
}
})}
</ReactRouterRoutes>
);
};

View file

@ -8,9 +8,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Switch, Redirect, RouteChildrenProps } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Route } from '@kbn/shared-ux-router';
import { Redirect, RouteChildrenProps } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { i18n } from '@kbn/i18n';
import { I18nProvider } from '@kbn/i18n-react';
@ -78,30 +77,28 @@ export async function mountManagementSection(
<KibanaThemeProvider theme$={params.theme$}>
<I18nProvider>
<Router history={params.history}>
<CompatRouter>
<Switch>
{/* TODO: remove route param (`query`) in 7.13 */}
<Route path={`/:${QUERY}`}>
{(props: RedirectUrlProps) => <Redirect to={redirectUrl(props)} />}
</Route>
<Route path="/">
<Settings
history={params.history}
enableSaving={{
namespace: canSaveAdvancedSettings,
global: canSaveGlobalSettings,
}}
enableShowing={{ namespace: true, global: canShowGlobalSettings }}
toasts={notifications.toasts}
docLinks={docLinks.links}
settingsService={settings}
theme={params.theme$}
componentRegistry={componentRegistry}
trackUiMetric={trackUiMetric}
/>
</Route>
</Switch>
</CompatRouter>
<Routes>
{/* TODO: remove route param (`query`) in 7.13 */}
<Route path={`/:${QUERY}`}>
{(props: RedirectUrlProps) => <Redirect to={redirectUrl(props)} />}
</Route>
<Route path="/">
<Settings
history={params.history}
enableSaving={{
namespace: canSaveAdvancedSettings,
global: canSaveGlobalSettings,
}}
enableShowing={{ namespace: true, global: canShowGlobalSettings }}
toasts={notifications.toasts}
docLinks={docLinks.links}
settingsService={settings}
theme={params.theme$}
componentRegistry={componentRegistry}
trackUiMetric={trackUiMetric}
/>
</Route>
</Routes>
</Router>
</I18nProvider>
</KibanaThemeProvider>,

View file

@ -11,10 +11,8 @@ import './_dashboard_app.scss';
import React from 'react';
import { parse, ParsedQuery } from 'query-string';
import { render, unmountComponentAtNode } from 'react-dom';
import { Switch, RouteComponentProps, HashRouter, Redirect } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Route } from '@kbn/shared-ux-router';
import { HashRouter, RouteComponentProps, Redirect } from 'react-router-dom';
import { Routes, Route } from '@kbn/shared-ux-router';
import { I18nProvider } from '@kbn/i18n-react';
import { ViewMode } from '@kbn/embeddable-plugin/public';
import { AppMountParameters, CoreSetup } from '@kbn/core/public';
@ -150,19 +148,17 @@ export async function mountApp({ core, element, appUnMounted, mountContext }: Da
<DashboardMountContext.Provider value={mountContext}>
<KibanaThemeProvider theme$={core.theme.theme$}>
<HashRouter>
<CompatRouter>
<Switch>
<Route
path={[CREATE_NEW_DASHBOARD_URL, `${VIEW_DASHBOARD_URL}/:id`]}
render={renderDashboard}
/>
<Route exact path={LANDING_PAGE_PATH} render={renderListingPage} />
<Route exact path="/">
<Redirect to={LANDING_PAGE_PATH} />
</Route>
<Route render={renderNoMatch} />
</Switch>
</CompatRouter>
<Routes>
<Route
path={[CREATE_NEW_DASHBOARD_URL, `${VIEW_DASHBOARD_URL}/:id`]}
render={renderDashboard}
/>
<Route exact path={LANDING_PAGE_PATH} render={renderListingPage} />
<Route exact path="/">
<Redirect to={LANDING_PAGE_PATH} />
</Route>
<Route render={renderNoMatch} />
</Routes>
</HashRouter>
</KibanaThemeProvider>
</DashboardMountContext.Provider>

View file

@ -8,9 +8,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Switch, Redirect } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Route } from '@kbn/shared-ux-router';
import { Redirect } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { i18n } from '@kbn/i18n';
import { I18nProvider } from '@kbn/i18n-react';
@ -88,23 +87,21 @@ export async function mountManagementSection(
<KibanaThemeProvider theme$={theme.theme$}>
<I18nProvider>
<Router history={params.history}>
<CompatRouter>
<Switch>
<Route path={['/create']}>
<IndexPatternTableWithRouter canSave={canSave} showCreateDialog={true} />
</Route>
<Route path={['/dataView/:id/field/:fieldName', '/dataView/:id/create-field/']}>
<CreateEditFieldContainer />
</Route>
<Route path={['/dataView/:id']}>
<EditIndexPatternContainer />
</Route>
<Redirect path={'/patterns*'} to={'dataView*'} />
<Route path={['/']}>
<IndexPatternTableWithRouter canSave={canSave} />
</Route>
</Switch>
</CompatRouter>
<Routes>
<Route path={['/create']}>
<IndexPatternTableWithRouter canSave={canSave} showCreateDialog={true} />
</Route>
<Route path={['/dataView/:id/field/:fieldName', '/dataView/:id/create-field/']}>
<CreateEditFieldContainer />
</Route>
<Route path={['/dataView/:id']}>
<EditIndexPatternContainer />
</Route>
<Redirect path={'/patterns*'} to={'dataView*'} />
<Route path={['/']}>
<IndexPatternTableWithRouter canSave={canSave} />
</Route>
</Routes>
</Router>
</I18nProvider>
</KibanaThemeProvider>

View file

@ -9,9 +9,8 @@
import React, { useEffect, useRef } from 'react';
import { Observable } from 'rxjs';
import ReactDOM from 'react-dom';
import { HashRouter as Router, Switch, Redirect, RouteComponentProps } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Route } from '@kbn/shared-ux-router';
import { Redirect, RouteComponentProps } from 'react-router-dom';
import { HashRouter as Router, Routes, Route } from '@kbn/shared-ux-router';
import { EuiTab, EuiTabs, EuiToolTip, EuiBetaBadge } from '@elastic/eui';
import { I18nProvider } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
@ -184,33 +183,31 @@ export function renderApp(
<I18nProvider>
<KibanaThemeProvider theme$={theme$}>
<Router>
<CompatRouter>
<Switch>
{devTools
// Only create routes for devtools that are not disabled
.filter((devTool) => !devTool.isDisabled())
.map((devTool) => (
<Route
key={devTool.id}
path={`/${devTool.id}`}
exact={!devTool.enableRouting}
render={(props) => (
<DevToolsWrapper
updateRoute={props.history.push}
location={props.location}
activeDevTool={devTool}
devTools={devTools}
theme$={theme$}
appServices={appServices}
/>
)}
/>
))}
<Route path="/">
<Redirect to={`/${devTools[0].id}`} />
</Route>
</Switch>
</CompatRouter>
<Routes>
{devTools
// Only create routes for devtools that are not disabled
.filter((devTool) => !devTool.isDisabled())
.map((devTool) => (
<Route
key={devTool.id}
path={`/${devTool.id}`}
exact={!devTool.enableRouting}
render={(props) => (
<DevToolsWrapper
updateRoute={props.history.push}
location={props.location}
activeDevTool={devTool}
devTools={devTools}
theme$={theme$}
appServices={appServices}
/>
)}
/>
))}
<Route path="/">
<Redirect to={`/${devTools[0].id}`} />
</Route>
</Routes>
</Router>
</KibanaThemeProvider>
</I18nProvider>,

View file

@ -6,9 +6,8 @@
* Side Public License, v 1.
*/
import { Redirect, Router, Switch, useParams } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { Route } from '@kbn/shared-ux-router';
import { Redirect, useParams } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import React, { useCallback, useMemo } from 'react';
import { History } from 'history';
import { EuiErrorBoundary } from '@elastic/eui';
@ -36,7 +35,7 @@ export const DiscoverRoutes = ({ prefix, ...mainRouteProps }: DiscoverRoutesProp
);
return (
<Switch>
<Routes>
<Route path={prefixPath('context/:dataViewId/:id')}>
<ContextAppRoute />
</Route>
@ -61,7 +60,7 @@ export const DiscoverRoutes = ({ prefix, ...mainRouteProps }: DiscoverRoutesProp
<DiscoverMainRoute {...mainRouteProps} />
</Route>
<NotFoundRoute />
</Switch>
</Routes>
);
};
@ -112,16 +111,14 @@ export const DiscoverRouter = ({
<KibanaContextProvider services={services}>
<EuiErrorBoundary>
<Router history={history} data-test-subj="discover-react-router">
<CompatRouter>
<Switch>
<Route path={addProfile('', ':profile')}>
<CustomDiscoverRoutes profileRegistry={profileRegistry} {...routeProps} />
</Route>
<Route path="/">
<DiscoverRoutes customizationCallbacks={customizationCallbacks} {...routeProps} />
</Route>
</Switch>
</CompatRouter>
<Routes>
<Route path={addProfile('', ':profile')}>
<CustomDiscoverRoutes profileRegistry={profileRegistry} {...routeProps} />
</Route>
<Route path="/">
<DiscoverRoutes customizationCallbacks={customizationCallbacks} {...routeProps} />
</Route>
</Routes>
</Router>
</EuiErrorBoundary>
</KibanaContextProvider>

View file

@ -15,7 +15,7 @@ import { DiscoverTopNav } from './components/top_nav/discover_topnav';
import { setHeaderActionMenuMounter, setUrlTracker } from '../../kibana_services';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { discoverServiceMock } from '../../__mocks__/services';
import { Router } from 'react-router-dom';
import { Router } from '@kbn/shared-ux-router';
import { createMemoryHistory } from 'history';
import { urlTrackerMock } from '../../__mocks__/url_tracker.mock';
import { getDiscoverStateMock } from '../../__mocks__/discover_state.mock';

View file

@ -8,7 +8,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Router } from 'react-router-dom';
import { Router } from '@kbn/shared-ux-router';
import { Route } from '@kbn/shared-ux-router';
import { KibanaThemeProvider, toMountPoint } from '@kbn/kibana-react-plugin/public';
import { I18nProvider, FormattedRelative } from '@kbn/i18n-react';

View file

@ -12,8 +12,9 @@ import PropTypes from 'prop-types';
import { Home } from './home';
import { TutorialDirectory } from './tutorial_directory';
import { Tutorial } from './tutorial/tutorial';
// eslint-disable-next-line no-restricted-imports
import { HashRouter as Router, Switch, Route, Redirect } from 'react-router-dom';
import { Redirect } from 'react-router-dom';
import { HashRouter as Router, Routes, Route } from '@kbn/shared-ux-router';
import { getTutorial } from '../load_tutorials';
import { replaceTemplateStrings } from './tutorial/replace_template_strings';
import { getServices } from '../kibana_services';
@ -67,7 +68,7 @@ export function HomeApp({ directories, solutions }) {
return (
<I18nProvider>
<Router>
<Switch>
<Routes>
<Route path="/tutorial/:id" render={renderTutorial} />
<Route path="/tutorial_directory/:tab?" render={renderTutorialDirectory} />
{guidedOnboardingService.isEnabled && (
@ -87,7 +88,7 @@ export function HomeApp({ directories, solutions }) {
/>
</Route>
<Redirect to="/" />
</Switch>
</Routes>
</Router>
</I18nProvider>
);

View file

@ -31,6 +31,7 @@
"@kbn/core-analytics-server",
"@kbn/storybook",
"@kbn/cloud-chat-provider-plugin",
"@kbn/shared-ux-router",
],
"exclude": [
"target/**/*",

View file

@ -9,8 +9,8 @@
import React, { useEffect, useState } from 'react';
import { Observable } from 'rxjs';
import { I18nProvider } from '@kbn/i18n-react';
import { HashRouter as Router, Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { HashRouter as Router } from 'react-router-dom';
import { Route, Routes } from '@kbn/shared-ux-router';
import { CoreStart } from '@kbn/core/public';
import { NavigationPublicPluginStart } from '@kbn/navigation-plugin/public';
import { FetchResult } from '@kbn/newsfeed-plugin/public';
@ -48,11 +48,11 @@ export const KibanaOverviewApp = ({
return (
<Router basename={basename}>
<I18nProvider>
<Switch>
<Routes>
<Route exact path="/">
<Overview {...{ newsFetchResult, solutions, features }} />
</Route>
</Switch>
</Routes>
</I18nProvider>
</Router>
);

View file

@ -51,8 +51,6 @@ export type { ToolbarButtonProps } from './toolbar_button';
/** @deprecated ToolbarButton - use `ToolbarButton` from `@kbn/shared-ux-button-toolbar` */
export { POSITIONS, WEIGHTS, TOOLBAR_BUTTON_SIZES, ToolbarButton } from './toolbar_button';
export { Route } from './router';
export { reactRouterNavigate, reactRouterOnClickHandler } from './react_router_navigate';
export type {

View file

@ -1,9 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export { Route } from './router';

View file

@ -7,8 +7,8 @@
*/
import React, { memo } from 'react';
import { Router, Switch, Redirect } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Redirect } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { AppMountParameters, ChromeBreadcrumb, ScopedHistory } from '@kbn/core/public';
import { ManagementAppWrapper } from '../management_app_wrapper';
import { ManagementLandingPage } from '../landing';
@ -34,7 +34,7 @@ export const ManagementRouter = memo(
theme$,
}: ManagementRouterProps) => (
<Router history={history}>
<Switch>
<Routes>
{sections.map((section) =>
section
.getAppsEnabled()
@ -69,7 +69,7 @@ export const ManagementRouter = memo(
/>
)}
/>
</Switch>
</Routes>
</Router>
)
);

View file

@ -8,8 +8,7 @@
import React, { lazy, Suspense } from 'react';
import ReactDOM from 'react-dom';
import { Router, Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { I18nProvider } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import { EuiLoadingSpinner } from '@elastic/eui';
@ -60,7 +59,7 @@ export const mountManagementSection = async ({ core, mountParams }: MountParams)
wrapWithTheme(
<I18nProvider>
<Router history={history}>
<Switch>
<Routes>
<Route path={'/:type/:id'} exact={true}>
<RedirectToHomeIfUnauthorized>
<Suspense fallback={<EuiLoadingSpinner />}>
@ -89,7 +88,7 @@ export const mountManagementSection = async ({ core, mountParams }: MountParams)
</Suspense>
</RedirectToHomeIfUnauthorized>
</Route>
</Switch>
</Routes>
</Router>
</I18nProvider>,
theme$

View file

@ -8,8 +8,8 @@
import './app.scss';
import React, { useEffect, useCallback, useState } from 'react';
import { Switch, useLocation } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { useLocation } from 'react-router-dom';
import { Routes, Route } from '@kbn/shared-ux-router';
import { EuiLoadingSpinner } from '@elastic/eui';
import { AppMountParameters, CoreStart } from '@kbn/core/public';
import type { DataViewEditorStart } from '@kbn/data-view-editor-plugin/public';
@ -130,7 +130,7 @@ export const VisualizeApp = ({ onAppLeave }: VisualizeAppProps) => {
}
return (
<Switch>
<Routes>
<Route exact path={`${VisualizeConstants.EDIT_BY_VALUE_PATH}`}>
<VisualizeByValueEditor onAppLeave={onAppLeave} />
</Route>
@ -148,6 +148,6 @@ export const VisualizeApp = ({ onAppLeave }: VisualizeAppProps) => {
<VisualizeListing />
</Route>
<VisualizeNoMatch />
</Switch>
</Routes>
);
};

View file

@ -8,7 +8,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Router } from 'react-router-dom';
import { Router } from '@kbn/shared-ux-router';
import { AppMountParameters } from '@kbn/core/public';
import {

View file

@ -8,8 +8,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
// eslint-disable-next-line no-restricted-imports
import { Router, Switch, Route, Prompt } from 'react-router-dom';
import { Prompt } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import type { AppMountParameters, IBasePath, ApplicationStart } from '@kbn/core/public';
import { RedirectAppLinks } from '@kbn/kibana-react-plugin/public';
@ -69,14 +69,14 @@ export const renderApp = (
) => {
ReactDOM.render(
<Router history={history}>
<Switch>
<Routes>
<Route path="/" exact={true}>
<HomePage basePath={basePath} application={application} />
</Route>
<Route path="/foo" exact={true}>
<FooPage basePath={basePath} application={application} />
</Route>
</Switch>
</Routes>
</Router>,
element
);

View file

@ -9,6 +9,7 @@
],
"kbn_references": [
"@kbn/core",
"@kbn/kibana-react-plugin"
"@kbn/kibana-react-plugin",
"@kbn/shared-ux-router"
]
}

View file

@ -9,8 +9,8 @@
import { History } from 'history';
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, withRouter, RouteComponentProps, Redirect } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { withRouter, RouteComponentProps, Redirect } from 'react-router-dom';
import { Router, Route } from '@kbn/shared-ux-router';
import {
EuiPage,

View file

@ -9,8 +9,8 @@
import { History } from 'history';
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, withRouter, RouteComponentProps } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { withRouter, RouteComponentProps } from 'react-router-dom';
import { Router, Route } from '@kbn/shared-ux-router';
import {
EuiPage,

View file

@ -9,8 +9,8 @@
import { History } from 'history';
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, withRouter, RouteComponentProps, Redirect } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { withRouter, RouteComponentProps, Redirect } from 'react-router-dom';
import { Router, Route } from '@kbn/shared-ux-router';
import {
EuiPage,

View file

@ -8,8 +8,8 @@
import * as React from 'react';
import ReactDOM from 'react-dom';
import { Router, Switch, Link } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Link } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { CoreSetup, Plugin } from '@kbn/core/public';
import { ManagementSetup } from '@kbn/management-plugin/public';
@ -28,7 +28,7 @@ export class ManagementTestPlugin
ReactDOM.render(
<Router history={params.history}>
<h1 data-test-subj="test-management-header">Hello from management test plugin</h1>
<Switch>
<Routes>
<Route path={'/one'}>
<Link to={`${params.basePath}`} data-test-subj="test-management-link-basepath">
Link to basePath
@ -39,7 +39,7 @@ export class ManagementTestPlugin
Link to /one
</Link>
</Route>
</Switch>
</Routes>
</Router>,
params.element
);

View file

@ -7,8 +7,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { AppMountParameters, CoreStart } from '@kbn/core/public';
import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import { CaptureTest } from './containers/capture_test';
@ -27,10 +26,10 @@ export const renderApp = (
<ApplicationContextProvider forwardedState={forwardedParams}>
<KibanaThemeProvider theme$={coreStart.theme.theme$}>
<Router history={history}>
<Switch>
<Routes>
<Route path={ROUTES.captureTest} exact render={() => <CaptureTest />} />
<Route render={() => <Main basename={appBasePath} {...coreStart} {...deps} />} />
</Switch>
</Routes>
</Router>
</KibanaThemeProvider>
</ApplicationContextProvider>,

View file

@ -7,9 +7,8 @@
import React, { Suspense } from 'react';
import ReactDOM from 'react-dom';
import { Router, Switch } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { Route } from '@kbn/shared-ux-router';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { CoreStart } from '@kbn/core/public';
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
@ -33,7 +32,7 @@ const App = React.memo(() => {
const hasLicense = isAtLeastPlatinum();
return (
<Switch>
<Routes>
{hasLicense ? (
<Route
key={MAINTENANCE_WINDOW_PATHS.alerting.maintenanceWindowsCreate}
@ -61,7 +60,7 @@ const App = React.memo(() => {
<MaintenanceWindowsLazy />
</Suspense>
</Route>
</Switch>
</Routes>
);
});
App.displayName = 'App';

View file

@ -9,7 +9,6 @@ import { render } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import { createMemoryHistory } from 'history';
import React from 'react';
import { Router } from 'react-router-dom';
import { MockApmPluginContextWrapper } from '../../../../context/apm_plugin/mock_apm_plugin_context';
import { MockUrlParamsContextProvider } from '../../../../context/url_params_context/mock_url_params_context_provider';
import {
@ -21,12 +20,10 @@ const history = createMemoryHistory();
function wrapper({ queryParams }: { queryParams?: Record<string, unknown> }) {
return ({ children }: { children: React.ReactElement }) => (
<MockApmPluginContextWrapper>
<Router history={history}>
<MockUrlParamsContextProvider params={queryParams}>
{children}
</MockUrlParamsContextProvider>
</Router>
<MockApmPluginContextWrapper history={history}>
<MockUrlParamsContextProvider params={queryParams}>
{children}
</MockUrlParamsContextProvider>
</MockApmPluginContextWrapper>
);
}

View file

@ -9,7 +9,6 @@ import { render } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import { createMemoryHistory } from 'history';
import React from 'react';
import { Router } from 'react-router-dom';
import { MockApmPluginContextWrapper } from '../../../../context/apm_plugin/mock_apm_plugin_context';
import { MockUrlParamsContextProvider } from '../../../../context/url_params_context/mock_url_params_context_provider';
import {
@ -21,10 +20,8 @@ const history = createMemoryHistory();
function Wrapper({ children }: { children: React.ReactElement }) {
return (
<MockApmPluginContextWrapper>
<Router history={history}>
<MockUrlParamsContextProvider>{children}</MockUrlParamsContextProvider>
</Router>
<MockApmPluginContextWrapper history={history}>
<MockUrlParamsContextProvider>{children}</MockUrlParamsContextProvider>
</MockApmPluginContextWrapper>
);
}

View file

@ -8,7 +8,6 @@
import { getByTestId, fireEvent, getByText, act } from '@testing-library/react';
import { createMemoryHistory, MemoryHistory } from 'history';
import React from 'react';
import { Router } from 'react-router-dom';
import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public';
import { MockApmPluginContextWrapper } from '../../../context/apm_plugin/mock_apm_plugin_context';
import { ApmServiceContextProvider } from '../../../context/apm_service/apm_service_context';
@ -74,14 +73,12 @@ function setup({
return renderWithTheme(
<KibanaReactContext.Provider>
<MockApmPluginContextWrapper>
<Router history={history}>
<UrlParamsProvider>
<ApmServiceContextProvider>
<SearchBar showTransactionTypeSelector />
</ApmServiceContextProvider>
</UrlParamsProvider>
</Router>
<MockApmPluginContextWrapper history={history}>
<UrlParamsProvider>
<ApmServiceContextProvider>
<SearchBar showTransactionTypeSelector />
</ApmServiceContextProvider>
</UrlParamsProvider>
</MockApmPluginContextWrapper>
</KibanaReactContext.Provider>
);

View file

@ -7,7 +7,7 @@
import { createMemoryHistory, MemoryHistory } from 'history';
import React from 'react';
import { Router, useLocation } from 'react-router-dom';
import { useLocation } from 'react-router-dom';
import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public';
import { MockApmPluginContextWrapper } from '../../../context/apm_plugin/mock_apm_plugin_context';
import * as useFetcherHook from '../../../hooks/use_fetcher';
@ -76,10 +76,8 @@ function setup({
const wrapper = mount(
<KibanaReactContext.Provider>
<MockApmPluginContextWrapper>
<Router history={history}>
<UnifiedSearchBar />
</Router>
<MockApmPluginContextWrapper history={history}>
<UnifiedSearchBar />
</MockApmPluginContextWrapper>
</KibanaReactContext.Provider>
);

View file

@ -10,7 +10,7 @@ import { mount } from 'enzyme';
import { History, Location } from 'history';
import moment from 'moment-timezone';
import * as React from 'react';
import { MemoryRouter, Router } from 'react-router-dom';
import { MemoryRouter, Router } from '@kbn/shared-ux-router';
import type { UrlParams } from './types';
import { UrlParamsContext, UrlParamsProvider } from './url_params_context';

View file

@ -6,8 +6,8 @@
*/
import React, { FC } from 'react';
import { Router, Switch, RouteComponentProps, Redirect } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { RouteComponentProps, Redirect } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { History } from 'history';
import { parse, stringify } from 'query-string';
import { HomeRoute } from './home';
@ -50,11 +50,11 @@ export const CanvasRouter: FC<{ history: History }> = ({ history }) => (
}
return (
<Switch>
<Routes>
{ExportWorkpadRoute()}
{WorkpadRoute()}
{HomeRoute()}
</Switch>
</Routes>
);
}}
/>

View file

@ -6,8 +6,8 @@
*/
import React, { FC, useEffect, useCallback } from 'react';
import { Switch, Redirect, useParams } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Redirect, useParams } from 'react-router-dom';
import { Routes, Route } from '@kbn/shared-ux-router';
import { useDispatch } from 'react-redux';
import { WorkpadApp } from '../../components/workpad_app';
import { ExportApp } from '../../components/export_app';
@ -56,7 +56,7 @@ const WorkpadRouteComponent: FC<{ route: WorkpadRouteProps }> = ({ route }) => {
getRedirectPath={getRedirectPath}
>
{(workpad: CanvasWorkpad) => (
<Switch>
<Routes>
<Route
path="/workpad/:id/page/:pageNumber"
children={(pageRoute) => (
@ -72,7 +72,7 @@ const WorkpadRouteComponent: FC<{ route: WorkpadRouteProps }> = ({ route }) => {
<Route path="/workpad/:id" strict={false} exact={true}>
<Redirect to={`/workpad/${route.match.params.id}/page/${workpad.page + 1}`} />
</Route>
</Switch>
</Routes>
)}
</WorkpadLoaderComponent>
);

View file

@ -7,7 +7,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Router } from 'react-router-dom';
import { Router } from '@kbn/shared-ux-router';
import { EuiErrorBoundary } from '@elastic/eui';
import { I18nProvider } from '@kbn/i18n-react';

View file

@ -6,8 +6,8 @@
*/
import React, { lazy, Suspense, useCallback } from 'react';
import { Redirect, Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Redirect } from 'react-router-dom';
import { Routes, Route } from '@kbn/shared-ux-router';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { EuiLoadingSpinner } from '@elastic/eui';
@ -53,7 +53,7 @@ const CasesRoutesComponent: React.FC<CasesRoutesProps> = ({
return (
<>
<ReactQueryDevtools initialIsOpen={false} />
<Switch>
<Routes>
<Route strict exact path={basePath}>
<AllCases />
</Route>
@ -95,7 +95,7 @@ const CasesRoutesComponent: React.FC<CasesRoutesProps> = ({
<Route path={basePath}>
<Redirect to={basePath} />
</Route>
</Switch>
</Routes>
</>
);
};

View file

@ -7,7 +7,7 @@
import type { PropsWithChildren } from 'react';
import React from 'react';
import { Router } from 'react-router-dom';
import { Router } from '@kbn/shared-ux-router';
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
import { useIsDarkTheme } from '../../../common/use_is_dark_theme';

View file

@ -7,7 +7,7 @@
import CloudDefendRouter from './router';
import React from 'react';
import { render } from '@testing-library/react';
import { Router } from 'react-router-dom';
import { Router } from '@kbn/shared-ux-router';
import type { CloudDefendPage, CloudDefendPageNavigationItem } from '../common/navigation/types';
import { CloudDefendSecuritySolutionContext } from '../types';
import { createMemoryHistory, MemoryHistory } from 'history';

View file

@ -7,8 +7,8 @@
import React from 'react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { Redirect, Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Redirect } from 'react-router-dom';
import { Routes, Route } from '@kbn/shared-ux-router';
import { cloudDefendPages } from '../common/navigation/constants';
import type { CloudDefendSecuritySolutionContext } from '../types';
import { SecuritySolutionContext } from './security_solution_context';
@ -26,13 +26,13 @@ export interface CloudDefendRouterProps {
export const CloudDefendRouter = ({ securitySolutionContext }: CloudDefendRouterProps) => {
const routerElement = (
<QueryClientProvider client={queryClient}>
<Switch>
<Routes>
<CloudDefendRoute {...cloudDefendPages.policies} component={Policies} />
<Route>
<Redirect to={cloudDefendPages.policies.path} />
</Route>
</Switch>
</Routes>
</QueryClientProvider>
);

View file

@ -8,8 +8,7 @@
import type { AppMountParameters, CoreStart } from '@kbn/core/public';
import React, { useMemo } from 'react';
import { I18nProvider } from '@kbn/i18n-react';
import { Router, Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { coreMock } from '@kbn/core/public/mocks';
import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
@ -58,9 +57,9 @@ export const TestProvider: React.FC<Partial<CloudDefendAppDeps>> = ({
<QueryClientProvider client={queryClient}>
<Router history={params.history}>
<I18nProvider>
<Switch>
<Routes>
<Route path="*" render={() => <>{children}</>} />
</Switch>
</Routes>
</I18nProvider>
</Router>
</QueryClientProvider>

View file

@ -7,7 +7,7 @@
import CspRouter from './csp_router';
import React from 'react';
import { render } from '@testing-library/react';
import { Router } from 'react-router-dom';
import { Router } from '@kbn/shared-ux-router';
import type { CspPage, CspPageNavigationItem } from '../common/navigation/types';
import { CspSecuritySolutionContext } from '../types';
import { createMemoryHistory, MemoryHistory } from 'history';

View file

@ -7,8 +7,8 @@
import React from 'react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { Redirect, Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Redirect } from 'react-router-dom';
import { Routes, Route } from '@kbn/shared-ux-router';
import { benchmarksNavigation, cloudPosturePages } from '../common/navigation/constants';
import type { CspSecuritySolutionContext } from '..';
import { SecuritySolutionContext } from './security_solution_context';
@ -27,7 +27,7 @@ export interface CspRouterProps {
export const CspRouter = ({ securitySolutionContext }: CspRouterProps) => {
const routerElement = (
<QueryClientProvider client={queryClient}>
<Switch>
<Routes>
<CspRoute {...cloudPosturePages.findings} component={pages.Findings} />
<CspRoute {...cloudPosturePages.dashboard} component={pages.ComplianceDashboard} />
<CspRoute
@ -36,16 +36,16 @@ export const CspRouter = ({ securitySolutionContext }: CspRouterProps) => {
/>
<CspRoute {...cloudPosturePages.benchmarks}>
<Switch>
<Routes>
<CspRoute {...benchmarksNavigation.rules} component={pages.Rules} />
<CspRoute {...cloudPosturePages.benchmarks} component={pages.Benchmarks} />
</Switch>
</Routes>
</CspRoute>
<Route>
<Redirect to={cloudPosturePages.dashboard.path} />
</Route>
</Switch>
</Routes>
</QueryClientProvider>
);

View file

@ -5,8 +5,8 @@
* 2.0.
*/
import React from 'react';
import { Redirect, Switch, useLocation } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Redirect, useLocation } from 'react-router-dom';
import { Routes, Route } from '@kbn/shared-ux-router';
import { TrackApplicationView } from '@kbn/usage-collection-plugin/public';
import { LATEST_FINDINGS_INDEX_PATTERN } from '../../../common/constants';
import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api';
@ -33,7 +33,7 @@ export const Configurations = () => {
return (
<CloudPosturePage query={dataViewQuery}>
<Switch>
<Routes>
<Route
exact
path={cloudPosturePages.findings.path}
@ -59,7 +59,7 @@ export const Configurations = () => {
render={() => <FindingsByResourceContainer dataView={dataViewQuery.data!} />}
/>
<Route path="*" render={() => <Redirect to={findingsNavigation.findings_default.path} />} />
</Switch>
</Routes>
</CloudPosturePage>
);
};

View file

@ -29,7 +29,7 @@ jest.mock('../../../common/api/use_cis_kubernetes_integration');
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useHistory: () => ({ push: jest.fn() }),
useHistory: () => ({ push: jest.fn(), location: { pathname: '' } }),
useLocation: jest.fn(),
}));

View file

@ -5,8 +5,7 @@
* 2.0.
*/
import React from 'react';
import { Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { TrackApplicationView } from '@kbn/usage-collection-plugin/public';
@ -41,7 +40,7 @@ const getDefaultQuery = ({
});
export const FindingsByResourceContainer = ({ dataView }: FindingsBaseProps) => (
<Switch>
<Routes>
<Route
exact
path={findingsNavigation.findings_by_resource.path}
@ -59,7 +58,7 @@ export const FindingsByResourceContainer = ({ dataView }: FindingsBaseProps) =>
</TrackApplicationView>
)}
/>
</Switch>
</Routes>
);
const LatestFindingsByResource = ({ dataView }: FindingsBaseProps) => {

View file

@ -16,8 +16,8 @@ import {
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { css } from '@emotion/react';
import { Redirect, Switch, useHistory, useLocation, matchPath } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Redirect, useHistory, useLocation, matchPath } from 'react-router-dom';
import { Routes, Route } from '@kbn/shared-ux-router';
import { Configurations } from '../configurations';
import { cloudPosturePages, findingsNavigation } from '../../common/navigation/constants';
import { Vulnerabilities } from '../vulnerabilities';
@ -103,7 +103,7 @@ export const Findings = () => {
</EuiTabs>
</>
)}
<Switch>
<Routes>
<Route
exact
path={cloudPosturePages.findings.path}
@ -125,7 +125,7 @@ export const Findings = () => {
/>
{/* Redirect to default findings page if no match */}
<Route path="*" render={() => <Redirect to={findingsNavigation.findings_default.path} />} />
</Switch>
</Routes>
</>
);
};

View file

@ -18,8 +18,7 @@ import { cx } from '@emotion/css';
import { DataView } from '@kbn/data-views-plugin/common';
import React, { useCallback, useMemo, useState, useEffect } from 'react';
import { i18n } from '@kbn/i18n';
import { Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { LOCAL_STORAGE_PAGE_SIZE_FINDINGS_KEY } from '../../common/constants';
import { useCloudPostureTable } from '../../common/hooks/use_cloud_posture_table';
import { useLatestVulnerabilities } from './hooks/use_latest_vulnerabilities';
@ -82,7 +81,7 @@ export const Vulnerabilities = () => {
}
return (
<Switch>
<Routes>
<Route
exact
path={findingsNavigation.resource_vulnerabilities.path}
@ -97,7 +96,7 @@ export const Vulnerabilities = () => {
path={findingsNavigation.vulnerabilities.path}
render={() => <VulnerabilitiesContent dataView={data} />}
/>
</Switch>
</Routes>
);
};

View file

@ -8,8 +8,9 @@
import type { AppMountParameters, CoreStart } from '@kbn/core/public';
import React, { useMemo } from 'react';
import { I18nProvider } from '@kbn/i18n-react';
import { Router, Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
// eslint-disable-next-line no-restricted-imports
import { Router } from 'react-router-dom';
import { Route, Routes } from '@kbn/shared-ux-router';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { coreMock } from '@kbn/core/public/mocks';
@ -47,9 +48,9 @@ export const TestProvider: React.FC<Partial<CspAppDeps>> = ({
<QueryClientProvider client={queryClient}>
<Router history={params.history}>
<I18nProvider>
<Switch>
<Routes>
<Route path="*" render={() => <>{children}</>} />
</Switch>
</Routes>
</I18nProvider>
</Router>
</QueryClientProvider>

View file

@ -6,8 +6,8 @@
*/
import React, { Component } from 'react';
import { Switch, Router, Redirect } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Redirect } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { ScopedHistory, ApplicationStart } from '@kbn/core/public';
import { i18n } from '@kbn/i18n';
@ -167,14 +167,14 @@ class AppComponent extends Component<AppProps, AppState> {
return (
<Router history={this.props.history}>
<Switch>
<Routes>
<Redirect exact from="/" to="/follower_indices" />
<Route exact path="/auto_follow_patterns/add" component={AutoFollowPatternAdd} />
<Route exact path="/auto_follow_patterns/edit/:id" component={AutoFollowPatternEdit} />
<Route exact path="/follower_indices/add" component={FollowerIndexAdd} />
<Route exact path="/follower_indices/edit/:id" component={FollowerIndexEdit} />
<Route exact path={['/:section']} component={CrossClusterReplicationHome} />
</Switch>
</Routes>
</Router>
);
}

View file

@ -6,8 +6,7 @@
*/
import React, { PureComponent } from 'react';
// eslint-disable-next-line no-restricted-imports
import { Route, Switch } from 'react-router-dom';
import { Route, Routes } from '@kbn/shared-ux-router';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiSpacer, EuiPageHeader } from '@elastic/eui';
@ -89,10 +88,10 @@ export class CrossClusterReplicationHome extends PureComponent {
<EuiSpacer size="l" />
<Switch>
<Routes>
<Route exact path={`/follower_indices`} component={FollowerIndicesList} />
<Route exact path={`/auto_follow_patterns`} component={AutoFollowPatternList} />
</Switch>
</Routes>
</>
);
}

View file

@ -7,14 +7,13 @@
import React, { useEffect } from 'react';
import { useParams } from 'react-router-dom';
import { Switch } from 'react-router-dom';
import { useActions, useMountedLogic, useValues } from 'kea';
import { EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import {
COLLECTION_EXPLORER_PATH,
@ -48,7 +47,7 @@ export const AnalyticsCollectionView: React.FC = () => {
if (analyticsCollection) {
return (
<Switch>
<Routes>
<Route exact path={COLLECTION_OVERVIEW_PATH}>
<AnalyticsCollectionOverview analyticsCollection={analyticsCollection} />
</Route>
@ -60,7 +59,7 @@ export const AnalyticsCollectionView: React.FC = () => {
<Route exact path={COLLECTION_EXPLORER_PATH}>
<AnalyticsCollectionExplorer />
</Route>
</Switch>
</Routes>
);
}

View file

@ -6,9 +6,8 @@
*/
import React from 'react';
import { Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { isVersionMismatch } from '../../../common/is_version_mismatch';
import { InitialAppData } from '../../../common/types';
@ -24,7 +23,7 @@ export const Analytics: React.FC<InitialAppData> = (props) => {
const incompatibleVersions = isVersionMismatch(enterpriseSearchVersion, kibanaVersion);
return (
<Switch>
<Routes>
<Route exact path={ROOT_PATH}>
{incompatibleVersions ? (
<VersionMismatchPage
@ -38,6 +37,6 @@ export const Analytics: React.FC<InitialAppData> = (props) => {
<Route path={COLLECTION_VIEW_PATH}>
<AnalyticsCollectionView />
</Route>
</Switch>
</Routes>
);
};

View file

@ -9,11 +9,9 @@ import '../../__mocks__/engine_logic.mock';
import React from 'react';
import { Switch } from 'react-router-dom';
import { shallow } from 'enzyme';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { AnalyticsRouter } from '.';
@ -22,7 +20,7 @@ describe('AnalyticsRouter', () => {
it('renders', () => {
const wrapper = shallow(<AnalyticsRouter />);
expect(wrapper.find(Switch)).toHaveLength(1);
expect(wrapper.find(Routes)).toHaveLength(1);
expect(wrapper.find(Route)).toHaveLength(9);
});
});

View file

@ -6,9 +6,9 @@
*/
import React from 'react';
import { Switch, Redirect } from 'react-router-dom';
import { Redirect } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import {
ENGINE_ANALYTICS_PATH,
@ -36,7 +36,7 @@ import {
export const AnalyticsRouter: React.FC = () => {
return (
<Switch>
<Routes>
<Route exact path={ENGINE_ANALYTICS_PATH}>
<Analytics />
</Route>
@ -64,6 +64,6 @@ export const AnalyticsRouter: React.FC = () => {
<Route>
<NotFound pageChrome={getEngineBreadcrumbs([ANALYTICS_TITLE])} />
</Route>
</Switch>
</Routes>
);
};

View file

@ -6,11 +6,10 @@
*/
import React, { useEffect } from 'react';
import { Switch } from 'react-router-dom';
import { useActions } from 'kea';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { ENGINE_CRAWLER_DOMAIN_PATH, ENGINE_CRAWLER_PATH } from '../../routes';
@ -27,13 +26,13 @@ export const CrawlerRouter: React.FC = () => {
}, []);
return (
<Switch>
<Routes>
<Route exact path={ENGINE_CRAWLER_PATH}>
<CrawlerOverview />
</Route>
<Route exact path={ENGINE_CRAWLER_DOMAIN_PATH}>
<CrawlerSingleDomain />
</Route>
</Switch>
</Routes>
);
};

View file

@ -8,11 +8,10 @@
import '../../__mocks__/engine_logic.mock';
import React from 'react';
import { Switch } from 'react-router-dom';
import { shallow } from 'enzyme';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { CurationsRouter } from '.';
@ -20,7 +19,7 @@ describe('CurationsRouter', () => {
it('renders', () => {
const wrapper = shallow(<CurationsRouter />);
expect(wrapper.find(Switch)).toHaveLength(1);
expect(wrapper.find(Routes)).toHaveLength(1);
expect(wrapper.find(Route)).toHaveLength(4);
});
});

View file

@ -6,9 +6,8 @@
*/
import React from 'react';
import { Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import {
ENGINE_CURATIONS_PATH,
@ -22,7 +21,7 @@ import { Curations, CurationCreation, CurationSuggestion } from './views';
export const CurationsRouter: React.FC = () => {
return (
<Switch>
<Routes>
<Route exact path={ENGINE_CURATIONS_PATH}>
<Curations />
</Route>
@ -35,6 +34,6 @@ export const CurationsRouter: React.FC = () => {
<Route path={ENGINE_CURATION_PATH}>
<Curation />
</Route>
</Switch>
</Routes>
);
};

View file

@ -15,10 +15,12 @@ import { unmountHandler } from '../../../__mocks__/shallow_useeffect.mock';
import { mockEngineValues } from '../../__mocks__';
import React from 'react';
import { Switch, Redirect } from 'react-router-dom';
import { Redirect } from 'react-router-dom';
import { shallow } from 'enzyme';
import { Routes } from '@kbn/shared-ux-router';
import { AnalyticsRouter } from '../analytics';
import { ApiLogs } from '../api_logs';
import { CrawlerRouter } from '../crawler';
@ -107,7 +109,7 @@ describe('EngineRouter', () => {
it('renders a default engine overview', () => {
const wrapper = shallow(<EngineRouter />);
expect(wrapper.find(Switch)).toHaveLength(1);
expect(wrapper.find(Routes)).toHaveLength(1);
expect(wrapper.find(EngineOverview)).toHaveLength(1);
});

View file

@ -6,12 +6,12 @@
*/
import React, { useEffect } from 'react';
import { Switch, Redirect, useParams } from 'react-router-dom';
import { Redirect, useParams } from 'react-router-dom';
import { useValues, useActions } from 'kea';
import { i18n } from '@kbn/i18n';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { setQueuedErrorMessage } from '../../../shared/flash_messages';
import { AppLogic } from '../../app_logic';
@ -96,7 +96,7 @@ export const EngineRouter: React.FC = () => {
if (isLoadingNewEngine || dataLoading) return <AppSearchPageTemplate isLoading />;
return (
<Switch>
<Routes>
<Route exact path={ENGINE_PATH}>
<EngineOverview />
</Route>
@ -163,6 +163,6 @@ export const EngineRouter: React.FC = () => {
<Route>
<NotFound pageChrome={getEngineBreadcrumbs()} />
</Route>
</Switch>
</Routes>
);
};

View file

@ -9,11 +9,10 @@ import { setMockValues } from '../../../__mocks__/kea_logic';
import '../../__mocks__/engine_logic.mock';
import React from 'react';
import { Switch } from 'react-router-dom';
import { shallow } from 'enzyme';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { rerender } from '../../../test_helpers';
@ -26,7 +25,7 @@ describe('SchemaRouter', () => {
const wrapper = shallow(<SchemaRouter />);
it('renders', () => {
expect(wrapper.find(Switch)).toHaveLength(1);
expect(wrapper.find(Routes)).toHaveLength(1);
expect(wrapper.find(Route)).toHaveLength(2);
});

View file

@ -6,11 +6,10 @@
*/
import React from 'react';
import { Switch } from 'react-router-dom';
import { useValues } from 'kea';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { ENGINE_REINDEX_JOB_PATH } from '../../routes';
import { EngineLogic } from '../engine';
@ -22,11 +21,11 @@ export const SchemaRouter: React.FC = () => {
const { isMetaEngine } = useValues(EngineLogic);
return (
<Switch>
<Routes>
<Route path={ENGINE_REINDEX_JOB_PATH}>
<ReindexJob />
</Route>
<Route>{isMetaEngine ? <MetaEngineSchema /> : <Schema />}</Route>
</Switch>
</Routes>
);
};

View file

@ -6,11 +6,11 @@
*/
import React, { useEffect } from 'react';
import { Redirect, Switch } from 'react-router-dom';
import { Redirect } from 'react-router-dom';
import { useValues } from 'kea';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { isVersionMismatch } from '../../../common/is_version_mismatch';
import { InitialAppData } from '../../../common/types';
@ -68,21 +68,21 @@ export const AppSearch: React.FC<InitialAppData> = (props) => {
};
return (
<Switch>
<Routes>
<Route exact path={SETUP_GUIDE_PATH}>
<SetupGuide />
</Route>
<Route>{showView()}</Route>
</Switch>
</Routes>
);
};
export const AppSearchUnconfigured: React.FC = () => (
<Switch>
<Routes>
<Route>
<Redirect to={SETUP_GUIDE_PATH} />
</Route>
</Switch>
</Routes>
);
export const AppSearchConfigured: React.FC<Required<InitialAppData>> = (props) => {
@ -102,7 +102,7 @@ export const AppSearchConfigured: React.FC<Required<InitialAppData>> = (props) =
}, []);
return (
<Switch>
<Routes>
{process.env.NODE_ENV === 'development' && (
<Route path={LIBRARY_PATH}>
<Library />
@ -145,6 +145,6 @@ export const AppSearchConfigured: React.FC<Required<InitialAppData>> = (props) =
<Route>
<NotFound />
</Route>
</Switch>
</Routes>
);
};

View file

@ -6,11 +6,11 @@
*/
import React, { useEffect } from 'react';
import { Redirect, Switch, useParams } from 'react-router-dom';
import { Redirect, useParams } from 'react-router-dom';
import { useActions } from 'kea';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { generateEncodedPath } from '../../../shared/encode_path_params';
import {
@ -41,7 +41,7 @@ export const SearchApplicationRouter: React.FC = () => {
}, [searchApplicationName]);
return (
<Switch>
<Routes>
<Redirect
from={SEARCH_APPLICATION_PATH}
to={generateEncodedPath(SEARCH_APPLICATION_TAB_PATH, {
@ -53,6 +53,6 @@ export const SearchApplicationRouter: React.FC = () => {
<Route path={SEARCH_APPLICATION_TAB_PATH}>
<SearchApplicationView />
</Route>
</Switch>
</Routes>
);
};

View file

@ -6,11 +6,11 @@
*/
import React, { useEffect, useLayoutEffect } from 'react';
import { useParams, Redirect, Switch } from 'react-router-dom';
import { useParams, Redirect } from 'react-router-dom';
import { useValues, useActions } from 'kea';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { Status } from '../../../../../common/types/api';
@ -88,7 +88,7 @@ export const SearchApplicationView: React.FC = () => {
onClose={closeDeleteSearchApplicationModal}
/>
) : null}
<Switch>
<Routes>
<Route
exact
path={`${SEARCH_APPLICATION_PATH}/${SearchApplicationViewTabs.PREVIEW}`}
@ -120,7 +120,7 @@ export const SearchApplicationView: React.FC = () => {
<SearchApplicationError notFound />
</EnterpriseSearchApplicationsPageTemplate>
</Route>
</Switch>
</Routes>
</>
);
};

View file

@ -6,9 +6,8 @@
*/
import React from 'react';
import { Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import {
SEARCH_APPLICATIONS_PATH,
@ -23,7 +22,7 @@ import { SearchApplicationsList } from './search_applications_list';
export const SearchApplicationsRouter: React.FC = () => {
return (
<Switch>
<Routes>
<Route exact path={SEARCH_APPLICATIONS_PATH}>
<SearchApplicationsList />
</Route>
@ -36,6 +35,6 @@ export const SearchApplicationsRouter: React.FC = () => {
<Route>
<NotFound />
</Route>
</Switch>
</Routes>
);
};

View file

@ -6,9 +6,9 @@
*/
import React from 'react';
import { Redirect, Switch } from 'react-router-dom';
import { Redirect } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { NotFound } from './components/not_found';
import { SearchApplicationsRouter } from './components/search_applications/search_applications_router';
@ -16,7 +16,7 @@ import { ROOT_PATH, SEARCH_APPLICATIONS_PATH } from './routes';
export const Applications = () => {
return (
<Switch>
<Routes>
<Redirect exact from={ROOT_PATH} to={SEARCH_APPLICATIONS_PATH} />
<Route path={SEARCH_APPLICATIONS_PATH}>
<SearchApplicationsRouter />
@ -24,6 +24,6 @@ export const Applications = () => {
<Route>
<NotFound />
</Route>
</Switch>
</Routes>
);
};

View file

@ -6,9 +6,8 @@
*/
import React from 'react';
import { Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { isVersionMismatch } from '../../../common/is_version_mismatch';
import { InitialAppData } from '../../../common/types';
@ -36,10 +35,10 @@ export const Elasticsearch: React.FC<InitialAppData> = (props) => {
};
return (
<Switch>
<Routes>
<Route exact path={ROOT_PATH}>
{showView()}
</Route>
</Switch>
</Routes>
);
};

View file

@ -6,9 +6,8 @@
*/
import React from 'react';
import { Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import {
NEW_INDEX_PATH,
@ -22,7 +21,7 @@ import { SelectConnector } from './select_connector/select_connector';
export const NewIndexRouter: React.FC = () => {
return (
<Switch>
<Routes>
<Route path={NEW_INDEX_PATH} exact>
<NewIndex />
</Route>
@ -32,6 +31,6 @@ export const NewIndexRouter: React.FC = () => {
<Route path={NEW_INDEX_METHOD_PATH} exact>
<NewSearchIndexPage />
</Route>
</Switch>
</Routes>
);
};

View file

@ -6,11 +6,11 @@
*/
import React, { useEffect } from 'react';
import { Redirect, Switch, useParams } from 'react-router-dom';
import { Redirect, useParams } from 'react-router-dom';
import { useActions } from 'kea';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import {
OLD_SEARCH_INDEX_CRAWLER_DOMAIN_DETAIL_PATH,
@ -42,7 +42,7 @@ export const SearchIndexRouter: React.FC = () => {
}, [indexName]);
return (
<Switch>
<Routes>
<Route path={SEARCH_INDEX_PATH} exact>
<SearchIndex />
</Route>
@ -56,6 +56,6 @@ export const SearchIndexRouter: React.FC = () => {
from={OLD_SEARCH_INDEX_CRAWLER_DOMAIN_DETAIL_PATH}
to={`${SEARCH_INDEX_PATH}/domain_management/:domainId}`}
/>
</Switch>
</Routes>
);
};

View file

@ -8,10 +8,11 @@
import '../../../__mocks__/react_router';
import React from 'react';
import { Switch } from 'react-router-dom';
import { shallow } from 'enzyme';
import { Routes } from '@kbn/shared-ux-router';
import { NewIndexRouter } from '../new_index/new_index_router';
import { SearchIndexRouter } from '../search_index/search_index_router';
@ -23,7 +24,7 @@ describe('SearchIndicesRouter', () => {
it('renders Search index routes', () => {
const wrapper = shallow(<SearchIndicesRouter />);
const routeSwitch = wrapper.find(Switch);
const routeSwitch = wrapper.find(Routes);
expect(routeSwitch.find(NewIndexRouter)).toHaveLength(1);
expect(routeSwitch.find(SearchIndices)).toHaveLength(1);

View file

@ -6,9 +6,8 @@
*/
import React from 'react';
import { Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { SEARCH_INDICES_PATH, SEARCH_INDEX_PATH, NEW_INDEX_PATH } from '../../routes';
@ -19,7 +18,7 @@ import { SearchIndices } from './search_indices';
export const SearchIndicesRouter: React.FC = () => {
return (
<Switch>
<Routes>
<Route path={NEW_INDEX_PATH}>
<NewIndexRouter />
</Route>
@ -29,6 +28,6 @@ export const SearchIndicesRouter: React.FC = () => {
<Route path={SEARCH_INDEX_PATH}>
<SearchIndexRouter />
</Route>
</Switch>
</Routes>
);
};

View file

@ -6,11 +6,11 @@
*/
import React from 'react';
import { Redirect, Switch } from 'react-router-dom';
import { Redirect } from 'react-router-dom';
import { useValues } from 'kea';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { isVersionMismatch } from '../../../common/is_version_mismatch';
import { InitialAppData } from '../../../common/types';
@ -49,26 +49,26 @@ export const EnterpriseSearchContent: React.FC<InitialAppData> = (props) => {
};
return (
<Switch>
<Routes>
<Route exact path={SETUP_GUIDE_PATH}>
<SetupGuide />
</Route>
<Route>{showView()}</Route>
</Switch>
</Routes>
);
};
export const EnterpriseSearchContentUnconfigured: React.FC = () => (
<Switch>
<Routes>
<Route>
<Redirect to={SETUP_GUIDE_PATH} />
</Route>
</Switch>
</Routes>
);
export const EnterpriseSearchContentConfigured: React.FC<Required<InitialAppData>> = () => {
return (
<Switch>
<Routes>
<Redirect exact from={ROOT_PATH} to={SEARCH_INDICES_PATH} />
<Route path={SEARCH_INDICES_PATH}>
<SearchIndicesRouter />
@ -79,6 +79,6 @@ export const EnterpriseSearchContentConfigured: React.FC<Required<InitialAppData
<Route>
<NotFound />
</Route>
</Switch>
</Routes>
);
};

View file

@ -6,11 +6,10 @@
*/
import React from 'react';
import { Switch } from 'react-router-dom';
import { useValues } from 'kea';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { isVersionMismatch } from '../../../common/is_version_mismatch';
import { InitialAppData } from '../../../common/types';
@ -54,13 +53,13 @@ export const EnterpriseSearchOverview: React.FC<InitialAppData> = ({
};
return (
<Switch>
<Routes>
<Route exact path={SETUP_GUIDE_PATH}>
<SetupGuide />
</Route>
<Route exact path={ROOT_PATH}>
{showView()}
</Route>
</Switch>
</Routes>
);
};

View file

@ -6,9 +6,8 @@
*/
import React from 'react';
import { Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { isVersionMismatch } from '../../../common/is_version_mismatch';
import { InitialAppData } from '../../../common/types';
@ -36,10 +35,10 @@ export const EnterpriseSearchEsre: React.FC<InitialAppData> = (props) => {
};
return (
<Switch>
<Routes>
<Route exact path={ROOT_PATH}>
{showView()}
</Route>
</Switch>
</Routes>
);
};

View file

@ -8,7 +8,6 @@
import React, { FC } from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { Router } from 'react-router-dom';
import { getContext, resetContext } from 'kea';
import { Store } from 'redux';
@ -17,6 +16,7 @@ import { AppMountParameters, CoreStart } from '@kbn/core/public';
import { I18nProvider } from '@kbn/i18n-react';
import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import { Router } from '@kbn/shared-ux-router';
import { DEFAULT_PRODUCT_FEATURES } from '../../common/constants';
import { ClientConfigType, InitialAppData, ProductAccess } from '../../common/types';

View file

@ -6,9 +6,8 @@
*/
import React from 'react';
import { Switch } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { Routes, Route } from '@kbn/shared-ux-router';
import { isVersionMismatch } from '../../../common/is_version_mismatch';
import { InitialAppData } from '../../../common/types';
@ -36,10 +35,10 @@ export const SearchExperiences: React.FC<InitialAppData> = (props) => {
};
return (
<Switch>
<Routes>
<Route exact path={ROOT_PATH}>
{showView()}
</Route>
</Switch>
</Routes>
);
};

Some files were not shown because too many files have changed in this diff Show more