Do not use getMutationState explicitly

This commit is contained in:
dominik-zeglen 2019-12-06 18:11:46 +01:00
parent fad6dfe22a
commit 6b62f5cc40
56 changed files with 2127 additions and 2904 deletions

View file

@ -4,7 +4,7 @@ import slugify from "slugify";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ReorderEvent, UserError } from "@saleor/types"; import { ReorderEvent, UserError } from "@saleor/types";
import { import {
add, add,
@ -131,88 +131,80 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
return ( return (
<AttributeCreateMutation onCompleted={handleCreate}> <AttributeCreateMutation onCompleted={handleCreate}>
{(attributeCreate, attributeCreateOpts) => { {(attributeCreate, attributeCreateOpts) => (
const createTransitionState = getMutationState( <>
attributeCreateOpts.called, <AttributePage
attributeCreateOpts.loading, attribute={null}
maybe(() => attributeCreateOpts.data.attributeCreate.errors) disabled={false}
); errors={maybe(
() => attributeCreateOpts.data.attributeCreate.errors,
return ( []
<>
<AttributePage
attribute={null}
disabled={false}
errors={maybe(
() => attributeCreateOpts.data.attributeCreate.errors,
[]
)}
onBack={() => navigate(attributeListUrl())}
onDelete={undefined}
onSubmit={input =>
attributeCreate({
variables: {
input: {
...input,
storefrontSearchPosition: parseInt(
input.storefrontSearchPosition,
0
),
values: values.map(value => ({
name: value.name
}))
}
}
})
}
onValueAdd={() => openModal("add-value")}
onValueDelete={id => openModal("remove-value", id)}
onValueReorder={handleValueReorder}
onValueUpdate={id => openModal("edit-value", id)}
saveButtonBarState={createTransitionState}
values={values.map((value, valueIndex) => ({
__typename: "AttributeValue" as "AttributeValue",
id: valueIndex.toString(),
slug: slugify(value.name).toLowerCase(),
sortOrder: valueIndex,
type: null,
value: null,
...value
}))}
/>
<AttributeValueEditDialog
attributeValue={null}
confirmButtonState="default"
disabled={false}
errors={valueErrors}
open={params.action === "add-value"}
onClose={closeModal}
onSubmit={handleValueCreate}
/>
{values.length > 0 && (
<>
<AttributeValueDeleteDialog
attributeName={undefined}
open={params.action === "remove-value"}
name={maybe(() => values[id].name, "...")}
confirmButtonState="default"
onClose={closeModal}
onConfirm={handleValueDelete}
/>
<AttributeValueEditDialog
attributeValue={maybe(() => values[params.id])}
confirmButtonState="default"
disabled={false}
errors={valueErrors}
open={params.action === "edit-value"}
onClose={closeModal}
onSubmit={handleValueUpdate}
/>
</>
)} )}
</> onBack={() => navigate(attributeListUrl())}
); onDelete={undefined}
}} onSubmit={input =>
attributeCreate({
variables: {
input: {
...input,
storefrontSearchPosition: parseInt(
input.storefrontSearchPosition,
0
),
values: values.map(value => ({
name: value.name
}))
}
}
})
}
onValueAdd={() => openModal("add-value")}
onValueDelete={id => openModal("remove-value", id)}
onValueReorder={handleValueReorder}
onValueUpdate={id => openModal("edit-value", id)}
saveButtonBarState={attributeCreateOpts.state}
values={values.map((value, valueIndex) => ({
__typename: "AttributeValue" as "AttributeValue",
id: valueIndex.toString(),
slug: slugify(value.name).toLowerCase(),
sortOrder: valueIndex,
type: null,
value: null,
...value
}))}
/>
<AttributeValueEditDialog
attributeValue={null}
confirmButtonState="default"
disabled={false}
errors={valueErrors}
open={params.action === "add-value"}
onClose={closeModal}
onSubmit={handleValueCreate}
/>
{values.length > 0 && (
<>
<AttributeValueDeleteDialog
attributeName={undefined}
open={params.action === "remove-value"}
name={maybe(() => values[id].name, "...")}
confirmButtonState="default"
onClose={closeModal}
onConfirm={handleValueDelete}
/>
<AttributeValueEditDialog
attributeValue={maybe(() => values[params.id])}
confirmButtonState="default"
disabled={false}
errors={valueErrors}
open={params.action === "edit-value"}
onClose={closeModal}
onSubmit={handleValueUpdate}
/>
</>
)}
</>
)}
</AttributeCreateMutation> </AttributeCreateMutation>
); );
}; };

View file

@ -4,7 +4,7 @@ import { useIntl } from "react-intl";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ReorderEvent } from "@saleor/types"; import { ReorderEvent } from "@saleor/types";
import { move } from "@saleor/utils/lists"; import { move } from "@saleor/utils/lists";
import AttributeDeleteDialog from "../../components/AttributeDeleteDialog"; import AttributeDeleteDialog from "../../components/AttributeDeleteDialog";
@ -135,52 +135,6 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
onCompleted={handleValueReorderMutation} onCompleted={handleValueReorderMutation}
> >
{attributeValueReorder => { {attributeValueReorder => {
const deleteTransitionState = getMutationState(
attributeDeleteOpts.called,
attributeDeleteOpts.loading,
maybe(
() =>
attributeDeleteOpts.data.attributeDelete
.errors
)
);
const deleteValueTransitionState = getMutationState(
attributeValueDeleteOpts.called,
attributeValueDeleteOpts.loading,
maybe(
() =>
attributeValueDeleteOpts.data
.attributeValueDelete.errors
)
);
const updateTransitionState = getMutationState(
attributeUpdateOpts.called,
attributeUpdateOpts.loading,
maybe(
() =>
attributeUpdateOpts.data.attributeUpdate
.errors
)
);
const updateValueTransitionState = getMutationState(
attributeValueUpdateOpts.called,
attributeValueUpdateOpts.loading,
maybe(
() =>
attributeValueUpdateOpts.data
.attributeValueUpdate.errors
)
);
const createValueTransitionState = getMutationState(
attributeValueCreateOpts.called,
attributeValueCreateOpts.loading,
maybe(
() =>
attributeValueCreateOpts.data
.attributeValueCreate.errors
)
);
const handleValueReorder = ({ const handleValueReorder = ({
newIndex, newIndex,
oldIndex oldIndex
@ -252,7 +206,9 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
onValueUpdate={id => onValueUpdate={id =>
openModal("edit-value", id) openModal("edit-value", id)
} }
saveButtonBarState={updateTransitionState} saveButtonBarState={
attributeUpdateOpts.state
}
values={maybe( values={maybe(
() => data.attribute.values () => data.attribute.values
)} )}
@ -263,7 +219,9 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
() => data.attribute.name, () => data.attribute.name,
"..." "..."
)} )}
confirmButtonState={deleteTransitionState} confirmButtonState={
attributeDeleteOpts.state
}
onClose={closeModal} onClose={closeModal}
onConfirm={() => onConfirm={() =>
attributeDelete({ attributeDelete({
@ -288,7 +246,7 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
)} )}
useName={true} useName={true}
confirmButtonState={ confirmButtonState={
deleteValueTransitionState attributeValueDeleteOpts.state
} }
onClose={closeModal} onClose={closeModal}
onConfirm={() => onConfirm={() =>
@ -302,7 +260,7 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
<AttributeValueEditDialog <AttributeValueEditDialog
attributeValue={null} attributeValue={null}
confirmButtonState={ confirmButtonState={
createValueTransitionState attributeValueCreateOpts.state
} }
disabled={loading} disabled={loading}
errors={maybe( errors={maybe(
@ -329,7 +287,7 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
) )
)} )}
confirmButtonState={ confirmButtonState={
updateValueTransitionState attributeValueUpdateOpts.state
} }
disabled={loading} disabled={loading}
errors={maybe( errors={maybe(

View file

@ -23,7 +23,7 @@ import usePaginator, {
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import { PAGINATE_BY } from "../../../config"; import { PAGINATE_BY } from "../../../config";
import useBulkActions from "../../../hooks/useBulkActions"; import useBulkActions from "../../../hooks/useBulkActions";
import { getMutationState, maybe } from "../../../misc"; import { maybe } from "../../../misc";
import AttributeBulkDeleteDialog from "../../components/AttributeBulkDeleteDialog"; import AttributeBulkDeleteDialog from "../../components/AttributeBulkDeleteDialog";
import AttributeListPage from "../../components/AttributeListPage"; import AttributeListPage from "../../components/AttributeListPage";
import { AttributeBulkDeleteMutation } from "../../mutations"; import { AttributeBulkDeleteMutation } from "../../mutations";
@ -145,77 +145,67 @@ const AttributeList: React.FC<AttributeListProps> = ({ params }) => {
return ( return (
<AttributeBulkDeleteMutation onCompleted={handleBulkDelete}> <AttributeBulkDeleteMutation onCompleted={handleBulkDelete}>
{(attributeBulkDelete, attributeBulkDeleteOpts) => { {(attributeBulkDelete, attributeBulkDeleteOpts) => (
const bulkDeleteMutationState = getMutationState( <>
attributeBulkDeleteOpts.called, <AttributeListPage
attributeBulkDeleteOpts.loading, attributes={maybe(() =>
maybe( data.attributes.edges.map(edge => edge.node)
() => attributeBulkDeleteOpts.data.attributeBulkDelete.errors )}
) currentTab={currentTab}
); disabled={loading || attributeBulkDeleteOpts.loading}
initialSearch={params.query || ""}
return ( isChecked={isSelected}
<> onAdd={() => navigate(attributeAddUrl())}
<AttributeListPage onAll={() => navigate(attributeListUrl())}
attributes={maybe(() => onBack={() => navigate(configurationMenuUrl)}
data.attributes.edges.map(edge => edge.node) onNextPage={loadNextPage}
)} onPreviousPage={loadPreviousPage}
currentTab={currentTab} onRowClick={id => () => navigate(attributeUrl(id))}
disabled={loading || attributeBulkDeleteOpts.loading} onSearchChange={query => changeFilterField({ query })}
initialSearch={params.query || ""} onTabChange={handleTabChange}
isChecked={isSelected} onTabDelete={() => openModal("delete-search")}
onAdd={() => navigate(attributeAddUrl())} onTabSave={() => openModal("save-search")}
onAll={() => navigate(attributeListUrl())} pageInfo={pageInfo}
onBack={() => navigate(configurationMenuUrl)} selected={listElements.length}
onNextPage={loadNextPage} tabs={tabs.map(tab => tab.name)}
onPreviousPage={loadPreviousPage} toggle={toggle}
onRowClick={id => () => navigate(attributeUrl(id))} toggleAll={toggleAll}
onSearchChange={query => changeFilterField({ query })} toolbar={
onTabChange={handleTabChange} <IconButton
onTabDelete={() => openModal("delete-search")} color="primary"
onTabSave={() => openModal("save-search")} onClick={() => openModal("remove", listElements)}
pageInfo={pageInfo} >
selected={listElements.length} <DeleteIcon />
tabs={tabs.map(tab => tab.name)} </IconButton>
toggle={toggle} }
toggleAll={toggleAll} />
toolbar={ <AttributeBulkDeleteDialog
<IconButton confirmButtonState={attributeBulkDeleteOpts.state}
color="primary" open={
onClick={() => openModal("remove", listElements)} params.action === "remove" &&
> maybe(() => params.ids.length > 0)
<DeleteIcon /> }
</IconButton> onConfirm={() =>
} attributeBulkDelete({ variables: { ids: params.ids } })
/> }
<AttributeBulkDeleteDialog onClose={closeModal}
confirmButtonState={bulkDeleteMutationState} quantity={maybe(() => params.ids.length)}
open={ />
params.action === "remove" && <SaveFilterTabDialog
maybe(() => params.ids.length > 0) open={params.action === "save-search"}
} confirmButtonState="default"
onConfirm={() => onClose={closeModal}
attributeBulkDelete({ variables: { ids: params.ids } }) onSubmit={handleTabSave}
} />
onClose={closeModal} <DeleteFilterTabDialog
quantity={maybe(() => params.ids.length)} open={params.action === "delete-search"}
/> confirmButtonState="default"
<SaveFilterTabDialog onClose={closeModal}
open={params.action === "save-search"} onSubmit={handleTabDelete}
confirmButtonState="default" tabName={maybe(() => tabs[currentTab - 1].name, "...")}
onClose={closeModal} />
onSubmit={handleTabSave} </>
/> )}
<DeleteFilterTabDialog
open={params.action === "delete-search"}
confirmButtonState="default"
onClose={closeModal}
onSubmit={handleTabDelete}
tabName={maybe(() => tabs[currentTab - 1].name, "...")}
/>
</>
);
}}
</AttributeBulkDeleteMutation> </AttributeBulkDeleteMutation>
); );
}} }}

View file

@ -4,7 +4,7 @@ import { useIntl } from "react-intl";
import { WindowTitle } from "@saleor/components/WindowTitle"; import { WindowTitle } from "@saleor/components/WindowTitle";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import CategoryCreatePage from "../components/CategoryCreatePage"; import CategoryCreatePage from "../components/CategoryCreatePage";
import { useCategoryCreateMutation } from "../mutations"; import { useCategoryCreateMutation } from "../mutations";
import { CategoryCreate } from "../types/CategoryCreate"; import { CategoryCreate } from "../types/CategoryCreate";
@ -41,12 +41,6 @@ export const CategoryCreateView: React.FC<CategoryCreateViewProps> = ({
[] []
); );
const formTransitionState = getMutationState(
createCategoryResult.called,
createCategoryResult.loading,
errors
);
return ( return (
<> <>
<WindowTitle <WindowTitle
@ -56,7 +50,7 @@ export const CategoryCreateView: React.FC<CategoryCreateViewProps> = ({
})} })}
/> />
<CategoryCreatePage <CategoryCreatePage
saveButtonBarState={formTransitionState} saveButtonBarState={createCategoryResult.state}
errors={errors} errors={errors}
disabled={createCategoryResult.loading} disabled={createCategoryResult.loading}
onBack={() => onBack={() =>

View file

@ -14,7 +14,7 @@ import usePaginator, {
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { PAGINATE_BY } from "../../config"; import { PAGINATE_BY } from "../../config";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import { TypedProductBulkDeleteMutation } from "../../products/mutations"; import { TypedProductBulkDeleteMutation } from "../../products/mutations";
import { productBulkDelete } from "../../products/types/productBulkDelete"; import { productBulkDelete } from "../../products/types/productBulkDelete";
import { productAddUrl, productUrl } from "../../products/urls"; import { productAddUrl, productUrl } from "../../products/urls";
@ -147,17 +147,6 @@ export const CategoryDetails: React.FC<CategoryDetailsProps> = ({
}) })
); );
const formTransitionState = getMutationState(
updateResult.called,
updateResult.loading,
maybe(() => updateResult.data.categoryUpdate.errors)
);
const removeDialogTransitionState = getMutationState(
deleteResult.called,
deleteResult.loading,
maybe(() => deleteResult.data.categoryDelete.errors)
);
const handleBulkProductDelete = (data: productBulkDelete) => { const handleBulkProductDelete = (data: productBulkDelete) => {
if (data.productBulkDelete.errors.length === 0) { if (data.productBulkDelete.errors.length === 0) {
closeModal(); closeModal();
@ -181,196 +170,181 @@ export const CategoryDetails: React.FC<CategoryDetailsProps> = ({
<> <>
<WindowTitle title={maybe(() => data.category.name)} /> <WindowTitle title={maybe(() => data.category.name)} />
<TypedProductBulkDeleteMutation onCompleted={handleBulkProductDelete}> <TypedProductBulkDeleteMutation onCompleted={handleBulkProductDelete}>
{(productBulkDelete, productBulkDeleteOpts) => { {(productBulkDelete, productBulkDeleteOpts) => (
const categoryBulkDeleteMutationState = getMutationState( <>
categoryBulkDeleteOpts.called, <CategoryUpdatePage
categoryBulkDeleteOpts.loading, changeTab={changeTab}
maybe(() => categoryBulkDeleteOpts.data.categoryBulkDelete.errors) currentTab={params.activeTab}
); category={maybe(() => data.category)}
const productBulkDeleteMutationState = getMutationState( disabled={loading}
productBulkDeleteOpts.called, errors={maybe(() => updateResult.data.categoryUpdate.errors)}
productBulkDeleteOpts.loading, onAddCategory={() => navigate(categoryAddUrl(id))}
maybe(() => productBulkDeleteOpts.data.productBulkDelete.errors) onAddProduct={() => navigate(productAddUrl)}
); onBack={() =>
navigate(
return ( maybe(
<> () => categoryUrl(data.category.parent.id),
<CategoryUpdatePage categoryListUrl()
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")} onCategoryClick={id => () => navigate(categoryUrl(id))}
onImageDelete={() => onDelete={() => openModal("delete")}
updateCategory({ onImageDelete={() =>
variables: { updateCategory({
id, variables: {
input: { id,
backgroundImage: null input: {
backgroundImage: null
}
}
})
}
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
} }
} }
}) }
} })
onImageUpload={file => }
updateCategory({ products={maybe(() =>
variables: { data.category.products.edges.map(edge => edge.node)
id, )}
input: { saveButtonBarState={updateResult.state}
backgroundImage: file subcategories={maybe(() =>
} data.category.children.edges.map(edge => edge.node)
} )}
}) subcategoryListToolbar={
} <IconButton
onNextPage={loadNextPage} color="primary"
onPreviousPage={loadPreviousPage} onClick={() => openModal("delete-categories", listElements)}
pageInfo={pageInfo} >
onProductClick={id => () => navigate(productUrl(id))} <DeleteIcon />
onSubmit={formData => </IconButton>
updateCategory({ }
variables: { productListToolbar={
id, <IconButton
input: { color="primary"
backgroundImageAlt: formData.backgroundImageAlt, onClick={() => openModal("delete-products", listElements)}
descriptionJson: JSON.stringify(formData.description), >
name: formData.name, <DeleteIcon />
seo: { </IconButton>
description: formData.seoDescription, }
title: formData.seoTitle isChecked={isSelected}
} selected={listElements.length}
} toggle={toggle}
} toggleAll={toggleAll}
}) />
} <ActionDialog
products={maybe(() => confirmButtonState={deleteResult.state}
data.category.products.edges.map(edge => edge.node) onClose={closeModal}
)} onConfirm={() => deleteCategory({ variables: { id } })}
saveButtonBarState={formTransitionState} open={params.action === "delete"}
subcategories={maybe(() => title={intl.formatMessage({
data.category.children.edges.map(edge => edge.node) defaultMessage: "Delete category",
)} description: "dialog title"
subcategoryListToolbar={ })}
<IconButton variant="delete"
color="primary" >
onClick={() => openModal("delete-categories", listElements)} <DialogContentText>
> <FormattedMessage
<DeleteIcon /> defaultMessage="Are you sure you want to delete {categoryName}?"
</IconButton> values={{
} categoryName: (
productListToolbar={ <strong>{maybe(() => data.category.name, "...")}</strong>
<IconButton )
color="primary" }}
onClick={() => openModal("delete-products", listElements)} />
> </DialogContentText>
<DeleteIcon /> <DialogContentText>
</IconButton> <FormattedMessage defaultMessage="Remember this will also delete all products assigned to this category." />
} </DialogContentText>
isChecked={isSelected} </ActionDialog>
selected={listElements.length} <ActionDialog
toggle={toggle} open={
toggleAll={toggleAll} params.action === "delete-categories" &&
/> maybe(() => params.ids.length > 0)
<ActionDialog }
confirmButtonState={removeDialogTransitionState} confirmButtonState={categoryBulkDeleteOpts.state}
onClose={closeModal} onClose={closeModal}
onConfirm={() => deleteCategory({ variables: { id } })} onConfirm={() =>
open={params.action === "delete"} categoryBulkDelete({
title={intl.formatMessage({ variables: { ids: params.ids }
defaultMessage: "Delete category", }).then(() => refetch())
description: "dialog title" }
})} title={intl.formatMessage({
variant="delete" defaultMessage: "Delete categories",
> description: "dialog title"
<DialogContentText> })}
<FormattedMessage variant="delete"
defaultMessage="Are you sure you want to delete {categoryName}?" >
values={{ <DialogContentText>
categoryName: ( <FormattedMessage
<strong> defaultMessage="Are you sure you want to delete {counter,plural,one{this category} other{{displayQuantity} categories}}?"
{maybe(() => data.category.name, "...")} values={{
</strong> 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>
</DialogContentText> <DialogContentText>
</ActionDialog> <FormattedMessage defaultMessage="Remember this will also delete all products assigned to this category." />
<ActionDialog </DialogContentText>
open={ </ActionDialog>
params.action === "delete-categories" && <ActionDialog
maybe(() => params.ids.length > 0) open={params.action === "delete-products"}
} confirmButtonState={productBulkDeleteOpts.state}
confirmButtonState={categoryBulkDeleteMutationState} onClose={closeModal}
onClose={closeModal} onConfirm={() =>
onConfirm={() => productBulkDelete({
categoryBulkDelete({ variables: { ids: params.ids }
variables: { ids: params.ids } }).then(() => refetch())
}).then(() => refetch()) }
} title={intl.formatMessage({
title={intl.formatMessage({ defaultMessage: "Delete products",
defaultMessage: "Delete categories", description: "dialog title"
description: "dialog title" })}
})} variant="delete"
variant="delete" >
> <DialogContentText>
<DialogContentText> <FormattedMessage
<FormattedMessage defaultMessage="Are you sure you want to delete {counter,plural,one{this product} other{{displayQuantity} products}}?"
defaultMessage="Are you sure you want to delete {counter,plural,one{this category} other{{displayQuantity} categories}}?" values={{
values={{ counter: maybe(() => params.ids.length),
counter: maybe(() => params.ids.length), displayQuantity: (
displayQuantity: ( <strong>{maybe(() => params.ids.length)}</strong>
<strong>{maybe(() => params.ids.length)}</strong> )
) }}
}} />
/> </DialogContentText>
</DialogContentText> </ActionDialog>
<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> </TypedProductBulkDeleteMutation>
</> </>
); );

View file

@ -15,7 +15,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import usePaginator, { import usePaginator, {
createPaginationState createPaginationState
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import { CategoryListPage } from "../../components/CategoryListPage/CategoryListPage"; import { CategoryListPage } from "../../components/CategoryListPage/CategoryListPage";
import { useCategoryBulkDeleteMutation } from "../../mutations"; import { useCategoryBulkDeleteMutation } from "../../mutations";
@ -148,12 +148,6 @@ export const CategoryList: React.FC<CategoryListProps> = ({ params }) => {
onCompleted: handleCategoryBulkDelete onCompleted: handleCategoryBulkDelete
}); });
const bulkDeleteState = getMutationState(
categoryBulkDeleteOpts.called,
categoryBulkDeleteOpts.loading,
maybe(() => categoryBulkDeleteOpts.data.categoryBulkDelete.errors)
);
return ( return (
<> <>
<CategoryListPage <CategoryListPage
@ -199,7 +193,7 @@ export const CategoryList: React.FC<CategoryListProps> = ({ params }) => {
} }
/> />
<ActionDialog <ActionDialog
confirmButtonState={bulkDeleteState} confirmButtonState={categoryBulkDeleteOpts.state}
onClose={() => onClose={() =>
navigate( navigate(
categoryListUrl({ categoryListUrl({

View file

@ -4,7 +4,7 @@ import { useIntl } from "react-intl";
import { WindowTitle } from "@saleor/components/WindowTitle"; import { WindowTitle } from "@saleor/components/WindowTitle";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import { CollectionCreateInput } from "../../types/globalTypes"; import { CollectionCreateInput } from "../../types/globalTypes";
import CollectionCreatePage from "../components/CollectionCreatePage/CollectionCreatePage"; import CollectionCreatePage from "../components/CollectionCreatePage/CollectionCreatePage";
import { TypedCollectionCreateMutation } from "../mutations"; import { TypedCollectionCreateMutation } from "../mutations";
@ -38,46 +38,42 @@ export const CollectionCreate: React.FC = () => {
}; };
return ( return (
<TypedCollectionCreateMutation onCompleted={handleCollectionCreateSuccess}> <TypedCollectionCreateMutation onCompleted={handleCollectionCreateSuccess}>
{(createCollection, { called, data, loading }) => { {(createCollection, createCollectionOpts) => (
const formTransitionState = getMutationState( <>
called, <WindowTitle
loading, title={intl.formatMessage({
maybe(() => data.collectionCreate.errors) defaultMessage: "Create collection",
); description: "window title"
return ( })}
<> />
<WindowTitle <CollectionCreatePage
title={intl.formatMessage({ errors={maybe(
defaultMessage: "Create collection", () => createCollectionOpts.data.collectionCreate.errors,
description: "window title" []
})} )}
/> onBack={() => navigate(collectionListUrl())}
<CollectionCreatePage disabled={createCollectionOpts.loading}
errors={maybe(() => data.collectionCreate.errors, [])} onSubmit={formData =>
onBack={() => navigate(collectionListUrl())} createCollection({
disabled={loading} variables: {
onSubmit={formData => input: {
createCollection({ backgroundImage: formData.backgroundImage.value,
variables: { backgroundImageAlt: formData.backgroundImageAlt,
input: { descriptionJson: JSON.stringify(formData.description),
backgroundImage: formData.backgroundImage.value, isPublished: formData.isPublished,
backgroundImageAlt: formData.backgroundImageAlt, name: formData.name,
descriptionJson: JSON.stringify(formData.description), seo: {
isPublished: formData.isPublished, description: formData.seoDescription,
name: formData.name, title: formData.seoTitle
seo: {
description: formData.seoDescription,
title: formData.seoTitle
}
} }
} }
}) }
} })
saveButtonBarState={formTransitionState} }
/> saveButtonBarState={createCollectionOpts.state}
</> />
); </>
}} )}
</TypedCollectionCreateMutation> </TypedCollectionCreateMutation>
); );
}; };

View file

@ -195,31 +195,6 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
.homepageCollectionUpdate.errors .homepageCollectionUpdate.errors
) )
); );
const assignTransitionState = getMutationState(
assignProduct.opts.called,
assignProduct.opts.loading,
maybe(
() => assignProduct.opts.data.collectionAddProducts.errors
)
);
const unassignTransitionState = getMutationState(
unassignProduct.opts.called,
unassignProduct.opts.loading,
maybe(
() =>
unassignProduct.opts.data.collectionRemoveProducts.errors
)
);
const removeTransitionState = getMutationState(
removeCollection.opts.called,
removeCollection.opts.loading,
maybe(() => removeCollection.opts.data.collectionDelete.errors)
);
const imageRemoveTransitionState = getMutationState(
updateCollection.opts.called,
updateCollection.opts.loading,
maybe(() => updateCollection.opts.data.collectionUpdate.errors)
);
const { loadNextPage, loadPreviousPage, pageInfo } = paginate( const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
maybe(() => data.collection.products.pageInfo), maybe(() => data.collection.products.pageInfo),
@ -288,7 +263,7 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
toggleAll={toggleAll} toggleAll={toggleAll}
/> />
<AssignProductDialog <AssignProductDialog
confirmButtonState={assignTransitionState} confirmButtonState={assignProduct.opts.state}
open={params.action === "assign"} open={params.action === "assign"}
onFetch={search} onFetch={search}
loading={result.loading} loading={result.loading}
@ -307,7 +282,7 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
)} )}
/> />
<ActionDialog <ActionDialog
confirmButtonState={removeTransitionState} confirmButtonState={removeCollection.opts.state}
onClose={closeModal} onClose={closeModal}
onConfirm={() => removeCollection.mutate({ id })} onConfirm={() => removeCollection.mutate({ id })}
open={params.action === "remove"} open={params.action === "remove"}
@ -331,7 +306,7 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
</DialogContentText> </DialogContentText>
</ActionDialog> </ActionDialog>
<ActionDialog <ActionDialog
confirmButtonState={unassignTransitionState} confirmButtonState={unassignProduct.opts.state}
onClose={closeModal} onClose={closeModal}
onConfirm={() => onConfirm={() =>
unassignProduct.mutate({ unassignProduct.mutate({
@ -359,7 +334,7 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
</DialogContentText> </DialogContentText>
</ActionDialog> </ActionDialog>
<ActionDialog <ActionDialog
confirmButtonState={imageRemoveTransitionState} confirmButtonState={updateCollection.opts.state}
onClose={closeModal} onClose={closeModal}
onConfirm={() => onConfirm={() =>
updateCollection.mutate({ updateCollection.mutate({

View file

@ -18,7 +18,7 @@ import usePaginator, {
createPaginationState createPaginationState
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import CollectionListPage from "../../components/CollectionListPage/CollectionListPage"; import CollectionListPage from "../../components/CollectionListPage/CollectionListPage";
import { import {
@ -167,204 +167,174 @@ export const CollectionList: React.FC<CollectionListProps> = ({ params }) => {
<TypedCollectionBulkPublish <TypedCollectionBulkPublish
onCompleted={handleCollectionBulkPublish} onCompleted={handleCollectionBulkPublish}
> >
{(collectionBulkPublish, collectionBulkPublishOpts) => { {(collectionBulkPublish, collectionBulkPublishOpts) => (
const bulkDeleteTransitionState = getMutationState( <>
collectionBulkDeleteOpts.called, <CollectionListPage
collectionBulkDeleteOpts.loading, currentTab={currentTab}
maybe( initialSearch={params.query || ""}
() => onSearchChange={query => changeFilterField({ query })}
collectionBulkDeleteOpts.data.collectionBulkDelete onAdd={() => navigate(collectionAddUrl)}
.errors onAll={() => navigate(collectionListUrl())}
) onTabChange={handleTabChange}
); onTabDelete={() => openModal("delete-search")}
onTabSave={() => openModal("save-search")}
const bulkPublishTransitionState = getMutationState( tabs={tabs.map(tab => tab.name)}
collectionBulkPublishOpts.called, disabled={loading}
collectionBulkPublishOpts.loading, collections={maybe(() =>
maybe( data.collections.edges.map(edge => edge.node)
() => )}
collectionBulkPublishOpts.data.collectionBulkPublish settings={settings}
.errors onNextPage={loadNextPage}
) onPreviousPage={loadPreviousPage}
); onUpdateListSettings={updateListSettings}
pageInfo={pageInfo}
return ( onRowClick={id => () => navigate(collectionUrl(id))}
<> toolbar={
<CollectionListPage <>
currentTab={currentTab} <Button
initialSearch={params.query || ""} color="primary"
onSearchChange={query => changeFilterField({ query })} onClick={() => openModal("unpublish", listElements)}
onAdd={() => navigate(collectionAddUrl)} >
onAll={() => navigate(collectionListUrl())} <FormattedMessage
onTabChange={handleTabChange} defaultMessage="Unpublish"
onTabDelete={() => openModal("delete-search")} description="unpublish collections"
onTabSave={() => openModal("save-search")} />
tabs={tabs.map(tab => tab.name)} </Button>
disabled={loading} <Button
collections={maybe(() => color="primary"
data.collections.edges.map(edge => edge.node) onClick={() => openModal("publish", listElements)}
)} >
settings={settings} <FormattedMessage
onNextPage={loadNextPage} defaultMessage="Publish"
onPreviousPage={loadPreviousPage} description="publish collections"
onUpdateListSettings={updateListSettings} />
pageInfo={pageInfo} </Button>
onRowClick={id => () => navigate(collectionUrl(id))} <IconButton
toolbar={ color="primary"
<> onClick={() => openModal("remove", listElements)}
<Button >
color="primary" <DeleteIcon />
onClick={() => </IconButton>
openModal("unpublish", listElements) </>
} }
> isChecked={isSelected}
<FormattedMessage selected={listElements.length}
defaultMessage="Unpublish" toggle={toggle}
description="unpublish collections" toggleAll={toggleAll}
/> />
</Button> <ActionDialog
<Button open={
color="primary" params.action === "publish" &&
onClick={() => openModal("publish", listElements)} maybe(() => params.ids.length > 0)
> }
<FormattedMessage onClose={closeModal}
defaultMessage="Publish" confirmButtonState={collectionBulkPublishOpts.state}
description="publish collections" onConfirm={() =>
/> collectionBulkPublish({
</Button> variables: {
<IconButton ids: params.ids,
color="primary" isPublished: true
onClick={() => openModal("remove", listElements)} }
> })
<DeleteIcon /> }
</IconButton> variant="default"
</> title={intl.formatMessage({
} defaultMessage: "Publish collections",
isChecked={isSelected} description: "dialog title"
selected={listElements.length} })}
toggle={toggle} >
toggleAll={toggleAll} <DialogContentText>
/> <FormattedMessage
<ActionDialog defaultMessage="Are you sure you want to publish {counter,plural,one{this collection} other{{displayQuantity} collections}}?"
open={ values={{
params.action === "publish" && counter: maybe(() => params.ids.length),
maybe(() => params.ids.length > 0) displayQuantity: (
} <strong>{maybe(() => params.ids.length)}</strong>
onClose={closeModal} )
confirmButtonState={bulkPublishTransitionState} }}
onConfirm={() => />
collectionBulkPublish({ </DialogContentText>
variables: { </ActionDialog>
ids: params.ids, <ActionDialog
isPublished: true open={
} params.action === "unpublish" &&
}) maybe(() => params.ids.length > 0)
} }
variant="default" onClose={closeModal}
title={intl.formatMessage({ confirmButtonState={collectionBulkPublishOpts.state}
defaultMessage: "Publish collections", onConfirm={() =>
description: "dialog title" collectionBulkPublish({
})} variables: {
> ids: params.ids,
<DialogContentText> isPublished: false
<FormattedMessage }
defaultMessage="Are you sure you want to publish {counter,plural,one{this collection} other{{displayQuantity} collections}}?" })
values={{ }
counter: maybe(() => params.ids.length), variant="default"
displayQuantity: ( title={intl.formatMessage({
<strong> defaultMessage: "Unpublish collections",
{maybe(() => params.ids.length)} description: "dialog title"
</strong> })}
) >
}} <DialogContentText>
/> <FormattedMessage
</DialogContentText> defaultMessage="Are you sure you want to unpublish {counter,plural,one{this collection} other{{displayQuantity} collections}}?"
</ActionDialog> values={{
<ActionDialog counter: maybe(() => params.ids.length),
open={ displayQuantity: (
params.action === "unpublish" && <strong>{maybe(() => params.ids.length)}</strong>
maybe(() => params.ids.length > 0) )
} }}
onClose={closeModal} />
confirmButtonState={bulkPublishTransitionState} </DialogContentText>
onConfirm={() => </ActionDialog>
collectionBulkPublish({ <ActionDialog
variables: { open={
ids: params.ids, params.action === "remove" &&
isPublished: false maybe(() => params.ids.length > 0)
} }
}) onClose={closeModal}
} confirmButtonState={collectionBulkDeleteOpts.state}
variant="default" onConfirm={() =>
title={intl.formatMessage({ collectionBulkDelete({
defaultMessage: "Unpublish collections", variables: {
description: "dialog title" ids: params.ids
})} }
> })
<DialogContentText> }
<FormattedMessage variant="delete"
defaultMessage="Are you sure you want to unpublish {counter,plural,one{this collection} other{{displayQuantity} collections}}?" title={intl.formatMessage({
values={{ defaultMessage: "Delete collections",
counter: maybe(() => params.ids.length), description: "dialog title"
displayQuantity: ( })}
<strong> >
{maybe(() => params.ids.length)} <DialogContentText>
</strong> <FormattedMessage
) defaultMessage="Are you sure you want to delete {counter,plural,one{this collection} other{{displayQuantity} collections}}?"
}} values={{
/> counter: maybe(() => params.ids.length),
</DialogContentText> displayQuantity: (
</ActionDialog> <strong>{maybe(() => params.ids.length)}</strong>
<ActionDialog )
open={ }}
params.action === "remove" && />
maybe(() => params.ids.length > 0) </DialogContentText>
} </ActionDialog>
onClose={closeModal} <SaveFilterTabDialog
confirmButtonState={bulkDeleteTransitionState} open={params.action === "save-search"}
onConfirm={() => confirmButtonState="default"
collectionBulkDelete({ onClose={closeModal}
variables: { onSubmit={handleTabSave}
ids: params.ids />
} <DeleteFilterTabDialog
}) open={params.action === "delete-search"}
} confirmButtonState="default"
variant="delete" onClose={closeModal}
title={intl.formatMessage({ onSubmit={handleTabDelete}
defaultMessage: "Delete collections", tabName={maybe(() => tabs[currentTab - 1].name, "...")}
description: "dialog title" />
})} </>
> )}
<DialogContentText>
<FormattedMessage
defaultMessage="Are you sure you want to delete {counter,plural,one{this collection} other{{displayQuantity} collections}}?"
values={{
counter: maybe(() => params.ids.length),
displayQuantity: (
<strong>
{maybe(() => params.ids.length)}
</strong>
)
}}
/>
</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, "...")}
/>
</>
);
}}
</TypedCollectionBulkPublish> </TypedCollectionBulkPublish>
)} )}
</TypedCollectionBulkDelete> </TypedCollectionBulkDelete>

View file

@ -8,7 +8,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import CustomerAddressDialog from "../components/CustomerAddressDialog"; import CustomerAddressDialog from "../components/CustomerAddressDialog";
import CustomerAddressListPage from "../components/CustomerAddressListPage"; import CustomerAddressListPage from "../components/CustomerAddressListPage";
import { import {
@ -97,39 +97,6 @@ const CustomerAddresses: React.FC<CustomerAddressesProps> = ({
{(removeCustomerAddress, removeCustomerAddressOpts) => ( {(removeCustomerAddress, removeCustomerAddressOpts) => (
<TypedCustomerAddressesQuery variables={{ id }}> <TypedCustomerAddressesQuery variables={{ id }}>
{customerData => { {customerData => {
const createAddressTransitionState = getMutationState(
createCustomerAddressOpts.called,
createCustomerAddressOpts.loading,
maybe(
() =>
createCustomerAddressOpts.data.addressCreate
.errors,
[]
)
);
const updateAddressTransitionState = getMutationState(
updateCustomerAddressOpts.called,
updateCustomerAddressOpts.loading,
maybe(
() =>
updateCustomerAddressOpts.data.addressUpdate
.errors,
[]
)
);
const removeAddressTransitionState = getMutationState(
removeCustomerAddressOpts.called,
removeCustomerAddressOpts.loading,
maybe(
() =>
removeCustomerAddressOpts.data.addressDelete
.errors,
[]
)
);
const countryChoices = maybe( const countryChoices = maybe(
() => () =>
shop.countries.map(country => ({ shop.countries.map(country => ({
@ -161,7 +128,9 @@ const CustomerAddresses: React.FC<CustomerAddressesProps> = ({
/> />
<CustomerAddressDialog <CustomerAddressDialog
address={undefined} address={undefined}
confirmButtonState={createAddressTransitionState} confirmButtonState={
createCustomerAddressOpts.state
}
countries={countryChoices} countries={countryChoices}
errors={maybe( errors={maybe(
() => () =>
@ -187,7 +156,9 @@ const CustomerAddresses: React.FC<CustomerAddressesProps> = ({
addr => addr.id === params.id addr => addr.id === params.id
) )
)} )}
confirmButtonState={updateAddressTransitionState} confirmButtonState={
updateCustomerAddressOpts.state
}
countries={countryChoices} countries={countryChoices}
errors={maybe( errors={maybe(
() => () =>
@ -214,7 +185,9 @@ const CustomerAddresses: React.FC<CustomerAddressesProps> = ({
defaultMessage: "Delete Address", defaultMessage: "Delete Address",
description: "dialog header" description: "dialog header"
})} })}
confirmButtonState={removeAddressTransitionState} confirmButtonState={
removeCustomerAddressOpts.state
}
onClose={closeModal} onClose={closeModal}
onConfirm={() => onConfirm={() =>
removeCustomerAddress({ removeCustomerAddress({

View file

@ -7,7 +7,7 @@ import { WindowTitle } from "@saleor/components/WindowTitle";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import { orderListUrl, orderUrl } from "../../orders/urls"; import { orderListUrl, orderUrl } from "../../orders/urls";
import CustomerDetailsPage from "../components/CustomerDetailsPage/CustomerDetailsPage"; import CustomerDetailsPage from "../components/CustomerDetailsPage/CustomerDetailsPage";
import { import {
@ -67,99 +67,86 @@ export const CustomerDetailsView: React.FC<CustomerDetailsViewProps> = ({
variables={{ id }} variables={{ id }}
require={["user"]} require={["user"]}
> >
{customerDetails => { {customerDetails => (
const formTransitionState = getMutationState( <>
updateCustomerOpts.called, <WindowTitle
updateCustomerOpts.loading, title={maybe(() => customerDetails.data.user.email)}
maybe(() => updateCustomerOpts.data.customerUpdate.errors) />
); <CustomerDetailsPage
const removeTransitionState = getMutationState( customer={maybe(() => customerDetails.data.user)}
removeCustomerOpts.called, disabled={
removeCustomerOpts.loading, customerDetails.loading ||
maybe(() => removeCustomerOpts.data.customerDelete.errors) updateCustomerOpts.loading ||
); removeCustomerOpts.loading
}
return ( errors={maybe(
<> () => updateCustomerOpts.data.customerUpdate.errors
<WindowTitle )}
title={maybe(() => customerDetails.data.user.email)} saveButtonBar={updateCustomerOpts.state}
/> onAddressManageClick={() =>
<CustomerDetailsPage navigate(customerAddressesUrl(id))
customer={maybe(() => customerDetails.data.user)} }
disabled={ onBack={() => navigate(customerListUrl())}
customerDetails.loading || onRowClick={id => navigate(orderUrl(id))}
updateCustomerOpts.loading || onSubmit={formData =>
removeCustomerOpts.loading updateCustomer({
} variables: {
errors={maybe( id,
() => updateCustomerOpts.data.customerUpdate.errors input: {
)} email: formData.email,
saveButtonBar={formTransitionState} firstName: formData.firstName,
onAddressManageClick={() => isActive: formData.isActive,
navigate(customerAddressesUrl(id)) lastName: formData.lastName,
} note: formData.note
onBack={() => navigate(customerListUrl())}
onRowClick={id => navigate(orderUrl(id))}
onSubmit={formData =>
updateCustomer({
variables: {
id,
input: {
email: formData.email,
firstName: formData.firstName,
isActive: formData.isActive,
lastName: formData.lastName,
note: formData.note
}
} }
}
})
}
onDelete={() =>
navigate(
customerUrl(id, {
action: "remove"
}) })
} )
onDelete={() => }
navigate( onViewAllOrdersClick={() =>
customerUrl(id, { navigate(
action: "remove" orderListUrl({
}) email: maybe(() => customerDetails.data.user.email)
) })
} )
onViewAllOrdersClick={() => }
navigate( />
orderListUrl({ <ActionDialog
email: maybe(() => customerDetails.data.user.email) confirmButtonState={removeCustomerOpts.state}
}) onClose={() => navigate(customerUrl(id), true)}
) onConfirm={() => removeCustomer()}
} title={intl.formatMessage({
/> defaultMessage: "Delete Customer",
<ActionDialog description: "dialog header"
confirmButtonState={removeTransitionState} })}
onClose={() => navigate(customerUrl(id), true)} variant="delete"
onConfirm={() => removeCustomer()} open={params.action === "remove"}
title={intl.formatMessage({ >
defaultMessage: "Delete Customer", <DialogContentText>
description: "dialog header" <FormattedMessage
})} defaultMessage="Are you sure you want to delete {email}?"
variant="delete" description="delete customer, dialog content"
open={params.action === "remove"} values={{
> email: (
<DialogContentText> <strong>
<FormattedMessage {maybe(
defaultMessage="Are you sure you want to delete {email}?" () => customerDetails.data.user.email,
description="delete customer, dialog content" "..."
values={{ )}
email: ( </strong>
<strong> )
{maybe( }}
() => customerDetails.data.user.email, />
"..." </DialogContentText>
)} </ActionDialog>
</strong> </>
) )}
}}
/>
</DialogContentText>
</ActionDialog>
</>
);
}}
</TypedCustomerDetailsQuery> </TypedCustomerDetailsQuery>
)} )}
</TypedUpdateCustomerMutation> </TypedUpdateCustomerMutation>

View file

@ -17,7 +17,7 @@ import usePaginator, {
createPaginationState createPaginationState
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import CustomerListPage from "../../components/CustomerListPage"; import CustomerListPage from "../../components/CustomerListPage";
import { TypedBulkRemoveCustomers } from "../../mutations"; import { TypedBulkRemoveCustomers } from "../../mutations";
@ -147,105 +147,95 @@ export const CustomerList: React.FC<CustomerListProps> = ({ params }) => {
return ( return (
<TypedBulkRemoveCustomers onCompleted={handleBulkCustomerDelete}> <TypedBulkRemoveCustomers onCompleted={handleBulkCustomerDelete}>
{(bulkRemoveCustomers, bulkRemoveCustomersOpts) => { {(bulkRemoveCustomers, bulkRemoveCustomersOpts) => (
const removeTransitionState = getMutationState( <>
bulkRemoveCustomersOpts.called, <CustomerListPage
bulkRemoveCustomersOpts.loading, currentTab={currentTab}
maybe( initialSearch={params.query || ""}
() => bulkRemoveCustomersOpts.data.customerBulkDelete.errors onSearchChange={query => changeFilterField({ query })}
) onAll={() => navigate(customerListUrl())}
); onTabChange={handleTabChange}
onTabDelete={() => openModal("delete-search")}
return ( onTabSave={() => openModal("save-search")}
<> tabs={tabs.map(tab => tab.name)}
<CustomerListPage customers={maybe(() =>
currentTab={currentTab} data.customers.edges.map(edge => edge.node)
initialSearch={params.query || ""} )}
onSearchChange={query => changeFilterField({ query })} settings={settings}
onAll={() => navigate(customerListUrl())} disabled={loading}
onTabChange={handleTabChange} pageInfo={pageInfo}
onTabDelete={() => openModal("delete-search")} onAdd={() => navigate(customerAddUrl)}
onTabSave={() => openModal("save-search")} onNextPage={loadNextPage}
tabs={tabs.map(tab => tab.name)} onPreviousPage={loadPreviousPage}
customers={maybe(() => onUpdateListSettings={updateListSettings}
data.customers.edges.map(edge => edge.node) onRowClick={id => () => navigate(customerUrl(id))}
)} toolbar={
settings={settings} <IconButton
disabled={loading} color="primary"
pageInfo={pageInfo} onClick={() =>
onAdd={() => navigate(customerAddUrl)} navigate(
onNextPage={loadNextPage} customerListUrl({
onPreviousPage={loadPreviousPage} action: "remove",
onUpdateListSettings={updateListSettings} ids: listElements
onRowClick={id => () => navigate(customerUrl(id))} })
toolbar={ )
<IconButton }
color="primary" >
onClick={() => <DeleteIcon />
navigate( </IconButton>
customerListUrl({ }
action: "remove", isChecked={isSelected}
ids: listElements selected={listElements.length}
}) toggle={toggle}
) toggleAll={toggleAll}
} />
> <ActionDialog
<DeleteIcon /> open={
</IconButton> params.action === "remove" &&
} maybe(() => params.ids.length > 0)
isChecked={isSelected} }
selected={listElements.length} onClose={closeModal}
toggle={toggle} confirmButtonState={bulkRemoveCustomersOpts.state}
toggleAll={toggleAll} onConfirm={() =>
/> bulkRemoveCustomers({
<ActionDialog variables: {
open={ ids: params.ids
params.action === "remove" && }
maybe(() => params.ids.length > 0) })
} }
onClose={closeModal} variant="delete"
confirmButtonState={removeTransitionState} title={intl.formatMessage({
onConfirm={() => defaultMessage: "Delete Customers",
bulkRemoveCustomers({ description: "dialog header"
variables: { })}
ids: params.ids >
} <DialogContentText>
}) <FormattedMessage
} defaultMessage="Are you sure you want to delete {counter,plural,one{this customer} other{{displayQuantity} customers}}?"
variant="delete" values={{
title={intl.formatMessage({ counter: maybe(() => params.ids.length),
defaultMessage: "Delete Customers", displayQuantity: (
description: "dialog header" <strong>{maybe(() => params.ids.length)}</strong>
})} )
> }}
<DialogContentText> />
<FormattedMessage </DialogContentText>
defaultMessage="Are you sure you want to delete {counter,plural,one{this customer} other{{displayQuantity} customers}}?" </ActionDialog>
values={{ <SaveFilterTabDialog
counter: maybe(() => params.ids.length), open={params.action === "save-search"}
displayQuantity: ( confirmButtonState="default"
<strong>{maybe(() => params.ids.length)}</strong> onClose={closeModal}
) onSubmit={handleTabSave}
}} />
/> <DeleteFilterTabDialog
</DialogContentText> open={params.action === "delete-search"}
</ActionDialog> confirmButtonState="default"
<SaveFilterTabDialog onClose={closeModal}
open={params.action === "save-search"} onSubmit={handleTabDelete}
confirmButtonState="default" tabName={maybe(() => tabs[currentTab - 1].name, "...")}
onClose={closeModal} />
onSubmit={handleTabSave} </>
/> )}
<DeleteFilterTabDialog
open={params.action === "delete-search"}
confirmButtonState="default"
onClose={closeModal}
onSubmit={handleTabDelete}
tabName={maybe(() => tabs[currentTab - 1].name, "...")}
/>
</>
);
}}
</TypedBulkRemoveCustomers> </TypedBulkRemoveCustomers>
); );
}} }}

View file

@ -6,7 +6,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { decimal, getMutationState, joinDateTime, maybe } from "../../misc"; import { decimal, joinDateTime, maybe } from "../../misc";
import { DiscountValueTypeEnum, SaleType } from "../../types/globalTypes"; import { DiscountValueTypeEnum, SaleType } from "../../types/globalTypes";
import SaleCreatePage from "../components/SaleCreatePage"; import SaleCreatePage from "../components/SaleCreatePage";
import { TypedSaleCreate } from "../mutations"; import { TypedSaleCreate } from "../mutations";
@ -38,44 +38,36 @@ export const SaleDetails: React.FC = () => {
return ( return (
<TypedSaleCreate onCompleted={handleSaleCreate}> <TypedSaleCreate onCompleted={handleSaleCreate}>
{(saleCreate, saleCreateOpts) => { {(saleCreate, saleCreateOpts) => (
const formTransitionState = getMutationState( <>
saleCreateOpts.called, <WindowTitle title={intl.formatMessage(sectionNames.sales)} />
saleCreateOpts.loading, <SaleCreatePage
maybe(() => saleCreateOpts.data.saleCreate.errors) defaultCurrency={maybe(() => shop.defaultCurrency)}
); disabled={saleCreateOpts.loading}
errors={maybe(() => saleCreateOpts.data.saleCreate.errors)}
return ( onBack={() => navigate(saleListUrl())}
<> onSubmit={formData =>
<WindowTitle title={intl.formatMessage(sectionNames.sales)} /> saleCreate({
<SaleCreatePage variables: {
defaultCurrency={maybe(() => shop.defaultCurrency)} input: {
disabled={saleCreateOpts.loading} endDate: formData.hasEndDate
errors={maybe(() => saleCreateOpts.data.saleCreate.errors)} ? joinDateTime(formData.endDate, formData.endTime)
onBack={() => navigate(saleListUrl())} : null,
onSubmit={formData => name: formData.name,
saleCreate({ startDate: joinDateTime(
variables: { formData.startDate,
input: { formData.startTime
endDate: formData.hasEndDate ),
? joinDateTime(formData.endDate, formData.endTime) type: discountValueTypeEnum(formData.type),
: null, value: decimal(formData.value)
name: formData.name,
startDate: joinDateTime(
formData.startDate,
formData.startTime
),
type: discountValueTypeEnum(formData.type),
value: decimal(formData.value)
}
} }
}) }
} })
saveButtonBarState={formTransitionState} }
/> saveButtonBarState={saleCreateOpts.state}
</> />
); </>
}} )}
</TypedSaleCreate> </TypedSaleCreate>
); );
}; };

View file

@ -22,7 +22,7 @@ import useCollectionSearch from "@saleor/searches/useCollectionSearch";
import useProductSearch from "@saleor/searches/useProductSearch"; import useProductSearch from "@saleor/searches/useProductSearch";
import { categoryUrl } from "../../categories/urls"; import { categoryUrl } from "../../categories/urls";
import { collectionUrl } from "../../collections/urls"; import { collectionUrl } from "../../collections/urls";
import { decimal, getMutationState, joinDateTime, maybe } from "../../misc"; import { decimal, joinDateTime, maybe } from "../../misc";
import { productUrl } from "../../products/urls"; import { productUrl } from "../../products/urls";
import { DiscountValueTypeEnum, SaleType } from "../../types/globalTypes"; import { DiscountValueTypeEnum, SaleType } from "../../types/globalTypes";
import SaleDetailsPage, { import SaleDetailsPage, {
@ -169,34 +169,6 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
SaleDetailsPageTab.collections SaleDetailsPageTab.collections
? maybe(() => data.sale.collections.pageInfo) ? maybe(() => data.sale.collections.pageInfo)
: maybe(() => data.sale.products.pageInfo); : maybe(() => data.sale.products.pageInfo);
const formTransitionState = getMutationState(
saleUpdateOpts.called,
saleUpdateOpts.loading,
maybe(() => saleUpdateOpts.data.saleUpdate.errors)
);
const assignTransitionState = getMutationState(
saleCataloguesAddOpts.called,
saleCataloguesAddOpts.loading,
maybe(
() =>
saleCataloguesAddOpts.data.saleCataloguesAdd
.errors
)
);
const unassignTransitionState = getMutationState(
saleCataloguesRemoveOpts.called,
saleCataloguesRemoveOpts.loading,
maybe(
() =>
saleCataloguesRemoveOpts.data.saleCataloguesRemove
.errors
)
);
const removeTransitionState = getMutationState(
saleDeleteOpts.called,
saleDeleteOpts.loading,
maybe(() => saleDeleteOpts.data.saleDelete.errors)
);
const handleCategoriesUnassign = (ids: string[]) => const handleCategoriesUnassign = (ids: string[]) =>
saleCataloguesRemove({ saleCataloguesRemove({
@ -308,7 +280,7 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
}) })
} }
onRemove={() => openModal("remove")} onRemove={() => openModal("remove")}
saveButtonBarState={formTransitionState} saveButtonBarState={saleUpdateOpts.state}
categoryListToolbar={ categoryListToolbar={
<Button <Button
color="primary" color="primary"
@ -360,7 +332,7 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
toggleAll={toggleAll} toggleAll={toggleAll}
/> />
<AssignProductDialog <AssignProductDialog
confirmButtonState={assignTransitionState} confirmButtonState={saleCataloguesAddOpts.state}
open={params.action === "assign-product"} open={params.action === "assign-product"}
onFetch={searchProducts} onFetch={searchProducts}
loading={searchProductsOpts.loading} loading={searchProductsOpts.loading}
@ -394,7 +366,7 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
suggestedCategory => suggestedCategory.id suggestedCategory => suggestedCategory.id
) )
)} )}
confirmButtonState={assignTransitionState} confirmButtonState={saleCataloguesAddOpts.state}
open={params.action === "assign-category"} open={params.action === "assign-category"}
onFetch={searchCategories} onFetch={searchCategories}
loading={searchCategoriesOpts.loading} loading={searchCategoriesOpts.loading}
@ -421,7 +393,7 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
suggestedCategory => suggestedCategory.id suggestedCategory => suggestedCategory.id
) )
)} )}
confirmButtonState={assignTransitionState} confirmButtonState={saleCataloguesAddOpts.state}
open={params.action === "assign-collection"} open={params.action === "assign-collection"}
onFetch={searchCollections} onFetch={searchCollections}
loading={searchCollectionsOpts.loading} loading={searchCollectionsOpts.loading}
@ -449,7 +421,9 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
defaultMessage: "Unassign Categories From Sale", defaultMessage: "Unassign Categories From Sale",
description: "dialog header" description: "dialog header"
})} })}
confirmButtonState={unassignTransitionState} confirmButtonState={
saleCataloguesRemoveOpts.state
}
onClose={closeModal} onClose={closeModal}
onConfirm={() => onConfirm={() =>
handleCategoriesUnassign(params.ids) handleCategoriesUnassign(params.ids)
@ -480,7 +454,9 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
"Unassign Collections From Sale", "Unassign Collections From Sale",
description: "dialog header" description: "dialog header"
})} })}
confirmButtonState={unassignTransitionState} confirmButtonState={
saleCataloguesRemoveOpts.state
}
onClose={closeModal} onClose={closeModal}
onConfirm={() => onConfirm={() =>
handleCollectionsUnassign(params.ids) handleCollectionsUnassign(params.ids)
@ -510,7 +486,9 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
defaultMessage: "Unassign Products From Sale", defaultMessage: "Unassign Products From Sale",
description: "dialog header" description: "dialog header"
})} })}
confirmButtonState={unassignTransitionState} confirmButtonState={
saleCataloguesRemoveOpts.state
}
onClose={closeModal} onClose={closeModal}
onConfirm={() => onConfirm={() =>
handleProductsUnassign(params.ids) handleProductsUnassign(params.ids)
@ -537,7 +515,7 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
defaultMessage: "Delete Sale", defaultMessage: "Delete Sale",
description: "dialog header" description: "dialog header"
})} })}
confirmButtonState={removeTransitionState} confirmButtonState={saleDeleteOpts.state}
onClose={closeModal} onClose={closeModal}
variant="delete" variant="delete"
onConfirm={() => onConfirm={() =>

View file

@ -19,7 +19,7 @@ import usePaginator, {
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages, sectionNames } from "@saleor/intl"; import { commonMessages, sectionNames } from "@saleor/intl";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import SaleListPage from "../../components/SaleListPage"; import SaleListPage from "../../components/SaleListPage";
import { TypedSaleBulkDelete } from "../../mutations"; import { TypedSaleBulkDelete } from "../../mutations";
@ -153,11 +153,6 @@ export const SaleList: React.FC<SaleListProps> = ({ params }) => {
return ( return (
<TypedSaleBulkDelete onCompleted={handleSaleBulkDelete}> <TypedSaleBulkDelete onCompleted={handleSaleBulkDelete}>
{(saleBulkDelete, saleBulkDeleteOpts) => { {(saleBulkDelete, saleBulkDeleteOpts) => {
const bulkRemoveTransitionState = getMutationState(
saleBulkDeleteOpts.called,
saleBulkDeleteOpts.loading,
maybe(() => saleBulkDeleteOpts.data.saleBulkDelete.errors)
);
const onSaleBulkDelete = () => const onSaleBulkDelete = () =>
saleBulkDelete({ saleBulkDelete({
variables: { variables: {
@ -208,7 +203,7 @@ export const SaleList: React.FC<SaleListProps> = ({ params }) => {
} }
/> />
<ActionDialog <ActionDialog
confirmButtonState={bulkRemoveTransitionState} confirmButtonState={saleBulkDeleteOpts.state}
onClose={closeModal} onClose={closeModal}
onConfirm={onSaleBulkDelete} onConfirm={onSaleBulkDelete}
open={params.action === "remove" && canOpenBulkActionDialog} open={params.action === "remove" && canOpenBulkActionDialog}

View file

@ -6,7 +6,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { decimal, getMutationState, joinDateTime, maybe } from "../../misc"; import { decimal, joinDateTime, maybe } from "../../misc";
import { import {
DiscountValueTypeEnum, DiscountValueTypeEnum,
VoucherTypeEnum VoucherTypeEnum
@ -36,67 +36,59 @@ export const VoucherDetails: React.FC = () => {
return ( return (
<TypedVoucherCreate onCompleted={handleVoucherCreate}> <TypedVoucherCreate onCompleted={handleVoucherCreate}>
{(voucherCreate, voucherCreateOpts) => { {(voucherCreate, voucherCreateOpts) => (
const formTransitionState = getMutationState( <>
voucherCreateOpts.called, <WindowTitle title={intl.formatMessage(sectionNames.vouchers)} />
voucherCreateOpts.loading, <VoucherCreatePage
maybe(() => voucherCreateOpts.data.voucherCreate.errors) defaultCurrency={maybe(() => shop.defaultCurrency)}
); disabled={voucherCreateOpts.loading}
errors={maybe(() => voucherCreateOpts.data.voucherCreate.errors)}
return ( onBack={() => navigate(voucherListUrl())}
<> onSubmit={formData =>
<WindowTitle title={intl.formatMessage(sectionNames.vouchers)} /> voucherCreate({
<VoucherCreatePage variables: {
defaultCurrency={maybe(() => shop.defaultCurrency)} input: {
disabled={voucherCreateOpts.loading} applyOncePerCustomer: formData.applyOncePerCustomer,
errors={maybe(() => voucherCreateOpts.data.voucherCreate.errors)} applyOncePerOrder: formData.applyOncePerOrder,
onBack={() => navigate(voucherListUrl())} code: formData.code,
onSubmit={formData => discountValue:
voucherCreate({ formData.discountType.toString() === "SHIPPING"
variables: { ? 100
input: { : decimal(formData.value),
applyOncePerCustomer: formData.applyOncePerCustomer, discountValueType:
applyOncePerOrder: formData.applyOncePerOrder, formData.discountType.toString() === "SHIPPING"
code: formData.code, ? DiscountValueTypeEnum.PERCENTAGE
discountValue: : formData.discountType,
formData.discountType.toString() === "SHIPPING" endDate: formData.hasEndDate
? 100 ? joinDateTime(formData.endDate, formData.endTime)
: decimal(formData.value), : null,
discountValueType: minAmountSpent:
formData.discountType.toString() === "SHIPPING" formData.requirementsPicker !== RequirementsPicker.ORDER
? DiscountValueTypeEnum.PERCENTAGE ? 0
: formData.discountType, : parseFloat(formData.minAmountSpent),
endDate: formData.hasEndDate minCheckoutItemsQuantity:
? joinDateTime(formData.endDate, formData.endTime) formData.requirementsPicker !== RequirementsPicker.ITEM
: null, ? 0
minAmountSpent: : parseFloat(formData.minCheckoutItemsQuantity),
formData.requirementsPicker !== RequirementsPicker.ORDER startDate: joinDateTime(
? 0 formData.startDate,
: parseFloat(formData.minAmountSpent), formData.startTime
minCheckoutItemsQuantity: ),
formData.requirementsPicker !== RequirementsPicker.ITEM type:
? 0 formData.discountType.toString() === "SHIPPING"
: parseFloat(formData.minCheckoutItemsQuantity), ? VoucherTypeEnum.ENTIRE_ORDER
startDate: joinDateTime( : formData.type,
formData.startDate, usageLimit: formData.hasUsageLimit
formData.startTime ? parseInt(formData.usageLimit, 10)
), : 0
type:
formData.discountType.toString() === "SHIPPING"
? VoucherTypeEnum.ENTIRE_ORDER
: formData.type,
usageLimit: formData.hasUsageLimit
? parseInt(formData.usageLimit, 10)
: 0
}
} }
}) }
} })
saveButtonBarState={formTransitionState} }
/> saveButtonBarState={voucherCreateOpts.state}
</> />
); </>
}} )}
</TypedVoucherCreate> </TypedVoucherCreate>
); );
}; };

View file

@ -22,7 +22,7 @@ import useCollectionSearch from "@saleor/searches/useCollectionSearch";
import useProductSearch from "@saleor/searches/useProductSearch"; import useProductSearch from "@saleor/searches/useProductSearch";
import { categoryUrl } from "../../categories/urls"; import { categoryUrl } from "../../categories/urls";
import { collectionUrl } from "../../collections/urls"; import { collectionUrl } from "../../collections/urls";
import { decimal, getMutationState, joinDateTime, maybe } from "../../misc"; import { decimal, joinDateTime, maybe } from "../../misc";
import { productUrl } from "../../products/urls"; import { productUrl } from "../../products/urls";
import { import {
DiscountValueTypeEnum, DiscountValueTypeEnum,
@ -171,38 +171,6 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
VoucherDetailsPageTab.collections VoucherDetailsPageTab.collections
? maybe(() => data.voucher.collections.pageInfo) ? maybe(() => data.voucher.collections.pageInfo)
: maybe(() => data.voucher.products.pageInfo); : maybe(() => data.voucher.products.pageInfo);
const formTransitionState = getMutationState(
voucherUpdateOpts.called,
voucherUpdateOpts.loading,
maybe(
() => voucherUpdateOpts.data.voucherUpdate.errors
)
);
const assignTransitionState = getMutationState(
voucherCataloguesAddOpts.called,
voucherCataloguesAddOpts.loading,
maybe(
() =>
voucherCataloguesAddOpts.data.voucherCataloguesAdd
.errors
)
);
const unassignTransitionState = getMutationState(
voucherCataloguesRemoveOpts.called,
voucherCataloguesRemoveOpts.loading,
maybe(
() =>
voucherCataloguesRemoveOpts.data
.voucherCataloguesRemove.errors
)
);
const removeTransitionState = getMutationState(
voucherDeleteOpts.called,
voucherDeleteOpts.loading,
maybe(
() => voucherDeleteOpts.data.voucherDelete.errors
)
);
const handleCategoriesUnassign = (ids: string[]) => const handleCategoriesUnassign = (ids: string[]) =>
voucherCataloguesRemove({ voucherCataloguesRemove({
@ -387,7 +355,7 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
}) })
} }
onRemove={() => openModal("remove")} onRemove={() => openModal("remove")}
saveButtonBarState={formTransitionState} saveButtonBarState={voucherUpdateOpts.state}
categoryListToolbar={ categoryListToolbar={
<Button <Button
color="primary" color="primary"
@ -446,7 +414,9 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
suggestedCategory => suggestedCategory.id suggestedCategory => suggestedCategory.id
) )
)} )}
confirmButtonState={assignTransitionState} confirmButtonState={
voucherCataloguesAddOpts.state
}
open={params.action === "assign-category"} open={params.action === "assign-category"}
onFetch={searchCategories} onFetch={searchCategories}
loading={searchCategoriesOpts.loading} loading={searchCategoriesOpts.loading}
@ -473,7 +443,9 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
suggestedCategory => suggestedCategory.id suggestedCategory => suggestedCategory.id
) )
)} )}
confirmButtonState={assignTransitionState} confirmButtonState={
voucherCataloguesAddOpts.state
}
open={params.action === "assign-collection"} open={params.action === "assign-collection"}
onFetch={searchCollections} onFetch={searchCollections}
loading={searchCollectionsOpts.loading} loading={searchCollectionsOpts.loading}
@ -493,7 +465,7 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
} }
/> />
<DiscountCountrySelectDialog <DiscountCountrySelectDialog
confirmButtonState={formTransitionState} confirmButtonState={voucherUpdateOpts.state}
countries={maybe(() => shop.countries, [])} countries={maybe(() => shop.countries, [])}
onClose={() => navigate(voucherUrl(id))} onClose={() => navigate(voucherUrl(id))}
onConfirm={formData => onConfirm={formData =>
@ -516,7 +488,9 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
)} )}
/> />
<AssignProductDialog <AssignProductDialog
confirmButtonState={assignTransitionState} confirmButtonState={
voucherCataloguesAddOpts.state
}
open={params.action === "assign-product"} open={params.action === "assign-product"}
onFetch={searchProducts} onFetch={searchProducts}
loading={searchProductsOpts.loading} loading={searchProductsOpts.loading}
@ -552,7 +526,9 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
"Unassign Categories From Voucher", "Unassign Categories From Voucher",
description: "dialog header" description: "dialog header"
})} })}
confirmButtonState={unassignTransitionState} confirmButtonState={
voucherCataloguesRemoveOpts.state
}
onClose={closeModal} onClose={closeModal}
onConfirm={() => onConfirm={() =>
handleCategoriesUnassign(params.ids) handleCategoriesUnassign(params.ids)
@ -583,7 +559,9 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
"Unassign Collections From Voucher", "Unassign Collections From Voucher",
description: "dialog header" description: "dialog header"
})} })}
confirmButtonState={unassignTransitionState} confirmButtonState={
voucherCataloguesRemoveOpts.state
}
onClose={closeModal} onClose={closeModal}
onConfirm={() => onConfirm={() =>
handleCollectionsUnassign(params.ids) handleCollectionsUnassign(params.ids)
@ -614,7 +592,9 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
"Unassign Products From Voucher", "Unassign Products From Voucher",
description: "dialog header" description: "dialog header"
})} })}
confirmButtonState={unassignTransitionState} confirmButtonState={
voucherCataloguesRemoveOpts.state
}
onClose={closeModal} onClose={closeModal}
onConfirm={() => onConfirm={() =>
handleProductsUnassign(params.ids) handleProductsUnassign(params.ids)
@ -641,7 +621,7 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
defaultMessage: "Delete Voucher", defaultMessage: "Delete Voucher",
description: "dialog header" description: "dialog header"
})} })}
confirmButtonState={removeTransitionState} confirmButtonState={voucherDeleteOpts.state}
onClose={closeModal} onClose={closeModal}
variant="delete" variant="delete"
onConfirm={() => onConfirm={() =>

View file

@ -19,7 +19,7 @@ import usePaginator, {
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages, sectionNames } from "@saleor/intl"; import { commonMessages, sectionNames } from "@saleor/intl";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import VoucherListPage from "../../components/VoucherListPage"; import VoucherListPage from "../../components/VoucherListPage";
import { TypedVoucherBulkDelete } from "../../mutations"; import { TypedVoucherBulkDelete } from "../../mutations";
@ -153,17 +153,13 @@ export const VoucherList: React.FC<VoucherListProps> = ({ params }) => {
return ( return (
<TypedVoucherBulkDelete onCompleted={handleVoucherBulkDelete}> <TypedVoucherBulkDelete onCompleted={handleVoucherBulkDelete}>
{(voucherBulkDelete, voucherBulkDeleteOpts) => { {(voucherBulkDelete, voucherBulkDeleteOpts) => {
const bulkRemoveTransitionState = getMutationState(
voucherBulkDeleteOpts.called,
voucherBulkDeleteOpts.loading,
maybe(() => voucherBulkDeleteOpts.data.voucherBulkDelete.errors)
);
const onVoucherBulkDelete = () => const onVoucherBulkDelete = () =>
voucherBulkDelete({ voucherBulkDelete({
variables: { variables: {
ids: params.ids ids: params.ids
} }
}); });
return ( return (
<> <>
<WindowTitle <WindowTitle
@ -211,7 +207,7 @@ export const VoucherList: React.FC<VoucherListProps> = ({ params }) => {
} }
/> />
<ActionDialog <ActionDialog
confirmButtonState={bulkRemoveTransitionState} confirmButtonState={voucherBulkDeleteOpts.state}
onClose={closeModal} onClose={closeModal}
onConfirm={onVoucherBulkDelete} onConfirm={onVoucherBulkDelete}
open={params.action === "remove" && canOpenBulkActionDialog} open={params.action === "remove" && canOpenBulkActionDialog}

View file

@ -11,7 +11,7 @@ import useCollectionSearch from "@saleor/searches/useCollectionSearch";
import usePageSearch from "@saleor/searches/usePageSearch"; import usePageSearch from "@saleor/searches/usePageSearch";
import { categoryUrl } from "../../../categories/urls"; import { categoryUrl } from "../../../categories/urls";
import { collectionUrl } from "../../../collections/urls"; import { collectionUrl } from "../../../collections/urls";
import { getMutationState, maybe } from "../../../misc"; import { maybe } from "../../../misc";
import { pageUrl } from "../../../pages/urls"; import { pageUrl } from "../../../pages/urls";
import MenuDetailsPage, { import MenuDetailsPage, {
MenuDetailsSubmitData MenuDetailsSubmitData
@ -137,19 +137,6 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
onCompleted={data => handleUpdate(data, notify, refetch, intl)} onCompleted={data => handleUpdate(data, notify, refetch, intl)}
> >
{(menuUpdate, menuUpdateOpts) => { {(menuUpdate, menuUpdateOpts) => {
const deleteState = getMutationState(
menuDeleteOpts.called,
menuDeleteOpts.loading,
maybe(() => menuDeleteOpts.data.menuDelete.errors)
);
const updateState = getMutationState(
menuUpdateOpts.called,
menuUpdateOpts.loading,
maybe(() => menuUpdateOpts.data.menuUpdate.errors),
maybe(() => menuUpdateOpts.data.menuItemMove.errors)
);
// This is a workaround to let know <MenuDetailsPage /> // This is a workaround to let know <MenuDetailsPage />
// that it should clean operation stack if mutations // that it should clean operation stack if mutations
// were successful // were successful
@ -208,12 +195,12 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
) )
} }
onSubmit={handleSubmit} onSubmit={handleSubmit}
saveButtonState={updateState} saveButtonState={menuUpdateOpts.state}
/> />
<ActionDialog <ActionDialog
open={params.action === "remove"} open={params.action === "remove"}
onClose={closeModal} onClose={closeModal}
confirmButtonState={deleteState} confirmButtonState={menuDeleteOpts.state}
onConfirm={() => menuDelete({ variables: { id } })} onConfirm={() => menuDelete({ variables: { id } })}
variant="delete" variant="delete"
title={intl.formatMessage({ title={intl.formatMessage({
@ -253,15 +240,6 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
menuItemCreate({ variables }); menuItemCreate({ variables });
}; };
const formTransitionState = getMutationState(
menuItemCreateOpts.called,
menuItemCreateOpts.loading,
maybe(
() =>
menuItemCreateOpts.data.menuItemCreate.errors
)
);
return ( return (
<MenuItemDialog <MenuItemDialog
open={params.action === "add-item"} open={params.action === "add-item"}
@ -277,7 +255,7 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
categorySearch.result.loading || categorySearch.result.loading ||
collectionSearch.result.loading collectionSearch.result.loading
} }
confirmButtonState={formTransitionState} confirmButtonState={menuItemCreateOpts.state}
disabled={menuItemCreateOpts.loading} disabled={menuItemCreateOpts.loading}
onClose={closeModal} onClose={closeModal}
onSubmit={handleSubmit} onSubmit={handleSubmit}
@ -310,15 +288,6 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
) )
); );
const formTransitionState = getMutationState(
menuItemUpdateOpts.called,
menuItemUpdateOpts.loading,
maybe(
() =>
menuItemUpdateOpts.data.menuItemUpdate.errors
)
);
const initialFormData: MenuItemDialogFormData = { const initialFormData: MenuItemDialogFormData = {
id: maybe(() => getItemId(menuItem)), id: maybe(() => getItemId(menuItem)),
name: maybe(() => menuItem.name, "..."), name: maybe(() => menuItem.name, "..."),
@ -347,7 +316,7 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
categorySearch.result.loading || categorySearch.result.loading ||
collectionSearch.result.loading collectionSearch.result.loading
} }
confirmButtonState={formTransitionState} confirmButtonState={menuItemUpdateOpts.state}
disabled={menuItemUpdateOpts.loading} disabled={menuItemUpdateOpts.loading}
onClose={closeModal} onClose={closeModal}
onSubmit={handleSubmit} onSubmit={handleSubmit}

View file

@ -13,7 +13,7 @@ import usePaginator, {
createPaginationState createPaginationState
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import { buttonMessages, commonMessages } from "@saleor/intl"; import { buttonMessages, commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import MenuCreateDialog from "../components/MenuCreateDialog"; import MenuCreateDialog from "../components/MenuCreateDialog";
import MenuListPage from "../components/MenuListPage"; import MenuListPage from "../components/MenuListPage";
@ -107,167 +107,145 @@ const MenuList: React.FC<MenuListProps> = ({ params }) => {
<MenuDeleteMutation onCompleted={handleDelete}> <MenuDeleteMutation onCompleted={handleDelete}>
{(menuDelete, menuDeleteOpts) => ( {(menuDelete, menuDeleteOpts) => (
<MenuBulkDeleteMutation onCompleted={handleBulkDelete}> <MenuBulkDeleteMutation onCompleted={handleBulkDelete}>
{(menuBulkDelete, menuBulkDeleteOpts) => { {(menuBulkDelete, menuBulkDeleteOpts) => (
const createTransitionState = getMutationState( <>
menuCreateOpts.called, <MenuListPage
menuCreateOpts.loading, disabled={loading}
maybe(() => menuCreateOpts.data.menuCreate.errors) menus={maybe(() =>
); data.menus.edges.map(edge => edge.node)
)}
const deleteTransitionState = getMutationState( settings={settings}
menuDeleteOpts.called, onAdd={() =>
menuDeleteOpts.loading, navigate(
maybe(() => menuDeleteOpts.data.menuDelete.errors) menuListUrl({
); action: "add"
const bulkDeleteTransitionState = getMutationState(
menuBulkDeleteOpts.called,
menuBulkDeleteOpts.loading,
maybe(
() => menuBulkDeleteOpts.data.menuBulkDelete.errors
)
);
return (
<>
<MenuListPage
disabled={loading}
menus={maybe(() =>
data.menus.edges.map(edge => edge.node)
)}
settings={settings}
onAdd={() =>
navigate(
menuListUrl({
action: "add"
})
)
}
onBack={() => navigate(configurationMenuUrl)}
onDelete={id =>
navigate(
menuListUrl({
action: "remove",
id
})
)
}
onNextPage={loadNextPage}
onPreviousPage={loadPreviousPage}
onUpdateListSettings={updateListSettings}
onRowClick={id => () => navigate(menuUrl(id))}
pageInfo={pageInfo}
isChecked={isSelected}
selected={listElements.length}
toggle={toggle}
toggleAll={toggleAll}
toolbar={
<Button
color="primary"
onClick={() =>
navigate(
menuListUrl({
...params,
action: "remove-many",
ids: listElements
})
)
}
>
<FormattedMessage {...buttonMessages.remove} />
</Button>
}
/>
<MenuCreateDialog
open={params.action === "add"}
confirmButtonState={createTransitionState}
disabled={menuCreateOpts.loading}
onClose={closeModal}
onConfirm={formData =>
menuCreate({
variables: { input: formData }
}) })
} )
/> }
<ActionDialog onBack={() => navigate(configurationMenuUrl)}
open={params.action === "remove"} onDelete={id =>
onClose={closeModal} navigate(
confirmButtonState={deleteTransitionState} menuListUrl({
onConfirm={() => action: "remove",
menuDelete({ id
variables: {
id: params.id
}
}) })
} )
variant="delete" }
title={intl.formatMessage({ onNextPage={loadNextPage}
defaultMessage: "Delete Menu", onPreviousPage={loadPreviousPage}
description: "dialog header", onUpdateListSettings={updateListSettings}
id: "menuListDeleteMenuHeader" onRowClick={id => () => navigate(menuUrl(id))}
})} pageInfo={pageInfo}
> isChecked={isSelected}
<DialogContentText> selected={listElements.length}
<FormattedMessage toggle={toggle}
defaultMessage="Are you sure you want to delete {menuName}?" toggleAll={toggleAll}
id="menuListDeleteMenuContent" toolbar={
values={{ <Button
menuName: maybe( color="primary"
() => onClick={() =>
data.menus.edges.find( navigate(
edge => edge.node.id === params.id menuListUrl({
).node.name, ...params,
"..." action: "remove-many",
) ids: listElements
}} })
/> )
</DialogContentText> }
</ActionDialog> >
<ActionDialog <FormattedMessage {...buttonMessages.remove} />
open={ </Button>
params.action === "remove-many" && }
maybe(() => params.ids.length > 0) />
} <MenuCreateDialog
onClose={closeModal} open={params.action === "add"}
confirmButtonState={bulkDeleteTransitionState} confirmButtonState={menuCreateOpts.state}
onConfirm={() => disabled={menuCreateOpts.loading}
menuBulkDelete({ onClose={closeModal}
variables: { onConfirm={formData =>
ids: params.ids menuCreate({
} variables: { input: formData }
}) })
} }
variant="delete" />
title={intl.formatMessage({ <ActionDialog
defaultMessage: "Delete Menus", open={params.action === "remove"}
description: "dialog header", onClose={closeModal}
id: "menuListDeleteMenusHeader" confirmButtonState={menuDeleteOpts.state}
})} onConfirm={() =>
> menuDelete({
<DialogContentText> variables: {
<FormattedMessage id: params.id
defaultMessage="Are you sure you want to delete {counter,plural,one{this menu} other{{displayQuantity} menus}}?" }
id="menuListDeleteMenusContent" })
values={{ }
counter: maybe( variant="delete"
() => params.ids.length.toString(), title={intl.formatMessage({
"..." defaultMessage: "Delete Menu",
), description: "dialog header",
displayQuantity: ( id: "menuListDeleteMenuHeader"
<strong> })}
{maybe( >
() => params.ids.length.toString(), <DialogContentText>
"..." <FormattedMessage
)} defaultMessage="Are you sure you want to delete {menuName}?"
</strong> id="menuListDeleteMenuContent"
) values={{
}} menuName: maybe(
/> () =>
</DialogContentText> data.menus.edges.find(
</ActionDialog> edge => edge.node.id === params.id
</> ).node.name,
); "..."
}} )
}}
/>
</DialogContentText>
</ActionDialog>
<ActionDialog
open={
params.action === "remove-many" &&
maybe(() => params.ids.length > 0)
}
onClose={closeModal}
confirmButtonState={menuBulkDeleteOpts.state}
onConfirm={() =>
menuBulkDelete({
variables: {
ids: params.ids
}
})
}
variant="delete"
title={intl.formatMessage({
defaultMessage: "Delete Menus",
description: "dialog header",
id: "menuListDeleteMenusHeader"
})}
>
<DialogContentText>
<FormattedMessage
defaultMessage="Are you sure you want to delete {counter,plural,one{this menu} other{{displayQuantity} menus}}?"
id="menuListDeleteMenusContent"
values={{
counter: maybe(
() => params.ids.length.toString(),
"..."
),
displayQuantity: (
<strong>
{maybe(
() => params.ids.length.toString(),
"..."
)}
</strong>
)
}}
/>
</DialogContentText>
</ActionDialog>
</>
)}
</MenuBulkDeleteMutation> </MenuBulkDeleteMutation>
)} )}
</MenuDeleteMutation> </MenuDeleteMutation>

View file

@ -153,464 +153,451 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
orderDraftCancel, orderDraftCancel,
orderDraftFinalize, orderDraftFinalize,
orderPaymentMarkAsPaid orderPaymentMarkAsPaid
}) => { }) => (
const finalizeTransitionState = getMutationState( <>
orderDraftFinalize.opts.called, {maybe(() => order.status !== OrderStatus.DRAFT) ? (
orderDraftFinalize.opts.loading, <>
maybe( <WindowTitle
() => title={maybe(() => "Order #" + data.order.number)}
orderDraftFinalize.opts.data.draftOrderComplete.errors />
) <OrderDetailsPage
); onNoteAdd={variables =>
return ( orderAddNote.mutate({
<> input: variables,
{maybe(() => order.status !== OrderStatus.DRAFT) ? ( order: id
<> })
<WindowTitle }
title={maybe(() => "Order #" + data.order.number)} onBack={() => navigate(orderListUrl())}
/> order={order}
<OrderDetailsPage shippingMethods={maybe(
onNoteAdd={variables => () => data.order.availableShippingMethods,
orderAddNote.mutate({ []
input: variables, )}
order: id userPermissions={maybe(() => user.permissions, [])}
onOrderCancel={() => openModal("cancel")}
onOrderFulfill={() => openModal("fulfill")}
onFulfillmentCancel={fulfillmentId =>
navigate(
orderUrl(id, {
action: "cancel-fulfillment",
id: fulfillmentId
}) })
} )
onBack={() => navigate(orderListUrl())} }
order={order} onFulfillmentTrackingNumberUpdate={fulfillmentId =>
shippingMethods={maybe( navigate(
() => data.order.availableShippingMethods, orderUrl(id, {
[] action: "edit-fulfillment",
)} id: fulfillmentId
userPermissions={maybe(() => user.permissions, [])}
onOrderCancel={() => openModal("cancel")}
onOrderFulfill={() => openModal("fulfill")}
onFulfillmentCancel={fulfillmentId =>
navigate(
orderUrl(id, {
action: "cancel-fulfillment",
id: fulfillmentId
})
)
}
onFulfillmentTrackingNumberUpdate={fulfillmentId =>
navigate(
orderUrl(id, {
action: "edit-fulfillment",
id: fulfillmentId
})
)
}
onPaymentCapture={() => openModal("capture")}
onPaymentVoid={() => openModal("void")}
onPaymentRefund={() => openModal("refund")}
onProductClick={id => () =>
navigate(productUrl(id))}
onBillingAddressEdit={() =>
openModal("edit-billing-address")
}
onShippingAddressEdit={() =>
openModal("edit-shipping-address")
}
onPaymentPaid={() => openModal("mark-paid")}
onProfileView={() =>
navigate(customerUrl(order.user.id))
}
/>
<OrderCancelDialog
confirmButtonState={getMutationState(
orderCancel.opts.called,
orderCancel.opts.loading,
maybe(
() => orderCancel.opts.data.orderCancel.errors
)
)}
number={maybe(() => order.number)}
open={params.action === "cancel"}
onClose={closeModal}
onSubmit={variables =>
orderCancel.mutate({
id,
...variables
}) })
} )
/> }
<OrderMarkAsPaidDialog onPaymentCapture={() => openModal("capture")}
confirmButtonState={getMutationState( onPaymentVoid={() => openModal("void")}
orderPaymentMarkAsPaid.opts.called, onPaymentRefund={() => openModal("refund")}
orderPaymentMarkAsPaid.opts.loading, onProductClick={id => () => navigate(productUrl(id))}
maybe( onBillingAddressEdit={() =>
() => openModal("edit-billing-address")
orderPaymentMarkAsPaid.opts.data }
.orderMarkAsPaid.errors onShippingAddressEdit={() =>
) openModal("edit-shipping-address")
)} }
onClose={closeModal} onPaymentPaid={() => openModal("mark-paid")}
onConfirm={() => onProfileView={() =>
orderPaymentMarkAsPaid.mutate({ navigate(customerUrl(order.user.id))
id }
}) />
} <OrderCancelDialog
open={params.action === "mark-paid"} confirmButtonState={getMutationState(
/> orderCancel.opts.called,
<OrderPaymentVoidDialog orderCancel.opts.loading,
confirmButtonState={getMutationState( maybe(
orderVoid.opts.called, () => orderCancel.opts.data.orderCancel.errors
orderVoid.opts.loading, )
maybe(() => orderVoid.opts.data.orderVoid.errors) )}
)} number={maybe(() => order.number)}
open={params.action === "void"} open={params.action === "cancel"}
onClose={closeModal} onClose={closeModal}
onConfirm={() => orderVoid.mutate({ id })} onSubmit={variables =>
/> orderCancel.mutate({
<OrderPaymentDialog id,
confirmButtonState={getMutationState( ...variables
orderPaymentCapture.opts.called, })
orderPaymentCapture.opts.loading, }
maybe( />
() => <OrderMarkAsPaidDialog
orderPaymentCapture.opts.data.orderCapture confirmButtonState={getMutationState(
.errors orderPaymentMarkAsPaid.opts.called,
) orderPaymentMarkAsPaid.opts.loading,
)} maybe(
initial={maybe(() => order.total.gross.amount)} () =>
open={params.action === "capture"} orderPaymentMarkAsPaid.opts.data.orderMarkAsPaid
variant="capture" .errors
onClose={closeModal} )
onSubmit={variables => )}
orderPaymentCapture.mutate({ onClose={closeModal}
onConfirm={() =>
orderPaymentMarkAsPaid.mutate({
id
})
}
open={params.action === "mark-paid"}
/>
<OrderPaymentVoidDialog
confirmButtonState={getMutationState(
orderVoid.opts.called,
orderVoid.opts.loading,
maybe(() => orderVoid.opts.data.orderVoid.errors)
)}
open={params.action === "void"}
onClose={closeModal}
onConfirm={() => orderVoid.mutate({ id })}
/>
<OrderPaymentDialog
confirmButtonState={getMutationState(
orderPaymentCapture.opts.called,
orderPaymentCapture.opts.loading,
maybe(
() =>
orderPaymentCapture.opts.data.orderCapture
.errors
)
)}
initial={maybe(() => order.total.gross.amount)}
open={params.action === "capture"}
variant="capture"
onClose={closeModal}
onSubmit={variables =>
orderPaymentCapture.mutate({
...variables,
id
})
}
/>
<OrderPaymentDialog
confirmButtonState={getMutationState(
orderPaymentRefund.opts.called,
orderPaymentRefund.opts.loading,
maybe(
() =>
orderPaymentRefund.opts.data.orderRefund.errors
)
)}
initial={maybe(() => order.total.gross.amount)}
open={params.action === "refund"}
variant="refund"
onClose={closeModal}
onSubmit={variables =>
orderPaymentRefund.mutate({
...variables,
id
})
}
/>
<OrderFulfillmentDialog
confirmButtonState={getMutationState(
orderCreateFulfillment.opts.called,
orderCreateFulfillment.opts.loading,
maybe(
() =>
orderCreateFulfillment.opts.data
.orderFulfillmentCreate.errors
)
)}
open={params.action === "fulfill"}
lines={maybe(() => order.lines, []).filter(
line => line.quantityFulfilled < line.quantity
)}
onClose={closeModal}
onSubmit={variables =>
orderCreateFulfillment.mutate({
input: {
...variables, ...variables,
id lines: maybe(() => order.lines, [])
}) .filter(
} line =>
/> line.quantityFulfilled < line.quantity
<OrderPaymentDialog )
confirmButtonState={getMutationState( .map((line, lineIndex) => ({
orderPaymentRefund.opts.called, orderLineId: line.id,
orderPaymentRefund.opts.loading, quantity: variables.lines[lineIndex]
maybe( }))
() => .filter(line => line.quantity > 0)
orderPaymentRefund.opts.data.orderRefund },
.errors order: order.id
) })
)} }
initial={maybe(() => order.total.gross.amount)} />
open={params.action === "refund"} <OrderFulfillmentCancelDialog
variant="refund" confirmButtonState={getMutationState(
onClose={closeModal} orderFulfillmentCancel.opts.called,
onSubmit={variables => orderFulfillmentCancel.opts.loading,
orderPaymentRefund.mutate({ maybe(
() =>
orderFulfillmentCancel.opts.data
.orderFulfillmentCancel.errors
)
)}
open={params.action === "cancel-fulfillment"}
onConfirm={variables =>
orderFulfillmentCancel.mutate({
id: params.id,
input: variables
})
}
onClose={closeModal}
/>
<OrderFulfillmentTrackingDialog
confirmButtonState={getMutationState(
orderFulfillmentUpdateTracking.opts.called,
orderFulfillmentUpdateTracking.opts.loading,
maybe(
() =>
orderFulfillmentUpdateTracking.opts.data
.orderFulfillmentUpdateTracking.errors
)
)}
open={params.action === "edit-fulfillment"}
trackingNumber={maybe(
() =>
data.order.fulfillments.find(
fulfillment => fulfillment.id === params.id
).trackingNumber
)}
onConfirm={variables =>
orderFulfillmentUpdateTracking.mutate({
id: params.id,
input: {
...variables, ...variables,
id notifyCustomer: true
}) }
} })
/> }
<OrderFulfillmentDialog onClose={closeModal}
confirmButtonState={getMutationState( />
orderCreateFulfillment.opts.called, </>
orderCreateFulfillment.opts.loading, ) : (
maybe( <>
() => <WindowTitle
orderCreateFulfillment.opts.data title={maybe(
.orderFulfillmentCreate.errors () => "Draft order #" + data.order.number
) )}
)} />
open={params.action === "fulfill"} <OrderDraftPage
lines={maybe(() => order.lines, []).filter( disabled={loading}
line => line.quantityFulfilled < line.quantity onNoteAdd={variables =>
)} orderAddNote.mutate({
onClose={closeModal} input: variables,
onSubmit={variables => order: id
orderCreateFulfillment.mutate({ })
input: { }
...variables, users={maybe(
lines: maybe(() => order.lines, []) () =>
.filter( users.data.search.edges.map(edge => edge.node),
line => []
line.quantityFulfilled < line.quantity )}
) hasMore={maybe(
.map((line, lineIndex) => ({ () => users.data.search.pageInfo.hasNextPage,
orderLineId: line.id, false
quantity: variables.lines[lineIndex] )}
})) onFetchMore={loadMoreCustomers}
.filter(line => line.quantity > 0) fetchUsers={searchUsers}
}, loading={users.loading}
order: order.id usersLoading={users.loading}
}) onCustomerEdit={data =>
} orderDraftUpdate.mutate({
/> id,
<OrderFulfillmentCancelDialog input: data
confirmButtonState={getMutationState( })
orderFulfillmentCancel.opts.called, }
orderFulfillmentCancel.opts.loading, onDraftFinalize={() => openModal("finalize")}
maybe( onDraftRemove={() => openModal("cancel")}
() => onOrderLineAdd={() => openModal("add-order-line")}
orderFulfillmentCancel.opts.data onBack={() => navigate(orderListUrl())}
.orderFulfillmentCancel.errors order={order}
) countries={maybe(() => data.shop.countries, []).map(
)} country => ({
open={params.action === "cancel-fulfillment"} code: country.code,
onConfirm={variables => label: country.country
orderFulfillmentCancel.mutate({ })
id: params.id, )}
input: variables onProductClick={id => () =>
}) navigate(productUrl(encodeURIComponent(id)))}
} onBillingAddressEdit={() =>
onClose={closeModal} openModal("edit-billing-address")
/> }
<OrderFulfillmentTrackingDialog onShippingAddressEdit={() =>
confirmButtonState={getMutationState( openModal("edit-shipping-address")
orderFulfillmentUpdateTracking.opts.called, }
orderFulfillmentUpdateTracking.opts.loading, onShippingMethodEdit={() =>
maybe( openModal("edit-shipping")
() => }
orderFulfillmentUpdateTracking.opts.data onOrderLineRemove={id =>
.orderFulfillmentUpdateTracking.errors orderLineDelete.mutate({ id })
) }
)} onOrderLineChange={(id, data) =>
open={params.action === "edit-fulfillment"} orderLineUpdate.mutate({
trackingNumber={maybe( id,
input: data
})
}
saveButtonBarState="default"
onProfileView={() =>
navigate(customerUrl(order.user.id))
}
userPermissions={maybe(() => user.permissions, [])}
/>
<OrderDraftCancelDialog
confirmButtonState={getMutationState(
orderDraftCancel.opts.called,
orderDraftCancel.opts.loading,
maybe(
() => () =>
data.order.fulfillments.find( orderDraftCancel.opts.data.draftOrderDelete
fulfillment => fulfillment.id === params.id .errors
).trackingNumber )
)} )}
onConfirm={variables => onClose={closeModal}
orderFulfillmentUpdateTracking.mutate({ onConfirm={() => orderDraftCancel.mutate({ id })}
id: params.id, open={params.action === "cancel"}
input: { orderNumber={maybe(() => order.number)}
...variables, />
notifyCustomer: true <OrderDraftFinalizeDialog
} confirmButtonState={orderDraftFinalize.opts.state}
}) onClose={closeModal}
} onConfirm={() => orderDraftFinalize.mutate({ id })}
onClose={closeModal} open={params.action === "finalize"}
/> orderNumber={maybe(() => order.number)}
</> warnings={orderDraftFinalizeWarnings(order)}
) : ( />
<> <OrderShippingMethodEditDialog
<WindowTitle confirmButtonState={getMutationState(
title={maybe( orderShippingMethodUpdate.opts.called,
() => "Draft order #" + data.order.number orderShippingMethodUpdate.opts.loading,
)} maybe(
/>
<OrderDraftPage
disabled={loading}
onNoteAdd={variables =>
orderAddNote.mutate({
input: variables,
order: id
})
}
users={maybe(
() => () =>
users.data.search.edges.map(edge => edge.node), orderShippingMethodUpdate.opts.data
[] .orderUpdateShipping.errors
)} )
hasMore={maybe( )}
() => users.data.search.pageInfo.hasNextPage, open={params.action === "edit-shipping"}
false shippingMethod={maybe(
)} () => order.shippingMethod.id,
onFetchMore={loadMoreCustomers} "..."
fetchUsers={searchUsers} )}
loading={users.loading} shippingMethods={maybe(
usersLoading={users.loading} () => order.availableShippingMethods
onCustomerEdit={data => )}
orderDraftUpdate.mutate({ onClose={closeModal}
id, onSubmit={variables =>
input: data orderShippingMethodUpdate.mutate({
}) id,
} input: {
onDraftFinalize={() => openModal("finalize")} shippingMethod: variables.shippingMethod
onDraftRemove={() => openModal("cancel")} }
onOrderLineAdd={() => openModal("add-order-line")} })
onBack={() => navigate(orderListUrl())} }
order={order} />
countries={maybe(() => data.shop.countries, []).map( <OrderProductAddDialog
country => ({ confirmButtonState={getMutationState(
code: country.code, orderLinesAdd.opts.called,
label: country.country orderLinesAdd.opts.loading,
}) maybe(
)}
onProductClick={id => () =>
navigate(productUrl(encodeURIComponent(id)))}
onBillingAddressEdit={() =>
openModal("edit-billing-address")
}
onShippingAddressEdit={() =>
openModal("edit-shipping-address")
}
onShippingMethodEdit={() =>
openModal("edit-shipping")
}
onOrderLineRemove={id =>
orderLineDelete.mutate({ id })
}
onOrderLineChange={(id, data) =>
orderLineUpdate.mutate({
id,
input: data
})
}
saveButtonBarState="default"
onProfileView={() =>
navigate(customerUrl(order.user.id))
}
userPermissions={maybe(() => user.permissions, [])}
/>
<OrderDraftCancelDialog
confirmButtonState={getMutationState(
orderDraftCancel.opts.called,
orderDraftCancel.opts.loading,
maybe(
() =>
orderDraftCancel.opts.data.draftOrderDelete
.errors
)
)}
onClose={closeModal}
onConfirm={() => orderDraftCancel.mutate({ id })}
open={params.action === "cancel"}
orderNumber={maybe(() => order.number)}
/>
<OrderDraftFinalizeDialog
confirmButtonState={finalizeTransitionState}
onClose={closeModal}
onConfirm={() => orderDraftFinalize.mutate({ id })}
open={params.action === "finalize"}
orderNumber={maybe(() => order.number)}
warnings={orderDraftFinalizeWarnings(order)}
/>
<OrderShippingMethodEditDialog
confirmButtonState={getMutationState(
orderShippingMethodUpdate.opts.called,
orderShippingMethodUpdate.opts.loading,
maybe(
() =>
orderShippingMethodUpdate.opts.data
.orderUpdateShipping.errors
)
)}
open={params.action === "edit-shipping"}
shippingMethod={maybe(
() => order.shippingMethod.id,
"..."
)}
shippingMethods={maybe(
() => order.availableShippingMethods
)}
onClose={closeModal}
onSubmit={variables =>
orderShippingMethodUpdate.mutate({
id,
input: {
shippingMethod: variables.shippingMethod
}
})
}
/>
<OrderProductAddDialog
confirmButtonState={getMutationState(
orderLinesAdd.opts.called,
orderLinesAdd.opts.loading,
maybe(
() =>
orderLinesAdd.opts.data.draftOrderLinesCreate
.errors
)
)}
loading={variantSearchOpts.loading}
open={params.action === "add-order-line"}
hasMore={maybe(
() => () =>
variantSearchOpts.data.search.pageInfo orderLinesAdd.opts.data.draftOrderLinesCreate
.hasNextPage .errors
)} )
products={maybe(() => )}
variantSearchOpts.data.search.edges.map( loading={variantSearchOpts.loading}
edge => edge.node open={params.action === "add-order-line"}
) hasMore={maybe(
)} () =>
onClose={closeModal} variantSearchOpts.data.search.pageInfo.hasNextPage
onFetch={variantSearch} )}
onFetchMore={loadMore} products={maybe(() =>
onSubmit={variants => variantSearchOpts.data.search.edges.map(
orderLinesAdd.mutate({ edge => edge.node
id, )
input: variants.map(variant => ({ )}
quantity: 1, onClose={closeModal}
variantId: variant.id onFetch={variantSearch}
})) onFetchMore={loadMore}
}) onSubmit={variants =>
} orderLinesAdd.mutate({
/> id,
</> input: variants.map(variant => ({
quantity: 1,
variantId: variant.id
}))
})
}
/>
</>
)}
<OrderAddressEditDialog
confirmButtonState={getMutationState(
orderUpdate.opts.called,
orderUpdate.opts.loading,
maybe(() => orderUpdate.opts.data.orderUpdate.errors)
)} )}
<OrderAddressEditDialog address={transformAddressToForm(
confirmButtonState={getMutationState( maybe(() => order.shippingAddress)
orderUpdate.opts.called, )}
orderUpdate.opts.loading, countries={maybe(() => data.shop.countries, []).map(
maybe(() => orderUpdate.opts.data.orderUpdate.errors) country => ({
)} code: country.code,
address={transformAddressToForm( label: country.country
maybe(() => order.shippingAddress) })
)} )}
countries={maybe(() => data.shop.countries, []).map( errors={maybe(
country => ({ () => orderUpdate.opts.data.orderUpdate.errors,
code: country.code, []
label: country.country )}
}) open={params.action === "edit-shipping-address"}
)} variant="shipping"
errors={maybe( onClose={closeModal}
() => orderUpdate.opts.data.orderUpdate.errors, onConfirm={shippingAddress =>
[] orderUpdate.mutate({
)} id,
open={params.action === "edit-shipping-address"} input: {
variant="shipping" shippingAddress
onClose={closeModal} }
onConfirm={shippingAddress => })
orderUpdate.mutate({ }
id, />
input: { <OrderAddressEditDialog
shippingAddress confirmButtonState={getMutationState(
} orderUpdate.opts.called,
}) orderUpdate.opts.loading,
} maybe(() => orderUpdate.opts.data.orderUpdate.errors)
/> )}
<OrderAddressEditDialog address={transformAddressToForm(
confirmButtonState={getMutationState( maybe(() => order.billingAddress)
orderUpdate.opts.called, )}
orderUpdate.opts.loading, countries={maybe(() => data.shop.countries, []).map(
maybe(() => orderUpdate.opts.data.orderUpdate.errors) country => ({
)} code: country.code,
address={transformAddressToForm( label: country.country
maybe(() => order.billingAddress) })
)} )}
countries={maybe(() => data.shop.countries, []).map( errors={maybe(
country => ({ () => orderUpdate.opts.data.orderUpdate.errors,
code: country.code, []
label: country.country )}
}) open={params.action === "edit-billing-address"}
)} variant="billing"
errors={maybe( onClose={closeModal}
() => orderUpdate.opts.data.orderUpdate.errors, onConfirm={billingAddress =>
[] orderUpdate.mutate({
)} id,
open={params.action === "edit-billing-address"} input: {
variant="billing" billingAddress
onClose={closeModal} }
onConfirm={billingAddress => })
orderUpdate.mutate({ }
id, />
input: { </>
billingAddress )}
}
})
}
/>
</>
);
}}
</OrderOperations> </OrderOperations>
)} )}
</OrderDetailsMessages> </OrderDetailsMessages>

View file

@ -16,7 +16,7 @@ import useNotifier from "@saleor/hooks/useNotifier";
import usePaginator, { import usePaginator, {
createPaginationState createPaginationState
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import OrderDraftListPage from "../../components/OrderDraftListPage"; import OrderDraftListPage from "../../components/OrderDraftListPage";
import { import {
@ -167,14 +167,6 @@ export const OrderDraftList: React.FC<OrderDraftListProps> = ({ params }) => {
onCompleted={handleOrderDraftBulkCancel} onCompleted={handleOrderDraftBulkCancel}
> >
{(orderDraftBulkDelete, orderDraftBulkDeleteOpts) => { {(orderDraftBulkDelete, orderDraftBulkDeleteOpts) => {
const bulkRemoveTransitionState = getMutationState(
orderDraftBulkDeleteOpts.called,
orderDraftBulkDeleteOpts.loading,
maybe(
() =>
orderDraftBulkDeleteOpts.data.draftOrderBulkDelete.errors
)
);
const onOrderDraftBulkDelete = () => const onOrderDraftBulkDelete = () =>
orderDraftBulkDelete({ orderDraftBulkDelete({
variables: { variables: {
@ -225,7 +217,7 @@ export const OrderDraftList: React.FC<OrderDraftListProps> = ({ params }) => {
} }
/> />
<ActionDialog <ActionDialog
confirmButtonState={bulkRemoveTransitionState} confirmButtonState={orderDraftBulkDeleteOpts.state}
onClose={closeModal} onClose={closeModal}
onConfirm={onOrderDraftBulkDelete} onConfirm={onOrderDraftBulkDelete}
open={params.action === "remove"} open={params.action === "remove"}

View file

@ -15,7 +15,7 @@ import usePaginator, {
createPaginationState createPaginationState
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import OrderBulkCancelDialog from "../../components/OrderBulkCancelDialog"; import OrderBulkCancelDialog from "../../components/OrderBulkCancelDialog";
import OrderListPage from "../../components/OrderListPage/OrderListPage"; import OrderListPage from "../../components/OrderListPage/OrderListPage";
@ -176,11 +176,6 @@ export const OrderList: React.FC<OrderListProps> = ({ params }) => {
return ( return (
<TypedOrderBulkCancelMutation onCompleted={handleOrderBulkCancel}> <TypedOrderBulkCancelMutation onCompleted={handleOrderBulkCancel}>
{(orderBulkCancel, orderBulkCancelOpts) => { {(orderBulkCancel, orderBulkCancelOpts) => {
const orderBulkCancelTransitionState = getMutationState(
orderBulkCancelOpts.called,
orderBulkCancelOpts.loading,
maybe(() => orderBulkCancelOpts.data.orderBulkCancel.errors)
);
const onOrderBulkCancel = (restock: boolean) => const onOrderBulkCancel = (restock: boolean) =>
orderBulkCancel({ orderBulkCancel({
variables: { variables: {
@ -244,7 +239,7 @@ export const OrderList: React.FC<OrderListProps> = ({ params }) => {
} }
/> />
<OrderBulkCancelDialog <OrderBulkCancelDialog
confirmButtonState={orderBulkCancelTransitionState} confirmButtonState={orderBulkCancelOpts.state}
numberOfOrders={maybe( numberOfOrders={maybe(
() => params.ids.length.toString(), () => params.ids.length.toString(),
"..." "..."

View file

@ -4,7 +4,7 @@ import { useIntl } from "react-intl";
import { WindowTitle } from "@saleor/components/WindowTitle"; import { WindowTitle } from "@saleor/components/WindowTitle";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import PageDetailsPage from "../components/PageDetailsPage"; import PageDetailsPage from "../components/PageDetailsPage";
import { TypedPageCreate } from "../mutations"; import { TypedPageCreate } from "../mutations";
import { PageCreate as PageCreateData } from "../types/PageCreate"; import { PageCreate as PageCreateData } from "../types/PageCreate";
@ -32,53 +32,45 @@ export const PageCreate: React.FC<PageCreateProps> = () => {
return ( return (
<TypedPageCreate onCompleted={handlePageCreate}> <TypedPageCreate onCompleted={handlePageCreate}>
{(pageCreate, pageCreateOpts) => { {(pageCreate, pageCreateOpts) => (
const formTransitionState = getMutationState( <>
pageCreateOpts.called, <WindowTitle
pageCreateOpts.loading, title={intl.formatMessage({
maybe(() => pageCreateOpts.data.pageCreate.errors) defaultMessage: "Create Page",
); description: "header"
})}
return ( />
<> <PageDetailsPage
<WindowTitle disabled={pageCreateOpts.loading}
title={intl.formatMessage({ errors={maybe(() => pageCreateOpts.data.pageCreate.errors, [])}
defaultMessage: "Create Page", saveButtonBarState={pageCreateOpts.state}
description: "header" page={null}
})} onBack={() => navigate(pageListUrl())}
/> onRemove={() => undefined}
<PageDetailsPage onSubmit={formData =>
disabled={pageCreateOpts.loading} pageCreate({
errors={maybe(() => pageCreateOpts.data.pageCreate.errors, [])} variables: {
saveButtonBarState={formTransitionState} input: {
page={null} contentJson: JSON.stringify(formData.content),
onBack={() => navigate(pageListUrl())} isPublished: formData.isPublished,
onRemove={() => undefined} publicationDate: formData.isPublished
onSubmit={formData => ? null
pageCreate({ : formData.publicationDate === ""
variables: { ? null
input: { : formData.publicationDate,
contentJson: JSON.stringify(formData.content), seo: {
isPublished: formData.isPublished, description: formData.seoDescription,
publicationDate: formData.isPublished title: formData.seoTitle
? null },
: formData.publicationDate === "" slug: formData.slug === "" ? null : formData.slug,
? null title: formData.title
: formData.publicationDate,
seo: {
description: formData.seoDescription,
title: formData.seoTitle
},
slug: formData.slug === "" ? null : formData.slug,
title: formData.title
}
} }
}) }
} })
/> }
</> />
); </>
}} )}
</TypedPageCreate> </TypedPageCreate>
); );
}; };

View file

@ -6,7 +6,7 @@ import ActionDialog from "@saleor/components/ActionDialog";
import { WindowTitle } from "@saleor/components/WindowTitle"; import { WindowTitle } from "@saleor/components/WindowTitle";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import { PageInput } from "../../types/globalTypes"; import { PageInput } from "../../types/globalTypes";
import PageDetailsPage, { FormData } from "../components/PageDetailsPage"; import PageDetailsPage, { FormData } from "../components/PageDetailsPage";
import { TypedPageRemove, TypedPageUpdate } from "../mutations"; import { TypedPageRemove, TypedPageUpdate } from "../mutations";
@ -56,79 +56,63 @@ export const PageDetails: React.FC<PageDetailsProps> = ({ id, params }) => {
<TypedPageUpdate> <TypedPageUpdate>
{(pageUpdate, pageUpdateOpts) => ( {(pageUpdate, pageUpdateOpts) => (
<TypedPageDetailsQuery variables={{ id }}> <TypedPageDetailsQuery variables={{ id }}>
{pageDetails => { {pageDetails => (
const formTransitionState = getMutationState( <>
pageUpdateOpts.called, <WindowTitle
pageUpdateOpts.loading, title={maybe(() => pageDetails.data.page.title)}
maybe(() => pageUpdateOpts.data.pageUpdate.errors) />
); <PageDetailsPage
const removeTransitionState = getMutationState( disabled={pageDetails.loading}
pageRemoveOpts.called, errors={maybe(
pageRemoveOpts.loading, () => pageUpdateOpts.data.pageUpdate.errors,
maybe(() => pageRemoveOpts.data.pageDelete.errors) []
); )}
saveButtonBarState={pageUpdateOpts.state}
return ( page={maybe(() => pageDetails.data.page)}
<> onBack={() => navigate(pageListUrl())}
<WindowTitle onRemove={() =>
title={maybe(() => pageDetails.data.page.title)} navigate(
/> pageUrl(id, {
<PageDetailsPage action: "remove"
disabled={pageDetails.loading}
errors={maybe(
() => pageUpdateOpts.data.pageUpdate.errors,
[]
)}
saveButtonBarState={formTransitionState}
page={maybe(() => pageDetails.data.page)}
onBack={() => navigate(pageListUrl())}
onRemove={() =>
navigate(
pageUrl(id, {
action: "remove"
})
)
}
onSubmit={formData =>
pageUpdate({
variables: {
id,
input: createPageInput(formData)
}
}) })
} )
/> }
<ActionDialog onSubmit={formData =>
open={params.action === "remove"} pageUpdate({
confirmButtonState={removeTransitionState} variables: {
title={intl.formatMessage({ id,
defaultMessage: "Delete Page", input: createPageInput(formData)
description: "dialog header" }
})} })
onClose={() => navigate(pageUrl(id))} }
onConfirm={pageRemove} />
variant="delete" <ActionDialog
> open={params.action === "remove"}
<DialogContentText> confirmButtonState={pageRemoveOpts.state}
<FormattedMessage title={intl.formatMessage({
defaultMessage="Are you sure you want to delete {title}?" defaultMessage: "Delete Page",
description="delete page" description: "dialog header"
values={{ })}
title: ( onClose={() => navigate(pageUrl(id))}
<strong> onConfirm={pageRemove}
{maybe( variant="delete"
() => pageDetails.data.page.title, >
"..." <DialogContentText>
)} <FormattedMessage
</strong> defaultMessage="Are you sure you want to delete {title}?"
) description="delete page"
}} values={{
/> title: (
</DialogContentText> <strong>
</ActionDialog> {maybe(() => pageDetails.data.page.title, "...")}
</> </strong>
); )
}} }}
/>
</DialogContentText>
</ActionDialog>
</>
)}
</TypedPageDetailsQuery> </TypedPageDetailsQuery>
)} )}
</TypedPageUpdate> </TypedPageUpdate>

View file

@ -14,7 +14,7 @@ import useNotifier from "@saleor/hooks/useNotifier";
import usePaginator, { import usePaginator, {
createPaginationState createPaginationState
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import PageListPage from "../components/PageListPage/PageListPage"; import PageListPage from "../components/PageListPage/PageListPage";
import { TypedPageBulkPublish, TypedPageBulkRemove } from "../mutations"; import { TypedPageBulkPublish, TypedPageBulkRemove } from "../mutations";
@ -107,160 +107,142 @@ export const PageList: React.FC<PageListProps> = ({ params }) => {
<TypedPageBulkRemove onCompleted={handlePageBulkRemove}> <TypedPageBulkRemove onCompleted={handlePageBulkRemove}>
{(bulkPageRemove, bulkPageRemoveOpts) => ( {(bulkPageRemove, bulkPageRemoveOpts) => (
<TypedPageBulkPublish onCompleted={handlePageBulkPublish}> <TypedPageBulkPublish onCompleted={handlePageBulkPublish}>
{(bulkPagePublish, bulkPagePublishOpts) => { {(bulkPagePublish, bulkPagePublishOpts) => (
const deleteTransitionState = getMutationState( <>
bulkPageRemoveOpts.called, <PageListPage
bulkPageRemoveOpts.loading, disabled={loading}
maybe(() => bulkPageRemoveOpts.data.pageBulkDelete.errors) settings={settings}
); pages={maybe(() =>
data.pages.edges.map(edge => edge.node)
const publishTransitionState = getMutationState( )}
bulkPagePublishOpts.called, pageInfo={pageInfo}
bulkPagePublishOpts.loading, onAdd={() => navigate(pageCreateUrl)}
maybe(() => bulkPagePublishOpts.data.pageBulkPublish.errors) onBack={() => navigate(configurationMenuUrl)}
); onNextPage={loadNextPage}
onPreviousPage={loadPreviousPage}
return ( onUpdateListSettings={updateListSettings}
<> onRowClick={id => () => navigate(pageUrl(id))}
<PageListPage toolbar={
disabled={loading} <>
settings={settings} <Button
pages={maybe(() => color="primary"
data.pages.edges.map(edge => edge.node) onClick={() => openModal("unpublish", listElements)}
)} >
pageInfo={pageInfo} <FormattedMessage
onAdd={() => navigate(pageCreateUrl)} defaultMessage="Unpublish"
onBack={() => navigate(configurationMenuUrl)} description="unpublish page, button"
onNextPage={loadNextPage} />
onPreviousPage={loadPreviousPage} </Button>
onUpdateListSettings={updateListSettings} <Button
onRowClick={id => () => navigate(pageUrl(id))} color="primary"
toolbar={ onClick={() => openModal("publish", listElements)}
<> >
<Button <FormattedMessage
color="primary" defaultMessage="Publish"
onClick={() => description="publish page, button"
openModal("unpublish", listElements) />
} </Button>
> <IconButton
<FormattedMessage color="primary"
defaultMessage="Unpublish" onClick={() => openModal("remove", listElements)}
description="unpublish page, button" >
/> <DeleteIcon />
</Button> </IconButton>
<Button </>
color="primary" }
onClick={() => openModal("publish", listElements)} isChecked={isSelected}
> selected={listElements.length}
<FormattedMessage toggle={toggle}
defaultMessage="Publish" toggleAll={toggleAll}
description="publish page, button" />
/> <ActionDialog
</Button> open={params.action === "publish"}
<IconButton onClose={closeModal}
color="primary" confirmButtonState={bulkPagePublishOpts.state}
onClick={() => openModal("remove", listElements)} onConfirm={() =>
> bulkPagePublish({
<DeleteIcon /> variables: {
</IconButton> ids: params.ids,
</> isPublished: true
} }
isChecked={isSelected} })
selected={listElements.length} }
toggle={toggle} title={intl.formatMessage({
toggleAll={toggleAll} defaultMessage: "Publish Pages",
description: "dialog header"
})}
>
<DialogContentText>
<FormattedMessage
defaultMessage="Are you sure you want to publish {counter,plural,one{this page} other{{displayQuantity} pages}}?"
description="dialog content"
values={{
counter: maybe(() => params.ids.length),
displayQuantity: (
<strong>{maybe(() => params.ids.length)}</strong>
)
}}
/>
</DialogContentText>
</ActionDialog>
<ActionDialog
open={params.action === "unpublish"}
onClose={closeModal}
confirmButtonState={bulkPagePublishOpts.state}
onConfirm={() =>
bulkPagePublish({
variables: {
ids: params.ids,
isPublished: false
}
})
}
title={intl.formatMessage({
defaultMessage: "Unpublish Pages",
description: "dialog header"
})}
>
<FormattedMessage
defaultMessage="Are you sure you want to unpublish {counter,plural,one{this page} other{{displayQuantity} pages}}?"
description="dialog content"
values={{
counter: maybe(() => params.ids.length),
displayQuantity: (
<strong>{maybe(() => params.ids.length)}</strong>
)
}}
/> />
<ActionDialog </ActionDialog>
open={params.action === "publish"} <ActionDialog
onClose={closeModal} open={params.action === "remove"}
confirmButtonState={publishTransitionState} onClose={closeModal}
onConfirm={() => confirmButtonState={bulkPageRemoveOpts.state}
bulkPagePublish({ onConfirm={() =>
variables: { bulkPageRemove({
ids: params.ids, variables: {
isPublished: true ids: params.ids
} }
}) })
} }
title={intl.formatMessage({ variant="delete"
defaultMessage: "Publish Pages", title={intl.formatMessage({
description: "dialog header" defaultMessage: "Delete Pages",
})} description: "dialog header"
> })}
<DialogContentText> >
<FormattedMessage <FormattedMessage
defaultMessage="Are you sure you want to publish {counter,plural,one{this page} other{{displayQuantity} pages}}?" defaultMessage="Are you sure you want to delete {counter,plural,one{this page} other{{displayQuantity} pages}}?"
description="dialog content" description="dialog content"
values={{ values={{
counter: maybe(() => params.ids.length), counter: maybe(() => params.ids.length),
displayQuantity: ( displayQuantity: (
<strong> <strong>{maybe(() => params.ids.length)}</strong>
{maybe(() => params.ids.length)} )
</strong> }}
) />
}} </ActionDialog>
/> </>
</DialogContentText> )}
</ActionDialog>
<ActionDialog
open={params.action === "unpublish"}
onClose={closeModal}
confirmButtonState={publishTransitionState}
onConfirm={() =>
bulkPagePublish({
variables: {
ids: params.ids,
isPublished: false
}
})
}
title={intl.formatMessage({
defaultMessage: "Unpublish Pages",
description: "dialog header"
})}
>
<FormattedMessage
defaultMessage="Are you sure you want to unpublish {counter,plural,one{this page} other{{displayQuantity} pages}}?"
description="dialog content"
values={{
counter: maybe(() => params.ids.length),
displayQuantity: (
<strong>{maybe(() => params.ids.length)}</strong>
)
}}
/>
</ActionDialog>
<ActionDialog
open={params.action === "remove"}
onClose={closeModal}
confirmButtonState={deleteTransitionState}
onConfirm={() =>
bulkPageRemove({
variables: {
ids: params.ids
}
})
}
variant="delete"
title={intl.formatMessage({
defaultMessage: "Delete Pages",
description: "dialog header"
})}
>
<FormattedMessage
defaultMessage="Are you sure you want to delete {counter,plural,one{this page} other{{displayQuantity} pages}}?"
description="dialog content"
values={{
counter: maybe(() => params.ids.length),
displayQuantity: (
<strong>{maybe(() => params.ids.length)}</strong>
)
}}
/>
</ActionDialog>
</>
);
}}
</TypedPageBulkPublish> </TypedPageBulkPublish>
)} )}
</TypedPageBulkRemove> </TypedPageBulkRemove>

View file

@ -8,7 +8,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { ConfigurationItemInput } from "@saleor/types/globalTypes"; import { ConfigurationItemInput } from "@saleor/types/globalTypes";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import PluginsDetailsPage from "../components/PluginsDetailsPage"; import PluginsDetailsPage from "../components/PluginsDetailsPage";
import PluginSecretFieldDialog from "../components/PluginSecretFieldDialog"; import PluginSecretFieldDialog from "../components/PluginSecretFieldDialog";
import { TypedPluginUpdate } from "../mutations"; import { TypedPluginUpdate } from "../mutations";
@ -85,12 +85,6 @@ export const PluginsDetails: React.FC<PluginsDetailsProps> = ({
{pluginDetails => ( {pluginDetails => (
<TypedPluginUpdate onCompleted={handleUpdate}> <TypedPluginUpdate onCompleted={handleUpdate}>
{(pluginUpdate, pluginUpdateOpts) => { {(pluginUpdate, pluginUpdateOpts) => {
const formTransitionState = getMutationState(
pluginUpdateOpts.called,
pluginUpdateOpts.loading,
maybe(() => pluginUpdateOpts.data.pluginUpdate.errors)
);
const formErrors = maybe( const formErrors = maybe(
() => pluginUpdateOpts.data.pluginUpdate.errors, () => pluginUpdateOpts.data.pluginUpdate.errors,
[] []
@ -120,7 +114,7 @@ export const PluginsDetails: React.FC<PluginsDetailsProps> = ({
disabled={pluginDetails.loading} disabled={pluginDetails.loading}
errors={formErrors} errors={formErrors}
saveButtonBarState={ saveButtonBarState={
!params.action ? formTransitionState : "default" !params.action ? pluginUpdateOpts.state : "default"
} }
plugin={maybe(() => pluginDetails.data.plugin)} plugin={maybe(() => pluginDetails.data.plugin)}
onBack={() => navigate(pluginsListUrl())} onBack={() => navigate(pluginsListUrl())}
@ -145,7 +139,7 @@ export const PluginsDetails: React.FC<PluginsDetailsProps> = ({
<> <>
<ActionDialog <ActionDialog
confirmButtonState={ confirmButtonState={
!!params.action ? formTransitionState : "default" !!params.action ? pluginUpdateOpts.state : "default"
} }
onClose={closeModal} onClose={closeModal}
open={params.action === "clear" && !!params.field} open={params.action === "clear" && !!params.field}
@ -161,7 +155,7 @@ export const PluginsDetails: React.FC<PluginsDetailsProps> = ({
</ActionDialog> </ActionDialog>
<PluginSecretFieldDialog <PluginSecretFieldDialog
confirmButtonState={ confirmButtonState={
!!params.action ? formTransitionState : "default" !!params.action ? pluginUpdateOpts.state : "default"
} }
field={maybe(() => field={maybe(() =>
pluginDetails.data.plugin.configuration.find( pluginDetails.data.plugin.configuration.find(

View file

@ -4,7 +4,7 @@ import { useIntl } from "react-intl";
import { WindowTitle } from "@saleor/components/WindowTitle"; import { WindowTitle } from "@saleor/components/WindowTitle";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import ProductTypeCreatePage, { import ProductTypeCreatePage, {
ProductTypeForm ProductTypeForm
} from "../components/ProductTypeCreatePage"; } from "../components/ProductTypeCreatePage";
@ -30,11 +30,7 @@ export const ProductTypeCreate: React.FC = () => {
}; };
return ( return (
<TypedProductTypeCreateMutation onCompleted={handleCreateSuccess}> <TypedProductTypeCreateMutation onCompleted={handleCreateSuccess}>
{( {(createProductType, createProductTypeOpts) => {
createProductType,
{ called, loading, data: createProductTypeData }
) => {
const formTransitionState = getMutationState(loading, called);
const handleCreate = (formData: ProductTypeForm) => const handleCreate = (formData: ProductTypeForm) =>
createProductType({ createProductType({
variables: { variables: {
@ -61,17 +57,16 @@ export const ProductTypeCreate: React.FC = () => {
<ProductTypeCreatePage <ProductTypeCreatePage
defaultWeightUnit={maybe(() => data.shop.defaultWeightUnit)} defaultWeightUnit={maybe(() => data.shop.defaultWeightUnit)}
disabled={loading} disabled={loading}
errors={ errors={maybe(
createProductTypeData () => createProductTypeOpts.data.productTypeCreate.errors,
? createProductTypeData.productTypeCreate.errors []
: undefined )}
}
pageTitle={intl.formatMessage({ pageTitle={intl.formatMessage({
defaultMessage: "Create Product Type", defaultMessage: "Create Product Type",
description: "header", description: "header",
id: "productTypeCreatePageHeader" id: "productTypeCreatePageHeader"
})} })}
saveButtonBarState={formTransitionState} saveButtonBarState={createProductTypeOpts.state}
taxTypes={maybe(() => data.taxTypes, [])} taxTypes={maybe(() => data.taxTypes, [])}
onBack={() => navigate(productTypeListUrl())} onBack={() => navigate(productTypeListUrl())}
onSubmit={handleCreate} onSubmit={handleCreate}

View file

@ -19,7 +19,7 @@ import usePaginator, {
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import { configurationMenuUrl } from "../../../configuration"; import { configurationMenuUrl } from "../../../configuration";
import { getMutationState, maybe } from "../../../misc"; import { maybe } from "../../../misc";
import ProductTypeListPage from "../../components/ProductTypeListPage"; import ProductTypeListPage from "../../components/ProductTypeListPage";
import { TypedProductTypeBulkDeleteMutation } from "../../mutations"; import { TypedProductTypeBulkDeleteMutation } from "../../mutations";
import { TypedProductTypeListQuery } from "../../queries"; import { TypedProductTypeListQuery } from "../../queries";
@ -155,15 +155,6 @@ export const ProductTypeList: React.FC<ProductTypeListProps> = ({ params }) => {
onCompleted={handleProductTypeBulkDelete} onCompleted={handleProductTypeBulkDelete}
> >
{(productTypeBulkDelete, productTypeBulkDeleteOpts) => { {(productTypeBulkDelete, productTypeBulkDeleteOpts) => {
const bulkRemoveTransitionState = getMutationState(
productTypeBulkDeleteOpts.called,
productTypeBulkDeleteOpts.loading,
maybe(
() =>
productTypeBulkDeleteOpts.data.productTypeBulkDelete.errors
)
);
const onProductTypeBulkDelete = () => const onProductTypeBulkDelete = () =>
productTypeBulkDelete({ productTypeBulkDelete({
variables: { variables: {
@ -212,7 +203,7 @@ export const ProductTypeList: React.FC<ProductTypeListProps> = ({ params }) => {
} }
/> />
<ActionDialog <ActionDialog
confirmButtonState={bulkRemoveTransitionState} confirmButtonState={productTypeBulkDeleteOpts.state}
onClose={closeModal} onClose={closeModal}
onConfirm={onProductTypeBulkDelete} onConfirm={onProductTypeBulkDelete}
open={params.action === "remove"} open={params.action === "remove"}

View file

@ -9,7 +9,7 @@ import useBulkActions from "@saleor/hooks/useBulkActions";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import AssignAttributeDialog from "@saleor/productTypes/components/AssignAttributeDialog"; import AssignAttributeDialog from "@saleor/productTypes/components/AssignAttributeDialog";
import { ReorderEvent } from "@saleor/types"; import { ReorderEvent } from "@saleor/types";
import { AttributeTypeEnum } from "@saleor/types/globalTypes"; import { AttributeTypeEnum } from "@saleor/types/globalTypes";
@ -190,38 +190,6 @@ export const ProductTypeUpdate: React.FC<ProductTypeUpdateProps> = ({
const loading = updateProductType.opts.loading || dataLoading; const loading = updateProductType.opts.loading || dataLoading;
const assignTransactionState = getMutationState(
assignAttribute.opts.called,
assignAttribute.opts.loading,
maybe(
() => assignAttribute.opts.data.attributeAssign.errors
)
);
const unassignTransactionState = getMutationState(
unassignAttribute.opts.called,
unassignAttribute.opts.loading,
maybe(
() => unassignAttribute.opts.data.attributeUnassign.errors
)
);
const deleteTransactionState = getMutationState(
deleteProductType.opts.called,
deleteProductType.opts.loading,
maybe(
() => deleteProductType.opts.data.productTypeDelete.errors
)
);
const formTransitionState = getMutationState(
updateProductType.opts.called,
updateProductType.opts.loading,
maybe(
() => updateProductType.opts.data.productTypeUpdate.errors
)
);
const handleAttributeReorder = ( const handleAttributeReorder = (
event: ReorderEvent, event: ReorderEvent,
type: AttributeTypeEnum type: AttributeTypeEnum
@ -252,7 +220,7 @@ export const ProductTypeUpdate: React.FC<ProductTypeUpdateProps> = ({
errors={errors.formErrors} errors={errors.formErrors}
pageTitle={maybe(() => data.productType.name)} pageTitle={maybe(() => data.productType.name)}
productType={maybe(() => data.productType)} productType={maybe(() => data.productType)}
saveButtonBarState={formTransitionState} saveButtonBarState={updateProductType.opts.state}
taxTypes={maybe(() => data.taxTypes, [])} taxTypes={maybe(() => data.taxTypes, [])}
onAttributeAdd={type => onAttributeAdd={type =>
navigate( navigate(
@ -345,7 +313,7 @@ export const ProductTypeUpdate: React.FC<ProductTypeUpdateProps> = ({
edge => edge.node edge => edge.node
) )
)} )}
confirmButtonState={assignTransactionState} confirmButtonState={assignAttribute.opts.state}
errors={maybe( errors={maybe(
() => () =>
assignAttribute.opts.data.attributeAssign.errors.map( assignAttribute.opts.data.attributeAssign.errors.map(
@ -387,7 +355,7 @@ export const ProductTypeUpdate: React.FC<ProductTypeUpdateProps> = ({
/> />
))} ))}
<ProductTypeDeleteDialog <ProductTypeDeleteDialog
confirmButtonState={deleteTransactionState} confirmButtonState={deleteProductType.opts.state}
name={maybe(() => data.productType.name, "...")} name={maybe(() => data.productType.name, "...")}
open={params.action === "remove"} open={params.action === "remove"}
onClose={() => navigate(productTypeUrl(id))} onClose={() => navigate(productTypeUrl(id))}
@ -395,7 +363,7 @@ export const ProductTypeUpdate: React.FC<ProductTypeUpdateProps> = ({
/> />
<ProductTypeBulkAttributeUnassignDialog <ProductTypeBulkAttributeUnassignDialog
attributeQuantity={maybe(() => params.ids.length)} attributeQuantity={maybe(() => params.ids.length)}
confirmButtonState={unassignTransactionState} confirmButtonState={unassignAttribute.opts.state}
onClose={closeModal} onClose={closeModal}
onConfirm={handleBulkAttributeUnassign} onConfirm={handleBulkAttributeUnassign}
open={params.action === "unassign-attributes"} open={params.action === "unassign-attributes"}
@ -414,7 +382,7 @@ export const ProductTypeUpdate: React.FC<ProductTypeUpdateProps> = ({
.name, .name,
"..." "..."
)} )}
confirmButtonState={unassignTransactionState} confirmButtonState={unassignAttribute.opts.state}
onClose={closeModal} onClose={closeModal}
onConfirm={handleAttributeUnassign} onConfirm={handleAttributeUnassign}
open={params.action === "unassign-attribute"} open={params.action === "unassign-attribute"}

View file

@ -9,7 +9,7 @@ import useShop from "@saleor/hooks/useShop";
import useCategorySearch from "@saleor/searches/useCategorySearch"; import useCategorySearch from "@saleor/searches/useCategorySearch";
import useCollectionSearch from "@saleor/searches/useCollectionSearch"; import useCollectionSearch from "@saleor/searches/useCollectionSearch";
import useProductTypeSearch from "@saleor/searches/useProductTypeSearch"; import useProductTypeSearch from "@saleor/searches/useProductTypeSearch";
import { decimal, getMutationState, maybe } from "../../misc"; import { decimal, maybe } from "../../misc";
import ProductCreatePage, { import ProductCreatePage, {
ProductCreatePageSubmitData ProductCreatePageSubmitData
} from "../components/ProductCreatePage"; } from "../components/ProductCreatePage";
@ -70,14 +70,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = () => {
return ( return (
<TypedProductCreateMutation onCompleted={handleSuccess}> <TypedProductCreateMutation onCompleted={handleSuccess}>
{( {(productCreate, productCreateOpts) => {
productCreate,
{
called: productCreateCalled,
data: productCreateData,
loading: productCreateDataLoading
}
) => {
const handleSubmit = (formData: ProductCreatePageSubmitData) => { const handleSubmit = (formData: ProductCreatePageSubmitData) => {
productCreate({ productCreate({
variables: { variables: {
@ -108,11 +101,6 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = () => {
}); });
}; };
const formTransitionState = getMutationState(
productCreateCalled,
productCreateDataLoading,
maybe(() => productCreateData.productCreate.errors)
);
return ( return (
<> <>
<WindowTitle <WindowTitle
@ -131,8 +119,11 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = () => {
() => searchCollectionOpts.data.search.edges, () => searchCollectionOpts.data.search.edges,
[] []
).map(edge => edge.node)} ).map(edge => edge.node)}
disabled={productCreateDataLoading} disabled={productCreateOpts.loading}
errors={maybe(() => productCreateData.productCreate.errors, [])} errors={maybe(
() => productCreateOpts.data.productCreate.errors,
[]
)}
fetchCategories={searchCategory} fetchCategories={searchCategory}
fetchCollections={searchCollection} fetchCollections={searchCollection}
fetchProductTypes={searchProductTypes} fetchProductTypes={searchProductTypes}
@ -145,7 +136,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = () => {
)} )}
onBack={handleBack} onBack={handleBack}
onSubmit={handleSubmit} onSubmit={handleSubmit}
saveButtonBarState={formTransitionState} saveButtonBarState={productCreateOpts.state}
fetchMoreCategories={{ fetchMoreCategories={{
hasMore: maybe( hasMore: maybe(
() => searchCategoryOpts.data.search.pageInfo.hasNextPage () => searchCategoryOpts.data.search.pageInfo.hasNextPage

View file

@ -5,7 +5,7 @@ import { FormattedMessage, useIntl } from "react-intl";
import ActionDialog from "@saleor/components/ActionDialog"; import ActionDialog from "@saleor/components/ActionDialog";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import ProductImagePage from "../components/ProductImagePage"; import ProductImagePage from "../components/ProductImagePage";
import { import {
TypedProductImageDeleteMutation, TypedProductImageDeleteMutation,
@ -68,16 +68,6 @@ export const ProductImage: React.FC<ProductImageProps> = ({
}; };
const image = data && data.product && data.product.mainImage; const image = data && data.product && data.product.mainImage;
const formTransitionState = getMutationState(
updateResult.called,
updateResult.loading,
maybe(() => updateResult.data.productImageUpdate.errors)
);
const deleteTransitionState = getMutationState(
deleteResult.called,
deleteResult.loading,
[]
);
return ( return (
<> <>
<ProductImagePage <ProductImagePage
@ -95,7 +85,7 @@ export const ProductImage: React.FC<ProductImageProps> = ({
} }
onRowClick={handleImageClick} onRowClick={handleImageClick}
onSubmit={handleUpdate} onSubmit={handleUpdate}
saveButtonBarState={formTransitionState} saveButtonBarState={updateResult.state}
/> />
<ActionDialog <ActionDialog
onClose={() => onClose={() =>
@ -108,7 +98,7 @@ export const ProductImage: React.FC<ProductImageProps> = ({
description: "dialog header" description: "dialog header"
})} })}
variant="delete" variant="delete"
confirmButtonState={deleteTransitionState} confirmButtonState={deleteResult.state}
> >
<DialogContentText> <DialogContentText>
<FormattedMessage defaultMessage="Are you sure you want to delete this image?" /> <FormattedMessage defaultMessage="Are you sure you want to delete this image?" />

View file

@ -21,7 +21,7 @@ import usePaginator, {
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ProductListVariables } from "@saleor/products/types/ProductList"; import { ProductListVariables } from "@saleor/products/types/ProductList";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import { getSortUrlVariables } from "@saleor/utils/sort"; import { getSortUrlVariables } from "@saleor/utils/sort";
@ -216,281 +216,256 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
<TypedProductBulkPublishMutation <TypedProductBulkPublishMutation
onCompleted={handleBulkPublish} onCompleted={handleBulkPublish}
> >
{(productBulkPublish, productBulkPublishOpts) => { {(productBulkPublish, productBulkPublishOpts) => (
const bulkDeleteMutationState = getMutationState( <>
productBulkDeleteOpts.called, <ProductListPage
productBulkDeleteOpts.loading, activeAttributeSortId={params.attributeId}
maybe( sort={{
() => asc: params.asc,
productBulkDeleteOpts.data.productBulkDelete.errors sort: params.sort
) }}
); onSort={handleSort}
availableInGridAttributes={maybe(
const bulkPublishMutationState = getMutationState( () =>
productBulkPublishOpts.called, attributes.data.availableInGrid.edges.map(
productBulkPublishOpts.loading, edge => edge.node
maybe( ),
() => []
productBulkPublishOpts.data.productBulkPublish )}
.errors currencySymbol={currencySymbol}
) currentTab={currentTab}
); defaultSettings={
defaultListSettings[ListViews.PRODUCT_LIST]
return ( }
<> gridAttributes={maybe(
<ProductListPage () =>
activeAttributeSortId={params.attributeId} attributes.data.grid.edges.map(edge => edge.node),
sort={{ []
asc: params.asc, )}
sort: params.sort totalGridAttributes={maybe(
}} () => attributes.data.availableInGrid.totalCount,
onSort={handleSort} 0
availableInGridAttributes={maybe( )}
() => settings={settings}
attributes.data.availableInGrid.edges.map( loading={attributes.loading}
edge => edge.node hasMore={maybe(
), () =>
[] attributes.data.availableInGrid.pageInfo
)} .hasNextPage,
currencySymbol={currencySymbol} false
currentTab={currentTab} )}
defaultSettings={ filtersList={createFilterChips(
defaultListSettings[ListViews.PRODUCT_LIST] params,
} {
gridAttributes={maybe( currencySymbol,
() => locale
attributes.data.grid.edges.map( },
edge => edge.node changeFilterField,
), intl
[] )}
)} onAdd={() => navigate(productAddUrl)}
totalGridAttributes={maybe( disabled={loading}
() => attributes.data.availableInGrid.totalCount, products={maybe(() =>
0 data.products.edges.map(edge => edge.node)
)} )}
settings={settings} onFetchMore={() =>
loading={attributes.loading} attributes.loadMore(
hasMore={maybe( (prev, next) => {
() => if (
attributes.data.availableInGrid.pageInfo prev.availableInGrid.pageInfo.endCursor ===
.hasNextPage, next.availableInGrid.pageInfo.endCursor
false ) {
)} return prev;
filtersList={createFilterChips( }
params, return {
{ ...prev,
currencySymbol, availableInGrid: {
locale ...prev.availableInGrid,
edges: [
...prev.availableInGrid.edges,
...next.availableInGrid.edges
],
pageInfo: next.availableInGrid.pageInfo
}
};
}, },
changeFilterField, {
intl after:
)} attributes.data.availableInGrid.pageInfo
onAdd={() => navigate(productAddUrl)} .endCursor
disabled={loading} }
products={maybe(() => )
data.products.edges.map(edge => edge.node) }
)} onNextPage={loadNextPage}
onFetchMore={() => onPreviousPage={loadPreviousPage}
attributes.loadMore( onUpdateListSettings={updateListSettings}
(prev, next) => { pageInfo={pageInfo}
if ( onRowClick={id => () => navigate(productUrl(id))}
prev.availableInGrid.pageInfo.endCursor === onAll={() =>
next.availableInGrid.pageInfo.endCursor changeFilters({
) { status: undefined
return prev; })
} }
return { toolbar={
...prev, <>
availableInGrid: { <Button
...prev.availableInGrid, color="primary"
edges: [ onClick={() =>
...prev.availableInGrid.edges, openModal("unpublish", listElements)
...next.availableInGrid.edges
],
pageInfo: next.availableInGrid.pageInfo
}
};
},
{
after:
attributes.data.availableInGrid.pageInfo
.endCursor
} }
) >
} <FormattedMessage
onNextPage={loadNextPage} defaultMessage="Unpublish"
onPreviousPage={loadPreviousPage} description="unpublish product, button"
onUpdateListSettings={updateListSettings} />
pageInfo={pageInfo} </Button>
onRowClick={id => () => navigate(productUrl(id))} <Button
onAll={() => color="primary"
changeFilters({ onClick={() =>
status: undefined openModal("publish", listElements)
})
}
toolbar={
<>
<Button
color="primary"
onClick={() =>
openModal("unpublish", listElements)
}
>
<FormattedMessage
defaultMessage="Unpublish"
description="unpublish product, button"
/>
</Button>
<Button
color="primary"
onClick={() =>
openModal("publish", listElements)
}
>
<FormattedMessage
defaultMessage="Publish"
description="publish product, button"
/>
</Button>
<IconButton
color="primary"
onClick={() =>
openModal("delete", listElements)
}
>
<DeleteIcon />
</IconButton>
</>
}
isChecked={isSelected}
selected={listElements.length}
toggle={toggle}
toggleAll={toggleAll}
onSearchChange={query =>
changeFilterField({ query })
}
onFilterAdd={filter =>
changeFilterField(createFilter(filter))
}
onTabSave={() => openModal("save-search")}
onTabDelete={() => openModal("delete-search")}
onTabChange={handleTabChange}
initialSearch={params.query || ""}
tabs={getFilterTabs().map(tab => tab.name)}
/>
<ActionDialog
open={params.action === "delete"}
confirmButtonState={bulkDeleteMutationState}
onClose={closeModal}
onConfirm={() =>
productBulkDelete({
variables: { ids: params.ids }
})
}
title={intl.formatMessage({
defaultMessage: "Delete Products",
description: "dialog header"
})}
variant="delete"
>
<DialogContentText>
<FormattedMessage
defaultMessage="Are you sure you want to delete {counter,plural,one{this product} other{{displayQuantity} products}}?"
description="dialog content"
values={{
counter: maybe(() => params.ids.length),
displayQuantity: (
<strong>
{maybe(() => params.ids.length)}
</strong>
)
}}
/>
</DialogContentText>
</ActionDialog>
<ActionDialog
open={params.action === "publish"}
confirmButtonState={bulkPublishMutationState}
onClose={closeModal}
onConfirm={() =>
productBulkPublish({
variables: {
ids: params.ids,
isPublished: true
} }
}) >
} <FormattedMessage
title={intl.formatMessage({ defaultMessage="Publish"
defaultMessage: "Publish Products", description="publish product, button"
description: "dialog header" />
})} </Button>
> <IconButton
<DialogContentText> color="primary"
<FormattedMessage onClick={() =>
defaultMessage="Are you sure you want to publish {counter,plural,one{this product} other{{displayQuantity} products}}?" openModal("delete", listElements)
description="dialog content"
values={{
counter: maybe(() => params.ids.length),
displayQuantity: (
<strong>
{maybe(() => params.ids.length)}
</strong>
)
}}
/>
</DialogContentText>
</ActionDialog>
<ActionDialog
open={params.action === "unpublish"}
confirmButtonState={bulkPublishMutationState}
onClose={closeModal}
onConfirm={() =>
productBulkPublish({
variables: {
ids: params.ids,
isPublished: false
} }
}) >
} <DeleteIcon />
title={intl.formatMessage({ </IconButton>
defaultMessage: "Unpublish Products", </>
description: "dialog header" }
})} isChecked={isSelected}
> selected={listElements.length}
<DialogContentText> toggle={toggle}
<FormattedMessage toggleAll={toggleAll}
defaultMessage="Are you sure you want to unpublish {counter,plural,one{this product} other{{displayQuantity} products}}?" onSearchChange={query => changeFilterField({ query })}
description="dialog content" onFilterAdd={filter =>
values={{ changeFilterField(createFilter(filter))
counter: maybe(() => params.ids.length), }
displayQuantity: ( onTabSave={() => openModal("save-search")}
<strong> onTabDelete={() => openModal("delete-search")}
{maybe(() => params.ids.length)} onTabChange={handleTabChange}
</strong> initialSearch={params.query || ""}
) tabs={getFilterTabs().map(tab => tab.name)}
}} />
/> <ActionDialog
</DialogContentText> open={params.action === "delete"}
</ActionDialog> confirmButtonState={productBulkDeleteOpts.state}
<SaveFilterTabDialog onClose={closeModal}
open={params.action === "save-search"} onConfirm={() =>
confirmButtonState="default" productBulkDelete({
onClose={closeModal} variables: { ids: params.ids }
onSubmit={handleFilterTabSave} })
/> }
<DeleteFilterTabDialog title={intl.formatMessage({
open={params.action === "delete-search"} defaultMessage: "Delete Products",
confirmButtonState="default" description: "dialog header"
onClose={closeModal} })}
onSubmit={handleFilterTabDelete} variant="delete"
tabName={maybe( >
() => tabs[currentTab - 1].name, <DialogContentText>
"..." <FormattedMessage
)} defaultMessage="Are you sure you want to delete {counter,plural,one{this product} other{{displayQuantity} products}}?"
/> description="dialog content"
</> values={{
); counter: maybe(() => params.ids.length),
}} displayQuantity: (
<strong>
{maybe(() => params.ids.length)}
</strong>
)
}}
/>
</DialogContentText>
</ActionDialog>
<ActionDialog
open={params.action === "publish"}
confirmButtonState={productBulkPublishOpts.state}
onClose={closeModal}
onConfirm={() =>
productBulkPublish({
variables: {
ids: params.ids,
isPublished: true
}
})
}
title={intl.formatMessage({
defaultMessage: "Publish Products",
description: "dialog header"
})}
>
<DialogContentText>
<FormattedMessage
defaultMessage="Are you sure you want to publish {counter,plural,one{this product} other{{displayQuantity} products}}?"
description="dialog content"
values={{
counter: maybe(() => params.ids.length),
displayQuantity: (
<strong>
{maybe(() => params.ids.length)}
</strong>
)
}}
/>
</DialogContentText>
</ActionDialog>
<ActionDialog
open={params.action === "unpublish"}
confirmButtonState={productBulkPublishOpts.state}
onClose={closeModal}
onConfirm={() =>
productBulkPublish({
variables: {
ids: params.ids,
isPublished: false
}
})
}
title={intl.formatMessage({
defaultMessage: "Unpublish Products",
description: "dialog header"
})}
>
<DialogContentText>
<FormattedMessage
defaultMessage="Are you sure you want to unpublish {counter,plural,one{this product} other{{displayQuantity} products}}?"
description="dialog content"
values={{
counter: maybe(() => params.ids.length),
displayQuantity: (
<strong>
{maybe(() => params.ids.length)}
</strong>
)
}}
/>
</DialogContentText>
</ActionDialog>
<SaveFilterTabDialog
open={params.action === "save-search"}
confirmButtonState="default"
onClose={closeModal}
onSubmit={handleFilterTabSave}
/>
<DeleteFilterTabDialog
open={params.action === "delete-search"}
confirmButtonState="default"
onClose={closeModal}
onSubmit={handleFilterTabDelete}
tabName={maybe(
() => tabs[currentTab - 1].name,
"..."
)}
/>
</>
)}
</TypedProductBulkPublishMutation> </TypedProductBulkPublishMutation>
)} )}
</TypedProductBulkDeleteMutation> </TypedProductBulkDeleteMutation>

View file

@ -206,21 +206,6 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
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)
);
const bulkProductVariantDeleteTransitionState = getMutationState(
bulkProductVariantDelete.opts.called,
bulkProductVariantDelete.opts.loading,
maybe(
() =>
bulkProductVariantDelete.opts.data.productVariantBulkDelete
.errors
)
);
const categories = maybe( const categories = maybe(
() => searchCategoriesOpts.data.search.edges, () => searchCategoriesOpts.data.search.edges,
@ -308,7 +293,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
<ActionDialog <ActionDialog
open={params.action === "remove"} open={params.action === "remove"}
onClose={() => navigate(productUrl(id), true)} onClose={() => navigate(productUrl(id), true)}
confirmButtonState={deleteTransitionState} confirmButtonState={deleteProduct.opts.state}
onConfirm={() => deleteProduct.mutate({ id })} onConfirm={() => deleteProduct.mutate({ id })}
variant="delete" variant="delete"
title={intl.formatMessage({ title={intl.formatMessage({
@ -329,7 +314,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
<ActionDialog <ActionDialog
open={params.action === "remove-variants"} open={params.action === "remove-variants"}
onClose={() => navigate(productUrl(id), true)} onClose={() => navigate(productUrl(id), true)}
confirmButtonState={bulkProductVariantDeleteTransitionState} confirmButtonState={bulkProductVariantDelete.opts.state}
onConfirm={() => onConfirm={() =>
bulkProductVariantDelete.mutate({ bulkProductVariantDelete.mutate({
ids: params.ids ids: params.ids

View file

@ -6,7 +6,7 @@ import { WindowTitle } from "@saleor/components/WindowTitle";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { decimal, getMutationState, maybe } from "../../misc"; import { decimal, maybe } from "../../misc";
import ProductVariantDeleteDialog from "../components/ProductVariantDeleteDialog"; import ProductVariantDeleteDialog from "../components/ProductVariantDeleteDialog";
import ProductVariantPage, { import ProductVariantPage, {
ProductVariantPageSubmitData ProductVariantPageSubmitData
@ -77,19 +77,7 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
updateVariant.opts.loading || updateVariant.opts.loading ||
assignImage.opts.loading || assignImage.opts.loading ||
unassignImage.opts.loading; unassignImage.opts.loading;
const formTransitionState = getMutationState(
updateVariant.opts.called,
updateVariant.opts.loading,
maybe(
() =>
updateVariant.opts.data.productVariantUpdate.productErrors
)
);
const removeTransitionState = getMutationState(
deleteVariant.opts.called,
deleteVariant.opts.loading,
maybe(() => deleteVariant.opts.data.productVariantDelete.errors)
);
const handleImageSelect = (id: string) => () => { const handleImageSelect = (id: string) => () => {
if (variant) { if (variant) {
if ( if (
@ -114,7 +102,7 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
<WindowTitle title={maybe(() => data.productVariant.name)} /> <WindowTitle title={maybe(() => data.productVariant.name)} />
<ProductVariantPage <ProductVariantPage
errors={errors} errors={errors}
saveButtonBarState={formTransitionState} saveButtonBarState={updateVariant.opts.state}
loading={disableFormSave} loading={disableFormSave}
placeholderImage={placeholderImg} placeholderImage={placeholderImg}
variant={variant} variant={variant}
@ -150,7 +138,7 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
}} }}
/> />
<ProductVariantDeleteDialog <ProductVariantDeleteDialog
confirmButtonState={removeTransitionState} confirmButtonState={deleteVariant.opts.state}
onClose={() => onClose={() =>
navigate(productVariantEditUrl(productId, variantId)) navigate(productVariantEditUrl(productId, variantId))
} }

View file

@ -5,7 +5,7 @@ import { WindowTitle } from "@saleor/components/WindowTitle";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { decimal, getMutationState, maybe } from "../../misc"; import { decimal, maybe } from "../../misc";
import ProductVariantCreatePage, { import ProductVariantCreatePage, {
ProductVariantCreatePageSubmitData ProductVariantCreatePageSubmitData
} from "../components/ProductVariantCreatePage"; } from "../components/ProductVariantCreatePage";
@ -77,14 +77,6 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({ productId }) => {
const disableForm = productLoading || variantCreateResult.loading; const disableForm = productLoading || variantCreateResult.loading;
const formTransitionstate = getMutationState(
variantCreateResult.called,
variantCreateResult.loading,
maybe(
() =>
variantCreateResult.data.productVariantCreate.productErrors
)
);
return ( return (
<> <>
<WindowTitle <WindowTitle
@ -110,7 +102,7 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({ productId }) => {
onBack={handleBack} onBack={handleBack}
onSubmit={handleSubmit} onSubmit={handleSubmit}
onVariantClick={handleVariantClick} onVariantClick={handleVariantClick}
saveButtonBarState={formTransitionstate} saveButtonBarState={variantCreateResult.state}
/> />
</> </>
); );

View file

@ -6,7 +6,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ServiceCreateMutation } from "@saleor/services/mutations"; import { ServiceCreateMutation } from "@saleor/services/mutations";
import { ServiceCreate as ServiceCreateData } from "@saleor/services/types/ServiceCreate"; import { ServiceCreate as ServiceCreateData } from "@saleor/services/types/ServiceCreate";
import ServiceCreatePage, { import ServiceCreatePage, {
@ -51,12 +51,6 @@ export const ServiceCreate: React.FC<ServiceCreateProps> = ({ setToken }) => {
} }
}); });
const formTransitionState = getMutationState(
serviceCreateOpts.called,
serviceCreateOpts.loading,
maybe(() => serviceCreateOpts.data.serviceAccountCreate.errors)
);
return ( return (
<> <>
<WindowTitle <WindowTitle
@ -74,7 +68,7 @@ export const ServiceCreate: React.FC<ServiceCreateProps> = ({ setToken }) => {
onBack={handleBack} onBack={handleBack}
onSubmit={handleSubmit} onSubmit={handleSubmit}
permissions={maybe(() => shop.permissions)} permissions={maybe(() => shop.permissions)}
saveButtonBarState={formTransitionState} saveButtonBarState={serviceCreateOpts.state}
/> />
</> </>
); );

View file

@ -7,7 +7,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import ServiceDeleteDialog from "@saleor/services/components/ServiceDeleteDialog"; import ServiceDeleteDialog from "@saleor/services/components/ServiceDeleteDialog";
import ServiceTokenCreateDialog from "@saleor/services/components/ServiceTokenCreateDialog"; import ServiceTokenCreateDialog from "@saleor/services/components/ServiceTokenCreateDialog";
import ServiceTokenDeleteDialog from "@saleor/services/components/ServiceTokenDeleteDialog"; import ServiceTokenDeleteDialog from "@saleor/services/components/ServiceTokenDeleteDialog";
@ -162,46 +162,6 @@ export const ServiceDetails: React.FC<OrderListProps> = ({
} }
}); });
const formTransitionState = getMutationState(
updateServiceOpts.called,
updateServiceOpts.loading,
maybe(
() =>
updateServiceOpts.data.serviceAccountUpdate
.errors
)
);
const deleteTransitionState = getMutationState(
deleteServiceOpts.called,
deleteServiceOpts.loading,
maybe(
() =>
deleteServiceOpts.data.serviceAccountDelete
.errors
)
);
const createTokenTransitionState = getMutationState(
createTokenOpts.called,
createTokenOpts.loading,
maybe(
() =>
createTokenOpts.data.serviceAccountTokenCreate
.errors
)
);
const deleteTokenTransitionState = getMutationState(
deleteTokenOpts.called,
deleteTokenOpts.loading,
maybe(
() =>
deleteTokenOpts.data.serviceAccountTokenDelete
.errors
)
);
return ( return (
<> <>
<WindowTitle <WindowTitle
@ -223,10 +183,10 @@ export const ServiceDetails: React.FC<OrderListProps> = ({
} }
permissions={maybe(() => shop.permissions)} permissions={maybe(() => shop.permissions)}
service={maybe(() => data.serviceAccount)} service={maybe(() => data.serviceAccount)}
saveButtonBarState={formTransitionState} saveButtonBarState={updateServiceOpts.state}
/> />
<ServiceDeleteDialog <ServiceDeleteDialog
confirmButtonState={deleteTransitionState} confirmButtonState={deleteServiceOpts.state}
name={maybe( name={maybe(
() => data.serviceAccount.name, () => data.serviceAccount.name,
"..." "..."
@ -236,7 +196,7 @@ export const ServiceDetails: React.FC<OrderListProps> = ({
open={params.action === "remove"} open={params.action === "remove"}
/> />
<ServiceTokenCreateDialog <ServiceTokenCreateDialog
confirmButtonState={createTokenTransitionState} confirmButtonState={createTokenOpts.state}
onClose={closeModal} onClose={closeModal}
onCreate={handleTokenCreate} onCreate={handleTokenCreate}
open={params.action === "create-token"} open={params.action === "create-token"}
@ -247,7 +207,7 @@ export const ServiceDetails: React.FC<OrderListProps> = ({
)} )}
/> />
<ServiceTokenDeleteDialog <ServiceTokenDeleteDialog
confirmButtonState={deleteTokenTransitionState} confirmButtonState={deleteTokenOpts.state}
name={maybe(() => { name={maybe(() => {
const token = data.serviceAccount.tokens.find( const token = data.serviceAccount.tokens.find(
token => token.id === params.id token => token.id === params.id

View file

@ -14,7 +14,7 @@ import SaveFilterTabDialog, {
} from "@saleor/components/SaveFilterTabDialog"; } from "@saleor/components/SaveFilterTabDialog";
import { configurationMenuUrl } from "@saleor/configuration"; import { configurationMenuUrl } from "@saleor/configuration";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ServiceDeleteMutation } from "@saleor/services/mutations"; import { ServiceDeleteMutation } from "@saleor/services/mutations";
import { ServiceDelete } from "@saleor/services/types/ServiceDelete"; import { ServiceDelete } from "@saleor/services/types/ServiceDelete";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
@ -154,12 +154,6 @@ export const ServiceList: React.FC<ServiceListProps> = ({ params }) => {
} }
}); });
const removeTransitionState = getMutationState(
deleteServiceOpts.called,
deleteServiceOpts.loading,
maybe(() => deleteServiceOpts.data.serviceAccountDelete.errors)
);
return ( return (
<> <>
<ServiceListPage <ServiceListPage
@ -186,7 +180,7 @@ export const ServiceList: React.FC<ServiceListProps> = ({ params }) => {
onRemove={handleRemove} onRemove={handleRemove}
/> />
<ServiceDeleteDialog <ServiceDeleteDialog
confirmButtonState={removeTransitionState} confirmButtonState={deleteServiceOpts.state}
name={maybe( name={maybe(
() => () =>
data.serviceAccounts.edges.find( data.serviceAccounts.edges.find(

View file

@ -5,7 +5,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import ShippingZoneCreatePage from "../components/ShippingZoneCreatePage"; import ShippingZoneCreatePage from "../components/ShippingZoneCreatePage";
import { TypedCreateShippingZone } from "../mutations"; import { TypedCreateShippingZone } from "../mutations";
import { CreateShippingZone } from "../types/CreateShippingZone"; import { CreateShippingZone } from "../types/CreateShippingZone";
@ -27,32 +27,24 @@ const ShippingZoneCreate: React.FC<{}> = () => {
}; };
return ( return (
<TypedCreateShippingZone onCompleted={onShippingZoneCreate}> <TypedCreateShippingZone onCompleted={onShippingZoneCreate}>
{(createShippingZone, createShippingZoneOpts) => { {(createShippingZone, createShippingZoneOpts) => (
const formTransitionState = getMutationState( <ShippingZoneCreatePage
createShippingZoneOpts.called, countries={maybe(() => shop.countries, [])}
createShippingZoneOpts.loading, disabled={createShippingZoneOpts.loading}
maybe(() => createShippingZoneOpts.data.shippingZoneCreate.errors, []) errors={maybe(
); () => createShippingZoneOpts.data.shippingZoneCreate.errors
)}
return ( onBack={() => navigate(shippingZonesListUrl())}
<ShippingZoneCreatePage onSubmit={formData =>
countries={maybe(() => shop.countries, [])} createShippingZone({
disabled={createShippingZoneOpts.loading} variables: {
errors={maybe( input: formData
() => createShippingZoneOpts.data.shippingZoneCreate.errors }
)} })
onBack={() => navigate(shippingZonesListUrl())} }
onSubmit={formData => saveButtonBarState={createShippingZoneOpts.state}
createShippingZone({ />
variables: { )}
input: formData
}
})
}
saveButtonBarState={formTransitionState}
/>
);
}}
</TypedCreateShippingZone> </TypedCreateShippingZone>
); );
}; };

View file

@ -4,7 +4,7 @@ import { useIntl } from "react-intl";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "../../../misc"; import { maybe } from "../../../misc";
import { ShippingMethodTypeEnum } from "../../../types/globalTypes"; import { ShippingMethodTypeEnum } from "../../../types/globalTypes";
import ShippingZoneDetailsPage from "../../components/ShippingZoneDetailsPage"; import ShippingZoneDetailsPage from "../../components/ShippingZoneDetailsPage";
import { TypedShippingZone } from "../../queries"; import { TypedShippingZone } from "../../queries";
@ -91,143 +91,104 @@ const ShippingZoneDetails: React.FC<ShippingZoneDetailsProps> = ({
> >
{ops => ( {ops => (
<TypedShippingZone variables={{ id }}> <TypedShippingZone variables={{ id }}>
{({ data, loading }) => { {({ data, loading }) => (
const formTransitionState = getMutationState( <>
ops.shippingZoneUpdate.opts.called, <ShippingZoneDetailsPage
ops.shippingZoneUpdate.opts.loading, disabled={loading}
maybe( errors={maybe(
() => ops.shippingZoneUpdate.opts.data.shippingZoneUpdate.errors () =>
) ops.shippingZoneUpdate.opts.data.shippingZoneUpdate.errors
); )}
const createRateTransitionState = getMutationState( onBack={() => navigate(shippingZonesListUrl())}
ops.shippingRateCreate.opts.called, onCountryAdd={() =>
ops.shippingRateCreate.opts.loading, navigate(
maybe( shippingZoneUrl(id, {
() => action: "assign-country"
ops.shippingRateCreate.opts.data.shippingPriceCreate.errors
)
);
const deleteRateTransitionState = getMutationState(
ops.shippingRateDelete.opts.called,
ops.shippingRateDelete.opts.loading,
maybe(
() =>
ops.shippingRateDelete.opts.data.shippingPriceDelete.errors
)
);
const updateRateTransitionState = getMutationState(
ops.shippingRateUpdate.opts.called,
ops.shippingRateUpdate.opts.loading,
maybe(
() =>
ops.shippingRateUpdate.opts.data.shippingPriceUpdate.errors
)
);
const deleteZoneTransitionState = getMutationState(
ops.shippingZoneDelete.opts.called,
ops.shippingZoneDelete.opts.loading,
maybe(
() => ops.shippingZoneDelete.opts.data.shippingZoneDelete.errors
)
);
return (
<>
<ShippingZoneDetailsPage
disabled={loading}
errors={maybe(
() =>
ops.shippingZoneUpdate.opts.data.shippingZoneUpdate.errors
)}
onBack={() => navigate(shippingZonesListUrl())}
onCountryAdd={() =>
navigate(
shippingZoneUrl(id, {
action: "assign-country"
})
)
}
onCountryRemove={code =>
navigate(
shippingZoneUrl(id, {
action: "unassign-country",
id: code
})
)
}
onDelete={() =>
navigate(
shippingZoneUrl(id, {
action: "remove"
})
)
}
onPriceRateAdd={() =>
navigate(
shippingZoneUrl(id, {
action: "add-rate",
type: ShippingMethodTypeEnum.PRICE
})
)
}
onPriceRateEdit={rateId =>
navigate(
shippingZoneUrl(id, {
action: "edit-rate",
id: rateId
})
)
}
onRateRemove={rateId =>
navigate(
shippingZoneUrl(id, {
action: "remove-rate",
id: rateId
})
)
}
onSubmit={formData =>
ops.shippingZoneUpdate.mutate({
id,
input: {
name: formData.name
}
}) })
} )
onWeightRateAdd={() => }
navigate( onCountryRemove={code =>
shippingZoneUrl(id, { navigate(
action: "add-rate", shippingZoneUrl(id, {
type: ShippingMethodTypeEnum.WEIGHT action: "unassign-country",
}) id: code
) })
} )
onWeightRateEdit={rateId => }
navigate( onDelete={() =>
shippingZoneUrl(id, { navigate(
action: "edit-rate", shippingZoneUrl(id, {
id: rateId action: "remove"
}) })
) )
} }
saveButtonBarState={formTransitionState} onPriceRateAdd={() =>
shippingZone={maybe(() => data.shippingZone)} navigate(
/> shippingZoneUrl(id, {
<ShippingZoneDetailsDialogs action: "add-rate",
assignCountryTransitionState={formTransitionState} type: ShippingMethodTypeEnum.PRICE
createRateTransitionState={createRateTransitionState} })
deleteRateTransitionState={deleteRateTransitionState} )
deleteZoneTransitionState={deleteZoneTransitionState} }
id={id} onPriceRateEdit={rateId =>
ops={ops} navigate(
params={params} shippingZoneUrl(id, {
shippingZone={maybe(() => data.shippingZone)} action: "edit-rate",
unassignCountryTransitionState={formTransitionState} id: rateId
updateRateTransitionState={updateRateTransitionState} })
/> )
</> }
); onRateRemove={rateId =>
}} navigate(
shippingZoneUrl(id, {
action: "remove-rate",
id: rateId
})
)
}
onSubmit={formData =>
ops.shippingZoneUpdate.mutate({
id,
input: {
name: formData.name
}
})
}
onWeightRateAdd={() =>
navigate(
shippingZoneUrl(id, {
action: "add-rate",
type: ShippingMethodTypeEnum.WEIGHT
})
)
}
onWeightRateEdit={rateId =>
navigate(
shippingZoneUrl(id, {
action: "edit-rate",
id: rateId
})
)
}
saveButtonBarState={ops.shippingZoneUpdate.opts.state}
shippingZone={maybe(() => data.shippingZone)}
/>
<ShippingZoneDetailsDialogs
assignCountryTransitionState={ops.shippingZoneUpdate.opts.state}
createRateTransitionState={ops.shippingRateCreate.opts.state}
deleteRateTransitionState={ops.shippingRateDelete.opts.state}
deleteZoneTransitionState={ops.shippingZoneDelete.opts.state}
id={id}
ops={ops}
params={params}
shippingZone={maybe(() => data.shippingZone)}
unassignCountryTransitionState={
ops.shippingZoneUpdate.opts.state
}
updateRateTransitionState={ops.shippingRateUpdate.opts.state}
/>
</>
)}
</TypedShippingZone> </TypedShippingZone>
)} )}
</ShippingZoneOperations> </ShippingZoneOperations>

View file

@ -16,7 +16,7 @@ import usePaginator, {
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import useUser from "@saleor/hooks/useUser"; import useUser from "@saleor/hooks/useUser";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import ShippingZonesListPage from "../components/ShippingZonesListPage"; import ShippingZonesListPage from "../components/ShippingZonesListPage";
import { import {
@ -111,26 +111,6 @@ export const ShippingZonesList: React.FC<ShippingZonesListProps> = ({
onCompleted={handleBulkDeleteShippingZone} onCompleted={handleBulkDeleteShippingZone}
> >
{(bulkDeleteShippingZone, bulkDeleteShippingZoneOpts) => { {(bulkDeleteShippingZone, bulkDeleteShippingZoneOpts) => {
const deleteTransitionState = getMutationState(
deleteShippingZoneOpts.called,
deleteShippingZoneOpts.loading,
maybe(
() =>
deleteShippingZoneOpts.data.shippingZoneDelete
.errors
)
);
const bulkDeleteTransitionState = getMutationState(
bulkDeleteShippingZoneOpts.called,
bulkDeleteShippingZoneOpts.loading,
maybe(
() =>
bulkDeleteShippingZoneOpts.data
.shippingZoneBulkDelete.errors
)
);
const { const {
loadNextPage, loadNextPage,
loadPreviousPage, loadPreviousPage,
@ -202,7 +182,7 @@ export const ShippingZonesList: React.FC<ShippingZonesListProps> = ({
<ActionDialog <ActionDialog
open={params.action === "remove"} open={params.action === "remove"}
confirmButtonState={deleteTransitionState} confirmButtonState={deleteShippingZoneOpts.state}
variant="delete" variant="delete"
title={intl.formatMessage({ title={intl.formatMessage({
defaultMessage: "Delete Shipping Zone", defaultMessage: "Delete Shipping Zone",
@ -236,7 +216,9 @@ export const ShippingZonesList: React.FC<ShippingZonesListProps> = ({
</ActionDialog> </ActionDialog>
<ActionDialog <ActionDialog
open={params.action === "remove-many"} open={params.action === "remove-many"}
confirmButtonState={bulkDeleteTransitionState} confirmButtonState={
bulkDeleteShippingZoneOpts.state
}
variant="delete" variant="delete"
title={intl.formatMessage({ title={intl.formatMessage({
defaultMessage: "Delete Shipping Zones", defaultMessage: "Delete Shipping Zones",

View file

@ -7,7 +7,7 @@ import { commonMessages, sectionNames } from "@saleor/intl";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { configurationMenuUrl } from "../../configuration"; import { configurationMenuUrl } from "../../configuration";
import { findInEnum, getMutationState, maybe } from "../../misc"; import { findInEnum, maybe } from "../../misc";
import { AuthorizationKeyType, CountryCode } from "../../types/globalTypes"; import { AuthorizationKeyType, CountryCode } from "../../types/globalTypes";
import SiteSettingsKeyDialog, { import SiteSettingsKeyDialog, {
SiteSettingsKeyDialogForm SiteSettingsKeyDialogForm
@ -166,24 +166,6 @@ export const SiteSettings: React.FC<SiteSettingsProps> = ({ params }) => {
}); });
}; };
const formTransitionState = getMutationState(
updateShopSettingsOpts.called,
updateShopSettingsOpts.loading,
[
...maybe(
() =>
updateShopSettingsOpts.data.shopDomainUpdate.errors,
[]
),
...maybe(
() =>
updateShopSettingsOpts.data.shopSettingsUpdate
.errors,
[]
)
]
);
return ( return (
<> <>
<WindowTitle <WindowTitle
@ -207,7 +189,7 @@ export const SiteSettings: React.FC<SiteSettingsProps> = ({ params }) => {
}) })
} }
onSubmit={handleUpdateShopSettings} onSubmit={handleUpdateShopSettings}
saveButtonBarState={formTransitionState} saveButtonBarState={updateShopSettingsOpts.state}
/> />
<SiteSettingsKeyDialog <SiteSettingsKeyDialog
errors={maybe( errors={maybe(

View file

@ -9,7 +9,7 @@ import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import useUser from "@saleor/hooks/useUser"; import useUser from "@saleor/hooks/useUser";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import StaffDetailsPage from "../components/StaffDetailsPage/StaffDetailsPage"; import StaffDetailsPage from "../components/StaffDetailsPage/StaffDetailsPage";
import { import {
TypedStaffAvatarDeleteMutation, TypedStaffAvatarDeleteMutation,
@ -63,12 +63,6 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
onCompleted: handleChangePassword onCompleted: handleChangePassword
}); });
const changePasswordTransitionState = getMutationState(
changePasswordOpts.called,
changePasswordOpts.loading,
maybe(() => changePasswordOpts.data.passwordChange.errors)
);
return ( return (
<TypedStaffMemberDetailsQuery <TypedStaffMemberDetailsQuery
displayLoader displayLoader
@ -122,24 +116,6 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
onCompleted={handleStaffMemberAvatarDelete} onCompleted={handleStaffMemberAvatarDelete}
> >
{(deleteStaffAvatar, deleteAvatarResult) => { {(deleteStaffAvatar, deleteAvatarResult) => {
const formTransitionState = getMutationState(
updateResult.called,
updateResult.loading,
maybe(() => updateResult.data.staffUpdate.errors)
);
const deleteTransitionState = getMutationState(
deleteResult.called,
deleteResult.loading,
maybe(() => deleteResult.data.staffDelete.errors)
);
const deleteAvatarTransitionState = getMutationState(
deleteAvatarResult.called,
deleteAvatarResult.loading,
maybe(
() =>
deleteAvatarResult.data.userAvatarDelete.errors
)
);
const isUserSameAsViewer = maybe( const isUserSameAsViewer = maybe(
() => user.user.id === data.user.id, () => user.user.id === data.user.id,
true true
@ -201,7 +177,7 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
} }
permissions={maybe(() => shop.permissions)} permissions={maybe(() => shop.permissions)}
staffMember={maybe(() => data.user)} staffMember={maybe(() => data.user)}
saveButtonBarState={formTransitionState} saveButtonBarState={updateResult.state}
/> />
<ActionDialog <ActionDialog
open={params.action === "remove"} open={params.action === "remove"}
@ -209,7 +185,7 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
defaultMessage: "delete Staff User", defaultMessage: "delete Staff User",
description: "dialog header" description: "dialog header"
})} })}
confirmButtonState={deleteTransitionState} confirmButtonState={deleteResult.state}
variant="delete" variant="delete"
onClose={closeModal} onClose={closeModal}
onConfirm={deleteStaffMember} onConfirm={deleteStaffMember}
@ -229,7 +205,7 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
defaultMessage: "Delete Staff User Avatar", defaultMessage: "Delete Staff User Avatar",
description: "dialog header" description: "dialog header"
})} })}
confirmButtonState={deleteAvatarTransitionState} confirmButtonState={deleteAvatarResult.state}
variant="delete" variant="delete"
onClose={closeModal} onClose={closeModal}
onConfirm={deleteStaffAvatar} onConfirm={deleteStaffAvatar}
@ -248,9 +224,7 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
</DialogContentText> </DialogContentText>
</ActionDialog> </ActionDialog>
<StaffPasswordResetDialog <StaffPasswordResetDialog
confirmButtonState={ confirmButtonState={changePasswordOpts.state}
changePasswordTransitionState
}
errors={maybe( errors={maybe(
() => () =>
changePasswordOpts.data.passwordChange changePasswordOpts.data.passwordChange

View file

@ -18,7 +18,7 @@ import { APP_MOUNT_URI } from "@saleor/config";
import { configurationMenuUrl } from "@saleor/configuration"; import { configurationMenuUrl } from "@saleor/configuration";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import StaffAddMemberDialog, { import StaffAddMemberDialog, {
FormData as AddStaffMemberForm FormData as AddStaffMemberForm
@ -158,11 +158,6 @@ export const StaffList: React.FC<StaffListProps> = ({ params }) => {
} }
} }
}); });
const addTransitionState = getMutationState(
addStaffMemberData.called,
addStaffMemberData.loading,
maybe(() => addStaffMemberData.data.staffCreate.errors)
);
const { loadNextPage, loadPreviousPage, pageInfo } = paginate( const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
maybe(() => data.staffUsers.pageInfo), maybe(() => data.staffUsers.pageInfo),
@ -201,7 +196,7 @@ export const StaffList: React.FC<StaffListProps> = ({ params }) => {
onRowClick={id => () => navigate(staffMemberDetailsUrl(id))} onRowClick={id => () => navigate(staffMemberDetailsUrl(id))}
/> />
<StaffAddMemberDialog <StaffAddMemberDialog
confirmButtonState={addTransitionState} confirmButtonState={addStaffMemberData.state}
errors={maybe( errors={maybe(
() => addStaffMemberData.data.staffCreate.errors, () => addStaffMemberData.data.staffCreate.errors,
[] []

View file

@ -5,7 +5,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { configurationMenuUrl } from "../../configuration"; import { configurationMenuUrl } from "../../configuration";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import CountryListPage from "../components/CountryListPage"; import CountryListPage from "../components/CountryListPage";
import { TypedFetchTaxes, TypedUpdateTaxSettings } from "../mutations"; import { TypedFetchTaxes, TypedUpdateTaxSettings } from "../mutations";
import { TypedCountryListQuery } from "../queries"; import { TypedCountryListQuery } from "../queries";
@ -42,47 +42,36 @@ export const CountryList: React.FC = () => {
<TypedFetchTaxes onCompleted={handleFetchTaxes}> <TypedFetchTaxes onCompleted={handleFetchTaxes}>
{(fetchTaxes, fetchTaxesOpts) => ( {(fetchTaxes, fetchTaxesOpts) => (
<TypedCountryListQuery displayLoader={true}> <TypedCountryListQuery displayLoader={true}>
{({ data, loading }) => { {({ data, loading }) => (
const updateTaxSettingsTransitionState = getMutationState( <CountryListPage
updateTaxSettingsOpts.called, disabled={
updateTaxSettingsOpts.loading, loading ||
maybe( fetchTaxesOpts.loading ||
() => updateTaxSettingsOpts.data.shopSettingsUpdate.errors updateTaxSettingsOpts.loading
) }
); onBack={() => navigate(configurationMenuUrl)}
onRowClick={code => navigate(countryTaxRatesUrl(code))}
return ( onSubmit={formData =>
<CountryListPage updateTaxSettings({
disabled={ variables: {
loading || input: {
fetchTaxesOpts.loading || chargeTaxesOnShipping: formData.chargeTaxesOnShipping,
updateTaxSettingsOpts.loading displayGrossPrices: formData.showGross,
} includeTaxesInPrices: formData.includeTax
onBack={() => navigate(configurationMenuUrl)}
onRowClick={code => navigate(countryTaxRatesUrl(code))}
onSubmit={formData =>
updateTaxSettings({
variables: {
input: {
chargeTaxesOnShipping:
formData.chargeTaxesOnShipping,
displayGrossPrices: formData.showGross,
includeTaxesInPrices: formData.includeTax
}
} }
}) }
} })
onTaxFetch={fetchTaxes} }
saveButtonBarState={updateTaxSettingsTransitionState} onTaxFetch={fetchTaxes}
shop={maybe(() => ({ saveButtonBarState={updateTaxSettingsOpts.state}
...data.shop, shop={maybe(() => ({
countries: data.shop.countries.filter( ...data.shop,
country => country.vat countries: data.shop.countries.filter(
) country => country.vat
}))} )
/> }))}
); />
}} )}
</TypedCountryListQuery> </TypedCountryListQuery>
)} )}
</TypedFetchTaxes> </TypedFetchTaxes>

View file

@ -6,7 +6,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import { LanguageCodeEnum, TranslationInput } from "../../types/globalTypes"; import { LanguageCodeEnum, TranslationInput } from "../../types/globalTypes";
import TranslationsCategoriesPage, { import TranslationsCategoriesPage, {
fieldNames fieldNames
@ -84,15 +84,6 @@ const TranslationsCategories: React.FC<TranslationsCategoriesProps> = ({
}); });
}; };
const saveButtonState = getMutationState(
updateTranslationsOpts.called,
updateTranslationsOpts.loading,
maybe(
() => updateTranslationsOpts.data.categoryTranslate.errors,
[]
)
);
return ( return (
<TranslationsCategoriesPage <TranslationsCategoriesPage
activeField={params.activeField} activeField={params.activeField}
@ -101,7 +92,7 @@ const TranslationsCategories: React.FC<TranslationsCategoriesProps> = ({
} }
languageCode={languageCode} languageCode={languageCode}
languages={maybe(() => shop.languages, [])} languages={maybe(() => shop.languages, [])}
saveButtonState={saveButtonState} saveButtonState={updateTranslationsOpts.state}
onBack={() => onBack={() =>
navigate( navigate(
languageEntitiesUrl(languageCode, { languageEntitiesUrl(languageCode, {

View file

@ -6,7 +6,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import { LanguageCodeEnum, TranslationInput } from "../../types/globalTypes"; import { LanguageCodeEnum, TranslationInput } from "../../types/globalTypes";
import TranslationsCollectionsPage, { import TranslationsCollectionsPage, {
fieldNames fieldNames
@ -86,15 +86,6 @@ const TranslationsCollections: React.FC<TranslationsCollectionsProps> = ({
}); });
}; };
const saveButtonState = getMutationState(
updateTranslationsOpts.called,
updateTranslationsOpts.loading,
maybe(
() => updateTranslationsOpts.data.collectionTranslate.errors,
[]
)
);
return ( return (
<TranslationsCollectionsPage <TranslationsCollectionsPage
activeField={params.activeField} activeField={params.activeField}
@ -104,7 +95,7 @@ const TranslationsCollections: React.FC<TranslationsCollectionsProps> = ({
} }
languageCode={languageCode} languageCode={languageCode}
languages={maybe(() => shop.languages, [])} languages={maybe(() => shop.languages, [])}
saveButtonState={saveButtonState} saveButtonState={updateTranslationsOpts.state}
onEdit={onEdit} onEdit={onEdit}
onDiscard={onDiscard} onDiscard={onDiscard}
onBack={() => onBack={() =>

View file

@ -6,7 +6,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import { import {
LanguageCodeEnum, LanguageCodeEnum,
PageTranslationInput PageTranslationInput
@ -87,12 +87,6 @@ const TranslationsPages: React.FC<TranslationsPagesProps> = ({
}); });
}; };
const saveButtonState = getMutationState(
updateTranslationsOpts.called,
updateTranslationsOpts.loading,
maybe(() => updateTranslationsOpts.data.pageTranslate.errors, [])
);
return ( return (
<TranslationsPagesPage <TranslationsPagesPage
activeField={params.activeField} activeField={params.activeField}
@ -101,7 +95,7 @@ const TranslationsPages: React.FC<TranslationsPagesProps> = ({
} }
languageCode={languageCode} languageCode={languageCode}
languages={maybe(() => shop.languages, [])} languages={maybe(() => shop.languages, [])}
saveButtonState={saveButtonState} saveButtonState={updateTranslationsOpts.state}
onBack={() => onBack={() =>
navigate( navigate(
languageEntitiesUrl(languageCode, { languageEntitiesUrl(languageCode, {

View file

@ -114,9 +114,9 @@ const TranslationsProductTypes: React.FC<TranslationsProductTypesProps> = ({
const saveButtonState = getMutationState( const saveButtonState = getMutationState(
updateAttributeTranslationsOpts.called || updateAttributeTranslationsOpts.called ||
updateAttributeTranslationsOpts.called, updateAttributeValueTranslationsOpts.called,
updateAttributeTranslationsOpts.loading || updateAttributeTranslationsOpts.loading ||
updateAttributeTranslationsOpts.loading, updateAttributeValueTranslationsOpts.loading,
maybe( maybe(
() => () =>
updateAttributeTranslationsOpts.data.attributeTranslate updateAttributeTranslationsOpts.data.attributeTranslate

View file

@ -6,7 +6,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import { LanguageCodeEnum, TranslationInput } from "../../types/globalTypes"; import { LanguageCodeEnum, TranslationInput } from "../../types/globalTypes";
import TranslationsProductsPage, { import TranslationsProductsPage, {
fieldNames fieldNames
@ -84,15 +84,6 @@ const TranslationsProducts: React.FC<TranslationsProductsProps> = ({
}); });
}; };
const saveButtonState = getMutationState(
updateTranslationsOpts.called,
updateTranslationsOpts.loading,
maybe(
() => updateTranslationsOpts.data.productTranslate.errors,
[]
)
);
return ( return (
<TranslationsProductsPage <TranslationsProductsPage
activeField={params.activeField} activeField={params.activeField}
@ -101,7 +92,7 @@ const TranslationsProducts: React.FC<TranslationsProductsProps> = ({
} }
languageCode={languageCode} languageCode={languageCode}
languages={maybe(() => shop.languages, [])} languages={maybe(() => shop.languages, [])}
saveButtonState={saveButtonState} saveButtonState={updateTranslationsOpts.state}
onBack={() => onBack={() =>
navigate( navigate(
languageEntitiesUrl(languageCode, { languageEntitiesUrl(languageCode, {

View file

@ -6,7 +6,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import { import {
LanguageCodeEnum, LanguageCodeEnum,
NameTranslationInput NameTranslationInput
@ -81,12 +81,6 @@ const TranslationsSales: React.FC<TranslationsSalesProps> = ({
}); });
}; };
const saveButtonState = getMutationState(
updateTranslationsOpts.called,
updateTranslationsOpts.loading,
maybe(() => updateTranslationsOpts.data.saleTranslate.errors, [])
);
return ( return (
<TranslationsSalesPage <TranslationsSalesPage
activeField={params.activeField} activeField={params.activeField}
@ -95,7 +89,7 @@ const TranslationsSales: React.FC<TranslationsSalesProps> = ({
} }
languages={maybe(() => shop.languages, [])} languages={maybe(() => shop.languages, [])}
languageCode={languageCode} languageCode={languageCode}
saveButtonState={saveButtonState} saveButtonState={updateTranslationsOpts.state}
onBack={() => onBack={() =>
navigate( navigate(
languageEntitiesUrl(languageCode, { languageEntitiesUrl(languageCode, {

View file

@ -6,7 +6,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import { import {
LanguageCodeEnum, LanguageCodeEnum,
NameTranslationInput NameTranslationInput
@ -81,15 +81,6 @@ const TranslationsVouchers: React.FC<TranslationsVouchersProps> = ({
}); });
}; };
const saveButtonState = getMutationState(
updateTranslationsOpts.called,
updateTranslationsOpts.loading,
maybe(
() => updateTranslationsOpts.data.voucherTranslate.errors,
[]
)
);
return ( return (
<TranslationsVouchersPage <TranslationsVouchersPage
activeField={params.activeField} activeField={params.activeField}
@ -98,7 +89,7 @@ const TranslationsVouchers: React.FC<TranslationsVouchersProps> = ({
} }
languages={maybe(() => shop.languages, [])} languages={maybe(() => shop.languages, [])}
languageCode={languageCode} languageCode={languageCode}
saveButtonState={saveButtonState} saveButtonState={updateTranslationsOpts.state}
onBack={() => onBack={() =>
navigate( navigate(
languageEntitiesUrl(languageCode, { languageEntitiesUrl(languageCode, {

View file

@ -8,7 +8,7 @@ import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
import { WebhookCreate as WebhookCreateData } from "@saleor/webhooks/types/WebhookCreate"; import { WebhookCreate as WebhookCreateData } from "@saleor/webhooks/types/WebhookCreate";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import WebhookCreatePage, { FormData } from "../components/WebhookCreatePage"; import WebhookCreatePage, { FormData } from "../components/WebhookCreatePage";
import { TypedWebhookCreate } from "../mutations"; import { TypedWebhookCreate } from "../mutations";
import { import {
@ -63,12 +63,6 @@ export const WebhooksCreate: React.FC<WebhooksCreateProps> = () => {
} }
}); });
const formTransitionState = getMutationState(
webhookCreateOpts.called,
webhookCreateOpts.loading,
maybe(() => webhookCreateOpts.data.webhookCreate.webhookErrors)
);
return ( return (
<> <>
<WindowTitle <WindowTitle
@ -89,7 +83,7 @@ export const WebhooksCreate: React.FC<WebhooksCreateProps> = () => {
)} )}
onBack={handleBack} onBack={handleBack}
onSubmit={handleSubmit} onSubmit={handleSubmit}
saveButtonBarState={formTransitionState} saveButtonBarState={webhookCreateOpts.state}
/> />
</> </>
); );

View file

@ -11,7 +11,7 @@ import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
import WebhookDeleteDialog from "@saleor/webhooks/components/WebhookDeleteDialog"; import WebhookDeleteDialog from "@saleor/webhooks/components/WebhookDeleteDialog";
import { WebhookDelete } from "@saleor/webhooks/types/WebhookDelete"; import { WebhookDelete } from "@saleor/webhooks/types/WebhookDelete";
import { WebhookUpdate } from "@saleor/webhooks/types/WebhookUpdate"; import { WebhookUpdate } from "@saleor/webhooks/types/WebhookUpdate";
import { getMutationState, maybe } from "../../misc"; import { maybe } from "../../misc";
import WebhooksDetailsPage from "../components/WebhooksDetailsPage"; import WebhooksDetailsPage from "../components/WebhooksDetailsPage";
import { TypedWebhookDelete, TypedWebhookUpdate } from "../mutations"; import { TypedWebhookDelete, TypedWebhookUpdate } from "../mutations";
import { TypedWebhooksDetailsQuery } from "../queries"; import { TypedWebhooksDetailsQuery } from "../queries";
@ -85,14 +85,6 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({
{(webhookDelete, webhookDeleteOpts) => ( {(webhookDelete, webhookDeleteOpts) => (
<TypedWebhooksDetailsQuery variables={{ id }}> <TypedWebhooksDetailsQuery variables={{ id }}>
{webhookDetails => { {webhookDetails => {
const formTransitionState = getMutationState(
webhookUpdateOpts.called,
webhookUpdateOpts.loading,
maybe(
() => webhookUpdateOpts.data.webhookUpdate.webhookErrors
)
);
const handleRemoveConfirm = () => const handleRemoveConfirm = () =>
webhookDelete({ webhookDelete({
variables: { variables: {
@ -105,12 +97,6 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({
[] []
); );
const deleteTransitionState = getMutationState(
webhookDeleteOpts.called,
webhookDeleteOpts.loading,
maybe(() => webhookDeleteOpts.data.webhookDelete.errors)
);
return ( return (
<> <>
<WindowTitle <WindowTitle
@ -119,7 +105,7 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({
<WebhooksDetailsPage <WebhooksDetailsPage
disabled={webhookDetails.loading} disabled={webhookDetails.loading}
errors={formErrors} errors={formErrors}
saveButtonBarState={formTransitionState} saveButtonBarState={webhookUpdateOpts.state}
webhook={maybe(() => webhookDetails.data.webhook)} webhook={maybe(() => webhookDetails.data.webhook)}
fetchServiceAccounts={searchServiceAccount} fetchServiceAccounts={searchServiceAccount}
services={maybe(() => services={maybe(() =>
@ -148,7 +134,7 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({
}} }}
/> />
<WebhookDeleteDialog <WebhookDeleteDialog
confirmButtonState={deleteTransitionState} confirmButtonState={webhookDeleteOpts.state}
name={maybe( name={maybe(
() => webhookDetails.data.webhook.name, () => webhookDetails.data.webhook.name,
"..." "..."

View file

@ -10,7 +10,7 @@ import usePaginator, {
createPaginationState createPaginationState
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import WebhookDeleteDialog from "@saleor/webhooks/components/WebhookDeleteDialog"; import WebhookDeleteDialog from "@saleor/webhooks/components/WebhookDeleteDialog";
import { WebhookDelete } from "@saleor/webhooks/types/WebhookDelete"; import { WebhookDelete } from "@saleor/webhooks/types/WebhookDelete";
@ -150,12 +150,6 @@ export const WebhooksList: React.FC<WebhooksListProps> = ({ params }) => {
}); });
}; };
const deleteTransitionState = getMutationState(
webhookDeleteOpts.called,
webhookDeleteOpts.loading,
maybe(() => webhookDeleteOpts.data.webhookDelete.errors)
);
return ( return (
<> <>
<WebhooksListPage <WebhooksListPage
@ -182,7 +176,7 @@ export const WebhooksList: React.FC<WebhooksListProps> = ({ params }) => {
onRowClick={id => () => navigate(webhooksUrl(id))} onRowClick={id => () => navigate(webhooksUrl(id))}
/> />
<WebhookDeleteDialog <WebhookDeleteDialog
confirmButtonState={deleteTransitionState} confirmButtonState={webhookDeleteOpts.state}
name={maybe( name={maybe(
() => () =>
data.webhooks.edges.find( data.webhooks.edges.find(