Add search hooks
This commit is contained in:
parent
6f2bff218f
commit
4daec82206
3 changed files with 90 additions and 6 deletions
|
@ -31,7 +31,7 @@ type UseQueryHook<TData, TVariables> = (
|
|||
function makeQuery<TData, TVariables>(
|
||||
query: DocumentNode
|
||||
): UseQueryHook<TData, TVariables> {
|
||||
function useQuery<TData, TVariables>({
|
||||
function useQuery({
|
||||
displayLoader,
|
||||
require,
|
||||
skip,
|
||||
|
|
|
@ -1,18 +1,57 @@
|
|||
import { DocumentNode } from "graphql";
|
||||
import { useState } from "react";
|
||||
import { QueryResult } from "react-apollo";
|
||||
|
||||
import Debounce from "../components/Debounce";
|
||||
import { UseQueryResult } from "./makeQuery";
|
||||
import makeQuery, { UseQueryResult } from "./makeQuery";
|
||||
import useDebounce from "./useDebounce";
|
||||
|
||||
export interface SearchQueryVariables {
|
||||
export interface SearchVariables {
|
||||
after?: string;
|
||||
first: number;
|
||||
query: string;
|
||||
}
|
||||
|
||||
function makeSearch<TData, TVariables extends SearchQueryVariables>(
|
||||
export interface UseSearchResult<TData, TVariables extends SearchVariables> {
|
||||
loadMore: () => void;
|
||||
result: QueryResult<TData, TVariables>;
|
||||
search: (query: string) => void;
|
||||
}
|
||||
export type UseSearchOpts<TVariables extends SearchVariables> = Partial<{
|
||||
skip: boolean;
|
||||
variables: TVariables;
|
||||
}>;
|
||||
export type UseSearchHook<TData, TVariables extends SearchVariables> = (
|
||||
opts: UseSearchOpts<TVariables>
|
||||
) => UseSearchResult<TData, TVariables>;
|
||||
|
||||
function makeSearch<TData, TVariables extends SearchVariables>(
|
||||
query: DocumentNode,
|
||||
loadMoreFn: (result: UseQueryResult<TData, TVariables>) => void
|
||||
): UseSearchHook<TData, TVariables> {
|
||||
const useSearchQuery = makeQuery<TData, TVariables>(query);
|
||||
|
||||
function useSearch(
|
||||
opts: UseSearchOpts<TVariables>
|
||||
): UseSearchResult<TData, TVariables> {
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const debouncedSearch = useDebounce(setSearchQuery);
|
||||
const result = useSearchQuery({
|
||||
...opts,
|
||||
displayLoader: true,
|
||||
variables: {
|
||||
...opts.variables,
|
||||
query: searchQuery
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
loadMore: () => loadMoreFn(result),
|
||||
result,
|
||||
search: debouncedSearch
|
||||
};
|
||||
}
|
||||
|
||||
return useSearch;
|
||||
}
|
||||
|
||||
export default makeSearch;
|
||||
|
|
45
src/hooks/makeTopLevelSearch.ts
Normal file
45
src/hooks/makeTopLevelSearch.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
import { DocumentNode } from "graphql";
|
||||
|
||||
import { PageInfoFragment } from "@saleor/types/PageInfoFragment";
|
||||
import makeSearch, { SearchVariables, UseSearchHook } from "./makeSearch";
|
||||
|
||||
export interface SearchData {
|
||||
search: {
|
||||
edges: Array<{
|
||||
node: any;
|
||||
}>;
|
||||
pageInfo: PageInfoFragment;
|
||||
};
|
||||
}
|
||||
|
||||
function makeTopLevelSearch<
|
||||
TData extends SearchData,
|
||||
TVariables extends SearchVariables
|
||||
>(query: DocumentNode): UseSearchHook<TData, TVariables> {
|
||||
return makeSearch<TData, TVariables>(query, result => {
|
||||
if (result.data.search.pageInfo.hasNextPage) {
|
||||
result.loadMore(
|
||||
(prev, next) => {
|
||||
if (
|
||||
prev.search.pageInfo.endCursor === next.search.pageInfo.endCursor
|
||||
) {
|
||||
return prev;
|
||||
}
|
||||
|
||||
return {
|
||||
...prev,
|
||||
search: {
|
||||
...prev.search,
|
||||
edges: [...prev.search.edges, ...next.search.edges],
|
||||
pageInfo: next.search.pageInfo
|
||||
}
|
||||
};
|
||||
},
|
||||
{
|
||||
...result.variables,
|
||||
after: result.data.search.pageInfo.endCursor
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue