Create makeQuery hook
This commit is contained in:
parent
b12f3c35fa
commit
8a6cd1ef1f
4 changed files with 470 additions and 375 deletions
|
@ -1,6 +1,7 @@
|
|||
import gql from "graphql-tag";
|
||||
|
||||
import { pageInfoFragment, TypedQuery } from "../queries";
|
||||
import makeQuery from "@saleor/hooks/makeQuery";
|
||||
import { pageInfoFragment } from "../queries";
|
||||
import {
|
||||
CategoryDetails,
|
||||
CategoryDetailsVariables
|
||||
|
@ -65,7 +66,7 @@ export const rootCategories = gql`
|
|||
}
|
||||
}
|
||||
`;
|
||||
export const TypedRootCategoriesQuery = TypedQuery<RootCategories, {}>(
|
||||
export const useRootCategoriesQuery = makeQuery<RootCategories, {}>(
|
||||
rootCategories
|
||||
);
|
||||
|
||||
|
@ -119,7 +120,7 @@ export const categoryDetails = gql`
|
|||
}
|
||||
}
|
||||
`;
|
||||
export const TypedCategoryDetailsQuery = TypedQuery<
|
||||
export const useCategoryDetailsQuery = makeQuery<
|
||||
CategoryDetails,
|
||||
CategoryDetailsVariables
|
||||
>(categoryDetails);
|
||||
|
|
|
@ -28,7 +28,7 @@ import {
|
|||
useCategoryDeleteMutation,
|
||||
useCategoryUpdateMutation
|
||||
} from "../mutations";
|
||||
import { TypedCategoryDetailsQuery } from "../queries";
|
||||
import { useCategoryDetailsQuery } from "../queries";
|
||||
import { CategoryBulkDelete } from "../types/CategoryBulkDelete";
|
||||
import { CategoryDelete } from "../types/CategoryDelete";
|
||||
import { CategoryUpdate } from "../types/CategoryUpdate";
|
||||
|
@ -63,6 +63,13 @@ export const CategoryDetails: React.FC<CategoryDetailsProps> = ({
|
|||
);
|
||||
const intl = useIntl();
|
||||
|
||||
const paginationState = createPaginationState(PAGINATE_BY, params);
|
||||
const { data, loading, refetch } = useCategoryDetailsQuery({
|
||||
displayLoader: true,
|
||||
require: ["category"],
|
||||
variables: { ...paginationState, id }
|
||||
});
|
||||
|
||||
const handleCategoryDelete = (data: CategoryDelete) => {
|
||||
if (data.categoryDelete.errors.length === 0) {
|
||||
notify({
|
||||
|
@ -140,7 +147,6 @@ export const CategoryDetails: React.FC<CategoryDetailsProps> = ({
|
|||
})
|
||||
);
|
||||
|
||||
const paginationState = createPaginationState(PAGINATE_BY, params);
|
||||
const formTransitionState = getMutationState(
|
||||
updateResult.called,
|
||||
updateResult.loading,
|
||||
|
@ -152,245 +158,221 @@ export const CategoryDetails: React.FC<CategoryDetailsProps> = ({
|
|||
maybe(() => deleteResult.data.categoryDelete.errors)
|
||||
);
|
||||
|
||||
const handleBulkProductDelete = (data: productBulkDelete) => {
|
||||
if (data.productBulkDelete.errors.length === 0) {
|
||||
closeModal();
|
||||
notify({
|
||||
text: intl.formatMessage(commonMessages.savedChanges)
|
||||
});
|
||||
refetch();
|
||||
reset();
|
||||
}
|
||||
};
|
||||
|
||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||
params.activeTab === CategoryPageTab.categories
|
||||
? maybe(() => data.category.children.pageInfo)
|
||||
: maybe(() => data.category.products.pageInfo),
|
||||
paginationState,
|
||||
params
|
||||
);
|
||||
|
||||
return (
|
||||
<TypedCategoryDetailsQuery
|
||||
displayLoader
|
||||
variables={{ ...paginationState, id }}
|
||||
require={["category"]}
|
||||
>
|
||||
{({ data, loading, refetch }) => {
|
||||
const handleBulkProductDelete = (data: productBulkDelete) => {
|
||||
if (data.productBulkDelete.errors.length === 0) {
|
||||
closeModal();
|
||||
notify({
|
||||
text: intl.formatMessage(commonMessages.savedChanges)
|
||||
});
|
||||
refetch();
|
||||
reset();
|
||||
}
|
||||
};
|
||||
<>
|
||||
<WindowTitle title={maybe(() => data.category.name)} />
|
||||
<TypedProductBulkDeleteMutation onCompleted={handleBulkProductDelete}>
|
||||
{(productBulkDelete, productBulkDeleteOpts) => {
|
||||
const categoryBulkDeleteMutationState = getMutationState(
|
||||
categoryBulkDeleteOpts.called,
|
||||
categoryBulkDeleteOpts.loading,
|
||||
maybe(() => categoryBulkDeleteOpts.data.categoryBulkDelete.errors)
|
||||
);
|
||||
const productBulkDeleteMutationState = getMutationState(
|
||||
productBulkDeleteOpts.called,
|
||||
productBulkDeleteOpts.loading,
|
||||
maybe(() => productBulkDeleteOpts.data.productBulkDelete.errors)
|
||||
);
|
||||
|
||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||
params.activeTab === CategoryPageTab.categories
|
||||
? maybe(() => data.category.children.pageInfo)
|
||||
: maybe(() => data.category.products.pageInfo),
|
||||
paginationState,
|
||||
params
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WindowTitle title={maybe(() => data.category.name)} />
|
||||
<TypedProductBulkDeleteMutation
|
||||
onCompleted={handleBulkProductDelete}
|
||||
>
|
||||
{(productBulkDelete, productBulkDeleteOpts) => {
|
||||
const categoryBulkDeleteMutationState = getMutationState(
|
||||
categoryBulkDeleteOpts.called,
|
||||
categoryBulkDeleteOpts.loading,
|
||||
maybe(
|
||||
() => categoryBulkDeleteOpts.data.categoryBulkDelete.errors
|
||||
return (
|
||||
<>
|
||||
<CategoryUpdatePage
|
||||
changeTab={changeTab}
|
||||
currentTab={params.activeTab}
|
||||
category={maybe(() => data.category)}
|
||||
disabled={loading}
|
||||
errors={maybe(() => updateResult.data.categoryUpdate.errors)}
|
||||
onAddCategory={() => navigate(categoryAddUrl(id))}
|
||||
onAddProduct={() => navigate(productAddUrl)}
|
||||
onBack={() =>
|
||||
navigate(
|
||||
maybe(
|
||||
() => categoryUrl(data.category.parent.id),
|
||||
categoryListUrl()
|
||||
)
|
||||
)
|
||||
);
|
||||
const productBulkDeleteMutationState = getMutationState(
|
||||
productBulkDeleteOpts.called,
|
||||
productBulkDeleteOpts.loading,
|
||||
maybe(
|
||||
() => productBulkDeleteOpts.data.productBulkDelete.errors
|
||||
)
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<CategoryUpdatePage
|
||||
changeTab={changeTab}
|
||||
currentTab={params.activeTab}
|
||||
category={maybe(() => data.category)}
|
||||
disabled={loading}
|
||||
errors={maybe(
|
||||
() => updateResult.data.categoryUpdate.errors
|
||||
)}
|
||||
onAddCategory={() => navigate(categoryAddUrl(id))}
|
||||
onAddProduct={() => navigate(productAddUrl)}
|
||||
onBack={() =>
|
||||
navigate(
|
||||
maybe(
|
||||
() => categoryUrl(data.category.parent.id),
|
||||
categoryListUrl()
|
||||
)
|
||||
)
|
||||
}
|
||||
onCategoryClick={id => () => navigate(categoryUrl(id))}
|
||||
onDelete={() => openModal("delete")}
|
||||
onImageDelete={() =>
|
||||
updateCategory({
|
||||
variables: {
|
||||
id,
|
||||
input: {
|
||||
backgroundImage: null
|
||||
}
|
||||
onCategoryClick={id => () => navigate(categoryUrl(id))}
|
||||
onDelete={() => openModal("delete")}
|
||||
onImageDelete={() =>
|
||||
updateCategory({
|
||||
variables: {
|
||||
id,
|
||||
input: {
|
||||
backgroundImage: null
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
onImageUpload={file =>
|
||||
updateCategory({
|
||||
variables: {
|
||||
id,
|
||||
input: {
|
||||
backgroundImage: file
|
||||
}
|
||||
onImageUpload={file =>
|
||||
updateCategory({
|
||||
variables: {
|
||||
id,
|
||||
input: {
|
||||
backgroundImage: file
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
onNextPage={loadNextPage}
|
||||
onPreviousPage={loadPreviousPage}
|
||||
pageInfo={pageInfo}
|
||||
onProductClick={id => () => navigate(productUrl(id))}
|
||||
onSubmit={formData =>
|
||||
updateCategory({
|
||||
variables: {
|
||||
id,
|
||||
input: {
|
||||
backgroundImageAlt: formData.backgroundImageAlt,
|
||||
descriptionJson: JSON.stringify(formData.description),
|
||||
name: formData.name,
|
||||
seo: {
|
||||
description: formData.seoDescription,
|
||||
title: formData.seoTitle
|
||||
}
|
||||
}
|
||||
onNextPage={loadNextPage}
|
||||
onPreviousPage={loadPreviousPage}
|
||||
pageInfo={pageInfo}
|
||||
onProductClick={id => () => navigate(productUrl(id))}
|
||||
onSubmit={formData =>
|
||||
updateCategory({
|
||||
variables: {
|
||||
id,
|
||||
input: {
|
||||
backgroundImageAlt: formData.backgroundImageAlt,
|
||||
descriptionJson: JSON.stringify(
|
||||
formData.description
|
||||
),
|
||||
name: formData.name,
|
||||
seo: {
|
||||
description: formData.seoDescription,
|
||||
title: formData.seoTitle
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
products={maybe(() =>
|
||||
data.category.products.edges.map(edge => edge.node)
|
||||
)}
|
||||
saveButtonBarState={formTransitionState}
|
||||
subcategories={maybe(() =>
|
||||
data.category.children.edges.map(edge => edge.node)
|
||||
)}
|
||||
subcategoryListToolbar={
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={() =>
|
||||
openModal("delete-categories", listElements)
|
||||
}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
}
|
||||
productListToolbar={
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={() =>
|
||||
openModal("delete-products", listElements)
|
||||
}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
}
|
||||
isChecked={isSelected}
|
||||
selected={listElements.length}
|
||||
toggle={toggle}
|
||||
toggleAll={toggleAll}
|
||||
/>
|
||||
<ActionDialog
|
||||
confirmButtonState={removeDialogTransitionState}
|
||||
onClose={closeModal}
|
||||
onConfirm={() => deleteCategory({ variables: { id } })}
|
||||
open={params.action === "delete"}
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Delete category",
|
||||
description: "dialog title"
|
||||
})}
|
||||
variant="delete"
|
||||
>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete {categoryName}?"
|
||||
values={{
|
||||
categoryName: (
|
||||
<strong>
|
||||
{maybe(() => data.category.name, "...")}
|
||||
</strong>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</DialogContentText>
|
||||
<DialogContentText>
|
||||
<FormattedMessage defaultMessage="Remember this will also delete all products assigned to this category." />
|
||||
</DialogContentText>
|
||||
</ActionDialog>
|
||||
<ActionDialog
|
||||
open={
|
||||
params.action === "delete-categories" &&
|
||||
maybe(() => params.ids.length > 0)
|
||||
}
|
||||
confirmButtonState={categoryBulkDeleteMutationState}
|
||||
onClose={closeModal}
|
||||
onConfirm={() =>
|
||||
categoryBulkDelete({
|
||||
variables: { ids: params.ids }
|
||||
}).then(() => refetch())
|
||||
}
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Delete categories",
|
||||
description: "dialog title"
|
||||
})}
|
||||
variant="delete"
|
||||
>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete {counter,plural,one{this category} other{{displayQuantity} categories}}?"
|
||||
values={{
|
||||
counter: maybe(() => params.ids.length),
|
||||
displayQuantity: (
|
||||
<strong>{maybe(() => params.ids.length)}</strong>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</DialogContentText>
|
||||
<DialogContentText>
|
||||
<FormattedMessage defaultMessage="Remember this will also delete all products assigned to this category." />
|
||||
</DialogContentText>
|
||||
</ActionDialog>
|
||||
<ActionDialog
|
||||
open={params.action === "delete-products"}
|
||||
confirmButtonState={productBulkDeleteMutationState}
|
||||
onClose={closeModal}
|
||||
onConfirm={() =>
|
||||
productBulkDelete({
|
||||
variables: { ids: params.ids }
|
||||
}).then(() => refetch())
|
||||
}
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Delete products",
|
||||
description: "dialog title"
|
||||
})}
|
||||
variant="delete"
|
||||
>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete {counter,plural,one{this product} other{{displayQuantity} products}}?"
|
||||
values={{
|
||||
counter: maybe(() => params.ids.length),
|
||||
displayQuantity: (
|
||||
<strong>{maybe(() => params.ids.length)}</strong>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</DialogContentText>
|
||||
</ActionDialog>
|
||||
</>
|
||||
);
|
||||
}}
|
||||
</TypedProductBulkDeleteMutation>
|
||||
</>
|
||||
);
|
||||
}}
|
||||
</TypedCategoryDetailsQuery>
|
||||
}
|
||||
})
|
||||
}
|
||||
products={maybe(() =>
|
||||
data.category.products.edges.map(edge => edge.node)
|
||||
)}
|
||||
saveButtonBarState={formTransitionState}
|
||||
subcategories={maybe(() =>
|
||||
data.category.children.edges.map(edge => edge.node)
|
||||
)}
|
||||
subcategoryListToolbar={
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={() => openModal("delete-categories", listElements)}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
}
|
||||
productListToolbar={
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={() => openModal("delete-products", listElements)}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
}
|
||||
isChecked={isSelected}
|
||||
selected={listElements.length}
|
||||
toggle={toggle}
|
||||
toggleAll={toggleAll}
|
||||
/>
|
||||
<ActionDialog
|
||||
confirmButtonState={removeDialogTransitionState}
|
||||
onClose={closeModal}
|
||||
onConfirm={() => deleteCategory({ variables: { id } })}
|
||||
open={params.action === "delete"}
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Delete category",
|
||||
description: "dialog title"
|
||||
})}
|
||||
variant="delete"
|
||||
>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete {categoryName}?"
|
||||
values={{
|
||||
categoryName: (
|
||||
<strong>
|
||||
{maybe(() => data.category.name, "...")}
|
||||
</strong>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</DialogContentText>
|
||||
<DialogContentText>
|
||||
<FormattedMessage defaultMessage="Remember this will also delete all products assigned to this category." />
|
||||
</DialogContentText>
|
||||
</ActionDialog>
|
||||
<ActionDialog
|
||||
open={
|
||||
params.action === "delete-categories" &&
|
||||
maybe(() => params.ids.length > 0)
|
||||
}
|
||||
confirmButtonState={categoryBulkDeleteMutationState}
|
||||
onClose={closeModal}
|
||||
onConfirm={() =>
|
||||
categoryBulkDelete({
|
||||
variables: { ids: params.ids }
|
||||
}).then(() => refetch())
|
||||
}
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Delete categories",
|
||||
description: "dialog title"
|
||||
})}
|
||||
variant="delete"
|
||||
>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete {counter,plural,one{this category} other{{displayQuantity} categories}}?"
|
||||
values={{
|
||||
counter: maybe(() => params.ids.length),
|
||||
displayQuantity: (
|
||||
<strong>{maybe(() => params.ids.length)}</strong>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</DialogContentText>
|
||||
<DialogContentText>
|
||||
<FormattedMessage defaultMessage="Remember this will also delete all products assigned to this category." />
|
||||
</DialogContentText>
|
||||
</ActionDialog>
|
||||
<ActionDialog
|
||||
open={params.action === "delete-products"}
|
||||
confirmButtonState={productBulkDeleteMutationState}
|
||||
onClose={closeModal}
|
||||
onConfirm={() =>
|
||||
productBulkDelete({
|
||||
variables: { ids: params.ids }
|
||||
}).then(() => refetch())
|
||||
}
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Delete products",
|
||||
description: "dialog title"
|
||||
})}
|
||||
variant="delete"
|
||||
>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete {counter,plural,one{this product} other{{displayQuantity} products}}?"
|
||||
values={{
|
||||
counter: maybe(() => params.ids.length),
|
||||
displayQuantity: (
|
||||
<strong>{maybe(() => params.ids.length)}</strong>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</DialogContentText>
|
||||
</ActionDialog>
|
||||
</>
|
||||
);
|
||||
}}
|
||||
</TypedProductBulkDeleteMutation>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default CategoryDetails;
|
||||
|
|
|
@ -19,7 +19,7 @@ import { getMutationState, maybe } from "@saleor/misc";
|
|||
import { ListViews } from "@saleor/types";
|
||||
import { CategoryListPage } from "../../components/CategoryListPage/CategoryListPage";
|
||||
import { useCategoryBulkDeleteMutation } from "../../mutations";
|
||||
import { TypedRootCategoriesQuery } from "../../queries";
|
||||
import { useRootCategoriesQuery } from "../../queries";
|
||||
import { CategoryBulkDelete } from "../../types/CategoryBulkDelete";
|
||||
import {
|
||||
categoryAddUrl,
|
||||
|
@ -53,6 +53,20 @@ export const CategoryList: React.FC<CategoryListProps> = ({ params }) => {
|
|||
);
|
||||
const intl = useIntl();
|
||||
|
||||
const paginationState = createPaginationState(settings.rowNumber, params);
|
||||
const queryVariables = React.useMemo(
|
||||
() => ({
|
||||
...paginationState,
|
||||
filter: getFilterVariables(params)
|
||||
}),
|
||||
[params]
|
||||
);
|
||||
const { data, loading, refetch } = useRootCategoriesQuery({
|
||||
displayLoader: true,
|
||||
require: ["categories"],
|
||||
variables: queryVariables
|
||||
});
|
||||
|
||||
const tabs = getFilterTabs();
|
||||
|
||||
const currentTab =
|
||||
|
@ -113,146 +127,129 @@ export const CategoryList: React.FC<CategoryListProps> = ({ params }) => {
|
|||
handleTabChange(tabs.length + 1);
|
||||
};
|
||||
|
||||
const paginationState = createPaginationState(settings.rowNumber, params);
|
||||
const queryVariables = React.useMemo(
|
||||
() => ({
|
||||
...paginationState,
|
||||
filter: getFilterVariables(params)
|
||||
}),
|
||||
[params]
|
||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||
maybe(() => data.categories.pageInfo),
|
||||
paginationState,
|
||||
params
|
||||
);
|
||||
|
||||
const handleCategoryBulkDelete = (data: CategoryBulkDelete) => {
|
||||
if (data.categoryBulkDelete.errors.length === 0) {
|
||||
navigate(categoryListUrl(), true);
|
||||
refetch();
|
||||
reset();
|
||||
}
|
||||
};
|
||||
|
||||
const [
|
||||
categoryBulkDelete,
|
||||
categoryBulkDeleteOpts
|
||||
] = useCategoryBulkDeleteMutation({
|
||||
onCompleted: handleCategoryBulkDelete
|
||||
});
|
||||
|
||||
const bulkDeleteState = getMutationState(
|
||||
categoryBulkDeleteOpts.called,
|
||||
categoryBulkDeleteOpts.loading,
|
||||
maybe(() => categoryBulkDeleteOpts.data.categoryBulkDelete.errors)
|
||||
);
|
||||
|
||||
return (
|
||||
<TypedRootCategoriesQuery displayLoader variables={queryVariables}>
|
||||
{({ data, loading, refetch }) => {
|
||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||
maybe(() => data.categories.pageInfo),
|
||||
paginationState,
|
||||
params
|
||||
);
|
||||
|
||||
const handleCategoryBulkDelete = (data: CategoryBulkDelete) => {
|
||||
if (data.categoryBulkDelete.errors.length === 0) {
|
||||
navigate(categoryListUrl(), true);
|
||||
refetch();
|
||||
reset();
|
||||
}
|
||||
};
|
||||
|
||||
const [
|
||||
categoryBulkDelete,
|
||||
categoryBulkDeleteOpts
|
||||
] = useCategoryBulkDeleteMutation({
|
||||
onCompleted: handleCategoryBulkDelete
|
||||
});
|
||||
|
||||
const bulkDeleteState = getMutationState(
|
||||
categoryBulkDeleteOpts.called,
|
||||
categoryBulkDeleteOpts.loading,
|
||||
maybe(() => categoryBulkDeleteOpts.data.categoryBulkDelete.errors)
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<CategoryListPage
|
||||
categories={maybe(
|
||||
() => data.categories.edges.map(edge => edge.node),
|
||||
[]
|
||||
)}
|
||||
currentTab={currentTab}
|
||||
initialSearch={params.query || ""}
|
||||
onSearchChange={query => changeFilterField({ query })}
|
||||
onAll={() => navigate(categoryListUrl())}
|
||||
onTabChange={handleTabChange}
|
||||
onTabDelete={() => openModal("delete-search")}
|
||||
onTabSave={() => openModal("save-search")}
|
||||
tabs={tabs.map(tab => tab.name)}
|
||||
settings={settings}
|
||||
onAdd={() => navigate(categoryAddUrl())}
|
||||
onRowClick={id => () => navigate(categoryUrl(id))}
|
||||
disabled={loading}
|
||||
onNextPage={loadNextPage}
|
||||
onPreviousPage={loadPreviousPage}
|
||||
onUpdateListSettings={updateListSettings}
|
||||
pageInfo={pageInfo}
|
||||
isChecked={isSelected}
|
||||
selected={listElements.length}
|
||||
toggle={toggle}
|
||||
toggleAll={toggleAll}
|
||||
toolbar={
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={() =>
|
||||
navigate(
|
||||
categoryListUrl({
|
||||
...params,
|
||||
action: "delete",
|
||||
ids: listElements
|
||||
})
|
||||
)
|
||||
}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
}
|
||||
/>
|
||||
<ActionDialog
|
||||
confirmButtonState={bulkDeleteState}
|
||||
onClose={() =>
|
||||
navigate(
|
||||
categoryListUrl({
|
||||
...params,
|
||||
action: undefined,
|
||||
ids: undefined
|
||||
})
|
||||
)
|
||||
}
|
||||
onConfirm={() =>
|
||||
categoryBulkDelete({
|
||||
variables: {
|
||||
ids: params.ids
|
||||
}
|
||||
<>
|
||||
<CategoryListPage
|
||||
categories={maybe(
|
||||
() => data.categories.edges.map(edge => edge.node),
|
||||
[]
|
||||
)}
|
||||
currentTab={currentTab}
|
||||
initialSearch={params.query || ""}
|
||||
onSearchChange={query => changeFilterField({ query })}
|
||||
onAll={() => navigate(categoryListUrl())}
|
||||
onTabChange={handleTabChange}
|
||||
onTabDelete={() => openModal("delete-search")}
|
||||
onTabSave={() => openModal("save-search")}
|
||||
tabs={tabs.map(tab => tab.name)}
|
||||
settings={settings}
|
||||
onAdd={() => navigate(categoryAddUrl())}
|
||||
onRowClick={id => () => navigate(categoryUrl(id))}
|
||||
disabled={loading}
|
||||
onNextPage={loadNextPage}
|
||||
onPreviousPage={loadPreviousPage}
|
||||
onUpdateListSettings={updateListSettings}
|
||||
pageInfo={pageInfo}
|
||||
isChecked={isSelected}
|
||||
selected={listElements.length}
|
||||
toggle={toggle}
|
||||
toggleAll={toggleAll}
|
||||
toolbar={
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={() =>
|
||||
navigate(
|
||||
categoryListUrl({
|
||||
...params,
|
||||
action: "delete",
|
||||
ids: listElements
|
||||
})
|
||||
}
|
||||
open={params.action === "delete"}
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Delete categories",
|
||||
description: "dialog title"
|
||||
})}
|
||||
variant="delete"
|
||||
>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete {counter,plural,one{this category} other{{displayQuantity} categories}}?"
|
||||
values={{
|
||||
counter: maybe(() => params.ids.length),
|
||||
displayQuantity: (
|
||||
<strong>{maybe(() => params.ids.length)}</strong>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</DialogContentText>
|
||||
<DialogContentText>
|
||||
<FormattedMessage defaultMessage="Remember this will also delete all products assigned to this category." />
|
||||
</DialogContentText>
|
||||
</ActionDialog>
|
||||
<SaveFilterTabDialog
|
||||
open={params.action === "save-search"}
|
||||
confirmButtonState="default"
|
||||
onClose={closeModal}
|
||||
onSubmit={handleTabSave}
|
||||
/>
|
||||
<DeleteFilterTabDialog
|
||||
open={params.action === "delete-search"}
|
||||
confirmButtonState="default"
|
||||
onClose={closeModal}
|
||||
onSubmit={handleTabDelete}
|
||||
tabName={maybe(() => tabs[currentTab - 1].name, "...")}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}}
|
||||
</TypedRootCategoriesQuery>
|
||||
)
|
||||
}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
}
|
||||
/>
|
||||
<ActionDialog
|
||||
confirmButtonState={bulkDeleteState}
|
||||
onClose={() =>
|
||||
navigate(
|
||||
categoryListUrl({
|
||||
...params,
|
||||
action: undefined,
|
||||
ids: undefined
|
||||
})
|
||||
)
|
||||
}
|
||||
onConfirm={() =>
|
||||
categoryBulkDelete({
|
||||
variables: {
|
||||
ids: params.ids
|
||||
}
|
||||
})
|
||||
}
|
||||
open={params.action === "delete"}
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Delete categories",
|
||||
description: "dialog title"
|
||||
})}
|
||||
variant="delete"
|
||||
>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete {counter,plural,one{this category} other{{displayQuantity} categories}}?"
|
||||
values={{
|
||||
counter: maybe(() => params.ids.length),
|
||||
displayQuantity: <strong>{maybe(() => params.ids.length)}</strong>
|
||||
}}
|
||||
/>
|
||||
</DialogContentText>
|
||||
<DialogContentText>
|
||||
<FormattedMessage defaultMessage="Remember this will also delete all products assigned to this category." />
|
||||
</DialogContentText>
|
||||
</ActionDialog>
|
||||
<SaveFilterTabDialog
|
||||
open={params.action === "save-search"}
|
||||
confirmButtonState="default"
|
||||
onClose={closeModal}
|
||||
onSubmit={handleTabSave}
|
||||
/>
|
||||
<DeleteFilterTabDialog
|
||||
open={params.action === "delete-search"}
|
||||
confirmButtonState="default"
|
||||
onClose={closeModal}
|
||||
onSubmit={handleTabDelete}
|
||||
tabName={maybe(() => tabs[currentTab - 1].name, "...")}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default CategoryList;
|
||||
|
|
115
src/hooks/makeQuery.ts
Normal file
115
src/hooks/makeQuery.ts
Normal file
|
@ -0,0 +1,115 @@
|
|||
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";
|
||||
import useAppState from "./useAppState";
|
||||
import useNotifier from "./useNotifier";
|
||||
|
||||
export interface LoadMore<TData, TVariables> {
|
||||
loadMore: (
|
||||
mergeFunc: (prev: TData, next: TData) => TData,
|
||||
extraVariables: Partial<TVariables>
|
||||
) => Promise<ApolloQueryResult<TData>>;
|
||||
}
|
||||
|
||||
type UseQuery<TData, TVariables> = QueryResult<TData, TVariables> &
|
||||
LoadMore<TData, TVariables>;
|
||||
type UseQueryOpts<TData, TVariables> = Partial<{
|
||||
displayLoader: boolean;
|
||||
require: Array<keyof TData>;
|
||||
skip: boolean;
|
||||
variables: TVariables;
|
||||
}>;
|
||||
type UseQueryHook<TData, TVariables> = (
|
||||
opts: UseQueryOpts<TData, TVariables>
|
||||
) => UseQuery<TData, TVariables>;
|
||||
|
||||
function makeQuery<TData, TVariables>(
|
||||
query: DocumentNode
|
||||
): UseQueryHook<TData, TVariables> {
|
||||
function useQuery<TData, TVariables>({
|
||||
displayLoader,
|
||||
require,
|
||||
skip,
|
||||
variables
|
||||
}: UseQueryOpts<TData, TVariables>): UseQuery<TData, TVariables> {
|
||||
const notify = useNotifier();
|
||||
const intl = useIntl();
|
||||
const [, dispatchAppState] = useAppState();
|
||||
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) {
|
||||
if (
|
||||
!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 }
|
||||
});
|
||||
|
||||
if (
|
||||
!queryData.loading &&
|
||||
require &&
|
||||
queryData.data &&
|
||||
!require.reduce((acc, key) => acc && queryData.data[key] !== null, true)
|
||||
) {
|
||||
dispatchAppState({
|
||||
payload: {
|
||||
error: "not-found"
|
||||
},
|
||||
type: "displayError"
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
...queryData,
|
||||
loadMore
|
||||
};
|
||||
}
|
||||
|
||||
return useQuery;
|
||||
}
|
||||
|
||||
export default makeQuery;
|
Loading…
Reference in a new issue