Merge pull request #262 from mirumee/ref/hook-searches

Use searches as hooks instead of components
This commit is contained in:
Marcin Gębala 2019-11-21 16:10:22 +01:00 committed by GitHub
commit 29bd1a43a8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 1812 additions and 1990 deletions

View file

@ -12,6 +12,7 @@ All notable, unreleased changes to this project will be documented in this file.
- Use Apollo Hooks - #254 by @dominik-zeglen
- Fix disappearing products description - #259 by @dominik-zeglen
- Improve mobile appearance - #240 by @benekex2 and @dominik-zeglen
- Use searches as hooks instead of components - #262 by @dominik-zeglen
## 2.0.0

View file

@ -6,6 +6,7 @@ import { FormattedMessage, useIntl } from "react-intl";
import ActionDialog from "@saleor/components/ActionDialog";
import AssignProductDialog from "@saleor/components/AssignProductDialog";
import { WindowTitle } from "@saleor/components/WindowTitle";
import { DEFAULT_INITIAL_SEARCH_DATA, PAGINATE_BY } from "@saleor/config";
import useBulkActions from "@saleor/hooks/useBulkActions";
import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
@ -13,8 +14,7 @@ import usePaginator, {
createPaginationState
} from "@saleor/hooks/usePaginator";
import { commonMessages } from "@saleor/intl";
import { DEFAULT_INITIAL_SEARCH_DATA, PAGINATE_BY } from "../../config";
import SearchProducts from "../../containers/SearchProducts";
import useProductSearch from "@saleor/searches/useProductSearch";
import { getMutationState, maybe } from "../../misc";
import { productUrl } from "../../products/urls";
import { CollectionInput } from "../../types/globalTypes";
@ -50,6 +50,9 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
);
const paginate = usePaginator();
const intl = useIntl();
const { search, result } = useProductSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const closeModal = () =>
navigate(
@ -284,8 +287,6 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
toggle={toggle}
toggleAll={toggleAll}
/>
<SearchProducts variables={DEFAULT_INITIAL_SEARCH_DATA}>
{({ search, result }) => (
<AssignProductDialog
confirmButtonState={assignTransitionState}
open={params.action === "assign"}
@ -305,8 +306,6 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
.filter(suggestedProduct => suggestedProduct.id)
)}
/>
)}
</SearchProducts>
<ActionDialog
confirmButtonState={removeTransitionState}
onClose={closeModal}

View file

@ -19,7 +19,7 @@ import FormSpacer from "@saleor/components/FormSpacer";
import ResponsiveTable from "@saleor/components/ResponsiveTable";
import useSearchQuery from "@saleor/hooks/useSearchQuery";
import { buttonMessages } from "@saleor/intl";
import { SearchCategories_search_edges_node } from "../../containers/SearchCategories/types/SearchCategories";
import { SearchCategories_search_edges_node } from "@saleor/searches/types/SearchCategories";
import Checkbox from "../Checkbox";
export interface FormData {

View file

@ -15,7 +15,7 @@ import { FormattedMessage, useIntl } from "react-intl";
import ResponsiveTable from "@saleor/components/ResponsiveTable";
import useSearchQuery from "@saleor/hooks/useSearchQuery";
import { buttonMessages } from "@saleor/intl";
import { SearchCollections_search_edges_node } from "../../containers/SearchCollections/types/SearchCollections";
import { SearchCollections_search_edges_node } from "@saleor/searches/types/SearchCollections";
import Checkbox from "../Checkbox";
import ConfirmButton, {
ConfirmButtonTransitionState

View file

@ -21,7 +21,7 @@ import TableCellAvatar from "@saleor/components/TableCellAvatar";
import useSearchQuery from "@saleor/hooks/useSearchQuery";
import { buttonMessages } from "@saleor/intl";
import { maybe } from "@saleor/misc";
import { SearchProducts_search_edges_node } from "../../containers/SearchProducts/types/SearchProducts";
import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts";
import Checkbox from "../Checkbox";
export interface FormData {

View file

@ -1,10 +1,10 @@
import { SearchQueryVariables } from "./containers/BaseSearch";
import { SearchVariables } from "./hooks/makeSearch";
import { ListSettings, ListViews } from "./types";
export const APP_MOUNT_URI = process.env.APP_MOUNT_URI || "/";
export const API_URI = process.env.API_URI || "/graphql/";
export const DEFAULT_INITIAL_SEARCH_DATA: SearchQueryVariables = {
export const DEFAULT_INITIAL_SEARCH_DATA: SearchVariables = {
after: null,
first: 20,
query: ""

View file

@ -1,77 +0,0 @@
import { DocumentNode } from "graphql";
import React from "react";
import Debounce from "../components/Debounce";
import { TypedQuery, TypedQueryResult } from "../queries";
export interface SearchQueryVariables {
after?: string;
first: number;
query: string;
}
interface BaseSearchProps<
TQuery,
TQueryVariables extends SearchQueryVariables
> {
children: (props: {
loadMore: () => void;
search: (query: string) => void;
result: TypedQueryResult<TQuery, TQueryVariables>;
}) => React.ReactElement<any>;
variables: TQueryVariables;
}
function BaseSearch<TQuery, TQueryVariables extends SearchQueryVariables>(
query: DocumentNode,
loadMoreFn: (result: TypedQueryResult<TQuery, TQueryVariables>) => void
) {
const Query = TypedQuery<TQuery, TQueryVariables>(query);
class BaseSearchComponent extends React.Component<
BaseSearchProps<TQuery, TQueryVariables>,
SearchQueryVariables
> {
state: SearchQueryVariables = {
first: this.props.variables.first,
query: this.props.variables.query
};
search = (query: string) => {
if (query === undefined) {
this.setState({ query: "" });
} else {
this.setState({ query });
}
};
render() {
const { children, variables } = this.props;
return (
<Debounce debounceFn={this.search} time={200}>
{search => (
<Query
displayLoader={true}
variables={{
...variables,
query: this.state.query
}}
>
{result =>
children({
loadMore: () => loadMoreFn(result),
result,
search
})
}
</Query>
)}
</Debounce>
);
}
}
return BaseSearchComponent;
}
export default BaseSearch;

View file

@ -8,6 +8,7 @@ import AssignCategoriesDialog from "@saleor/components/AssignCategoryDialog";
import AssignCollectionDialog from "@saleor/components/AssignCollectionDialog";
import AssignProductDialog from "@saleor/components/AssignProductDialog";
import { WindowTitle } from "@saleor/components/WindowTitle";
import { DEFAULT_INITIAL_SEARCH_DATA, PAGINATE_BY } from "@saleor/config";
import useBulkActions from "@saleor/hooks/useBulkActions";
import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
@ -16,12 +17,11 @@ import usePaginator, {
} from "@saleor/hooks/usePaginator";
import useShop from "@saleor/hooks/useShop";
import { commonMessages, sectionNames } from "@saleor/intl";
import useCategorySearch from "@saleor/searches/useCategorySearch";
import useCollectionSearch from "@saleor/searches/useCollectionSearch";
import useProductSearch from "@saleor/searches/useProductSearch";
import { categoryUrl } from "../../categories/urls";
import { collectionUrl } from "../../collections/urls";
import { DEFAULT_INITIAL_SEARCH_DATA, PAGINATE_BY } from "../../config";
import SearchCategories from "../../containers/SearchCategories";
import SearchCollections from "../../containers/SearchCollections";
import SearchProducts from "../../containers/SearchProducts";
import { decimal, getMutationState, joinDateTime, maybe } from "../../misc";
import { productUrl } from "../../products/urls";
import { DiscountValueTypeEnum, SaleType } from "../../types/globalTypes";
@ -66,6 +66,24 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
params.ids
);
const intl = useIntl();
const {
search: searchCategories,
result: searchCategoriesOpts
} = useCategorySearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const {
search: searchCollections,
result: searchCollectionsOpts
} = useCollectionSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const {
search: searchProducts,
result: searchProductsOpts
} = useProductSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const paginationState = createPaginationState(PAGINATE_BY, params);
const changeTab = (tab: SaleDetailsPageTab) => {
@ -341,13 +359,6 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
toggle={toggle}
toggleAll={toggleAll}
/>
<SearchProducts
variables={DEFAULT_INITIAL_SEARCH_DATA}
>
{({
search: searchProducts,
result: searchProductsOpts
}) => (
<AssignProductDialog
confirmButtonState={assignTransitionState}
open={params.action === "assign-product"}
@ -375,22 +386,12 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
)
)}
/>
)}
</SearchProducts>
<SearchCategories
variables={DEFAULT_INITIAL_SEARCH_DATA}
>
{({
search: searchCategories,
result: searchCategoriesOpts
}) => (
<AssignCategoriesDialog
categories={maybe(() =>
searchCategoriesOpts.data.search.edges
.map(edge => edge.node)
.filter(
suggestedCategory =>
suggestedCategory.id
suggestedCategory => suggestedCategory.id
)
)}
confirmButtonState={assignTransitionState}
@ -412,22 +413,12 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
})
}
/>
)}
</SearchCategories>
<SearchCollections
variables={DEFAULT_INITIAL_SEARCH_DATA}
>
{({
search: searchCollections,
result: searchCollectionsOpts
}) => (
<AssignCollectionDialog
collections={maybe(() =>
searchCollectionsOpts.data.search.edges
.map(edge => edge.node)
.filter(
suggestedCategory =>
suggestedCategory.id
suggestedCategory => suggestedCategory.id
)
)}
confirmButtonState={assignTransitionState}
@ -449,8 +440,6 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
})
}
/>
)}
</SearchCollections>
<ActionDialog
open={
params.action === "unassign-category" &&

View file

@ -8,6 +8,7 @@ import AssignCategoriesDialog from "@saleor/components/AssignCategoryDialog";
import AssignCollectionDialog from "@saleor/components/AssignCollectionDialog";
import AssignProductDialog from "@saleor/components/AssignProductDialog";
import { WindowTitle } from "@saleor/components/WindowTitle";
import { DEFAULT_INITIAL_SEARCH_DATA, PAGINATE_BY } from "@saleor/config";
import useBulkActions from "@saleor/hooks/useBulkActions";
import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
@ -16,12 +17,11 @@ import usePaginator, {
} from "@saleor/hooks/usePaginator";
import useShop from "@saleor/hooks/useShop";
import { commonMessages, sectionNames } from "@saleor/intl";
import useCategorySearch from "@saleor/searches/useCategorySearch";
import useCollectionSearch from "@saleor/searches/useCollectionSearch";
import useProductSearch from "@saleor/searches/useProductSearch";
import { categoryUrl } from "../../categories/urls";
import { collectionUrl } from "../../collections/urls";
import { DEFAULT_INITIAL_SEARCH_DATA, PAGINATE_BY } from "../../config";
import SearchCategories from "../../containers/SearchCategories";
import SearchCollections from "../../containers/SearchCollections";
import SearchProducts from "../../containers/SearchProducts";
import { decimal, getMutationState, joinDateTime, maybe } from "../../misc";
import { productUrl } from "../../products/urls";
import {
@ -68,6 +68,24 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
params.ids
);
const intl = useIntl();
const {
search: searchCategories,
result: searchCategoriesOpts
} = useCategorySearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const {
search: searchCollections,
result: searchCollectionsOpts
} = useCollectionSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const {
search: searchProducts,
result: searchProductsOpts
} = useProductSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const paginationState = createPaginationState(PAGINATE_BY, params);
const changeTab = (tab: VoucherDetailsPageTab) => {
@ -420,20 +438,12 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
toggle={toggle}
toggleAll={toggleAll}
/>
<SearchCategories
variables={DEFAULT_INITIAL_SEARCH_DATA}
>
{({
search: searchCategories,
result: searchCategoriesOpts
}) => (
<AssignCategoriesDialog
categories={maybe(() =>
searchCategoriesOpts.data.search.edges
.map(edge => edge.node)
.filter(
suggestedCategory =>
suggestedCategory.id
suggestedCategory => suggestedCategory.id
)
)}
confirmButtonState={assignTransitionState}
@ -455,22 +465,12 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
})
}
/>
)}
</SearchCategories>
<SearchCollections
variables={DEFAULT_INITIAL_SEARCH_DATA}
>
{({
search: searchCollections,
result: searchCollectionsOpts
}) => (
<AssignCollectionDialog
collections={maybe(() =>
searchCollectionsOpts.data.search.edges
.map(edge => edge.node)
.filter(
suggestedCategory =>
suggestedCategory.id
suggestedCategory => suggestedCategory.id
)
)}
confirmButtonState={assignTransitionState}
@ -492,8 +492,6 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
})
}
/>
)}
</SearchCollections>
<DiscountCountrySelectDialog
confirmButtonState={formTransitionState}
countries={maybe(() => shop.countries, [])}
@ -517,13 +515,6 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
[]
)}
/>
<SearchProducts
variables={DEFAULT_INITIAL_SEARCH_DATA}
>
{({
search: searchProducts,
result: searchProductsOpts
}) => (
<AssignProductDialog
confirmButtonState={assignTransitionState}
open={params.action === "assign-product"}
@ -551,8 +542,6 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
)
)}
/>
)}
</SearchProducts>
<ActionDialog
open={
params.action === "unassign-category" &&

View file

@ -16,7 +16,7 @@ export interface LoadMore<TData, TVariables> {
) => Promise<ApolloQueryResult<TData>>;
}
type UseQuery<TData, TVariables> = QueryResult<TData, TVariables> &
export type UseQueryResult<TData, TVariables> = QueryResult<TData, TVariables> &
LoadMore<TData, TVariables>;
type UseQueryOpts<TData, TVariables> = Partial<{
displayLoader: boolean;
@ -26,17 +26,17 @@ type UseQueryOpts<TData, TVariables> = Partial<{
}>;
type UseQueryHook<TData, TVariables> = (
opts: UseQueryOpts<TData, TVariables>
) => UseQuery<TData, TVariables>;
) => UseQueryResult<TData, TVariables>;
function makeQuery<TData, TVariables>(
query: DocumentNode
): UseQueryHook<TData, TVariables> {
function useQuery<TData, TVariables>({
function useQuery({
displayLoader,
require,
skip,
variables
}: UseQueryOpts<TData, TVariables>): UseQuery<TData, TVariables> {
}: UseQueryOpts<TData, TVariables>): UseQueryResult<TData, TVariables> {
const notify = useNotifier();
const intl = useIntl();
const [, dispatchAppState] = useAppState();

57
src/hooks/makeSearch.ts Normal file
View file

@ -0,0 +1,57 @@
import { DocumentNode } from "graphql";
import { useState } from "react";
import { QueryResult } from "react-apollo";
import makeQuery, { UseQueryResult } from "./makeQuery";
import useDebounce from "./useDebounce";
export interface SearchVariables {
after?: string;
first: number;
query: string;
}
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

@ -1,9 +1,9 @@
import { DocumentNode } from "graphql";
import { PageInfoFragment } from "@saleor/types/PageInfoFragment";
import BaseSearch, { SearchQueryVariables } from "./BaseSearch";
import makeSearch, { SearchVariables, UseSearchHook } from "./makeSearch";
export interface SearchQuery {
export interface SearchData {
search: {
edges: Array<{
node: any;
@ -12,11 +12,11 @@ export interface SearchQuery {
};
}
function TopLevelSearch<
TQuery extends SearchQuery,
TQueryVariables extends SearchQueryVariables
>(query: DocumentNode) {
return BaseSearch<TQuery, TQueryVariables>(query, result => {
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) => {
@ -44,4 +44,4 @@ function TopLevelSearch<
});
}
export default TopLevelSearch;
export default makeTopLevelSearch;

19
src/hooks/useDebounce.ts Normal file
View file

@ -0,0 +1,19 @@
import { useEffect, useRef } from "react";
export type UseDebounceFn<T> = (...args: T[]) => void;
function useDebounce<T>(
debounceFn: UseDebounceFn<T>,
time = 200
): UseDebounceFn<T> {
const timer = useRef(null);
useEffect(() => () => clearTimeout(timer.current));
return (...args: T[]) => {
if (timer.current) {
clearTimeout(timer.current);
}
timer.current = setTimeout(() => debounceFn(...args), time);
};
}
export default useDebounce;

View file

@ -14,13 +14,13 @@ import ConfirmButton, {
ConfirmButtonTransitionState
} from "@saleor/components/ConfirmButton";
import FormSpacer from "@saleor/components/FormSpacer";
import { SearchCategories_search_edges_node } from "@saleor/containers/SearchCategories/types/SearchCategories";
import { SearchCollections_search_edges_node } from "@saleor/containers/SearchCollections/types/SearchCollections";
import { SearchPages_search_edges_node } from "@saleor/containers/SearchPages/types/SearchPages";
import useModalDialogErrors from "@saleor/hooks/useModalDialogErrors";
import useModalDialogOpen from "@saleor/hooks/useModalDialogOpen";
import useStateFromProps from "@saleor/hooks/useStateFromProps";
import { buttonMessages, sectionNames } from "@saleor/intl";
import { SearchCategories_search_edges_node } from "@saleor/searches/types/SearchCategories";
import { SearchCollections_search_edges_node } from "@saleor/searches/types/SearchCollections";
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
import { UserError } from "@saleor/types";
import { getErrors, getFieldError } from "@saleor/utils/errors";
import { getMenuItemByValue, IMenu } from "@saleor/utils/menu";

View file

@ -3,14 +3,14 @@ import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import ActionDialog from "@saleor/components/ActionDialog";
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
import useCategorySearch from "@saleor/searches/useCategorySearch";
import useCollectionSearch from "@saleor/searches/useCollectionSearch";
import usePageSearch from "@saleor/searches/usePageSearch";
import { categoryUrl } from "../../../categories/urls";
import { collectionUrl } from "../../../collections/urls";
import { DEFAULT_INITIAL_SEARCH_DATA } from "../../../config";
import SearchCategories from "../../../containers/SearchCategories";
import SearchCollections from "../../../containers/SearchCollections";
import SearchPages from "../../../containers/SearchPages";
import { getMutationState, maybe } from "../../../misc";
import { pageUrl } from "../../../pages/urls";
import MenuDetailsPage, {
@ -59,6 +59,15 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
const navigate = useNavigator();
const notify = useNotifier();
const intl = useIntl();
const categorySearch = useCategorySearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const collectionSearch = useCollectionSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const pageSearch = usePageSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const closeModal = () =>
navigate(
@ -95,12 +104,6 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
};
return (
<SearchPages variables={DEFAULT_INITIAL_SEARCH_DATA}>
{pageSearch => (
<SearchCategories variables={DEFAULT_INITIAL_SEARCH_DATA}>
{categorySearch => (
<SearchCollections variables={DEFAULT_INITIAL_SEARCH_DATA}>
{collectionSearch => (
<MenuDetailsQuery displayLoader variables={{ id }}>
{({ data, loading, refetch }) => {
const handleQueryChange = (query: string) => {
@ -110,67 +113,47 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
};
const categories = maybe(
() =>
categorySearch.result.data.search.edges.map(
edge => edge.node
),
() => categorySearch.result.data.search.edges.map(edge => edge.node),
[]
);
const collections = maybe(
() =>
collectionSearch.result.data.search.edges.map(
edge => edge.node
),
collectionSearch.result.data.search.edges.map(edge => edge.node),
[]
);
const pages = maybe(
() =>
pageSearch.result.data.search.edges.map(
edge => edge.node
),
() => pageSearch.result.data.search.edges.map(edge => edge.node),
[]
);
return (
<MenuDeleteMutation
onCompleted={data =>
handleDelete(data, navigate, notify, intl)
}
onCompleted={data => handleDelete(data, navigate, notify, intl)}
>
{(menuDelete, menuDeleteOpts) => (
<MenuUpdateMutation
onCompleted={data =>
handleUpdate(data, notify, refetch, intl)
}
onCompleted={data => handleUpdate(data, notify, refetch, intl)}
>
{(menuUpdate, menuUpdateOpts) => {
const deleteState = getMutationState(
menuDeleteOpts.called,
menuDeleteOpts.loading,
maybe(
() => menuDeleteOpts.data.menuDelete.errors
)
maybe(() => menuDeleteOpts.data.menuDelete.errors)
);
const updateState = getMutationState(
menuUpdateOpts.called,
menuUpdateOpts.loading,
maybe(
() => menuUpdateOpts.data.menuUpdate.errors
),
maybe(
() => menuUpdateOpts.data.menuItemMove.errors
)
maybe(() => menuUpdateOpts.data.menuUpdate.errors),
maybe(() => menuUpdateOpts.data.menuItemMove.errors)
);
// This is a workaround to let know <MenuDetailsPage />
// that it should clean operation stack if mutations
// were successful
const handleSubmit = async (
data: MenuDetailsSubmitData
) => {
const handleSubmit = async (data: MenuDetailsSubmitData) => {
try {
const result = await menuUpdate({
variables: {
@ -182,10 +165,8 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
});
if (result) {
if (
result.data.menuItemBulkDelete.errors
.length > 0 ||
result.data.menuItemMove.errors.length >
0 ||
result.data.menuItemBulkDelete.errors.length > 0 ||
result.data.menuItemMove.errors.length > 0 ||
result.data.menuUpdate.errors.length > 0
) {
return false;
@ -233,9 +214,7 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
open={params.action === "remove"}
onClose={closeModal}
confirmButtonState={deleteState}
onConfirm={() =>
menuDelete({ variables: { id } })
}
onConfirm={() => menuDelete({ variables: { id } })}
variant="delete"
title={intl.formatMessage({
defaultMessage: "Delete Menu",
@ -250,10 +229,7 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
values={{
menuName: (
<strong>
{maybe(
() => data.menu.name,
"..."
)}
{maybe(() => data.menu.name, "...")}
</strong>
)
}}
@ -263,12 +239,7 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
<MenuItemCreateMutation
onCompleted={data =>
handleItemCreate(
data,
notify,
closeModal,
intl
)
handleItemCreate(data, notify, closeModal, intl)
}
>
{(menuItemCreate, menuItemCreateOpts) => {
@ -276,10 +247,7 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
data: MenuItemDialogFormData
) => {
const variables: MenuItemCreateVariables = {
input: getMenuItemCreateInputData(
id,
data
)
input: getMenuItemCreateInputData(id, data)
};
menuItemCreate({ variables });
@ -290,8 +258,7 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
menuItemCreateOpts.loading,
maybe(
() =>
menuItemCreateOpts.data
.menuItemCreate.errors
menuItemCreateOpts.data.menuItemCreate.errors
)
);
@ -302,8 +269,7 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
collections={collections}
errors={maybe(
() =>
menuItemCreateOpts.data
.menuItemCreate.errors,
menuItemCreateOpts.data.menuItemCreate.errors,
[]
)}
pages={pages}
@ -311,9 +277,7 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
categorySearch.result.loading ||
collectionSearch.result.loading
}
confirmButtonState={
formTransitionState
}
confirmButtonState={formTransitionState}
disabled={menuItemCreateOpts.loading}
onClose={closeModal}
onSubmit={handleSubmit}
@ -324,13 +288,7 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
</MenuItemCreateMutation>
<MenuItemUpdateMutation
onCompleted={data =>
handleItemUpdate(
data,
id,
navigate,
notify,
intl
)
handleItemUpdate(data, id, navigate, notify, intl)
}
>
{(menuItemUpdate, menuItemUpdateOpts) => {
@ -357,8 +315,7 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
menuItemUpdateOpts.loading,
maybe(
() =>
menuItemUpdateOpts.data
.menuItemUpdate.errors
menuItemUpdateOpts.data.menuItemUpdate.errors
)
);
@ -378,8 +335,7 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
collections={collections}
errors={maybe(
() =>
menuItemUpdateOpts.data
.menuItemUpdate.errors,
menuItemUpdateOpts.data.menuItemUpdate.errors,
[]
)}
pages={pages}
@ -391,9 +347,7 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
categorySearch.result.loading ||
collectionSearch.result.loading
}
confirmButtonState={
formTransitionState
}
confirmButtonState={formTransitionState}
disabled={menuItemUpdateOpts.loading}
onClose={closeModal}
onSubmit={handleSubmit}
@ -411,12 +365,6 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
);
}}
</MenuDetailsQuery>
)}
</SearchCollections>
)}
</SearchCategories>
)}
</SearchPages>
);
};
MenuDetails.displayName = "MenuDetails";

View file

@ -16,10 +16,10 @@ import SingleAutocompleteSelectField from "@saleor/components/SingleAutocomplete
import Skeleton from "@saleor/components/Skeleton";
import useStateFromProps from "@saleor/hooks/useStateFromProps";
import { buttonMessages } from "@saleor/intl";
import { SearchCustomers_search_edges_node } from "@saleor/searches/types/SearchCustomers";
import { FetchMoreProps, UserPermissionProps } from "@saleor/types";
import { PermissionEnum } from "@saleor/types/globalTypes";
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
import { SearchCustomers_search_edges_node } from "../../../containers/SearchCustomers/types/SearchCustomers";
import { customerUrl } from "../../../customers/urls";
import { createHref, maybe } from "../../../misc";
import { OrderDetails_order } from "../../types/OrderDetails";

View file

@ -13,8 +13,8 @@ import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar";
import Skeleton from "@saleor/components/Skeleton";
import { sectionNames } from "@saleor/intl";
import { SearchCustomers_search_edges_node } from "@saleor/searches/types/SearchCustomers";
import { FetchMoreProps, UserPermissionProps } from "@saleor/types";
import { SearchCustomers_search_edges_node } from "../../../containers/SearchCustomers/types/SearchCustomers";
import { maybe } from "../../../misc";
import { DraftOrderInput } from "../../../types/globalTypes";
import { OrderDetails_order } from "../../types/OrderDetails";

View file

@ -1,5 +1,5 @@
import { SearchCustomers_search_edges_node } from "@saleor/searches/types/SearchCustomers";
import { MessageDescriptor } from "react-intl";
import { SearchCustomers_search_edges_node } from "../containers/SearchCustomers/types/SearchCustomers";
import { transformOrderStatus, transformPaymentStatus } from "../misc";
import {
FulfillmentStatus,

View file

@ -1,6 +1,6 @@
import gql from "graphql-tag";
import TopLevelSearch from "../containers/TopLevelSearch";
import makeTopLevelSearch from "@saleor/hooks/makeTopLevelSearch";
import { TypedQuery } from "../queries";
import { OrderDetails, OrderDetailsVariables } from "./types/OrderDetails";
import {
@ -314,7 +314,7 @@ export const searchOrderVariant = gql`
}
}
`;
export const SearchOrderVariant = TopLevelSearch<
export const useOrderVariantSearch = makeTopLevelSearch<
SearchOrderVariantType,
SearchOrderVariantVariables
>(searchOrderVariant);

View file

@ -1,10 +1,10 @@
import React from "react";
import { WindowTitle } from "@saleor/components/WindowTitle";
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
import useNavigator from "@saleor/hooks/useNavigator";
import useUser from "@saleor/hooks/useUser";
import { DEFAULT_INITIAL_SEARCH_DATA } from "../../../config";
import SearchCustomers from "../../../containers/SearchCustomers";
import useCustomerSearch from "@saleor/searches/useCustomerSearch";
import { customerUrl } from "../../../customers/urls";
import { getMutationState, maybe, transformAddressToForm } from "../../../misc";
import { productUrl } from "../../../products/urls";
@ -26,7 +26,7 @@ import OrderPaymentVoidDialog from "../../components/OrderPaymentVoidDialog";
import OrderProductAddDialog from "../../components/OrderProductAddDialog";
import OrderShippingMethodEditDialog from "../../components/OrderShippingMethodEditDialog";
import OrderOperations from "../../containers/OrderOperations";
import { SearchOrderVariant, TypedOrderDetailsQuery } from "../../queries";
import { TypedOrderDetailsQuery, useOrderVariantSearch } from "../../queries";
import { OrderDetails_order } from "../../types/OrderDetails";
import {
orderListUrl,
@ -74,6 +74,20 @@ interface OrderDetailsProps {
export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
const navigate = useNavigator();
const { user } = useUser();
const {
loadMore: loadMoreCustomers,
search: searchUsers,
result: users
} = useCustomerSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const {
loadMore,
search: variantSearch,
result: variantSearchOpts
} = useOrderVariantSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
return (
<TypedOrderDetailsQuery
@ -91,12 +105,6 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
})
);
return (
<SearchCustomers variables={DEFAULT_INITIAL_SEARCH_DATA}>
{({
loadMore: loadMoreCustomers,
search: searchUsers,
result: users
}) => (
<OrderDetailsMessages>
{orderMessages => (
<OrderOperations
@ -151,8 +159,7 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
orderDraftFinalize.opts.loading,
maybe(
() =>
orderDraftFinalize.opts.data.draftOrderComplete
.errors
orderDraftFinalize.opts.data.draftOrderComplete.errors
)
);
return (
@ -160,9 +167,7 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
{maybe(() => order.status !== OrderStatus.DRAFT) ? (
<>
<WindowTitle
title={maybe(
() => "Order #" + data.order.number
)}
title={maybe(() => "Order #" + data.order.number)}
/>
<OrderDetailsPage
onNoteAdd={variables =>
@ -177,10 +182,7 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
() => data.order.availableShippingMethods,
[]
)}
userPermissions={maybe(
() => user.permissions,
[]
)}
userPermissions={maybe(() => user.permissions, [])}
onOrderCancel={() => openModal("cancel")}
onOrderFulfill={() => openModal("fulfill")}
onFulfillmentCancel={fulfillmentId =>
@ -220,8 +222,7 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
orderCancel.opts.called,
orderCancel.opts.loading,
maybe(
() =>
orderCancel.opts.data.orderCancel.errors
() => orderCancel.opts.data.orderCancel.errors
)
)}
number={maybe(() => order.number)}
@ -256,9 +257,7 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
confirmButtonState={getMutationState(
orderVoid.opts.called,
orderVoid.opts.loading,
maybe(
() => orderVoid.opts.data.orderVoid.errors
)
maybe(() => orderVoid.opts.data.orderVoid.errors)
)}
open={params.action === "void"}
onClose={closeModal}
@ -328,8 +327,7 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
lines: maybe(() => order.lines, [])
.filter(
line =>
line.quantityFulfilled <
line.quantity
line.quantityFulfilled < line.quantity
)
.map((line, lineIndex) => ({
orderLineId: line.id,
@ -374,8 +372,7 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
trackingNumber={maybe(
() =>
data.order.fulfillments.find(
fulfillment =>
fulfillment.id === params.id
fulfillment => fulfillment.id === params.id
).trackingNumber
)}
onConfirm={variables =>
@ -407,9 +404,7 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
}
users={maybe(
() =>
users.data.search.edges.map(
edge => edge.node
),
users.data.search.edges.map(edge => edge.node),
[]
)}
hasMore={maybe(
@ -428,18 +423,15 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
}
onDraftFinalize={() => openModal("finalize")}
onDraftRemove={() => openModal("cancel")}
onOrderLineAdd={() =>
openModal("add-order-line")
}
onOrderLineAdd={() => openModal("add-order-line")}
onBack={() => navigate(orderListUrl())}
order={order}
countries={maybe(
() => data.shop.countries,
[]
).map(country => ({
countries={maybe(() => data.shop.countries, []).map(
country => ({
code: country.code,
label: country.country
}))}
})
)}
onProductClick={id => () =>
navigate(productUrl(encodeURIComponent(id)))}
onBillingAddressEdit={() =>
@ -464,10 +456,7 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
onProfileView={() =>
navigate(customerUrl(order.user.id))
}
userPermissions={maybe(
() => user.permissions,
[]
)}
userPermissions={maybe(() => user.permissions, [])}
/>
<OrderDraftCancelDialog
confirmButtonState={getMutationState(
@ -475,23 +464,19 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
orderDraftCancel.opts.loading,
maybe(
() =>
orderDraftCancel.opts.data
.draftOrderDelete.errors
orderDraftCancel.opts.data.draftOrderDelete
.errors
)
)}
onClose={closeModal}
onConfirm={() =>
orderDraftCancel.mutate({ id })
}
onConfirm={() => orderDraftCancel.mutate({ id })}
open={params.action === "cancel"}
orderNumber={maybe(() => order.number)}
/>
<OrderDraftFinalizeDialog
confirmButtonState={finalizeTransitionState}
onClose={closeModal}
onConfirm={() =>
orderDraftFinalize.mutate({ id })
}
onConfirm={() => orderDraftFinalize.mutate({ id })}
open={params.action === "finalize"}
orderNumber={maybe(() => order.number)}
warnings={orderDraftFinalizeWarnings(order)}
@ -524,22 +509,14 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
})
}
/>
<SearchOrderVariant
variables={DEFAULT_INITIAL_SEARCH_DATA}
>
{({
loadMore,
search: variantSearch,
result: variantSearchOpts
}) => (
<OrderProductAddDialog
confirmButtonState={getMutationState(
orderLinesAdd.opts.called,
orderLinesAdd.opts.loading,
maybe(
() =>
orderLinesAdd.opts.data
.draftOrderLinesCreate.errors
orderLinesAdd.opts.data.draftOrderLinesCreate
.errors
)
)}
loading={variantSearchOpts.loading}
@ -567,17 +544,13 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
})
}
/>
)}
</SearchOrderVariant>
</>
)}
<OrderAddressEditDialog
confirmButtonState={getMutationState(
orderUpdate.opts.called,
orderUpdate.opts.loading,
maybe(
() => orderUpdate.opts.data.orderUpdate.errors
)
maybe(() => orderUpdate.opts.data.orderUpdate.errors)
)}
address={transformAddressToForm(
maybe(() => order.shippingAddress)
@ -608,9 +581,7 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
confirmButtonState={getMutationState(
orderUpdate.opts.called,
orderUpdate.opts.loading,
maybe(
() => orderUpdate.opts.data.orderUpdate.errors
)
maybe(() => orderUpdate.opts.data.orderUpdate.errors)
)}
address={transformAddressToForm(
maybe(() => order.billingAddress)
@ -643,8 +614,6 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
</OrderOperations>
)}
</OrderDetailsMessages>
)}
</SearchCustomers>
);
}}
</TypedOrderDetailsQuery>

View file

@ -30,7 +30,7 @@ import useSearchQuery from "@saleor/hooks/useSearchQuery";
import { buttonMessages } from "@saleor/intl";
import { maybe, renderCollection } from "@saleor/misc";
import { FetchMoreProps } from "@saleor/types";
import { SearchAttributes_productType_availableAttributes_edges_node } from "../../containers/SearchAttributes/types/SearchAttributes";
import { SearchAttributes_productType_availableAttributes_edges_node } from "../../hooks/useAvailableAttributeSearch/types/SearchAttributes";
const useStyles = makeStyles(theme => ({
actions: {

View file

@ -1,7 +1,7 @@
import {
SearchProductTypes_search_edges_node,
SearchProductTypes_search_edges_node_productAttributes
} from "@saleor/containers/SearchProductTypes/types/SearchProductTypes";
} from "@saleor/searches/types/SearchProductTypes";
import { AttributeInputTypeEnum } from "../types/globalTypes";
import { ProductTypeDetails_productType } from "./types/ProductTypeDetails";
import { ProductTypeList_productTypes_edges_node } from "./types/ProductTypeList";

View file

@ -1,7 +1,7 @@
import gql from "graphql-tag";
import makeSearch from "@saleor/hooks/makeSearch";
import { pageInfoFragment } from "@saleor/queries";
import BaseSearch from "../../../containers/BaseSearch";
import {
SearchAttributes,
SearchAttributesVariables
@ -37,11 +37,19 @@ export const searchAttributes = gql`
}
`;
export default BaseSearch<SearchAttributes, SearchAttributesVariables>(
export default makeSearch<SearchAttributes, SearchAttributesVariables>(
searchAttributes,
result =>
result.loadMore(
(prev, next) => ({
(prev, next) => {
if (
prev.productType.availableAttributes.pageInfo.endCursor ===
next.productType.availableAttributes.pageInfo.endCursor
) {
return prev;
}
return {
...prev,
productType: {
...prev.productType,
@ -54,7 +62,8 @@ export default BaseSearch<SearchAttributes, SearchAttributesVariables>(
pageInfo: next.productType.availableAttributes.pageInfo
}
}
}),
};
},
{
after: result.data.productType.availableAttributes.pageInfo.endCursor
}

View file

@ -4,6 +4,7 @@ import { FormattedMessage, useIntl } from "react-intl";
import { attributeUrl } from "@saleor/attributes/urls";
import { WindowTitle } from "@saleor/components/WindowTitle";
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
import useBulkActions from "@saleor/hooks/useBulkActions";
import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
@ -19,7 +20,7 @@ import ProductTypeDetailsPage, {
ProductTypeForm
} from "../../components/ProductTypeDetailsPage";
import ProductTypeOperations from "../../containers/ProductTypeOperations";
import SearchAttributes from "../../containers/SearchAttributes";
import useAvailableAttributeSearch from "../../hooks/useAvailableAttributeSearch";
import { TypedProductTypeDetailsQuery } from "../../queries";
import { AssignAttribute } from "../../types/AssignAttribute";
import { ProductTypeDelete } from "../../types/ProductTypeDelete";
@ -46,6 +47,12 @@ export const ProductTypeUpdate: React.FC<ProductTypeUpdateProps> = ({
const productAttributeListActions = useBulkActions();
const variantAttributeListActions = useBulkActions();
const intl = useIntl();
const { loadMore, search, result } = useAvailableAttributeSearch({
variables: {
...DEFAULT_INITIAL_SEARCH_DATA,
id
}
});
return (
<ProductTypeUpdateErrors>
@ -330,55 +337,8 @@ export const ProductTypeUpdate: React.FC<ProductTypeUpdateProps> = ({
)
}}
/>
{!dataLoading && (
<SearchAttributes
variables={{
first: 15,
id,
query: ""
}}
>
{({ search, result }) => {
const fetchMore = () =>
result.loadMore(
(prev, next) => {
if (
prev.productType.availableAttributes
.pageInfo.endCursor ===
next.productType.availableAttributes
.pageInfo.endCursor
) {
return prev;
}
return {
...prev,
productType: {
...prev.productType,
availableAttributes: {
...prev.productType.availableAttributes,
edges: [
...prev.productType
.availableAttributes.edges,
...next.productType
.availableAttributes.edges
],
pageInfo:
next.productType.availableAttributes
.pageInfo
}
}
};
},
{
after:
result.data.productType.availableAttributes
.pageInfo.endCursor
}
);
return (
<>
{Object.keys(AttributeTypeEnum).map(key => (
{!dataLoading &&
Object.keys(AttributeTypeEnum).map(key => (
<AssignAttributeDialog
attributes={maybe(() =>
result.data.productType.availableAttributes.edges.map(
@ -397,13 +357,12 @@ export const ProductTypeUpdate: React.FC<ProductTypeUpdateProps> = ({
onClose={closeModal}
onSubmit={handleAssignAttribute}
onFetch={search}
onFetchMore={fetchMore}
onFetchMore={loadMore}
onOpen={result.refetch}
hasMore={maybe(
() =>
result.data.productType
.availableAttributes.pageInfo
.hasNextPage,
result.data.productType.availableAttributes
.pageInfo.hasNextPage,
false
)}
open={
@ -418,8 +377,7 @@ export const ProductTypeUpdate: React.FC<ProductTypeUpdateProps> = ({
...params,
ids: ids.includes(attributeId)
? params.ids.filter(
selectedId =>
selectedId !== attributeId
selectedId => selectedId !== attributeId
)
: [...ids, attributeId]
})
@ -428,11 +386,6 @@ export const ProductTypeUpdate: React.FC<ProductTypeUpdateProps> = ({
key={key}
/>
))}
</>
);
}}
</SearchAttributes>
)}
<ProductTypeDeleteDialog
confirmButtonState={deleteTransactionState}
name={maybe(() => data.productType.name, "...")}

View file

@ -13,9 +13,6 @@ import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar";
import SeoForm from "@saleor/components/SeoForm";
import VisibilityCard from "@saleor/components/VisibilityCard";
import { SearchCategories_search_edges_node } from "@saleor/containers/SearchCategories/types/SearchCategories";
import { SearchCollections_search_edges_node } from "@saleor/containers/SearchCollections/types/SearchCollections";
import { SearchProductTypes_search_edges_node_productAttributes } from "@saleor/containers/SearchProductTypes/types/SearchProductTypes";
import useDateLocalize from "@saleor/hooks/useDateLocalize";
import useFormset from "@saleor/hooks/useFormset";
import useStateFromProps from "@saleor/hooks/useStateFromProps";
@ -25,6 +22,9 @@ import {
ProductAttributeValueChoices,
ProductType
} from "@saleor/products/utils/data";
import { SearchCategories_search_edges_node } from "@saleor/searches/types/SearchCategories";
import { SearchCollections_search_edges_node } from "@saleor/searches/types/SearchCollections";
import { SearchProductTypes_search_edges_node_productAttributes } from "@saleor/searches/types/SearchProductTypes";
import createMultiAutocompleteSelectHandler from "@saleor/utils/handlers/multiAutocompleteSelectChangeHandler";
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
import { FetchMoreProps, UserError } from "../../../types";

View file

@ -12,13 +12,13 @@ import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar";
import SeoForm from "@saleor/components/SeoForm";
import VisibilityCard from "@saleor/components/VisibilityCard";
import { SearchCategories_search_edges_node } from "@saleor/containers/SearchCategories/types/SearchCategories";
import { SearchCollections_search_edges_node } from "@saleor/containers/SearchCollections/types/SearchCollections";
import useDateLocalize from "@saleor/hooks/useDateLocalize";
import useFormset from "@saleor/hooks/useFormset";
import useStateFromProps from "@saleor/hooks/useStateFromProps";
import { sectionNames } from "@saleor/intl";
import { maybe } from "@saleor/misc";
import { SearchCategories_search_edges_node } from "@saleor/searches/types/SearchCategories";
import { SearchCollections_search_edges_node } from "@saleor/searches/types/SearchCollections";
import { FetchMoreProps, ListActions, UserError } from "@saleor/types";
import createMultiAutocompleteSelectHandler from "@saleor/utils/handlers/multiAutocompleteSelectChangeHandler";
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";

View file

@ -2,13 +2,13 @@ import { RawDraftContentState } from "draft-js";
import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField";
import { SingleAutocompleteChoiceType } from "@saleor/components/SingleAutocompleteSelectField";
import { SearchProductTypes_search_edges_node_productAttributes } from "@saleor/containers/SearchProductTypes/types/SearchProductTypes";
import { maybe } from "@saleor/misc";
import {
ProductDetails_product,
ProductDetails_product_collections,
ProductDetails_product_variants
} from "@saleor/products/types/ProductDetails";
import { SearchProductTypes_search_edges_node_productAttributes } from "@saleor/searches/types/SearchProductTypes";
import { ProductAttributeInput } from "../components/ProductAttributes";
import { VariantAttributeInput } from "../components/ProductVariantAttributes";
import { ProductVariant } from "../types/ProductVariant";

View file

@ -2,13 +2,13 @@ import React from "react";
import { useIntl } from "react-intl";
import { WindowTitle } from "@saleor/components/WindowTitle";
import SearchProductTypes from "@saleor/containers/SearchProductTypes";
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop";
import { DEFAULT_INITIAL_SEARCH_DATA } from "../../config";
import SearchCategories from "../../containers/SearchCategories";
import SearchCollections from "../../containers/SearchCollections";
import useCategorySearch from "@saleor/searches/useCategorySearch";
import useCollectionSearch from "@saleor/searches/useCollectionSearch";
import useProductTypeSearch from "@saleor/searches/useProductTypeSearch";
import { decimal, getMutationState, maybe } from "../../misc";
import ProductCreatePage, {
ProductCreatePageSubmitData
@ -26,28 +26,30 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = () => {
const notify = useNotifier();
const shop = useShop();
const intl = useIntl();
const handleBack = () => navigate(productListUrl());
return (
<SearchCategories variables={DEFAULT_INITIAL_SEARCH_DATA}>
{({
const {
loadMore: loadMoreCategories,
search: searchCategory,
result: searchCategoryOpts
}) => (
<SearchCollections variables={DEFAULT_INITIAL_SEARCH_DATA}>
{({
} = useCategorySearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const {
loadMore: loadMoreCollections,
search: searchCollection,
result: searchCollectionOpts
}) => (
<SearchProductTypes variables={DEFAULT_INITIAL_SEARCH_DATA}>
{({
} = useCollectionSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const {
loadMore: loadMoreProductTypes,
search: searchProductTypes,
result: searchProductTypesOpts
}) => {
} = useProductTypeSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const handleBack = () => navigate(productListUrl());
const handleSuccess = (data: ProductCreate) => {
if (data.productCreate.errors.length === 0) {
notify({
@ -76,9 +78,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = () => {
loading: productCreateDataLoading
}
) => {
const handleSubmit = (
formData: ProductCreatePageSubmitData
) => {
const handleSubmit = (formData: ProductCreatePageSubmitData) => {
productCreate({
variables: {
attributes: formData.attributes.map(attribute => ({
@ -89,9 +89,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = () => {
category: formData.category,
chargeTaxes: formData.chargeTaxes,
collections: formData.collections,
descriptionJson: JSON.stringify(
formData.description
),
descriptionJson: JSON.stringify(formData.description),
isPublished: formData.isPublished,
name: formData.name,
productType: formData.productType,
@ -105,9 +103,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = () => {
},
sku: formData.sku,
stockQuantity:
formData.stockQuantity !== null
? formData.stockQuantity
: 0
formData.stockQuantity !== null ? formData.stockQuantity : 0
}
});
};
@ -136,10 +132,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = () => {
[]
).map(edge => edge.node)}
disabled={productCreateDataLoading}
errors={maybe(
() => productCreateData.productCreate.errors,
[]
)}
errors={maybe(() => productCreateData.productCreate.errors, [])}
fetchCategories={searchCategory}
fetchCollections={searchCollection}
fetchProductTypes={searchProductTypes}
@ -148,36 +141,28 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = () => {
description: "page header"
})}
productTypes={maybe(() =>
searchProductTypesOpts.data.search.edges.map(
edge => edge.node
)
searchProductTypesOpts.data.search.edges.map(edge => edge.node)
)}
onBack={handleBack}
onSubmit={handleSubmit}
saveButtonBarState={formTransitionState}
fetchMoreCategories={{
hasMore: maybe(
() =>
searchCategoryOpts.data.search.pageInfo
.hasNextPage
() => searchCategoryOpts.data.search.pageInfo.hasNextPage
),
loading: searchCategoryOpts.loading,
onFetchMore: loadMoreCategories
}}
fetchMoreCollections={{
hasMore: maybe(
() =>
searchCollectionOpts.data.search.pageInfo
.hasNextPage
() => searchCollectionOpts.data.search.pageInfo.hasNextPage
),
loading: searchCollectionOpts.loading,
onFetchMore: loadMoreCollections
}}
fetchMoreProductTypes={{
hasMore: maybe(
() =>
searchProductTypesOpts.data.search.pageInfo
.hasNextPage
() => searchProductTypesOpts.data.search.pageInfo.hasNextPage
),
loading: searchProductTypesOpts.loading,
onFetchMore: loadMoreProductTypes
@ -188,12 +173,5 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = () => {
}}
</TypedProductCreateMutation>
);
}}
</SearchProductTypes>
)}
</SearchCollections>
)}
</SearchCategories>
);
};
export default ProductUpdate;

View file

@ -7,6 +7,7 @@ import { FormattedMessage, useIntl } from "react-intl";
import placeholderImg from "@assets/images/placeholder255x255.png";
import ActionDialog from "@saleor/components/ActionDialog";
import { WindowTitle } from "@saleor/components/WindowTitle";
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
import useBulkActions from "@saleor/hooks/useBulkActions";
import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
@ -14,9 +15,8 @@ import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl";
import ProductVariantCreateDialog from "@saleor/products/components/ProductVariantCreateDialog/ProductVariantCreateDialog";
import { ProductVariantBulkCreate } from "@saleor/products/types/ProductVariantBulkCreate";
import { DEFAULT_INITIAL_SEARCH_DATA } from "../../../config";
import SearchCategories from "../../../containers/SearchCategories";
import SearchCollections from "../../../containers/SearchCollections";
import useCategorySearch from "@saleor/searches/useCategorySearch";
import useCollectionSearch from "@saleor/searches/useCollectionSearch";
import { getMutationState, maybe } from "../../../misc";
import ProductUpdatePage from "../../components/ProductUpdatePage";
import ProductUpdateOperations from "../../containers/ProductUpdateOperations";
@ -55,6 +55,20 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
);
const intl = useIntl();
const shop = useShop();
const {
loadMore: loadMoreCategories,
search: searchCategories,
result: searchCategoriesOpts
} = useCategorySearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const {
loadMore: loadMoreCollections,
search: searchCollections,
result: searchCollectionsOpts
} = useCollectionSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const openModal = (action: ProductUrlDialog) =>
navigate(
@ -64,18 +78,6 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
);
return (
<SearchCategories variables={DEFAULT_INITIAL_SEARCH_DATA}>
{({
loadMore: loadMoreCategories,
search: searchCategories,
result: searchCategoriesOpts
}) => (
<SearchCollections variables={DEFAULT_INITIAL_SEARCH_DATA}>
{({
loadMore: loadMoreCollections,
search: searchCollections,
result: searchCollectionsOpts
}) => (
<TypedProductDetailsQuery
displayLoader
require={["product"]}
@ -108,8 +110,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
const handleImageCreate = (data: ProductImageCreate) => {
const imageError = data.productImageCreate.errors.find(
error =>
error.field ===
("image" as keyof ProductImageCreateVariables)
error.field === ("image" as keyof ProductImageCreateVariables)
);
if (imageError) {
notify({
@ -121,8 +122,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
notify({
text: intl.formatMessage(commonMessages.savedChanges)
});
const handleVariantAdd = () =>
navigate(productVariantAddUrl(id));
const handleVariantAdd = () => navigate(productVariantAddUrl(id));
const handleBulkProductVariantCreate = (
data: ProductVariantBulkCreate
@ -197,29 +197,19 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
updateProduct.opts.loading ||
loading;
const formTransitionState = getMutationState(
updateProduct.opts.called ||
updateSimpleProduct.opts.called,
updateProduct.opts.loading ||
updateSimpleProduct.opts.loading,
maybe(
() => updateProduct.opts.data.productUpdate.errors
),
updateProduct.opts.called || updateSimpleProduct.opts.called,
updateProduct.opts.loading || updateSimpleProduct.opts.loading,
maybe(() => updateProduct.opts.data.productUpdate.errors),
maybe(() => updateSimpleProduct.opts.data.productUpdate.errors),
maybe(
() =>
updateSimpleProduct.opts.data.productUpdate.errors
),
maybe(
() =>
updateSimpleProduct.opts.data.productVariantUpdate
.errors
updateSimpleProduct.opts.data.productVariantUpdate.errors
)
);
const deleteTransitionState = getMutationState(
deleteProduct.opts.called,
deleteProduct.opts.loading,
maybe(
() => deleteProduct.opts.data.productDelete.errors
)
maybe(() => deleteProduct.opts.data.productDelete.errors)
);
const bulkProductVariantDeleteTransitionState = getMutationState(
@ -227,8 +217,8 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
bulkProductVariantDelete.opts.loading,
maybe(
() =>
bulkProductVariantDelete.opts.data
.productVariantBulkDelete.errors
bulkProductVariantDelete.opts.data.productVariantBulkDelete
.errors
)
);
@ -275,9 +265,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
onVariantAdd={handleVariantAdd}
onVariantsAdd={handleVariantCreatorOpen}
onVariantShow={variantId => () =>
navigate(
productVariantEditUrl(product.id, variantId)
)}
navigate(productVariantEditUrl(product.id, variantId))}
onImageUpload={handleImageUpload}
onImageEdit={handleImageEdit}
onImageDelete={handleImageDelete}
@ -303,8 +291,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
fetchMoreCategories={{
hasMore: maybe(
() =>
searchCategoriesOpts.data.search.pageInfo
.hasNextPage
searchCategoriesOpts.data.search.pageInfo.hasNextPage
),
loading: searchCategoriesOpts.loading,
onFetchMore: loadMoreCategories
@ -312,8 +299,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
fetchMoreCollections={{
hasMore: maybe(
() =>
searchCollectionsOpts.data.search.pageInfo
.hasNextPage
searchCollectionsOpts.data.search.pageInfo.hasNextPage
),
loading: searchCollectionsOpts.loading,
onFetchMore: loadMoreCollections
@ -343,9 +329,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
<ActionDialog
open={params.action === "remove-variants"}
onClose={() => navigate(productUrl(id), true)}
confirmButtonState={
bulkProductVariantDeleteTransitionState
}
confirmButtonState={bulkProductVariantDeleteTransitionState}
onConfirm={() =>
bulkProductVariantDelete.mutate({
ids: params.ids
@ -364,9 +348,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
values={{
counter: maybe(() => params.ids.length),
displayQuantity: (
<strong>
{maybe(() => params.ids.length)}
</strong>
<strong>{maybe(() => params.ids.length)}</strong>
)
}}
/>
@ -410,10 +392,6 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
);
}}
</TypedProductDetailsQuery>
)}
</SearchCollections>
)}
</SearchCategories>
);
};
export default ProductUpdate;

View file

@ -2,7 +2,7 @@
/* eslint-disable */
// This file was automatically generated and should not be edited.
import { AttributeInputTypeEnum } from "./../../../types/globalTypes";
import { AttributeInputTypeEnum } from "./../../types/globalTypes";
// ====================================================
// GraphQL query operation: SearchProductTypes
@ -22,7 +22,9 @@ export interface SearchProductTypes_search_edges_node_productAttributes {
slug: string | null;
name: string | null;
valueRequired: boolean;
values: (SearchProductTypes_search_edges_node_productAttributes_values | null)[] | null;
values:
| (SearchProductTypes_search_edges_node_productAttributes_values | null)[]
| null;
}
export interface SearchProductTypes_search_edges_node {
@ -30,7 +32,9 @@ export interface SearchProductTypes_search_edges_node {
id: string;
name: string;
hasVariants: boolean;
productAttributes: (SearchProductTypes_search_edges_node_productAttributes | null)[] | null;
productAttributes:
| (SearchProductTypes_search_edges_node_productAttributes | null)[]
| null;
}
export interface SearchProductTypes_search_edges {

View file

@ -1,7 +1,7 @@
import gql from "graphql-tag";
import makeTopLevelSearch from "@saleor/hooks/makeTopLevelSearch";
import { pageInfoFragment } from "@saleor/queries";
import TopLevelSearch from "../TopLevelSearch";
import {
SearchCategories,
SearchCategoriesVariables
@ -24,6 +24,6 @@ export const searchCategories = gql`
}
`;
export default TopLevelSearch<SearchCategories, SearchCategoriesVariables>(
export default makeTopLevelSearch<SearchCategories, SearchCategoriesVariables>(
searchCategories
);

View file

@ -1,7 +1,7 @@
import gql from "graphql-tag";
import makeTopLevelSearch from "@saleor/hooks/makeTopLevelSearch";
import { pageInfoFragment } from "@saleor/queries";
import TopLevelSearch from "../TopLevelSearch";
import {
SearchCollections,
SearchCollectionsVariables
@ -24,6 +24,7 @@ export const searchCollections = gql`
}
`;
export default TopLevelSearch<SearchCollections, SearchCollectionsVariables>(
searchCollections
);
export default makeTopLevelSearch<
SearchCollections,
SearchCollectionsVariables
>(searchCollections);

View file

@ -1,7 +1,7 @@
import gql from "graphql-tag";
import makeTopLevelSearch from "@saleor/hooks/makeTopLevelSearch";
import { pageInfoFragment } from "@saleor/queries";
import TopLevelSearch from "../TopLevelSearch";
import {
SearchCustomers,
SearchCustomersVariables
@ -24,6 +24,6 @@ export const searchCustomers = gql`
}
`;
export default TopLevelSearch<SearchCustomers, SearchCustomersVariables>(
export default makeTopLevelSearch<SearchCustomers, SearchCustomersVariables>(
searchCustomers
);

View file

@ -1,7 +1,7 @@
import gql from "graphql-tag";
import makeTopLevelSearch from "@saleor/hooks/makeTopLevelSearch";
import { pageInfoFragment } from "@saleor/queries";
import TopLevelSearch from "../TopLevelSearch";
import { SearchPages, SearchPagesVariables } from "./types/SearchPages";
export const searchPages = gql`
@ -21,4 +21,6 @@ export const searchPages = gql`
}
`;
export default TopLevelSearch<SearchPages, SearchPagesVariables>(searchPages);
export default makeTopLevelSearch<SearchPages, SearchPagesVariables>(
searchPages
);

View file

@ -1,7 +1,7 @@
import gql from "graphql-tag";
import makeTopLevelSearch from "@saleor/hooks/makeTopLevelSearch";
import { pageInfoFragment } from "@saleor/queries";
import TopLevelSearch from "../TopLevelSearch";
import {
SearchProducts,
SearchProductsVariables
@ -27,6 +27,6 @@ export const searchProducts = gql`
}
`;
export default TopLevelSearch<SearchProducts, SearchProductsVariables>(
export default makeTopLevelSearch<SearchProducts, SearchProductsVariables>(
searchProducts
);

View file

@ -1,7 +1,7 @@
import gql from "graphql-tag";
import makeTopLevelSearch from "@saleor/hooks/makeTopLevelSearch";
import { pageInfoFragment } from "@saleor/queries";
import TopLevelSearch from "../TopLevelSearch";
import {
SearchProductTypes,
SearchProductTypesVariables
@ -41,6 +41,7 @@ export const searchProductTypes = gql`
}
`;
export default TopLevelSearch<SearchProductTypes, SearchProductTypesVariables>(
searchProductTypes
);
export default makeTopLevelSearch<
SearchProductTypes,
SearchProductTypesVariables
>(searchProductTypes);

View file

@ -1,7 +1,7 @@
import gql from "graphql-tag";
import makeTopLevelSearch from "@saleor/hooks/makeTopLevelSearch";
import { pageInfoFragment } from "@saleor/queries";
import TopLevelSearch from "../TopLevelSearch";
import {
SearchServiceAccount,
SearchServiceAccountVariables
@ -28,7 +28,7 @@ export const searchServiceAccount = gql`
}
`;
export default TopLevelSearch<
export default makeTopLevelSearch<
SearchServiceAccount,
SearchServiceAccountVariables
>(searchServiceAccount);

View file

@ -125505,6 +125505,7 @@ exports[`Storyshots Views / Webhooks / Create webhook default 1`] = `
class="MuiInputBase-input-id MuiOutlinedInput-input-id"
name="name"
type="text"
value=""
/>
<fieldset
aria-hidden="true"
@ -126037,6 +126038,7 @@ exports[`Storyshots Views / Webhooks / Create webhook form errors 1`] = `
class="MuiInputBase-input-id MuiOutlinedInput-input-id"
name="name"
type="text"
value=""
/>
<fieldset
aria-hidden="true"
@ -126575,6 +126577,7 @@ exports[`Storyshots Views / Webhooks / Create webhook loading 1`] = `
disabled=""
name="name"
type="text"
value=""
/>
<fieldset
aria-hidden="true"

View file

@ -6,9 +6,9 @@ import FormSpacer from "@saleor/components/FormSpacer";
import Grid from "@saleor/components/Grid";
import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar";
import { SearchServiceAccount_search_edges_node } from "@saleor/containers/SearchServiceAccount/types/SearchServiceAccount";
import { sectionNames } from "@saleor/intl";
import { maybe } from "@saleor/misc";
import { SearchServiceAccount_search_edges_node } from "@saleor/searches/types/SearchServiceAccount";
import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
import WebhookEvents from "@saleor/webhooks/components/WebhookEvents";
@ -19,7 +19,6 @@ import React from "react";
import { useIntl } from "react-intl";
export interface FormData {
id: string;
events: WebhookEventTypeEnum[];
isActive: boolean;
name: string;
@ -52,9 +51,8 @@ const WebhookCreatePage: React.FC<WebhookCreatePageProps> = ({
const initialForm: FormData = {
allEvents: false,
events: [],
id: null,
isActive: false,
name: null,
name: "",
secretKey: "",
serviceAccount: "",
targetUrl: ""

View file

@ -1,3 +1,6 @@
import React from "react";
import { useIntl } from "react-intl";
import AppHeader from "@saleor/components/AppHeader";
import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
import Container from "@saleor/components/Container";
@ -6,10 +9,10 @@ import FormSpacer from "@saleor/components/FormSpacer";
import Grid from "@saleor/components/Grid";
import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar";
import { SearchServiceAccount_search_edges_node } from "@saleor/containers/SearchServiceAccount/types/SearchServiceAccount";
import useStateFromProps from "@saleor/hooks/useStateFromProps";
import { sectionNames } from "@saleor/intl";
import { maybe } from "@saleor/misc";
import { SearchServiceAccount_search_edges_node } from "@saleor/searches/types/SearchServiceAccount";
import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
import WebhookEvents from "@saleor/webhooks/components/WebhookEvents";
@ -18,11 +21,7 @@ import WebhookStatus from "@saleor/webhooks/components/WebhookStatus";
import { WebhookCreate_webhookCreate_webhookErrors } from "@saleor/webhooks/types/WebhookCreate";
import { WebhookDetails_webhook } from "@saleor/webhooks/types/WebhookDetails";
import React from "react";
import { useIntl } from "react-intl";
export interface FormData {
id: string;
events: WebhookEventTypeEnum[];
isActive: boolean;
name: string;
@ -63,7 +62,6 @@ const WebhooksDetailsPage: React.FC<WebhooksDetailsPageProps> = ({
events: maybe(() => webhook.events, [])
.map(event => event.eventType)
.filter(event => event !== WebhookEventTypeEnum.ANY_EVENTS),
id: maybe(() => webhook.id, null),
isActive: maybe(() => webhook.isActive, false),
name: maybe(() => webhook.name, ""),
secretKey: maybe(() => webhook.secretKey, ""),

View file

@ -1,13 +1,13 @@
import { WindowTitle } from "@saleor/components/WindowTitle";
import SearchServiceAccount from "@saleor/containers/SearchServiceAccount";
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
import { commonMessages } from "@saleor/intl";
import useServiceAccountSearch from "@saleor/searches/useServiceAccountSearch";
import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
import { WebhookCreate as WebhookCreateData } from "@saleor/webhooks/types/WebhookCreate";
import React from "react";
import { useIntl } from "react-intl";
import { DEFAULT_INITIAL_SEARCH_DATA } from "../../config";
import { getMutationState, maybe } from "../../misc";
import WebhookCreatePage, { FormData } from "../components/WebhookCreatePage";
import { TypedWebhookCreate } from "../mutations";
@ -26,6 +26,12 @@ export const WebhooksCreate: React.FC<WebhooksCreateProps> = () => {
const navigate = useNavigator();
const notify = useNotifier();
const intl = useIntl();
const {
search: searchServiceAccount,
result: searchServiceAccountOpt
} = useServiceAccountSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const onSubmit = (data: WebhookCreateData) => {
if (data.webhookCreate.webhookErrors.length === 0) {
@ -39,8 +45,6 @@ export const WebhooksCreate: React.FC<WebhooksCreateProps> = () => {
const handleBack = () => navigate(webhooksListUrl());
return (
<SearchServiceAccount variables={DEFAULT_INITIAL_SEARCH_DATA}>
{({ search: searchServiceAccount, result: searchServiceAccountOpt }) => (
<TypedWebhookCreate onCompleted={onSubmit}>
{(webhookCreate, webhookCreateOpts) => {
const handleSubmit = (data: FormData) =>
@ -81,9 +85,7 @@ export const WebhooksCreate: React.FC<WebhooksCreateProps> = () => {
)}
fetchServiceAccounts={searchServiceAccount}
services={maybe(() =>
searchServiceAccountOpt.data.search.edges.map(
edge => edge.node
)
searchServiceAccountOpt.data.search.edges.map(edge => edge.node)
)}
onBack={handleBack}
onSubmit={handleSubmit}
@ -93,8 +95,6 @@ export const WebhooksCreate: React.FC<WebhooksCreateProps> = () => {
);
}}
</TypedWebhookCreate>
)}
</SearchServiceAccount>
);
};
WebhooksCreate.displayName = "WebhooksCreate";

View file

@ -1,15 +1,16 @@
import React from "react";
import { useIntl } from "react-intl";
import { WindowTitle } from "@saleor/components/WindowTitle";
import SearchServiceAccount from "@saleor/containers/SearchServiceAccount";
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
import { commonMessages } from "@saleor/intl";
import useServiceAccountSearch from "@saleor/searches/useServiceAccountSearch";
import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
import WebhookDeleteDialog from "@saleor/webhooks/components/WebhookDeleteDialog";
import { WebhookDelete } from "@saleor/webhooks/types/WebhookDelete";
import { WebhookUpdate } from "@saleor/webhooks/types/WebhookUpdate";
import React from "react";
import { useIntl } from "react-intl";
import { DEFAULT_INITIAL_SEARCH_DATA } from "../../config";
import { getMutationState, maybe } from "../../misc";
import WebhooksDetailsPage from "../components/WebhooksDetailsPage";
import { TypedWebhookDelete, TypedWebhookUpdate } from "../mutations";
@ -33,6 +34,12 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({
const navigate = useNavigator();
const notify = useNotifier();
const intl = useIntl();
const {
search: searchServiceAccount,
result: searchServiceAccountOpt
} = useServiceAccountSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const closeModal = () =>
navigate(
@ -72,8 +79,6 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({
};
return (
<SearchServiceAccount variables={DEFAULT_INITIAL_SEARCH_DATA}>
{({ search: searchServiceAccount, result: searchServiceAccountOpt }) => (
<TypedWebhookUpdate onCompleted={onWebhookUpdate}>
{(webhookUpdate, webhookUpdateOpts) => (
<TypedWebhookDelete onCompleted={onWebhookDelete}>
@ -160,8 +165,6 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({
</TypedWebhookDelete>
)}
</TypedWebhookUpdate>
)}
</SearchServiceAccount>
);
};
WebhooksDetails.displayName = "WebhooksDetails";