Add search hooks

This commit is contained in:
dominik-zeglen 2019-11-19 16:01:54 +01:00
parent 6f2bff218f
commit 4daec82206
3 changed files with 90 additions and 6 deletions

View file

@ -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,

View file

@ -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;

View 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
}
);
}
});
}