saleor-dashboard/src/hooks/makeQuery.ts

109 lines
2.9 KiB
TypeScript
Raw Normal View History

2019-11-14 14:37:32 +00:00
import { ApolloQueryResult } from "apollo-client";
import { DocumentNode } from "graphql";
import { useEffect } from "react";
import { QueryResult, useQuery as useBaseQuery } from "react-apollo";
import { useIntl } from "react-intl";
import { commonMessages } from "@saleor/intl";
import { maybe, RequireAtLeastOne } from "@saleor/misc";
2020-05-07 11:04:15 +00:00
import { isJwtError } from "@saleor/auth/errors";
2019-11-14 14:37:32 +00:00
import useAppState from "./useAppState";
import useNotifier from "./useNotifier";
2020-05-07 11:04:15 +00:00
import useUser from "./useUser";
2019-11-14 14:37:32 +00:00
export interface LoadMore<TData, TVariables> {
loadMore: (
mergeFunc: (prev: TData, next: TData) => TData,
extraVariables: Partial<TVariables>
) => Promise<ApolloQueryResult<TData>>;
}
2019-11-19 11:31:32 +00:00
export type UseQueryResult<TData, TVariables> = QueryResult<TData, TVariables> &
2019-11-14 14:37:32 +00:00
LoadMore<TData, TVariables>;
2020-02-20 14:18:22 +00:00
type UseQueryOpts<TVariables> = Partial<{
2019-11-14 14:37:32 +00:00
displayLoader: boolean;
skip: boolean;
variables: TVariables;
}>;
type UseQueryHook<TData, TVariables> = (
2020-02-20 14:18:22 +00:00
opts: UseQueryOpts<TVariables>
2019-11-19 11:31:32 +00:00
) => UseQueryResult<TData, TVariables>;
2019-11-14 14:37:32 +00:00
function makeQuery<TData, TVariables>(
query: DocumentNode
): UseQueryHook<TData, TVariables> {
2019-11-19 15:01:54 +00:00
function useQuery({
2019-11-14 14:37:32 +00:00
displayLoader,
skip,
variables
2020-02-20 14:18:22 +00:00
}: UseQueryOpts<TVariables>): UseQueryResult<TData, TVariables> {
2019-11-14 14:37:32 +00:00
const notify = useNotifier();
const intl = useIntl();
const [, dispatchAppState] = useAppState();
2020-05-07 11:04:15 +00:00
const user = useUser();
2019-11-14 14:37:32 +00:00
const queryData = useBaseQuery(query, {
context: {
useBatching: true
},
errorPolicy: "all",
fetchPolicy: "cache-and-network",
skip,
variables
});
useEffect(() => {
if (displayLoader) {
dispatchAppState({
payload: {
value: queryData.loading
},
type: "displayLoader"
});
}
}, [queryData.loading]);
if (queryData.error) {
2020-05-07 11:04:15 +00:00
if (queryData.error.graphQLErrors.every(isJwtError)) {
user.logout();
notify({
text: intl.formatMessage(commonMessages.sessionExpired)
});
} else if (
2019-11-14 14:37:32 +00:00
!queryData.error.graphQLErrors.every(
err =>
maybe(() => err.extensions.exception.code) === "PermissionDenied"
)
) {
notify({
text: intl.formatMessage(commonMessages.somethingWentWrong)
});
}
}
const loadMore = (
mergeFunc: (previousResults: TData, fetchMoreResult: TData) => TData,
extraVariables: RequireAtLeastOne<TVariables>
) =>
queryData.fetchMore({
query,
updateQuery: (previousResults, { fetchMoreResult }) => {
if (!fetchMoreResult) {
return previousResults;
}
return mergeFunc(previousResults, fetchMoreResult);
},
variables: { ...variables, ...extraVariables }
});
return {
...queryData,
loadMore
};
}
return useQuery;
}
export default makeQuery;