From b8d808c17c09035dff84ea2fdea10bc77c54a798 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Fri, 10 Jan 2020 15:27:01 +0300 Subject: [PATCH] move useUrlTracker to kibana_react, as it is a react hook improve --- .../state_containers_examples/public/todo.tsx | 2 +- src/plugins/kibana_react/public/index.ts | 1 + .../public/use_url_tracker/index.ts | 20 ++++++ .../use_url_tracker/use_url_tracker.test.tsx | 70 +++++++++++++++++++ .../use_url_tracker/use_url_tracker.tsx | 52 ++++++++++++++ src/plugins/kibana_utils/public/index.ts | 1 - .../public/state_management/url/index.ts | 2 +- .../state_management/url/url_tracker.ts | 20 ------ 8 files changed, 145 insertions(+), 23 deletions(-) create mode 100644 src/plugins/kibana_react/public/use_url_tracker/index.ts create mode 100644 src/plugins/kibana_react/public/use_url_tracker/use_url_tracker.test.tsx create mode 100644 src/plugins/kibana_react/public/use_url_tracker/use_url_tracker.tsx diff --git a/examples/state_containers_examples/public/todo.tsx b/examples/state_containers_examples/public/todo.tsx index fe84f48a4b9080..84defb4a91e3f1 100644 --- a/examples/state_containers_examples/public/todo.tsx +++ b/examples/state_containers_examples/public/todo.tsx @@ -40,9 +40,9 @@ import { createStateContainerReactHelpers, PureTransition, syncStates, - useUrlTracker, getStateFromKbnUrl, } from '../../../src/plugins/kibana_utils/public'; +import { useUrlTracker } from '../../../src/plugins/kibana_react/public'; import { defaultState, pureTransitions, diff --git a/src/plugins/kibana_react/public/index.ts b/src/plugins/kibana_react/public/index.ts index 10b7dd2b4da449..cfe89f16e99dd5 100644 --- a/src/plugins/kibana_react/public/index.ts +++ b/src/plugins/kibana_react/public/index.ts @@ -25,4 +25,5 @@ export * from './overlays'; export * from './ui_settings'; export * from './field_icon'; export * from './table_list_view'; +export { useUrlTracker } from './use_url_tracker'; export { toMountPoint } from './util'; diff --git a/src/plugins/kibana_react/public/use_url_tracker/index.ts b/src/plugins/kibana_react/public/use_url_tracker/index.ts new file mode 100644 index 00000000000000..fdceaf34e04ee7 --- /dev/null +++ b/src/plugins/kibana_react/public/use_url_tracker/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { useUrlTracker } from './use_url_tracker'; diff --git a/src/plugins/kibana_react/public/use_url_tracker/use_url_tracker.test.tsx b/src/plugins/kibana_react/public/use_url_tracker/use_url_tracker.test.tsx new file mode 100644 index 00000000000000..d1425a09b2f9c5 --- /dev/null +++ b/src/plugins/kibana_react/public/use_url_tracker/use_url_tracker.test.tsx @@ -0,0 +1,70 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { renderHook } from '@testing-library/react-hooks'; +import { useUrlTracker } from './use_url_tracker'; +import { StubBrowserStorage } from 'test_utils/stub_browser_storage'; +import { createMemoryHistory } from 'history'; + +describe('useUrlTracker', () => { + const key = 'key'; + let storage = new StubBrowserStorage(); + let history = createMemoryHistory(); + beforeEach(() => { + storage = new StubBrowserStorage(); + history = createMemoryHistory(); + }); + + it('should track history changes and save them to storage', () => { + expect(storage.getItem(key)).toBeNull(); + const { unmount } = renderHook(() => { + useUrlTracker(key, history, () => false, storage); + }); + expect(storage.getItem(key)).toBe('/'); + history.push('/change'); + expect(storage.getItem(key)).toBe('/change'); + unmount(); + history.push('/other-change'); + expect(storage.getItem(key)).toBe('/change'); + }); + + it('by default should restore initial url', () => { + storage.setItem(key, '/change'); + renderHook(() => { + useUrlTracker(key, history, undefined, storage); + }); + expect(history.location.pathname).toBe('/change'); + }); + + it('should restore initial url if shouldRestoreUrl cb returns true', () => { + storage.setItem(key, '/change'); + renderHook(() => { + useUrlTracker(key, history, () => true, storage); + }); + expect(history.location.pathname).toBe('/change'); + }); + + it('should not restore initial url if shouldRestoreUrl cb returns false', () => { + storage.setItem(key, '/change'); + renderHook(() => { + useUrlTracker(key, history, () => false, storage); + }); + expect(history.location.pathname).toBe('/'); + }); +}); diff --git a/src/plugins/kibana_react/public/use_url_tracker/use_url_tracker.tsx b/src/plugins/kibana_react/public/use_url_tracker/use_url_tracker.tsx new file mode 100644 index 00000000000000..97e69fe22a8420 --- /dev/null +++ b/src/plugins/kibana_react/public/use_url_tracker/use_url_tracker.tsx @@ -0,0 +1,52 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { History } from 'history'; +import { useLayoutEffect } from 'react'; +import { createUrlTracker } from '../../../kibana_utils/public/'; + +/** + * State management url_tracker in react hook form + * + * Replicates what src/legacy/ui/public/chrome/api/nav.ts did + * Persists the url in sessionStorage so it could be restored if navigated back to the app + * + * @param key - key to use in storage + * @param history - history instance to use + * @param shouldRestoreUrl - cb if url should be restored + * @param storage - storage to use. window.sessionStorage is default + */ +export function useUrlTracker( + key: string, + history: History, + shouldRestoreUrl: (urlToRestore: string) => boolean = () => true, + storage: Storage = sessionStorage +) { + useLayoutEffect(() => { + const urlTracker = createUrlTracker(key, storage); + const urlToRestore = urlTracker.getTrackedUrl(); + if (urlToRestore && shouldRestoreUrl(urlToRestore)) { + history.replace(urlToRestore); + } + const stopTrackingUrl = urlTracker.startTrackingUrl(history); + return () => { + stopTrackingUrl(); + }; + }, [key, history]); +} diff --git a/src/plugins/kibana_utils/public/index.ts b/src/plugins/kibana_utils/public/index.ts index 2c904a096072cb..0ba444c4e93956 100644 --- a/src/plugins/kibana_utils/public/index.ts +++ b/src/plugins/kibana_utils/public/index.ts @@ -40,7 +40,6 @@ export { unhashUrl, unhashQuery, createUrlTracker, - useUrlTracker, createKbnUrlControls, getStateFromKbnUrl, getStatesFromKbnUrl, diff --git a/src/plugins/kibana_utils/public/state_management/url/index.ts b/src/plugins/kibana_utils/public/state_management/url/index.ts index 6db029e12eb4d0..40491bf7a274bf 100644 --- a/src/plugins/kibana_utils/public/state_management/url/index.ts +++ b/src/plugins/kibana_utils/public/state_management/url/index.ts @@ -25,4 +25,4 @@ export { getStatesFromKbnUrl, IKbnUrlControls, } from './kbn_url_storage'; -export { createUrlTracker, useUrlTracker } from './url_tracker'; +export { createUrlTracker } from './url_tracker'; diff --git a/src/plugins/kibana_utils/public/state_management/url/url_tracker.ts b/src/plugins/kibana_utils/public/state_management/url/url_tracker.ts index 01f29357f3d61f..89e72e94ba6b46 100644 --- a/src/plugins/kibana_utils/public/state_management/url/url_tracker.ts +++ b/src/plugins/kibana_utils/public/state_management/url/url_tracker.ts @@ -18,7 +18,6 @@ */ import { createBrowserHistory, History, Location } from 'history'; -import { useLayoutEffect } from 'react'; import { getRelativeToHistoryPath } from './kbn_url_storage'; export interface IUrlTracker { @@ -48,22 +47,3 @@ export function createUrlTracker(key: string, storage: Storage = sessionStorage) }, }; } - -export function useUrlTracker( - key: string, - history: History, - shouldRestoreUrl: (urlToRestore: string) => boolean = () => true, - storage: Storage = sessionStorage -) { - useLayoutEffect(() => { - const urlTracker = createUrlTracker(key, storage); - const urlToRestore = urlTracker.getTrackedUrl(); - if (urlToRestore && shouldRestoreUrl(urlToRestore)) { - history.replace(urlToRestore); - } - const stopTrackingUrl = urlTracker.startTrackingUrl(history); - return () => { - stopTrackingUrl(); - }; - }, [key, history]); -}