EntityStore: make fetching the first page override the old list
This commit is contained in:
parent
e2510489c5
commit
cb8363d179
4 changed files with 61 additions and 7 deletions
|
@ -3,6 +3,7 @@ import {
|
|||
dismissEntities,
|
||||
entitiesFetchFail,
|
||||
entitiesFetchRequest,
|
||||
entitiesFetchSuccess,
|
||||
importEntities,
|
||||
} from '../actions';
|
||||
import reducer, { State } from '../reducer';
|
||||
|
@ -88,6 +89,44 @@ test('failure adds the error to the state', () => {
|
|||
expect(result.TestEntity!.lists.thingies!.state.error).toBe(error);
|
||||
});
|
||||
|
||||
test('import entities with override', () => {
|
||||
const state: State = {
|
||||
TestEntity: {
|
||||
store: { '1': { id: '1' }, '2': { id: '2' }, '3': { id: '3' } },
|
||||
lists: {
|
||||
thingies: {
|
||||
ids: new Set(['1', '2', '3']),
|
||||
state: { ...createListState(), totalCount: 3 },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const entities: TestEntity[] = [
|
||||
{ id: '4', msg: 'yolo' },
|
||||
{ id: '5', msg: 'benis' },
|
||||
];
|
||||
|
||||
const now = new Date();
|
||||
|
||||
const action = entitiesFetchSuccess(entities, 'TestEntity', 'thingies', {
|
||||
next: undefined,
|
||||
prev: undefined,
|
||||
totalCount: 2,
|
||||
error: null,
|
||||
fetched: true,
|
||||
fetching: false,
|
||||
lastFetchedAt: now,
|
||||
invalid: false,
|
||||
}, true);
|
||||
|
||||
const result = reducer(state, action);
|
||||
const cache = result.TestEntity as EntityCache<TestEntity>;
|
||||
|
||||
expect([...cache.lists.thingies!.ids]).toEqual(['4', '5']);
|
||||
expect(cache.lists.thingies!.state.lastFetchedAt).toBe(now); // Also check that newState worked
|
||||
});
|
||||
|
||||
test('deleting items', () => {
|
||||
const state: State = {
|
||||
TestEntity: {
|
||||
|
@ -114,7 +153,7 @@ test('dismiss items', () => {
|
|||
TestEntity: {
|
||||
store: { '1': { id: '1' }, '2': { id: '2' }, '3': { id: '3' } },
|
||||
lists: {
|
||||
'yolo': {
|
||||
yolo: {
|
||||
ids: new Set(['1', '2', '3']),
|
||||
state: { ...createListState(), totalCount: 3 },
|
||||
},
|
||||
|
|
|
@ -48,13 +48,20 @@ function entitiesFetchRequest(entityType: string, listKey?: string) {
|
|||
};
|
||||
}
|
||||
|
||||
function entitiesFetchSuccess(entities: Entity[], entityType: string, listKey?: string, newState?: EntityListState) {
|
||||
function entitiesFetchSuccess(
|
||||
entities: Entity[],
|
||||
entityType: string,
|
||||
listKey?: string,
|
||||
newState?: EntityListState,
|
||||
overwrite = false,
|
||||
) {
|
||||
return {
|
||||
type: ENTITIES_FETCH_SUCCESS,
|
||||
entityType,
|
||||
entities,
|
||||
listKey,
|
||||
newState,
|
||||
overwrite,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ function useEntities<TEntity extends Entity>(
|
|||
const next = useListState(path, 'next');
|
||||
const prev = useListState(path, 'prev');
|
||||
|
||||
const fetchPage = async(url: string): Promise<void> => {
|
||||
const fetchPage = async(url: string, overwrite = false): Promise<void> => {
|
||||
// Get `isFetching` state from the store again to prevent race conditions.
|
||||
const isFetching = selectListState(getState(), path, 'fetching');
|
||||
if (isFetching) return;
|
||||
|
@ -74,7 +74,7 @@ function useEntities<TEntity extends Entity>(
|
|||
error: null,
|
||||
lastFetchedAt: new Date(),
|
||||
invalid: false,
|
||||
}));
|
||||
}, overwrite));
|
||||
} catch (error) {
|
||||
dispatch(entitiesFetchFail(entityType, listKey, error));
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ function useEntities<TEntity extends Entity>(
|
|||
|
||||
const fetchEntities = async(): Promise<void> => {
|
||||
if (endpoint) {
|
||||
await fetchPage(endpoint);
|
||||
await fetchPage(endpoint, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -29,17 +29,25 @@ const importEntities = (
|
|||
entities: Entity[],
|
||||
listKey?: string,
|
||||
newState?: EntityListState,
|
||||
overwrite = false,
|
||||
): State => {
|
||||
return produce(state, draft => {
|
||||
const cache = draft[entityType] ?? createCache();
|
||||
cache.store = updateStore(cache.store, entities);
|
||||
|
||||
if (typeof listKey === 'string') {
|
||||
let list = { ...(cache.lists[listKey] ?? createList()) };
|
||||
let list = cache.lists[listKey] ?? createList();
|
||||
|
||||
if (overwrite) {
|
||||
list.ids = new Set();
|
||||
}
|
||||
|
||||
list = updateList(list, entities);
|
||||
|
||||
if (newState) {
|
||||
list.state = newState;
|
||||
}
|
||||
|
||||
cache.lists[listKey] = list;
|
||||
}
|
||||
|
||||
|
@ -133,7 +141,7 @@ function reducer(state: Readonly<State> = {}, action: EntityAction): State {
|
|||
case ENTITIES_DISMISS:
|
||||
return dismissEntities(state, action.entityType, action.ids, action.listKey);
|
||||
case ENTITIES_FETCH_SUCCESS:
|
||||
return importEntities(state, action.entityType, action.entities, action.listKey, action.newState);
|
||||
return importEntities(state, action.entityType, action.entities, action.listKey, action.newState, action.overwrite);
|
||||
case ENTITIES_FETCH_REQUEST:
|
||||
return setFetching(state, action.entityType, action.listKey, true);
|
||||
case ENTITIES_FETCH_FAIL:
|
||||
|
|
Loading…
Reference in a new issue