Skip to content

Commit

Permalink
move useUrlTracker to kibana_react, as it is a react hook
Browse files Browse the repository at this point in the history
improve
  • Loading branch information
Dosant committed Jan 10, 2020
1 parent e49d9ff commit b8d808c
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 23 deletions.
2 changes: 1 addition & 1 deletion examples/state_containers_examples/public/todo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions src/plugins/kibana_react/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
20 changes: 20 additions & 0 deletions src/plugins/kibana_react/public/use_url_tracker/index.ts
Original file line number Diff line number Diff line change
@@ -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';
Original file line number Diff line number Diff line change
@@ -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('/');
});
});
Original file line number Diff line number Diff line change
@@ -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]);
}
1 change: 0 additions & 1 deletion src/plugins/kibana_utils/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ export {
unhashUrl,
unhashQuery,
createUrlTracker,
useUrlTracker,
createKbnUrlControls,
getStateFromKbnUrl,
getStatesFromKbnUrl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ export {
getStatesFromKbnUrl,
IKbnUrlControls,
} from './kbn_url_storage';
export { createUrlTracker, useUrlTracker } from './url_tracker';
export { createUrlTracker } from './url_tracker';
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
*/

import { createBrowserHistory, History, Location } from 'history';
import { useLayoutEffect } from 'react';
import { getRelativeToHistoryPath } from './kbn_url_storage';

export interface IUrlTracker {
Expand Down Expand Up @@ -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]);
}

0 comments on commit b8d808c

Please sign in to comment.