mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 10:40:07 -04:00
[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:
parent
bb3aa54c86
commit
a1d02824f1
274 changed files with 2130 additions and 2506 deletions
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
) : (
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -22,5 +22,6 @@
|
|||
"@kbn/developer-examples-plugin",
|
||||
"@kbn/analytics",
|
||||
"@kbn/i18n-react",
|
||||
"@kbn/shared-ux-router",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue