Skip to content

Commit 5f52cf0

Browse files
[State Management] State syncing utilities (#53582) (#54454)
Today, apps rely on AppState and GlobalState in the ui/state_management module to deal with internal (app) and shared (global) state. These classes give apps an ability to read/write state, when is then synced to the URL as well as sessionStorage. They also react to changes in the URL and automatically update state & emit events when changes occur. This PR introduces new state synching utilities, which together with state containers src/plugins/kibana_utils/public/state_containers will be a replacement for AppState and GlobalState in New Platform. Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
1 parent 8636011 commit 5f52cf0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2790
-168
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"id": "stateContainersExamples",
3+
"version": "0.0.1",
4+
"kibanaVersion": "kibana",
5+
"configPath": ["state_containers_examples"],
6+
"server": false,
7+
"ui": true,
8+
"requiredPlugins": [],
9+
"optionalPlugins": []
10+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "state_containers_examples",
3+
"version": "1.0.0",
4+
"main": "target/examples/state_containers_examples",
5+
"kibana": {
6+
"version": "kibana",
7+
"templateVersion": "1.0.0"
8+
},
9+
"license": "Apache-2.0",
10+
"scripts": {
11+
"kbn": "node ../../scripts/kbn.js",
12+
"build": "rm -rf './target' && tsc"
13+
},
14+
"devDependencies": {
15+
"typescript": "3.7.2"
16+
}
17+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import { AppMountParameters } from 'kibana/public';
21+
import ReactDOM from 'react-dom';
22+
import React from 'react';
23+
import { createHashHistory, createBrowserHistory } from 'history';
24+
import { TodoAppPage } from './todo';
25+
26+
export interface AppOptions {
27+
appInstanceId: string;
28+
appTitle: string;
29+
historyType: History;
30+
}
31+
32+
export enum History {
33+
Browser,
34+
Hash,
35+
}
36+
37+
export const renderApp = (
38+
{ appBasePath, element }: AppMountParameters,
39+
{ appInstanceId, appTitle, historyType }: AppOptions
40+
) => {
41+
const history =
42+
historyType === History.Browser
43+
? createBrowserHistory({ basename: appBasePath })
44+
: createHashHistory();
45+
ReactDOM.render(
46+
<TodoAppPage
47+
history={history}
48+
appInstanceId={appInstanceId}
49+
appTitle={appTitle}
50+
appBasePath={appBasePath}
51+
isInitialRoute={() => {
52+
const stripTrailingSlash = (path: string) =>
53+
path.charAt(path.length - 1) === '/' ? path.substr(0, path.length - 1) : path;
54+
const currentAppUrl = stripTrailingSlash(history.createHref(history.location));
55+
if (historyType === History.Browser) {
56+
// browser history
57+
const basePath = stripTrailingSlash(appBasePath);
58+
return currentAppUrl === basePath && !history.location.search && !history.location.hash;
59+
} else {
60+
// hashed history
61+
return currentAppUrl === '#' && !history.location.search;
62+
}
63+
}}
64+
/>,
65+
element
66+
);
67+
68+
return () => ReactDOM.unmountComponentAtNode(element);
69+
};

test/typings/encode_uri_query.d.ts renamed to examples/state_containers_examples/public/index.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
* under the License.
1818
*/
1919

20-
declare module 'encode-uri-query' {
21-
function encodeUriQuery(query: string, usePercentageSpace?: boolean): string;
22-
// eslint-disable-next-line import/no-default-export
23-
export default encodeUriQuery;
24-
}
20+
import { StateContainersExamplesPlugin } from './plugin';
21+
22+
export const plugin = () => new StateContainersExamplesPlugin();
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import { AppMountParameters, CoreSetup, Plugin } from 'kibana/public';
21+
22+
export class StateContainersExamplesPlugin implements Plugin {
23+
public setup(core: CoreSetup) {
24+
core.application.register({
25+
id: 'state-containers-example-browser-history',
26+
title: 'State containers example - browser history routing',
27+
async mount(params: AppMountParameters) {
28+
const { renderApp, History } = await import('./app');
29+
return renderApp(params, {
30+
appInstanceId: '1',
31+
appTitle: 'Routing with browser history',
32+
historyType: History.Browser,
33+
});
34+
},
35+
});
36+
core.application.register({
37+
id: 'state-containers-example-hash-history',
38+
title: 'State containers example - hash history routing',
39+
async mount(params: AppMountParameters) {
40+
const { renderApp, History } = await import('./app');
41+
return renderApp(params, {
42+
appInstanceId: '2',
43+
appTitle: 'Routing with hash history',
44+
historyType: History.Hash,
45+
});
46+
},
47+
});
48+
}
49+
50+
public start() {}
51+
public stop() {}
52+
}

0 commit comments

Comments
 (0)