Skip to content

Commit

Permalink
[Docs] Clean up state management examples (#88980) (#89005)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dosant authored Jan 22, 2021
1 parent 71a4715 commit 104fdb8
Show file tree
Hide file tree
Showing 19 changed files with 302 additions and 544 deletions.
2 changes: 1 addition & 1 deletion examples/state_containers_examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This example app shows how to:
- Use state containers to manage your application state
- Integrate with browser history and hash history routing
- Integrate with browser history or hash history routing
- Sync your state container with the URL

To run this example, use the command `yarn start --run-examples`.
10 changes: 0 additions & 10 deletions examples/state_containers_examples/common/index.ts

This file was deleted.

4 changes: 2 additions & 2 deletions examples/state_containers_examples/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
"id": "stateContainersExamples",
"version": "0.0.1",
"kibanaVersion": "kibana",
"server": true,
"server": false,
"ui": true,
"requiredPlugins": ["navigation", "data", "developerExamples"],
"optionalPlugins": [],
"requiredBundles": ["kibanaUtils", "kibanaReact"]
"requiredBundles": ["kibanaUtils"]
}
62 changes: 62 additions & 0 deletions examples/state_containers_examples/public/common/example_page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* and the Server Side Public License, v 1; you may not use this file except in
* compliance with, at your election, the Elastic License or the Server Side
* Public License, v 1.
*/

import React, { PropsWithChildren } from 'react';
import { EuiPage, EuiPageSideBar, EuiSideNav } from '@elastic/eui';
import { CoreStart } from '../../../../src/core/public';

export interface ExampleLink {
title: string;
appId: string;
}

interface NavProps {
navigateToApp: CoreStart['application']['navigateToApp'];
exampleLinks: ExampleLink[];
}

const SideNav: React.FC<NavProps> = ({ navigateToApp, exampleLinks }: NavProps) => {
const navItems = exampleLinks.map((example) => ({
id: example.appId,
name: example.title,
onClick: () => navigateToApp(example.appId),
'data-test-subj': example.appId,
}));

return (
<EuiSideNav
items={[
{
name: 'State management examples',
id: 'home',
items: [...navItems],
},
]}
/>
);
};

interface Props {
navigateToApp: CoreStart['application']['navigateToApp'];
exampleLinks: ExampleLink[];
}

export const StateContainersExamplesPage: React.FC<Props> = ({
navigateToApp,
children,
exampleLinks,
}: PropsWithChildren<Props>) => {
return (
<EuiPage>
<EuiPageSideBar>
<SideNav navigateToApp={navigateToApp} exampleLinks={exampleLinks} />
</EuiPageSideBar>
{children}
</EuiPage>
);
};
106 changes: 52 additions & 54 deletions examples/state_containers_examples/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,106 +8,104 @@

import { AppMountParameters, CoreSetup, Plugin, AppNavLinkStatus } from '../../../src/core/public';
import { AppPluginDependencies } from './with_data_services/types';
import { PLUGIN_ID, PLUGIN_NAME } from '../common';
import { DeveloperExamplesSetup } from '../../developer_examples/public';
import image from './state_sync.png';

interface SetupDeps {
developerExamples: DeveloperExamplesSetup;
}

export class StateContainersExamplesPlugin implements Plugin {
public setup(core: CoreSetup, { developerExamples }: SetupDeps) {
const examples = {
stateContainersExampleBrowserHistory: {
title: 'Todo App (browser history)',
},
stateContainersExampleHashHistory: {
title: 'Todo App (hash history)',
},
stateContainersExampleWithDataServices: {
title: 'Search bar integration',
},
};

const exampleLinks = Object.keys(examples).map((id: string) => ({
appId: id,
title: examples[id as keyof typeof examples].title,
}));

core.application.register({
id: 'stateContainersExampleBrowserHistory',
title: 'State containers example - browser history routing',
title: examples.stateContainersExampleBrowserHistory.title,
navLinkStatus: AppNavLinkStatus.hidden,
async mount(params: AppMountParameters) {
const { renderApp, History } = await import('./todo/app');
return renderApp(params, {
appInstanceId: '1',
appTitle: 'Routing with browser history',
historyType: History.Browser,
});
const [coreStart] = await core.getStartServices();
return renderApp(
params,
{
appTitle: examples.stateContainersExampleBrowserHistory.title,
historyType: History.Browser,
},
{ navigateToApp: coreStart.application.navigateToApp, exampleLinks }
);
},
});
core.application.register({
id: 'stateContainersExampleHashHistory',
title: 'State containers example - hash history routing',
title: examples.stateContainersExampleHashHistory.title,
navLinkStatus: AppNavLinkStatus.hidden,
async mount(params: AppMountParameters) {
const { renderApp, History } = await import('./todo/app');
return renderApp(params, {
appInstanceId: '2',
appTitle: 'Routing with hash history',
historyType: History.Hash,
});
const [coreStart] = await core.getStartServices();
return renderApp(
params,
{
appTitle: examples.stateContainersExampleHashHistory.title,
historyType: History.Hash,
},
{ navigateToApp: coreStart.application.navigateToApp, exampleLinks }
);
},
});

core.application.register({
id: PLUGIN_ID,
title: PLUGIN_NAME,
id: 'stateContainersExampleWithDataServices',
title: examples.stateContainersExampleWithDataServices.title,
navLinkStatus: AppNavLinkStatus.hidden,
async mount(params: AppMountParameters) {
// Load application bundle
const { renderApp } = await import('./with_data_services/application');
// Get start services as specified in kibana.json
const [coreStart, depsStart] = await core.getStartServices();
// Render the application
return renderApp(coreStart, depsStart as AppPluginDependencies, params);
return renderApp(coreStart, depsStart as AppPluginDependencies, params, { exampleLinks });
},
});

developerExamples.register({
appId: 'stateContainersExampleBrowserHistory',
title: 'State containers using browser history',
description: `An example todo app that uses browser history and state container utilities like createStateContainerReactHelpers,
createStateContainer, createKbnUrlStateStorage, createSessionStorageStateStorage,
syncStates and getStateFromKbnUrl to keep state in sync with the URL. Change some parameters, navigate away and then back, and the
state should be preserved.`,
appId: exampleLinks[0].appId,
title: 'State Management',
description: 'Examples of using state containers and state syncing utils.',
image,
links: [
{
label: 'README',
label: 'State containers README',
href:
'https://github.com/elastic/kibana/tree/master/src/plugins/kibana_utils/docs/state_containers/README.md',
'https://github.com/elastic/kibana/tree/master/src/plugins/kibana_utils/docs/state_containers',
iconType: 'logoGithub',
size: 's',
target: '_blank',
},
],
});

developerExamples.register({
appId: 'stateContainersExampleHashHistory',
title: 'State containers using hash history',
description: `An example todo app that uses hash history and state container utilities like createStateContainerReactHelpers,
createStateContainer, createKbnUrlStateStorage, createSessionStorageStateStorage,
syncStates and getStateFromKbnUrl to keep state in sync with the URL. Change some parameters, navigate away and then back, and the
state should be preserved.`,
links: [
{
label: 'README',
label: 'State sync utils README',
href:
'https://github.com/elastic/kibana/tree/master/src/plugins/kibana_utils/docs/state_containers/README.md',
'https://github.com/elastic/kibana/tree/master/src/plugins/kibana_utils/docs/state_sync',
iconType: 'logoGithub',
size: 's',
target: '_blank',
},
],
});

developerExamples.register({
appId: PLUGIN_ID,
title: 'Sync state from a query bar with the url',
description: `Shows how to use data.syncQueryStateWitUrl in combination with state container utilities from kibana_utils to
show a query bar that stores state in the url and is kept in sync.
`,
links: [
{
label: 'README',
href:
'https://github.com/elastic/kibana/blob/master/src/plugins/data/public/query/state_sync/README.md',
iconType: 'logoGithub',
label: 'Kibana navigation best practices',
href: 'https://www.elastic.co/guide/en/kibana/master/kibana-navigation.html',
iconType: 'logoKibana',
size: 's',
target: '_blank',
},
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 12 additions & 21 deletions examples/state_containers_examples/public/todo/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
* Public License, v 1.
*/

import { AppMountParameters } from 'kibana/public';
import { AppMountParameters, CoreStart } from 'kibana/public';
import ReactDOM from 'react-dom';
import React from 'react';
import { createHashHistory } from 'history';
import { TodoAppPage } from './todo';
import { StateContainersExamplesPage, ExampleLink } from '../common/example_page';

export interface AppOptions {
appInstanceId: string;
appTitle: string;
historyType: History;
}
Expand All @@ -23,30 +23,21 @@ export enum History {
Hash,
}

export interface Deps {
navigateToApp: CoreStart['application']['navigateToApp'];
exampleLinks: ExampleLink[];
}

export const renderApp = (
{ appBasePath, element, history: platformHistory }: AppMountParameters,
{ appInstanceId, appTitle, historyType }: AppOptions
{ appTitle, historyType }: AppOptions,
{ navigateToApp, exampleLinks }: Deps
) => {
const history = historyType === History.Browser ? platformHistory : createHashHistory();
ReactDOM.render(
<TodoAppPage
history={history}
appInstanceId={appInstanceId}
appTitle={appTitle}
appBasePath={appBasePath}
isInitialRoute={() => {
const stripTrailingSlash = (path: string) =>
path.charAt(path.length - 1) === '/' ? path.substr(0, path.length - 1) : path;
const currentAppUrl = stripTrailingSlash(history.createHref(history.location));
if (historyType === History.Browser) {
// browser history
return currentAppUrl === '' && !history.location.search && !history.location.hash;
} else {
// hashed history
return currentAppUrl === '#' && !history.location.search;
}
}}
/>,
<StateContainersExamplesPage navigateToApp={navigateToApp} exampleLinks={exampleLinks}>
<TodoAppPage history={history} appTitle={appTitle} appBasePath={appBasePath} />
</StateContainersExamplesPage>,
element
);

Expand Down
Loading

0 comments on commit 104fdb8

Please sign in to comment.