refactor(core): refactor search actions and reducer

Convert to TS
Proper search action type
Replace immutable with immer
General cleanup
This commit is contained in:
Vladislav Shkodin
2021-04-06 19:28:15 +03:00
committed by GitHub
parent 3211f94f4a
commit e32ffdf587
10 changed files with 162 additions and 228 deletions

View File

@ -1,3 +1,4 @@
import { List } from 'immutable';
import auth from './auth';
import config from './config';
import integrations, * as fromIntegrations from './integrations';
@ -50,14 +51,10 @@ export function selectPublishedSlugs(state: State, collection: string) {
}
export function selectSearchedEntries(state: State, availableCollections: string[]) {
const searchItems = state.search.get('entryIds');
// only return search results for actually available collections
return (
searchItems &&
searchItems
.filter(({ collection }) => availableCollections.indexOf(collection) !== -1)
.map(({ collection, slug }) => fromEntries.selectEntry(state.entries, collection, slug))
);
return List(state.search.entryIds)
.filter(entryId => availableCollections.indexOf(entryId!.collection) !== -1)
.map(entryId => fromEntries.selectEntry(state.entries, entryId!.collection, entryId!.slug));
}
export function selectDeployPreview(state: State, collection: string, slug: string) {

View File

@ -1,89 +0,0 @@
import { Map, List } from 'immutable';
import {
SEARCH_ENTRIES_REQUEST,
SEARCH_ENTRIES_SUCCESS,
QUERY_REQUEST,
QUERY_SUCCESS,
SEARCH_CLEAR,
} from 'Actions/search';
let loadedEntries;
let response;
let page;
let searchTerm;
let searchCollections;
const defaultState = Map({
isFetching: false,
term: null,
collections: null,
page: 0,
entryIds: List([]),
queryHits: Map({}),
});
function entries(state = defaultState, action) {
switch (action.type) {
case SEARCH_CLEAR:
return defaultState;
case SEARCH_ENTRIES_REQUEST:
if (action.payload.searchTerm !== state.get('term')) {
return state.withMutations(map => {
map.set('isFetching', true);
map.set('term', action.payload.searchTerm);
map.set('collections', List(action.payload.searchCollections));
map.set('page', action.payload.page);
});
}
return state;
case SEARCH_ENTRIES_SUCCESS:
loadedEntries = action.payload.entries;
page = action.payload.page;
searchTerm = action.payload.searchTerm;
searchCollections = action.payload.searchCollections;
return state.withMutations(map => {
const entryIds = List(
loadedEntries.map(entry => ({ collection: entry.collection, slug: entry.slug })),
);
map.set('isFetching', false);
map.set('fetchID', null);
map.set('page', page);
map.set('term', searchTerm);
map.set('collections', List(searchCollections));
map.set(
'entryIds',
!page || isNaN(page) || page === 0
? entryIds
: map.get('entryIds', List()).concat(entryIds),
);
});
case QUERY_REQUEST:
if (action.payload.searchTerm !== state.get('term')) {
return state.withMutations(map => {
map.set('isFetching', action.payload.namespace ? true : false);
map.set('fetchID', action.payload.namespace);
map.set('term', action.payload.searchTerm);
});
}
return state;
case QUERY_SUCCESS:
searchTerm = action.payload.searchTerm;
response = action.payload.response;
return state.withMutations(map => {
map.set('isFetching', false);
map.set('fetchID', null);
map.set('term', searchTerm);
map.mergeIn(['queryHits'], Map({ [action.payload.namespace]: response.hits }));
});
default:
return state;
}
}
export default entries;

View File

@ -0,0 +1,88 @@
import { produce } from 'immer';
import {
QUERY_FAILURE,
QUERY_REQUEST,
QUERY_SUCCESS,
SEARCH_CLEAR,
SEARCH_ENTRIES_FAILURE,
SEARCH_ENTRIES_REQUEST,
SEARCH_ENTRIES_SUCCESS,
SearchAction,
} from '../actions/search';
import { EntryValue } from '../valueObjects/Entry';
export type Search = {
isFetching: boolean;
term: string;
collections: string[];
page: number;
entryIds: { collection: string; slug: string }[];
queryHits: Record<string, EntryValue[]>;
error: Error | undefined;
};
const defaultState: Search = {
isFetching: false,
term: '',
collections: [],
page: 0,
entryIds: [],
queryHits: {},
error: undefined,
};
const search = produce((state: Search, action: SearchAction) => {
switch (action.type) {
case SEARCH_CLEAR:
return defaultState;
case SEARCH_ENTRIES_REQUEST: {
const { page, searchTerm, searchCollections } = action.payload;
state.isFetching = true;
state.term = searchTerm;
state.collections = searchCollections;
state.page = page;
break;
}
case SEARCH_ENTRIES_SUCCESS: {
const { entries, page } = action.payload;
const entryIds = entries.map(entry => ({ collection: entry.collection, slug: entry.slug }));
state.isFetching = false;
state.page = page;
state.entryIds =
!page || isNaN(page) || page === 0 ? entryIds : state.entryIds.concat(entryIds);
break;
}
case SEARCH_ENTRIES_FAILURE: {
const { error } = action.payload;
state.isFetching = false;
state.error = error;
break;
}
case QUERY_REQUEST: {
const { searchTerm } = action.payload;
state.isFetching = true;
state.term = searchTerm;
break;
}
case QUERY_SUCCESS: {
const { namespace, hits } = action.payload;
state.isFetching = false;
state.queryHits[namespace] = hits;
break;
}
case QUERY_FAILURE: {
const { error } = action.payload;
state.isFetching = false;
state.error = error;
}
}
}, defaultState);
export default search;