Use query hooks in product variant view
This commit is contained in:
parent
0fc4d1afb2
commit
419525f493
5 changed files with 243 additions and 325 deletions
|
@ -1,7 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { TypedMutationInnerProps } from "../../mutations";
|
import { TypedMutationInnerProps } from "../../mutations";
|
||||||
import { TypedProductImagesReorder } from "../mutations";
|
import { useProductImagesReorder } from "../mutations";
|
||||||
import {
|
import {
|
||||||
ProductImageReorder,
|
ProductImageReorder,
|
||||||
ProductImageReorderVariables
|
ProductImageReorderVariables
|
||||||
|
@ -24,10 +24,12 @@ const ProductImagesReorderProvider: React.FC<ProductImagesReorderProviderProps>
|
||||||
productId,
|
productId,
|
||||||
productImages,
|
productImages,
|
||||||
...mutationProps
|
...mutationProps
|
||||||
}) => (
|
}) => {
|
||||||
<TypedProductImagesReorder {...mutationProps}>
|
const [mutate, mutationResult] = useProductImagesReorder(mutationProps);
|
||||||
{(mutate, mutationResult) =>
|
|
||||||
children(opts => {
|
return (
|
||||||
|
<>
|
||||||
|
{children(opts => {
|
||||||
const productImagesMap = productImages.reduce((prev, curr) => {
|
const productImagesMap = productImages.reduce((prev, curr) => {
|
||||||
prev[curr.id] = curr;
|
prev[curr.id] = curr;
|
||||||
return prev;
|
return prev;
|
||||||
|
@ -52,9 +54,9 @@ const ProductImagesReorderProvider: React.FC<ProductImagesReorderProviderProps>
|
||||||
...opts,
|
...opts,
|
||||||
optimisticResponse
|
optimisticResponse
|
||||||
});
|
});
|
||||||
}, mutationResult)
|
}, mutationResult)}
|
||||||
}
|
</>
|
||||||
</TypedProductImagesReorder>
|
);
|
||||||
);
|
};
|
||||||
|
|
||||||
export default ProductImagesReorderProvider;
|
export default ProductImagesReorderProvider;
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
import { getMutationProviderData } from "../../misc";
|
|
||||||
import { PartialMutationProviderOutput } from "../../types";
|
|
||||||
import {
|
|
||||||
TypedVariantDeleteMutation,
|
|
||||||
TypedVariantImageAssignMutation,
|
|
||||||
TypedVariantImageUnassignMutation,
|
|
||||||
TypedVariantUpdateMutation
|
|
||||||
} from "../mutations";
|
|
||||||
import { VariantDelete, VariantDeleteVariables } from "../types/VariantDelete";
|
|
||||||
import {
|
|
||||||
VariantImageAssign,
|
|
||||||
VariantImageAssignVariables
|
|
||||||
} from "../types/VariantImageAssign";
|
|
||||||
import {
|
|
||||||
VariantImageUnassign,
|
|
||||||
VariantImageUnassignVariables
|
|
||||||
} from "../types/VariantImageUnassign";
|
|
||||||
import { VariantUpdate, VariantUpdateVariables } from "../types/VariantUpdate";
|
|
||||||
|
|
||||||
interface VariantDeleteOperationsProps {
|
|
||||||
children: (props: {
|
|
||||||
deleteVariant: PartialMutationProviderOutput<
|
|
||||||
VariantDelete,
|
|
||||||
VariantDeleteVariables
|
|
||||||
>;
|
|
||||||
updateVariant: PartialMutationProviderOutput<
|
|
||||||
VariantUpdate,
|
|
||||||
VariantUpdateVariables
|
|
||||||
>;
|
|
||||||
assignImage: PartialMutationProviderOutput<
|
|
||||||
VariantImageAssign,
|
|
||||||
VariantImageAssignVariables
|
|
||||||
>;
|
|
||||||
unassignImage: PartialMutationProviderOutput<
|
|
||||||
VariantImageUnassign,
|
|
||||||
VariantImageUnassignVariables
|
|
||||||
>;
|
|
||||||
}) => React.ReactNode;
|
|
||||||
onDelete?: (data: VariantDelete) => void;
|
|
||||||
onImageAssign?: (data: VariantImageAssign) => void;
|
|
||||||
onImageUnassign?: (data: VariantImageUnassign) => void;
|
|
||||||
onUpdate?: (data: VariantUpdate) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const VariantUpdateOperations: React.FC<VariantDeleteOperationsProps> = ({
|
|
||||||
children,
|
|
||||||
onDelete,
|
|
||||||
onUpdate,
|
|
||||||
onImageAssign,
|
|
||||||
onImageUnassign
|
|
||||||
}) => (
|
|
||||||
<TypedVariantImageAssignMutation onCompleted={onImageAssign}>
|
|
||||||
{(...assignImage) => (
|
|
||||||
<TypedVariantImageUnassignMutation onCompleted={onImageUnassign}>
|
|
||||||
{(...unassignImage) => (
|
|
||||||
<TypedVariantUpdateMutation onCompleted={onUpdate}>
|
|
||||||
{(...updateVariant) => (
|
|
||||||
<TypedVariantDeleteMutation onCompleted={onDelete}>
|
|
||||||
{(...deleteVariant) =>
|
|
||||||
children({
|
|
||||||
assignImage: getMutationProviderData(...assignImage),
|
|
||||||
deleteVariant: getMutationProviderData(...deleteVariant),
|
|
||||||
unassignImage: getMutationProviderData(...unassignImage),
|
|
||||||
updateVariant: getMutationProviderData(...updateVariant)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</TypedVariantDeleteMutation>
|
|
||||||
)}
|
|
||||||
</TypedVariantUpdateMutation>
|
|
||||||
)}
|
|
||||||
</TypedVariantImageUnassignMutation>
|
|
||||||
)}
|
|
||||||
</TypedVariantImageAssignMutation>
|
|
||||||
);
|
|
||||||
export default VariantUpdateOperations;
|
|
|
@ -10,7 +10,6 @@ import { warehouseFragment } from "@saleor/fragments/warehouses";
|
||||||
import makeQuery from "@saleor/hooks/makeQuery";
|
import makeQuery from "@saleor/hooks/makeQuery";
|
||||||
import gql from "graphql-tag";
|
import gql from "graphql-tag";
|
||||||
|
|
||||||
import { TypedQuery } from "../queries";
|
|
||||||
import { CountAllProducts } from "./types/CountAllProducts";
|
import { CountAllProducts } from "./types/CountAllProducts";
|
||||||
import {
|
import {
|
||||||
CreateMultipleVariantsData,
|
CreateMultipleVariantsData,
|
||||||
|
@ -186,7 +185,7 @@ const productVariantQuery = gql`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
export const TypedProductVariantQuery = TypedQuery<
|
export const useProductVariantQuery = makeQuery<
|
||||||
ProductVariantDetails,
|
ProductVariantDetails,
|
||||||
ProductVariantDetailsVariables
|
ProductVariantDetailsVariables
|
||||||
>(productVariantQuery);
|
>(productVariantQuery);
|
||||||
|
|
|
@ -14,8 +14,7 @@ import { decimal, maybe, weight } from "../../misc";
|
||||||
import ProductCreatePage, {
|
import ProductCreatePage, {
|
||||||
ProductCreatePageSubmitData
|
ProductCreatePageSubmitData
|
||||||
} from "../components/ProductCreatePage";
|
} from "../components/ProductCreatePage";
|
||||||
import { TypedProductCreateMutation } from "../mutations";
|
import { useProductCreateMutation } from "../mutations";
|
||||||
import { ProductCreate } from "../types/ProductCreate";
|
|
||||||
import { productListUrl, productUrl } from "../urls";
|
import { productListUrl, productUrl } from "../urls";
|
||||||
|
|
||||||
export const ProductCreateView: React.FC = () => {
|
export const ProductCreateView: React.FC = () => {
|
||||||
|
@ -53,118 +52,111 @@ export const ProductCreateView: React.FC = () => {
|
||||||
|
|
||||||
const handleBack = () => navigate(productListUrl());
|
const handleBack = () => navigate(productListUrl());
|
||||||
|
|
||||||
const handleSuccess = (data: ProductCreate) => {
|
const [productCreate, productCreateOpts] = useProductCreateMutation({
|
||||||
if (data.productCreate.errors.length === 0) {
|
onCompleted: data => {
|
||||||
notify({
|
if (data.productCreate.errors.length === 0) {
|
||||||
status: "success",
|
notify({
|
||||||
text: intl.formatMessage({
|
status: "success",
|
||||||
defaultMessage: "Product created"
|
text: intl.formatMessage({
|
||||||
})
|
defaultMessage: "Product created"
|
||||||
});
|
})
|
||||||
navigate(productUrl(data.productCreate.product.id));
|
});
|
||||||
|
navigate(productUrl(data.productCreate.product.id));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleSubmit = (formData: ProductCreatePageSubmitData) => {
|
||||||
|
productCreate({
|
||||||
|
variables: {
|
||||||
|
attributes: formData.attributes.map(attribute => ({
|
||||||
|
id: attribute.id,
|
||||||
|
values: attribute.value
|
||||||
|
})),
|
||||||
|
basePrice: decimal(formData.basePrice),
|
||||||
|
category: formData.category,
|
||||||
|
chargeTaxes: formData.chargeTaxes,
|
||||||
|
collections: formData.collections,
|
||||||
|
descriptionJson: JSON.stringify(formData.description),
|
||||||
|
isPublished: formData.isPublished,
|
||||||
|
name: formData.name,
|
||||||
|
productType: formData.productType,
|
||||||
|
publicationDate:
|
||||||
|
formData.publicationDate !== "" ? formData.publicationDate : null,
|
||||||
|
seo: {
|
||||||
|
description: formData.seoDescription,
|
||||||
|
title: formData.seoTitle
|
||||||
|
},
|
||||||
|
sku: formData.sku,
|
||||||
|
stocks: formData.stocks.map(stock => ({
|
||||||
|
quantity: parseInt(stock.value, 0),
|
||||||
|
warehouse: stock.id
|
||||||
|
})),
|
||||||
|
trackInventory: formData.trackInventory,
|
||||||
|
weight: weight(formData.weight)
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TypedProductCreateMutation onCompleted={handleSuccess}>
|
<>
|
||||||
{(productCreate, productCreateOpts) => {
|
<WindowTitle
|
||||||
const handleSubmit = (formData: ProductCreatePageSubmitData) => {
|
title={intl.formatMessage({
|
||||||
productCreate({
|
defaultMessage: "Create Product",
|
||||||
variables: {
|
description: "window title"
|
||||||
attributes: formData.attributes.map(attribute => ({
|
})}
|
||||||
id: attribute.id,
|
/>
|
||||||
values: attribute.value
|
<ProductCreatePage
|
||||||
})),
|
currency={maybe(() => shop.defaultCurrency)}
|
||||||
basePrice: decimal(formData.basePrice),
|
categories={maybe(() => searchCategoryOpts.data.search.edges, []).map(
|
||||||
category: formData.category,
|
edge => edge.node
|
||||||
chargeTaxes: formData.chargeTaxes,
|
)}
|
||||||
collections: formData.collections,
|
collections={maybe(
|
||||||
descriptionJson: JSON.stringify(formData.description),
|
() => searchCollectionOpts.data.search.edges,
|
||||||
isPublished: formData.isPublished,
|
[]
|
||||||
name: formData.name,
|
).map(edge => edge.node)}
|
||||||
productType: formData.productType,
|
disabled={productCreateOpts.loading}
|
||||||
publicationDate:
|
errors={productCreateOpts.data?.productCreate.errors || []}
|
||||||
formData.publicationDate !== ""
|
fetchCategories={searchCategory}
|
||||||
? formData.publicationDate
|
fetchCollections={searchCollection}
|
||||||
: null,
|
fetchProductTypes={searchProductTypes}
|
||||||
seo: {
|
header={intl.formatMessage({
|
||||||
description: formData.seoDescription,
|
defaultMessage: "New Product",
|
||||||
title: formData.seoTitle
|
description: "page header"
|
||||||
},
|
})}
|
||||||
sku: formData.sku,
|
productTypes={maybe(() =>
|
||||||
stocks: formData.stocks.map(stock => ({
|
searchProductTypesOpts.data.search.edges.map(edge => edge.node)
|
||||||
quantity: parseInt(stock.value, 0),
|
)}
|
||||||
warehouse: stock.id
|
onBack={handleBack}
|
||||||
})),
|
onSubmit={handleSubmit}
|
||||||
trackInventory: formData.trackInventory,
|
saveButtonBarState={productCreateOpts.status}
|
||||||
weight: weight(formData.weight)
|
fetchMoreCategories={{
|
||||||
}
|
hasMore: maybe(
|
||||||
});
|
() => searchCategoryOpts.data.search.pageInfo.hasNextPage
|
||||||
};
|
),
|
||||||
|
loading: searchCategoryOpts.loading,
|
||||||
return (
|
onFetchMore: loadMoreCategories
|
||||||
<>
|
}}
|
||||||
<WindowTitle
|
fetchMoreCollections={{
|
||||||
title={intl.formatMessage({
|
hasMore: maybe(
|
||||||
defaultMessage: "Create Product",
|
() => searchCollectionOpts.data.search.pageInfo.hasNextPage
|
||||||
description: "window title"
|
),
|
||||||
})}
|
loading: searchCollectionOpts.loading,
|
||||||
/>
|
onFetchMore: loadMoreCollections
|
||||||
<ProductCreatePage
|
}}
|
||||||
currency={maybe(() => shop.defaultCurrency)}
|
fetchMoreProductTypes={{
|
||||||
categories={maybe(
|
hasMore: maybe(
|
||||||
() => searchCategoryOpts.data.search.edges,
|
() => searchProductTypesOpts.data.search.pageInfo.hasNextPage
|
||||||
[]
|
),
|
||||||
).map(edge => edge.node)}
|
loading: searchProductTypesOpts.loading,
|
||||||
collections={maybe(
|
onFetchMore: loadMoreProductTypes
|
||||||
() => searchCollectionOpts.data.search.edges,
|
}}
|
||||||
[]
|
warehouses={
|
||||||
).map(edge => edge.node)}
|
warehouses.data?.warehouses.edges.map(edge => edge.node) || []
|
||||||
disabled={productCreateOpts.loading}
|
}
|
||||||
errors={productCreateOpts.data?.productCreate.errors || []}
|
weightUnit={shop?.defaultWeightUnit}
|
||||||
fetchCategories={searchCategory}
|
/>
|
||||||
fetchCollections={searchCollection}
|
</>
|
||||||
fetchProductTypes={searchProductTypes}
|
|
||||||
header={intl.formatMessage({
|
|
||||||
defaultMessage: "New Product",
|
|
||||||
description: "page header"
|
|
||||||
})}
|
|
||||||
productTypes={maybe(() =>
|
|
||||||
searchProductTypesOpts.data.search.edges.map(edge => edge.node)
|
|
||||||
)}
|
|
||||||
onBack={handleBack}
|
|
||||||
onSubmit={handleSubmit}
|
|
||||||
saveButtonBarState={productCreateOpts.status}
|
|
||||||
fetchMoreCategories={{
|
|
||||||
hasMore: maybe(
|
|
||||||
() => searchCategoryOpts.data.search.pageInfo.hasNextPage
|
|
||||||
),
|
|
||||||
loading: searchCategoryOpts.loading,
|
|
||||||
onFetchMore: loadMoreCategories
|
|
||||||
}}
|
|
||||||
fetchMoreCollections={{
|
|
||||||
hasMore: maybe(
|
|
||||||
() => searchCollectionOpts.data.search.pageInfo.hasNextPage
|
|
||||||
),
|
|
||||||
loading: searchCollectionOpts.loading,
|
|
||||||
onFetchMore: loadMoreCollections
|
|
||||||
}}
|
|
||||||
fetchMoreProductTypes={{
|
|
||||||
hasMore: maybe(
|
|
||||||
() => searchProductTypesOpts.data.search.pageInfo.hasNextPage
|
|
||||||
),
|
|
||||||
loading: searchProductTypesOpts.loading,
|
|
||||||
onFetchMore: loadMoreProductTypes
|
|
||||||
}}
|
|
||||||
warehouses={
|
|
||||||
warehouses.data?.warehouses.edges.map(edge => edge.node) || []
|
|
||||||
}
|
|
||||||
weightUnit={shop?.defaultWeightUnit}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</TypedProductCreateMutation>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default ProductCreateView;
|
export default ProductCreateView;
|
||||||
|
|
|
@ -15,12 +15,14 @@ import ProductVariantDeleteDialog from "../components/ProductVariantDeleteDialog
|
||||||
import ProductVariantPage, {
|
import ProductVariantPage, {
|
||||||
ProductVariantPageSubmitData
|
ProductVariantPageSubmitData
|
||||||
} from "../components/ProductVariantPage";
|
} from "../components/ProductVariantPage";
|
||||||
import ProductVariantOperations from "../containers/ProductVariantOperations";
|
|
||||||
import { TypedProductVariantQuery } from "../queries";
|
|
||||||
import {
|
import {
|
||||||
VariantUpdate,
|
useVariantDeleteMutation,
|
||||||
VariantUpdate_productVariantUpdate_errors
|
useVariantImageAssignMutation,
|
||||||
} from "../types/VariantUpdate";
|
useVariantImageUnassignMutation,
|
||||||
|
useVariantUpdateMutation
|
||||||
|
} from "../mutations";
|
||||||
|
import { useProductVariantQuery } from "../queries";
|
||||||
|
import { VariantUpdate_productVariantUpdate_errors } from "../types/VariantUpdate";
|
||||||
import {
|
import {
|
||||||
productUrl,
|
productUrl,
|
||||||
productVariantAddUrl,
|
productVariantAddUrl,
|
||||||
|
@ -59,6 +61,13 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { data, loading } = useProductVariantQuery({
|
||||||
|
displayLoader: true,
|
||||||
|
variables: {
|
||||||
|
id: variantId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const [openModal] = createDialogActionHandlers<
|
const [openModal] = createDialogActionHandlers<
|
||||||
ProductVariantEditUrlDialog,
|
ProductVariantEditUrlDialog,
|
||||||
ProductVariantEditUrlQueryParams
|
ProductVariantEditUrlQueryParams
|
||||||
|
@ -70,132 +79,125 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
|
||||||
|
|
||||||
const handleBack = () => navigate(productUrl(productId));
|
const handleBack = () => navigate(productUrl(productId));
|
||||||
|
|
||||||
return (
|
const [assignImage, assignImageOpts] = useVariantImageAssignMutation({});
|
||||||
<TypedProductVariantQuery displayLoader variables={{ id: variantId }}>
|
const [unassignImage, unassignImageOpts] = useVariantImageUnassignMutation(
|
||||||
{({ data, loading }) => {
|
{}
|
||||||
const variant = data?.productVariant;
|
);
|
||||||
|
const [deleteVariant, deleteVariantOpts] = useVariantDeleteMutation({
|
||||||
|
onCompleted: () => {
|
||||||
|
notify({
|
||||||
|
status: "success",
|
||||||
|
text: intl.formatMessage({
|
||||||
|
defaultMessage: "Variant removed"
|
||||||
|
})
|
||||||
|
});
|
||||||
|
navigate(productUrl(productId));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const [updateVariant, updateVariantOpts] = useVariantUpdateMutation({
|
||||||
|
onCompleted: data => {
|
||||||
|
if (data.productVariantUpdate.errors.length === 0) {
|
||||||
|
notify({
|
||||||
|
status: "success",
|
||||||
|
text: intl.formatMessage(commonMessages.savedChanges)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setErrors(data.productVariantUpdate.errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (variant === null) {
|
const variant = data?.productVariant;
|
||||||
return <NotFoundPage onBack={handleBack} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleDelete = () => {
|
if (variant === null) {
|
||||||
notify({
|
return <NotFoundPage onBack={handleBack} />;
|
||||||
status: "success",
|
}
|
||||||
text: intl.formatMessage({
|
|
||||||
defaultMessage: "Variant removed"
|
const disableFormSave =
|
||||||
})
|
loading ||
|
||||||
});
|
deleteVariantOpts.loading ||
|
||||||
navigate(productUrl(productId));
|
updateVariantOpts.loading ||
|
||||||
};
|
assignImageOpts.loading ||
|
||||||
const handleUpdate = (data: VariantUpdate) => {
|
unassignImageOpts.loading;
|
||||||
if (data.productVariantUpdate.errors.length === 0) {
|
|
||||||
notify({
|
const handleImageSelect = (id: string) => () => {
|
||||||
status: "success",
|
if (variant) {
|
||||||
text: intl.formatMessage(commonMessages.savedChanges)
|
if (
|
||||||
});
|
variant.images &&
|
||||||
} else {
|
variant.images.map(image => image.id).indexOf(id) !== -1
|
||||||
setErrors(data.productVariantUpdate.errors);
|
) {
|
||||||
|
unassignImage({
|
||||||
|
variables: {
|
||||||
|
imageId: id,
|
||||||
|
variantId: variant.id
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
} else {
|
||||||
|
assignImage({
|
||||||
|
variables: {
|
||||||
|
imageId: id,
|
||||||
|
variantId: variant.id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ProductVariantOperations
|
<>
|
||||||
onDelete={handleDelete}
|
<WindowTitle title={data?.productVariant?.name} />
|
||||||
onUpdate={handleUpdate}
|
<ProductVariantPage
|
||||||
>
|
defaultWeightUnit={shop?.defaultWeightUnit}
|
||||||
{({ assignImage, deleteVariant, updateVariant, unassignImage }) => {
|
errors={errors}
|
||||||
const disableFormSave =
|
saveButtonBarState={updateVariantOpts.status}
|
||||||
loading ||
|
loading={disableFormSave}
|
||||||
deleteVariant.opts.loading ||
|
placeholderImage={placeholderImg}
|
||||||
updateVariant.opts.loading ||
|
variant={variant}
|
||||||
assignImage.opts.loading ||
|
header={variant?.name || variant?.sku}
|
||||||
unassignImage.opts.loading;
|
warehouses={
|
||||||
|
warehouses.data?.warehouses.edges.map(edge => edge.node) || []
|
||||||
const handleImageSelect = (id: string) => () => {
|
}
|
||||||
if (variant) {
|
onAdd={() => navigate(productVariantAddUrl(productId))}
|
||||||
if (
|
onBack={handleBack}
|
||||||
variant.images &&
|
onDelete={() => openModal("remove")}
|
||||||
variant.images.map(image => image.id).indexOf(id) !== -1
|
onImageSelect={handleImageSelect}
|
||||||
) {
|
onSubmit={(data: ProductVariantPageSubmitData) =>
|
||||||
unassignImage.mutate({
|
updateVariant({
|
||||||
imageId: id,
|
variables: {
|
||||||
variantId: variant.id
|
addStocks: data.addStocks.map(mapFormsetStockToStockInput),
|
||||||
});
|
attributes: data.attributes.map(attribute => ({
|
||||||
} else {
|
id: attribute.id,
|
||||||
assignImage.mutate({
|
values: [attribute.value]
|
||||||
imageId: id,
|
})),
|
||||||
variantId: variant.id
|
costPrice: decimal(data.costPrice),
|
||||||
});
|
id: variantId,
|
||||||
}
|
price: decimal(data.price),
|
||||||
}
|
removeStocks: data.removeStocks,
|
||||||
};
|
sku: data.sku,
|
||||||
|
stocks: data.updateStocks.map(mapFormsetStockToStockInput),
|
||||||
return (
|
trackInventory: data.trackInventory,
|
||||||
<>
|
weight: weight(data.weight)
|
||||||
<WindowTitle title={data?.productVariant?.name} />
|
}
|
||||||
<ProductVariantPage
|
})
|
||||||
defaultWeightUnit={shop?.defaultWeightUnit}
|
}
|
||||||
errors={errors}
|
onVariantClick={variantId => {
|
||||||
saveButtonBarState={updateVariant.opts.status}
|
navigate(productVariantEditUrl(productId, variantId));
|
||||||
loading={disableFormSave}
|
}}
|
||||||
placeholderImage={placeholderImg}
|
/>
|
||||||
variant={variant}
|
<ProductVariantDeleteDialog
|
||||||
header={variant?.name || variant?.sku}
|
confirmButtonState={deleteVariantOpts.status}
|
||||||
warehouses={
|
onClose={() => navigate(productVariantEditUrl(productId, variantId))}
|
||||||
warehouses.data?.warehouses.edges.map(
|
onConfirm={() =>
|
||||||
edge => edge.node
|
deleteVariant({
|
||||||
) || []
|
variables: {
|
||||||
}
|
id: variantId
|
||||||
onAdd={() => navigate(productVariantAddUrl(productId))}
|
}
|
||||||
onBack={handleBack}
|
})
|
||||||
onDelete={() => openModal("remove")}
|
}
|
||||||
onImageSelect={handleImageSelect}
|
open={params.action === "remove"}
|
||||||
onSubmit={(data: ProductVariantPageSubmitData) =>
|
name={data?.productVariant?.name}
|
||||||
updateVariant.mutate({
|
/>
|
||||||
addStocks: data.addStocks.map(
|
</>
|
||||||
mapFormsetStockToStockInput
|
|
||||||
),
|
|
||||||
attributes: data.attributes.map(attribute => ({
|
|
||||||
id: attribute.id,
|
|
||||||
values: [attribute.value]
|
|
||||||
})),
|
|
||||||
costPrice: decimal(data.costPrice),
|
|
||||||
id: variantId,
|
|
||||||
price: decimal(data.price),
|
|
||||||
removeStocks: data.removeStocks,
|
|
||||||
sku: data.sku,
|
|
||||||
stocks: data.updateStocks.map(
|
|
||||||
mapFormsetStockToStockInput
|
|
||||||
),
|
|
||||||
trackInventory: data.trackInventory,
|
|
||||||
weight: weight(data.weight)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
onVariantClick={variantId => {
|
|
||||||
navigate(productVariantEditUrl(productId, variantId));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<ProductVariantDeleteDialog
|
|
||||||
confirmButtonState={deleteVariant.opts.status}
|
|
||||||
onClose={() =>
|
|
||||||
navigate(productVariantEditUrl(productId, variantId))
|
|
||||||
}
|
|
||||||
onConfirm={() =>
|
|
||||||
deleteVariant.mutate({
|
|
||||||
id: variantId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
open={params.action === "remove"}
|
|
||||||
name={data?.productVariant?.name}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</ProductVariantOperations>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</TypedProductVariantQuery>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default ProductVariant;
|
export default ProductVariant;
|
||||||
|
|
Loading…
Reference in a new issue