Skip to content

Commit

Permalink
fix merge
Browse files Browse the repository at this point in the history
  • Loading branch information
Dosant committed Jan 10, 2020
1 parent b6f7847 commit eed6b51
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 28 deletions.
17 changes: 7 additions & 10 deletions examples/state_containers_examples/public/todo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
PureTransition,
syncStates,
getStateFromKbnUrl,
BaseState,
} from '../../../src/plugins/kibana_utils/public';
import { useUrlTracker } from '../../../src/plugins/kibana_react/public';
import {
Expand Down Expand Up @@ -79,7 +80,7 @@ const TodoApp: React.FC<TodoAppProps> = ({ filter }) => {
const { setText } = GlobalStateHelpers.useTransitions();
const { text } = GlobalStateHelpers.useState();
const { edit: editTodo, delete: deleteTodo, add: addTodo } = useTransitions();
const todos = useState();
const todos = useState().todos;
const filteredTodos = todos.filter(todo => {
if (!filter) return true;
if (filter === 'completed') return todo.completed;
Expand Down Expand Up @@ -306,22 +307,18 @@ export const TodoAppPage: React.FC<{
);
};

function withDefaultState<State>(
function withDefaultState<State extends BaseState>(
stateContainer: BaseStateContainer<State>,
// eslint-disable-next-line no-shadow
defaultState: State
): INullableBaseStateContainer<State> {
return {
...stateContainer,
set: (state: State | null) => {
if (Array.isArray(defaultState)) {
stateContainer.set(state || defaultState);
} else {
stateContainer.set({
...defaultState,
...state,
});
}
stateContainer.set({
...defaultState,
...state,
});
},
};
}
2 changes: 1 addition & 1 deletion src/plugins/kibana_utils/demos/demos.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('demos', () => {
describe('state sync', () => {
test('url sync demo works', async () => {
expect(await urlSyncResult).toMatchInlineSnapshot(
`"http://localhost/#?_s=!((completed:!f,id:0,text:'Learning%20state%20containers'),(completed:!f,id:2,text:test))"`
`"http://localhost/#?_s=(todos:!((completed:!f,id:0,text:'Learning%20state%20containers'),(completed:!f,id:2,text:test)))"`
);
});
});
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/kibana_utils/demos/state_sync/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

import { defaultState, pureTransitions, TodoActions, TodoState } from '../state_containers/todomvc';
import { BaseStateContainer, createStateContainer } from '../../public/state_containers';
import { BaseState, BaseStateContainer, createStateContainer } from '../../public/state_containers';
import {
createKbnUrlStateStorage,
syncState,
Expand Down Expand Up @@ -55,7 +55,7 @@ export const result = Promise.resolve()
return window.location.href;
});

function withDefaultState<State>(
function withDefaultState<State extends BaseState>(
// eslint-disable-next-line no-shadow
stateContainer: BaseStateContainer<State>,
// eslint-disable-next-line no-shadow
Expand Down
25 changes: 14 additions & 11 deletions src/plugins/kibana_utils/public/state_sync/state_sync.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/

import { BaseStateContainer, createStateContainer } from '../state_containers';
import { BaseState, BaseStateContainer, createStateContainer } from '../state_containers';
import {
defaultState,
pureTransitions,
Expand Down Expand Up @@ -89,7 +89,7 @@ describe('state_sync', () => {
// initial sync of storage to state is not happening
expect(container.getState()).toEqual(defaultState);

const storageState2 = [{ id: 1, text: 'todo', completed: true }];
const storageState2 = { todos: [{ id: 1, text: 'todo', completed: true }] };
(testStateStorage.get as jest.Mock).mockImplementation(() => storageState2);
storageChange$.next(storageState2);

Expand Down Expand Up @@ -124,7 +124,7 @@ describe('state_sync', () => {
start();

const originalState = container.getState();
const storageState = [...originalState];
const storageState = { ...originalState };
(testStateStorage.get as jest.Mock).mockImplementation(() => storageState);
storageChange$.next(storageState);

Expand All @@ -134,7 +134,7 @@ describe('state_sync', () => {
});

it('storage change to null should notify state', () => {
container.set([{ completed: false, id: 1, text: 'changed' }]);
container.set({ todos: [{ completed: false, id: 1, text: 'changed' }] });
const { stop, start } = syncStates([
{
stateContainer: withDefaultState(container, defaultState),
Expand Down Expand Up @@ -189,8 +189,8 @@ describe('state_sync', () => {
]);
start();

const newStateFromUrl = [{ completed: false, id: 1, text: 'changed' }];
history.replace('/#?_s=!((completed:!f,id:1,text:changed))');
const newStateFromUrl = { todos: [{ completed: false, id: 1, text: 'changed' }] };
history.replace('/#?_s=(todos:!((completed:!f,id:1,text:changed)))');

expect(container.getState()).toEqual(newStateFromUrl);
expect(JSON.parse(sessionStorage.getItem(key)!)).toEqual(newStateFromUrl);
Expand Down Expand Up @@ -220,7 +220,7 @@ describe('state_sync', () => {
expect(history.length).toBe(startHistoryLength + 1);

expect(getCurrentUrl()).toMatchInlineSnapshot(
`"/#?_s=!((completed:!t,id:0,text:'Learning%20state%20containers'),(completed:!t,id:2,text:'2'),(completed:!t,id:3,text:'3'))"`
`"/#?_s=(todos:!((completed:!t,id:0,text:'Learning%20state%20containers'),(completed:!t,id:2,text:'2'),(completed:!t,id:3,text:'3')))"`
);

stop();
Expand Down Expand Up @@ -248,14 +248,14 @@ describe('state_sync', () => {

expect(history.length).toBe(startHistoryLength + 1);
expect(getCurrentUrl()).toMatchInlineSnapshot(
`"/#?_s=!((completed:!t,id:0,text:'Learning%20state%20containers'),(completed:!t,id:2,text:'2'),(completed:!t,id:3,text:'3'))"`
`"/#?_s=(todos:!((completed:!t,id:0,text:'Learning%20state%20containers'),(completed:!t,id:2,text:'2'),(completed:!t,id:3,text:'3')))"`
);

await tick();

expect(history.length).toBe(startHistoryLength + 1);
expect(getCurrentUrl()).toMatchInlineSnapshot(
`"/#?_s=!((completed:!t,id:0,text:'Learning%20state%20containers'),(completed:!t,id:2,text:'2'),(completed:!t,id:3,text:'3'))"`
`"/#?_s=(todos:!((completed:!t,id:0,text:'Learning%20state%20containers'),(completed:!t,id:2,text:'2'),(completed:!t,id:3,text:'3')))"`
);

stop();
Expand Down Expand Up @@ -294,15 +294,18 @@ describe('state_sync', () => {
});
});

function withDefaultState<State>(
function withDefaultState<State extends BaseState>(
stateContainer: BaseStateContainer<State>,
// eslint-disable-next-line no-shadow
defaultState: State
): INullableBaseStateContainer<State> {
return {
...stateContainer,
set: (state: State | null) => {
stateContainer.set(state || defaultState);
stateContainer.set({
...defaultState,
...state,
});
},
};
}
6 changes: 5 additions & 1 deletion src/plugins/kibana_utils/public/state_sync/state_sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import defaultComparator from 'fast-deep-equal';
import { IStateSyncConfig } from './types';
import { IStateStorage } from './state_sync_state_storage';
import { distinctUntilChangedWithInitialValue } from '../../common';
import { BaseState } from '../state_containers';

/**
* Utility for syncing application state wrapped in state container
Expand Down Expand Up @@ -86,7 +87,10 @@ export interface ISyncStateRef<stateStorage extends IStateStorage = IStateStorag
// start syncing state with storage
start: StartSyncStateFnType;
}
export function syncState<State = unknown, StateStorage extends IStateStorage = IStateStorage>({
export function syncState<
State extends BaseState,
StateStorage extends IStateStorage = IStateStorage
>({
storageKey,
stateStorage,
stateContainer,
Expand Down
7 changes: 4 additions & 3 deletions src/plugins/kibana_utils/public/state_sync/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
* under the License.
*/

import { BaseStateContainer } from '../state_containers/types';
import { BaseState, BaseStateContainer } from '../state_containers/types';
import { IStateStorage } from './state_sync_state_storage';

export interface INullableBaseStateContainer<State> extends BaseStateContainer<State> {
export interface INullableBaseStateContainer<State extends BaseState>
extends BaseStateContainer<State> {
// State container for stateSync() have to accept "null"
// for example, set() implementation could handle null and fallback to some default state
// this is required to handle edge case, when state in storage becomes empty and syncing is in progress.
Expand All @@ -29,7 +30,7 @@ export interface INullableBaseStateContainer<State> extends BaseStateContainer<S
}

export interface IStateSyncConfig<
State = unknown,
State extends BaseState,
StateStorage extends IStateStorage = IStateStorage
> {
/**
Expand Down

0 comments on commit eed6b51

Please sign in to comment.