2022-01-25 12:44:19 +00:00
|
|
|
import {
|
|
|
|
ApolloError,
|
|
|
|
ApolloQueryResult,
|
2022-11-24 14:24:08 +00:00
|
|
|
LazyQueryHookOptions as BaseLazyQueryHookOptions,
|
|
|
|
OperationVariables,
|
2022-03-09 08:56:55 +00:00
|
|
|
QueryHookOptions as BaseQueryHookOptions,
|
2022-02-21 13:32:38 +00:00
|
|
|
QueryResult,
|
2022-06-21 09:36:55 +00:00
|
|
|
useQuery as useBaseQuery,
|
2022-02-21 13:32:38 +00:00
|
|
|
} from "@apollo/client";
|
2022-03-09 08:56:55 +00:00
|
|
|
import { handleQueryAuthError, useUser } from "@saleor/auth";
|
|
|
|
import { PrefixedPermissions } from "@saleor/graphql/extendedTypes";
|
|
|
|
import {
|
|
|
|
PermissionEnum,
|
2022-06-21 09:36:55 +00:00
|
|
|
UserPermissionFragment,
|
2022-03-09 08:56:55 +00:00
|
|
|
} from "@saleor/graphql/types.generated";
|
2022-02-21 13:32:38 +00:00
|
|
|
import { RequireAtLeastOne } from "@saleor/misc";
|
2022-03-17 15:00:17 +00:00
|
|
|
import { DocumentNode } from "graphql";
|
2019-11-14 14:37:32 +00:00
|
|
|
import { useEffect } from "react";
|
|
|
|
import { useIntl } from "react-intl";
|
|
|
|
|
|
|
|
import useAppState from "./useAppState";
|
|
|
|
import useNotifier from "./useNotifier";
|
2022-11-24 14:24:08 +00:00
|
|
|
export { useLazyQuery } from "@apollo/client";
|
2019-11-14 14:37:32 +00:00
|
|
|
|
2021-03-09 08:44:09 +00:00
|
|
|
const getPermissionKey = (permission: string) =>
|
|
|
|
`PERMISSION_${permission}` as PrefixedPermissions;
|
|
|
|
|
2022-04-29 09:16:58 +00:00
|
|
|
export const allPermissions: Record<PrefixedPermissions, boolean> = Object.keys(
|
2022-06-21 09:36:55 +00:00
|
|
|
PermissionEnum,
|
2022-03-09 08:56:55 +00:00
|
|
|
).reduce(
|
2021-03-09 08:44:09 +00:00
|
|
|
(prev, code) => ({
|
|
|
|
...prev,
|
2022-06-21 09:36:55 +00:00
|
|
|
[getPermissionKey(code)]: false,
|
2021-03-09 08:44:09 +00:00
|
|
|
}),
|
2022-06-21 09:36:55 +00:00
|
|
|
{} as Record<PrefixedPermissions, boolean>,
|
2021-03-09 08:44:09 +00:00
|
|
|
);
|
|
|
|
|
2022-03-09 08:56:55 +00:00
|
|
|
const getUserPermissions = (
|
2022-06-21 09:36:55 +00:00
|
|
|
userPermissions: UserPermissionFragment[],
|
2022-03-09 08:56:55 +00:00
|
|
|
): Record<PrefixedPermissions, boolean> =>
|
2021-03-09 08:44:09 +00:00
|
|
|
userPermissions.reduce(
|
|
|
|
(prev, permission) => ({
|
|
|
|
...prev,
|
2022-06-21 09:36:55 +00:00
|
|
|
[getPermissionKey(permission.code)]: true,
|
2021-03-09 08:44:09 +00:00
|
|
|
}),
|
2022-06-21 09:36:55 +00:00
|
|
|
{} as Record<PrefixedPermissions, boolean>,
|
2021-03-09 08:44:09 +00:00
|
|
|
);
|
|
|
|
|
2019-11-14 14:37:32 +00:00
|
|
|
export interface LoadMore<TData, TVariables> {
|
|
|
|
loadMore: (
|
|
|
|
mergeFunc: (prev: TData, next: TData) => TData,
|
2022-06-21 09:36:55 +00:00
|
|
|
extraVariables: Partial<TVariables>,
|
2019-11-14 14:37:32 +00:00
|
|
|
) => Promise<ApolloQueryResult<TData>>;
|
|
|
|
}
|
|
|
|
|
2022-11-24 14:24:08 +00:00
|
|
|
export type LazyQueryHookOptions<
|
|
|
|
TData = any,
|
|
|
|
TVariables = OperationVariables
|
|
|
|
> = BaseLazyQueryHookOptions<TData, TVariables>;
|
|
|
|
|
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>;
|
2022-03-09 08:56:55 +00:00
|
|
|
export type QueryHookOptions<TData, TVariables> = Partial<
|
|
|
|
Omit<BaseQueryHookOptions<TData, TVariables>, "variables"> & {
|
|
|
|
displayLoader: boolean;
|
|
|
|
handleError?: (error: ApolloError) => void | undefined;
|
|
|
|
variables?: Omit<TVariables, PrefixedPermissions>;
|
|
|
|
}
|
|
|
|
>;
|
2022-11-24 14:24:08 +00:00
|
|
|
|
2019-11-14 14:37:32 +00:00
|
|
|
type UseQueryHook<TData, TVariables> = (
|
2022-06-21 09:36:55 +00:00
|
|
|
opts?: QueryHookOptions<TData, Omit<TVariables, PrefixedPermissions>>,
|
2019-11-19 11:31:32 +00:00
|
|
|
) => UseQueryResult<TData, TVariables>;
|
2019-11-14 14:37:32 +00:00
|
|
|
|
2022-03-09 08:56:55 +00:00
|
|
|
export function useQuery<TData, TVariables>(
|
|
|
|
query: DocumentNode,
|
|
|
|
{
|
2019-11-14 14:37:32 +00:00
|
|
|
displayLoader,
|
|
|
|
skip,
|
2021-08-20 13:58:53 +00:00
|
|
|
variables,
|
2022-01-25 12:44:19 +00:00
|
|
|
fetchPolicy,
|
2022-03-04 10:52:58 +00:00
|
|
|
handleError,
|
2022-03-09 08:56:55 +00:00
|
|
|
...opts
|
2022-06-21 09:36:55 +00:00
|
|
|
}: QueryHookOptions<TData, TVariables> = {},
|
2022-03-09 08:56:55 +00:00
|
|
|
): UseQueryResult<TData, TVariables> {
|
|
|
|
const notify = useNotifier();
|
|
|
|
const intl = useIntl();
|
|
|
|
const [, dispatchAppState] = useAppState();
|
|
|
|
const user = useUser();
|
|
|
|
const userPermissions = getUserPermissions(user.user?.userPermissions || []);
|
2021-03-09 08:44:09 +00:00
|
|
|
|
2022-03-09 08:56:55 +00:00
|
|
|
const variablesWithPermissions = {
|
|
|
|
...variables,
|
|
|
|
...allPermissions,
|
2022-06-21 09:36:55 +00:00
|
|
|
...userPermissions,
|
2022-03-09 08:56:55 +00:00
|
|
|
} as TVariables & Record<PrefixedPermissions, boolean>;
|
2020-05-07 11:04:15 +00:00
|
|
|
|
2022-03-09 08:56:55 +00:00
|
|
|
const queryData = useBaseQuery(query, {
|
|
|
|
...opts,
|
|
|
|
context: {
|
2022-06-21 09:36:55 +00:00
|
|
|
useBatching: true,
|
2022-03-09 08:56:55 +00:00
|
|
|
},
|
|
|
|
errorPolicy: "all",
|
|
|
|
fetchPolicy: fetchPolicy ?? "cache-and-network",
|
|
|
|
onError: error => {
|
2022-03-17 15:00:17 +00:00
|
|
|
if (!!handleError) {
|
|
|
|
handleError(error);
|
|
|
|
} else {
|
|
|
|
handleQueryAuthError(error, notify, user.logout, intl);
|
2019-11-14 14:37:32 +00:00
|
|
|
}
|
2022-03-09 08:56:55 +00:00
|
|
|
},
|
|
|
|
skip,
|
2022-06-21 09:36:55 +00:00
|
|
|
variables: variablesWithPermissions,
|
2022-03-09 08:56:55 +00:00
|
|
|
});
|
2019-11-14 14:37:32 +00:00
|
|
|
|
2022-03-09 08:56:55 +00:00
|
|
|
useEffect(() => {
|
|
|
|
if (displayLoader) {
|
|
|
|
dispatchAppState({
|
|
|
|
payload: {
|
2022-06-21 09:36:55 +00:00
|
|
|
value: queryData.loading,
|
2019-11-14 14:37:32 +00:00
|
|
|
},
|
2022-06-21 09:36:55 +00:00
|
|
|
type: "displayLoader",
|
2019-11-14 14:37:32 +00:00
|
|
|
});
|
2022-03-09 08:56:55 +00:00
|
|
|
}
|
|
|
|
}, [queryData.loading]);
|
2019-11-14 14:37:32 +00:00
|
|
|
|
2022-03-09 08:56:55 +00:00
|
|
|
const loadMore = (
|
|
|
|
mergeFunc: (previousResults: TData, fetchMoreResult: TData) => TData,
|
2022-06-21 09:36:55 +00:00
|
|
|
extraVariables: RequireAtLeastOne<TVariables>,
|
2022-03-09 08:56:55 +00:00
|
|
|
) =>
|
|
|
|
queryData.fetchMore({
|
|
|
|
query,
|
|
|
|
updateQuery: (previousResults, { fetchMoreResult }) => {
|
|
|
|
if (!fetchMoreResult) {
|
|
|
|
return previousResults;
|
|
|
|
}
|
|
|
|
return mergeFunc(previousResults, fetchMoreResult);
|
|
|
|
},
|
2022-06-21 09:36:55 +00:00
|
|
|
variables: { ...variablesWithPermissions, ...extraVariables },
|
2022-03-09 08:56:55 +00:00
|
|
|
});
|
2019-11-14 14:37:32 +00:00
|
|
|
|
2022-03-09 08:56:55 +00:00
|
|
|
return {
|
|
|
|
...queryData,
|
2022-06-21 09:36:55 +00:00
|
|
|
loadMore,
|
2022-03-09 08:56:55 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function makeQuery<TData, TVariables>(
|
2022-06-21 09:36:55 +00:00
|
|
|
query: DocumentNode,
|
2022-03-09 08:56:55 +00:00
|
|
|
): UseQueryHook<TData, TVariables> {
|
|
|
|
return (opts: QueryHookOptions<TData, TVariables>) =>
|
|
|
|
useQuery<TData, TVariables>(query, opts);
|
2019-11-14 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export default makeQuery;
|