Fix types
This commit is contained in:
parent
2f7867bf99
commit
ebd4f3093c
2 changed files with 75 additions and 105 deletions
|
@ -1,19 +1,14 @@
|
|||
import { ApolloError } from "apollo-client";
|
||||
import { ApolloError, MutationUpdaterFn } from "apollo-client";
|
||||
import { DocumentNode } from "graphql";
|
||||
import React from "react";
|
||||
import {
|
||||
Mutation,
|
||||
MutationFn,
|
||||
MutationResult,
|
||||
MutationUpdaterFn
|
||||
} from "react-apollo";
|
||||
import { Mutation, MutationFunction, MutationResult } from "react-apollo";
|
||||
|
||||
import useNotifier from "./hooks/useNotifier";
|
||||
import i18n from "./i18n";
|
||||
|
||||
export interface TypedMutationInnerProps<TData, TVariables> {
|
||||
children: (
|
||||
mutateFn: MutationFn<TData, TVariables>,
|
||||
mutateFn: MutationFunction<TData, TVariables>,
|
||||
result: MutationResult<TData>
|
||||
) => React.ReactNode;
|
||||
onCompleted?: (data: TData) => void;
|
||||
|
@ -21,26 +16,17 @@ export interface TypedMutationInnerProps<TData, TVariables> {
|
|||
variables?: TVariables;
|
||||
}
|
||||
|
||||
// For some reason Mutation returns () => Element instead of () => ReactNode
|
||||
export function TypedMutation<TData, TVariables>(
|
||||
mutation: DocumentNode,
|
||||
update?: MutationUpdaterFn<TData>
|
||||
) {
|
||||
class StrictTypedMutation extends Mutation<TData, TVariables> {}
|
||||
return (props: TypedMutationInnerProps<TData, TVariables>) => {
|
||||
const notify = useNotifier();
|
||||
// Obviously, this is workaround to the problem described here:
|
||||
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/32588
|
||||
const {
|
||||
children,
|
||||
onCompleted,
|
||||
onError,
|
||||
variables
|
||||
} = props as JSX.LibraryManagedAttributes<
|
||||
typeof StrictTypedMutation,
|
||||
typeof props
|
||||
>;
|
||||
const { children, onCompleted, onError, variables } = props;
|
||||
|
||||
return (
|
||||
<StrictTypedMutation
|
||||
<Mutation
|
||||
mutation={mutation}
|
||||
onCompleted={onCompleted}
|
||||
onError={err => {
|
||||
|
@ -55,8 +41,8 @@ export function TypedMutation<TData, TVariables>(
|
|||
variables={variables}
|
||||
update={update}
|
||||
>
|
||||
{children}
|
||||
</StrictTypedMutation>
|
||||
{(mutateFn, result) => <>{children(mutateFn, result)}</>}
|
||||
</Mutation>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
148
src/queries.tsx
148
src/queries.tsx
|
@ -1,9 +1,9 @@
|
|||
import { ApolloQueryResult } from "apollo-client";
|
||||
import { DocumentNode } from "graphql";
|
||||
import gql from "graphql-tag";
|
||||
import React from "react";
|
||||
import { Query, QueryResult } from "react-apollo";
|
||||
|
||||
import { ApolloQueryResult } from "apollo-client";
|
||||
import AppProgress from "./components/AppProgress";
|
||||
import ErrorPage from "./components/ErrorPage/ErrorPage";
|
||||
import useNavigator from "./hooks/useNavigator";
|
||||
|
@ -62,98 +62,82 @@ class QueryProgress extends React.Component<QueryProgressProps, {}> {
|
|||
}
|
||||
}
|
||||
|
||||
// For some reason Query returns () => Element instead of () => ReactNode
|
||||
export function TypedQuery<TData, TVariables>(
|
||||
query: DocumentNode
|
||||
): React.FC<TypedQueryInnerProps<TData, TVariables>> {
|
||||
class StrictTypedQuery extends Query<TData, TVariables> {}
|
||||
return props => {
|
||||
return ({ children, displayLoader, skip, variables, require }) => {
|
||||
const navigate = useNavigator();
|
||||
const pushMessage = useNotifier();
|
||||
|
||||
return (
|
||||
<AppProgress>
|
||||
{({ setProgressState }) => {
|
||||
// Obviously, this is workaround to the problem described here:
|
||||
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/32588
|
||||
const {
|
||||
children,
|
||||
displayLoader,
|
||||
skip,
|
||||
variables,
|
||||
require
|
||||
} = props as JSX.LibraryManagedAttributes<
|
||||
typeof StrictTypedQuery,
|
||||
typeof props
|
||||
>;
|
||||
return (
|
||||
<StrictTypedQuery
|
||||
fetchPolicy="cache-and-network"
|
||||
query={query}
|
||||
variables={variables}
|
||||
skip={skip}
|
||||
context={{ useBatching: true }}
|
||||
>
|
||||
{queryData => {
|
||||
if (queryData.error) {
|
||||
const msg = i18n.t("Something went wrong: {{ message }}", {
|
||||
message: queryData.error.message
|
||||
});
|
||||
pushMessage({ text: msg });
|
||||
}
|
||||
|
||||
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 }
|
||||
});
|
||||
|
||||
let childrenOrNotFound = children({
|
||||
...queryData,
|
||||
loadMore
|
||||
{({ setProgressState }) => (
|
||||
<Query
|
||||
fetchPolicy="cache-and-network"
|
||||
query={query}
|
||||
variables={variables}
|
||||
skip={skip}
|
||||
context={{ useBatching: true }}
|
||||
>
|
||||
{queryData => {
|
||||
if (queryData.error) {
|
||||
const msg = i18n.t("Something went wrong: {{ message }}", {
|
||||
message: queryData.error.message
|
||||
});
|
||||
if (
|
||||
!queryData.loading &&
|
||||
require &&
|
||||
queryData.data &&
|
||||
!require.reduce(
|
||||
(acc, key) => acc && queryData.data[key] !== null,
|
||||
true
|
||||
)
|
||||
) {
|
||||
childrenOrNotFound = (
|
||||
<ErrorPage onBack={() => navigate("/")} />
|
||||
);
|
||||
}
|
||||
pushMessage({ text: msg });
|
||||
}
|
||||
|
||||
if (displayLoader) {
|
||||
return (
|
||||
<QueryProgress
|
||||
loading={queryData.loading}
|
||||
onCompleted={() => setProgressState(false)}
|
||||
onLoading={() => setProgressState(true)}
|
||||
>
|
||||
{childrenOrNotFound}
|
||||
</QueryProgress>
|
||||
);
|
||||
}
|
||||
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 childrenOrNotFound;
|
||||
}}
|
||||
</StrictTypedQuery>
|
||||
);
|
||||
}}
|
||||
let childrenOrNotFound = children({
|
||||
...queryData,
|
||||
loadMore
|
||||
});
|
||||
if (
|
||||
!queryData.loading &&
|
||||
require &&
|
||||
queryData.data &&
|
||||
!require.reduce(
|
||||
(acc, key) => acc && queryData.data[key] !== null,
|
||||
true
|
||||
)
|
||||
) {
|
||||
childrenOrNotFound = <ErrorPage onBack={() => navigate("/")} />;
|
||||
}
|
||||
|
||||
if (displayLoader) {
|
||||
return (
|
||||
<QueryProgress
|
||||
loading={queryData.loading}
|
||||
onCompleted={() => setProgressState(false)}
|
||||
onLoading={() => setProgressState(true)}
|
||||
>
|
||||
{childrenOrNotFound}
|
||||
</QueryProgress>
|
||||
);
|
||||
}
|
||||
|
||||
return <>{childrenOrNotFound}</>;
|
||||
}}
|
||||
</Query>
|
||||
)}
|
||||
</AppProgress>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue