diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index 3721f20ef..640cd5f64 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -304,7 +304,7 @@ }, "productVariantCreatorWarehouseSectionDescription": { "context": "no warehouses info", - "string": "There are no warehouses set up for your store. You can configure your variants without providing stock quantites." + "string": "There are no warehouses set up for your store. You can configure variants without providing stock quantities." }, "productVariantCreatorWarehouseSectionHeader": { "context": "header", @@ -314,6 +314,22 @@ "context": "optional field", "string": "Optional" }, + "productVariantWarehouseSectionDescription": { + "context": "no warehouses info", + "string": "There are no warehouses set up for your store. To add stock quantity to the variant please" + }, + "productVariantWarehouseSectionDescriptionLink": { + "context": "no warehouses info", + "string": "configure a warehouse" + }, + "productWarehouseSectionDescription": { + "context": "no warehouses info", + "string": "There are no warehouses set up for your store. To add stock quantity to the product please" + }, + "productWarehouseSectionDescriptionLink": { + "context": "no warehouses info", + "string": "configure a warehouse" + }, "saleDetailsPageCategoriesQuantity": { "context": "number of categories", "string": "Categories ({quantity})" @@ -1577,6 +1593,10 @@ "context": "button", "string": "{languageName} - {languageCode}" }, + "src_dot_components_dot_LeaveScreenDialog_dot_3281163715": { + "context": "leaving screen warning message", + "string": "You're leaving this screen. Do you want to save previously made changes?" + }, "src_dot_components_dot_ListField_dot_3099331554": { "context": "button", "string": "Add" diff --git a/src/categories/views/CategoryDetails.tsx b/src/categories/views/CategoryDetails.tsx index cd52af91c..c24e11b89 100644 --- a/src/categories/views/CategoryDetails.tsx +++ b/src/categories/views/CategoryDetails.tsx @@ -211,7 +211,7 @@ export const CategoryDetails: React.FC = ({ disabled={loading} errors={updateResult.data?.categoryUpdate.errors || []} onAddCategory={() => navigate(categoryAddUrl(id))} - onAddProduct={() => navigate(productAddUrl)} + onAddProduct={() => navigate(productAddUrl())} onBack={() => navigate( maybe(() => categoryUrl(data.category.parent.id), categoryListUrl()) diff --git a/src/components/LeaveScreenDialog/LeaveScreenDialog.tsx b/src/components/LeaveScreenDialog/LeaveScreenDialog.tsx new file mode 100644 index 000000000..e15aba9f8 --- /dev/null +++ b/src/components/LeaveScreenDialog/LeaveScreenDialog.tsx @@ -0,0 +1,54 @@ +import Button from "@material-ui/core/Button"; +import Dialog from "@material-ui/core/Dialog"; +import DialogActions from "@material-ui/core/DialogActions"; +import DialogContent from "@material-ui/core/DialogContent"; +import { buttonMessages } from "@saleor/intl"; +import React from "react"; +import { FormattedMessage } from "react-intl"; + +import ConfirmButton, { ConfirmButtonTransitionState } from "../ConfirmButton"; +import Form from "../Form"; + +export interface LeaveScreenDialogProps { + confirmButtonState: ConfirmButtonTransitionState; + open: boolean; + onClose: () => void; + onSubmit: () => void; +} + +const LeaveScreenDialog: React.FC = ({ + confirmButtonState, + onClose, + onSubmit, + open +}) => ( + +
+ {({ submit }) => ( + <> + + + + + + + + + + + )} +
+
+); +LeaveScreenDialog.displayName = "LeaveScreenDialog"; +export default LeaveScreenDialog; diff --git a/src/components/LeaveScreenDialog/index.ts b/src/components/LeaveScreenDialog/index.ts new file mode 100644 index 000000000..c6bfa632e --- /dev/null +++ b/src/components/LeaveScreenDialog/index.ts @@ -0,0 +1,2 @@ +export { default } from "./LeaveScreenDialog"; +export * from "./LeaveScreenDialog"; diff --git a/src/components/Navigator/modes/commands/actions.ts b/src/components/Navigator/modes/commands/actions.ts index a10c60c5d..0e8fb31ca 100644 --- a/src/components/Navigator/modes/commands/actions.ts +++ b/src/components/Navigator/modes/commands/actions.ts @@ -46,7 +46,7 @@ export function searchInCommands( { label: intl.formatMessage(messages.createProduct), onClick: () => { - navigate(productAddUrl); + navigate(productAddUrl()); return false; } }, diff --git a/src/products/components/ProductCreatePage/ProductCreatePage.tsx b/src/products/components/ProductCreatePage/ProductCreatePage.tsx index 031abec20..b96d702fd 100644 --- a/src/products/components/ProductCreatePage/ProductCreatePage.tsx +++ b/src/products/components/ProductCreatePage/ProductCreatePage.tsx @@ -101,6 +101,7 @@ interface ProductCreatePageProps { fetchCategories: (data: string) => void; fetchCollections: (data: string) => void; fetchProductTypes: (data: string) => void; + onWarehouseConfigure: () => void; onBack?(); onSubmit?(data: ProductCreatePageSubmitData); } @@ -122,6 +123,7 @@ export const ProductCreatePage: React.FC = ({ warehouses, taxTypes, onBack, + onWarehouseConfigure, fetchProductTypes, weightUnit, onSubmit @@ -297,6 +299,7 @@ export const ProductCreatePage: React.FC = ({ = ({ triggerChange(); removeStock(id); }} + onWarehouseConfigure={onWarehouseConfigure} /> diff --git a/src/products/components/ProductStocks/ProductStocks.tsx b/src/products/components/ProductStocks/ProductStocks.tsx index 1f36f6601..cab8dfe8f 100644 --- a/src/products/components/ProductStocks/ProductStocks.tsx +++ b/src/products/components/ProductStocks/ProductStocks.tsx @@ -21,6 +21,7 @@ import CardTitle from "@saleor/components/CardTitle"; import ControlledCheckbox from "@saleor/components/ControlledCheckbox"; import FormSpacer from "@saleor/components/FormSpacer"; import Hr from "@saleor/components/Hr"; +import Link from "@saleor/components/Link"; import { ProductErrorFragment } from "@saleor/fragments/types/ProductErrorFragment"; import { WarehouseFragment } from "@saleor/fragments/types/WarehouseFragment"; import { FormChange } from "@saleor/hooks/useForm"; @@ -41,12 +42,14 @@ export interface ProductStocksProps { data: ProductStockFormData; disabled: boolean; errors: ProductErrorFragment[]; + hasVariants: boolean; stocks: ProductStockInput[]; warehouses: WarehouseFragment[]; onChange: FormsetChange; onFormDataChange: FormChange; onWarehouseStockAdd: (warehouseId: string) => void; onWarehouseStockDelete: (warehouseId: string) => void; + onWarehouseConfigure: () => void; } const useStyles = makeStyles( @@ -75,6 +78,9 @@ const useStyles = makeStyles( marginBottom: theme.spacing(2) } }, + noWarehouseInfo: { + marginTop: theme.spacing() + }, paper: { padding: theme.spacing(2) }, @@ -105,13 +111,15 @@ const useStyles = makeStyles( const ProductStocks: React.FC = ({ data, disabled, + hasVariants, errors, stocks, warehouses, onChange, onFormDataChange, onWarehouseStockAdd, - onWarehouseStockDelete + onWarehouseStockDelete, + onWarehouseConfigure }) => { const classes = useStyles({}); const intl = useIntl(); @@ -178,108 +186,147 @@ const ProductStocks: React.FC = ({ + {!warehouses.length && ( + + {hasVariants ? ( + <> + {" "} + + + + + ) : ( + <> + {" "} + + + + + )} + + )} - - - - - - - - - - - - - - {renderCollection(stocks, stock => ( - - {stock.label} - - onChange(stock.id, event.target.value)} - value={stock.value} + {warehouses.length > 0 && ( +
+ + + + - - onWarehouseStockDelete(stock.id)} - > - - + + + - ))} - {warehousesToAssign.length > 0 && ( - - - - + + {renderCollection(stocks, stock => ( + + {stock.label} + + onChange(stock.id, event.target.value)} + value={stock.value} /> - - - - setExpansionState(false)}> -
- setExpansionState(!isExpanded)} - > - - - - {({ TransitionProps }) => ( - - - {warehousesToAssign.map(warehouse => ( - - onWarehouseStockAdd(warehouse.id) - } - > - {warehouse.name} - - ))} - - - )} - -
-
-
-
- )} - -
+ + + onWarehouseStockDelete(stock.id)} + > + + + + + ))} + {warehousesToAssign.length > 0 && ( + + + + + + + + setExpansionState(false)} + > +
+ setExpansionState(!isExpanded)} + > + + + + {({ TransitionProps }) => ( + + + {warehousesToAssign.map(warehouse => ( + + onWarehouseStockAdd(warehouse.id) + } + > + {warehouse.name} + + ))} + + + )} + +
+
+
+
+ )} + + + )} ); }; diff --git a/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx b/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx index 79252b195..13e56879d 100644 --- a/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx +++ b/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx @@ -87,6 +87,7 @@ export interface ProductUpdatePageProps extends ListActions { onSubmit?(data: ProductUpdatePageSubmitData); onVariantAdd?(); onSetDefaultVariant(); + onWarehouseConfigure(); } export interface ProductUpdatePageSubmitData extends ProductUpdatePageFormData { @@ -128,6 +129,7 @@ export const ProductUpdatePage: React.FC = ({ onSetDefaultVariant, onVariantShow, onVariantReorder, + onWarehouseConfigure, isChecked, selected, toggle, @@ -346,6 +348,7 @@ export const ProductUpdatePage: React.FC = ({ = ({ triggerChange(); removeStock(id); }} + onWarehouseConfigure={onWarehouseConfigure} /> )} diff --git a/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx b/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx index 1237d8b98..8c345e4f2 100644 --- a/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx +++ b/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx @@ -58,6 +58,7 @@ interface ProductVariantCreatePageProps { onSubmit: (data: ProductVariantCreatePageSubmitData) => void; onVariantClick: (variantId: string) => void; onVariantReorder: ReorderAction; + onWarehouseConfigure: () => void; } const ProductVariantCreatePage: React.FC = ({ @@ -72,7 +73,8 @@ const ProductVariantCreatePage: React.FC = ({ onBack, onSubmit, onVariantClick, - onVariantReorder + onVariantReorder, + onWarehouseConfigure }) => { const intl = useIntl(); const attributeInput = React.useMemo( @@ -165,6 +167,7 @@ const ProductVariantCreatePage: React.FC = ({ = ({ triggerChange(); removeStock(id); }} + onWarehouseConfigure={onWarehouseConfigure} /> diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorStock.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorStock.tsx index 11066b09b..c07bfa598 100644 --- a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorStock.tsx +++ b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorStock.tsx @@ -126,7 +126,7 @@ const ProductVariantCreatorStock: React.FC = pr {!warehouses.length ? ( diff --git a/src/products/components/ProductVariantPage/ProductVariantPage.tsx b/src/products/components/ProductVariantPage/ProductVariantPage.tsx index 4d7643521..d875acf0d 100644 --- a/src/products/components/ProductVariantPage/ProductVariantPage.tsx +++ b/src/products/components/ProductVariantPage/ProductVariantPage.tsx @@ -70,6 +70,7 @@ interface ProductVariantPageProps { onImageSelect(id: string); onVariantClick(variantId: string); onSetDefaultVariant(); + onWarehouseConfigure(); } const ProductVariantPage: React.FC = ({ @@ -88,7 +89,8 @@ const ProductVariantPage: React.FC = ({ onSubmit, onVariantClick, onVariantReorder, - onSetDefaultVariant + onSetDefaultVariant, + onWarehouseConfigure }) => { const attributeInput = React.useMemo( () => getAttributeInputFromVariant(variant), @@ -240,6 +242,7 @@ const ProductVariantPage: React.FC = ({ = ({ triggerChange(); removeStock(id); }} + onWarehouseConfigure={onWarehouseConfigure} /> diff --git a/src/products/index.tsx b/src/products/index.tsx index 46b4df70d..2855010e8 100644 --- a/src/products/index.tsx +++ b/src/products/index.tsx @@ -9,6 +9,7 @@ import { Route, RouteComponentProps, Switch } from "react-router-dom"; import { WindowTitle } from "../components/WindowTitle"; import { productAddPath, + ProductAddUrlQueryParams, productImagePath, ProductImageUrlQueryParams, productListPath, @@ -17,11 +18,12 @@ import { productPath, ProductUrlQueryParams, productVariantAddPath, + ProductVariantAddUrlQueryParams, productVariantCreatorPath, productVariantEditPath, ProductVariantEditUrlQueryParams } from "./urls"; -import ProductCreate from "./views/ProductCreate"; +import ProductCreateComponent from "./views/ProductCreate"; import ProductImageComponent from "./views/ProductImage"; import ProductListComponent from "./views/ProductList"; import ProductUpdateComponent from "./views/ProductUpdate"; @@ -45,6 +47,13 @@ const ProductList: React.FC> = ({ location }) => { return ; }; +const ProductCreate: React.FC = () => { + const qs = parseQs(location.search.substr(1)); + const params: ProductAddUrlQueryParams = qs; + + return ; +}; + const ProductUpdate: React.FC> = ({ match }) => { const qs = parseQs(location.search.substr(1)); const params: ProductUrlQueryParams = qs; @@ -91,11 +100,17 @@ const ProductImage: React.FC> = ({ const ProductVariantCreate: React.FC> = ({ match -}) => ( - -); +}) => { + const qs = parseQs(location.search.substr(1)); + const params: ProductVariantAddUrlQueryParams = qs; + + return ( + + ); +}; const ProductVariantCreator: React.FC; +export const productAddUrl = (params?: ProductAddUrlQueryParams) => + productAddPath + "?" + stringifyQs(params); export const productListPath = productSection; export type ProductListUrlDialog = @@ -66,14 +69,14 @@ export const productListUrl = (params?: ProductListUrlQueryParams): string => productListPath + "?" + stringifyQs(params); export const productPath = (id: string) => urlJoin(productSection + id); -export type ProductUrlDialog = "remove" | "remove-variants"; +export type ProductUrlDialog = "remove" | "remove-variants" | "leave-screen"; export type ProductUrlQueryParams = BulkAction & Dialog; export const productUrl = (id: string, params?: ProductUrlQueryParams) => productPath(encodeURIComponent(id)) + "?" + stringifyQs(params); export const productVariantEditPath = (productId: string, variantId: string) => urlJoin(productSection, productId, "variant", variantId); -export type ProductVariantEditUrlDialog = "remove"; +export type ProductVariantEditUrlDialog = "remove" | "leave-screen"; export type ProductVariantEditUrlQueryParams = Dialog< ProductVariantEditUrlDialog >; @@ -96,8 +99,17 @@ export const productVariantCreatorUrl = (productId: string) => export const productVariantAddPath = (productId: string) => urlJoin(productSection, productId, "variant/add"); -export const productVariantAddUrl = (productId: string): string => - productVariantAddPath(encodeURIComponent(productId)); +export type ProductVariantAddUrlDialog = "leave-screen"; +export type ProductVariantAddUrlQueryParams = Dialog< + ProductVariantAddUrlDialog +>; +export const productVariantAddUrl = ( + productId: string, + params?: ProductVariantAddUrlQueryParams +): string => + productVariantAddPath(encodeURIComponent(productId)) + + "?" + + stringifyQs(params); export const productImagePath = (productId: string, imageId: string) => urlJoin(productSection, productId, "image", imageId); diff --git a/src/products/views/ProductCreate.tsx b/src/products/views/ProductCreate.tsx index 138e24e38..ff7c342a7 100644 --- a/src/products/views/ProductCreate.tsx +++ b/src/products/views/ProductCreate.tsx @@ -1,3 +1,4 @@ +import LeaveScreenDialog from "@saleor/components/LeaveScreenDialog"; import { WindowTitle } from "@saleor/components/WindowTitle"; import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config"; import useNavigator from "@saleor/hooks/useNavigator"; @@ -8,12 +9,14 @@ import useCategorySearch from "@saleor/searches/useCategorySearch"; import useCollectionSearch from "@saleor/searches/useCollectionSearch"; import useProductTypeSearch from "@saleor/searches/useProductTypeSearch"; import { useTaxTypeList } from "@saleor/taxes/queries"; +import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler"; import { useMetadataUpdate, usePrivateMetadataUpdate } from "@saleor/utils/metadata/updateMetadata"; import { useWarehouseList } from "@saleor/warehouses/queries"; +import { warehouseListPath } from "@saleor/warehouses/urls"; import React from "react"; import { useIntl } from "react-intl"; @@ -25,9 +28,22 @@ import { useProductCreateMutation, useProductSetAvailabilityForPurchase } from "../mutations"; -import { productListUrl, productUrl } from "../urls"; +import { + productAddUrl, + ProductAddUrlDialog, + ProductAddUrlQueryParams, + productListUrl, + productUrl +} from "../urls"; -export const ProductCreateView: React.FC = () => { +interface ProductCreateViewProps { + params: ProductAddUrlQueryParams; +} + +export const ProductCreateView: React.FC = ({ + params +}) => { + const { action } = params; const navigate = useNavigator(); const notify = useNotifier(); const shop = useShop(); @@ -90,6 +106,11 @@ export const ProductCreateView: React.FC = () => { } }); + const [openModal, closeModal] = createDialogActionHandlers< + ProductAddUrlDialog, + ProductAddUrlQueryParams + >(navigate, productAddUrl, params); + const handleCreate = async (formData: ProductCreatePageSubmitData) => { const result = await productCreate({ variables: { @@ -196,12 +217,19 @@ export const ProductCreateView: React.FC = () => { loading: searchProductTypesOpts.loading, onFetchMore: loadMoreProductTypes }} + onWarehouseConfigure={() => openModal("leave-screen")} warehouses={ warehouses.data?.warehouses.edges.map(edge => edge.node) || [] } taxTypes={taxTypes.data?.taxTypes || []} weightUnit={shop?.defaultWeightUnit} /> + navigate(warehouseListPath)} + onClose={closeModal} + open={action === "leave-screen"} + confirmButtonState="default" + /> ); }; diff --git a/src/products/views/ProductList/ProductList.tsx b/src/products/views/ProductList/ProductList.tsx index e25ca42eb..e032cc944 100644 --- a/src/products/views/ProductList/ProductList.tsx +++ b/src/products/views/ProductList/ProductList.tsx @@ -344,7 +344,7 @@ export const ProductList: React.FC = ({ params }) => { () => attributes.data.availableInGrid.pageInfo.hasNextPage, false )} - onAdd={() => navigate(productAddUrl)} + onAdd={() => navigate(productAddUrl())} disabled={loading} products={maybe(() => data.products.edges.map(edge => edge.node))} onFetchMore={() => diff --git a/src/products/views/ProductUpdate/ProductUpdate.tsx b/src/products/views/ProductUpdate/ProductUpdate.tsx index 4b03c68d6..7713b9e0d 100644 --- a/src/products/views/ProductUpdate/ProductUpdate.tsx +++ b/src/products/views/ProductUpdate/ProductUpdate.tsx @@ -3,6 +3,7 @@ import DialogContentText from "@material-ui/core/DialogContentText"; import IconButton from "@material-ui/core/IconButton"; import DeleteIcon from "@material-ui/icons/Delete"; import ActionDialog from "@saleor/components/ActionDialog"; +import LeaveScreenDialog from "@saleor/components/LeaveScreenDialog"; import NotFoundPage from "@saleor/components/NotFoundPage"; import { WindowTitle } from "@saleor/components/WindowTitle"; import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config"; @@ -33,6 +34,7 @@ import { usePrivateMetadataUpdate } from "@saleor/utils/metadata/updateMetadata"; import { useWarehouseList } from "@saleor/warehouses/queries"; +import { warehouseListPath } from "@saleor/warehouses/urls"; import React from "react"; import { FormattedMessage, useIntl } from "react-intl"; @@ -64,6 +66,7 @@ interface ProductUpdateProps { } export const ProductUpdate: React.FC = ({ id, params }) => { + const { action } = params; const navigate = useNavigator(); const notify = useNotifier(); const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions( @@ -312,6 +315,7 @@ export const ProductUpdate: React.FC = ({ id, params }) => { onImageUpload={handleImageUpload} onImageEdit={handleImageEdit} onImageDelete={handleImageDelete} + onWarehouseConfigure={() => openModal("leave-screen")} toolbar={ = ({ id, params }) => { /> + navigate(warehouseListPath)} + onClose={closeModal} + open={action === "leave-screen"} + confirmButtonState="default" + /> ); }; diff --git a/src/products/views/ProductVariant.tsx b/src/products/views/ProductVariant.tsx index 845a92246..d972cce90 100644 --- a/src/products/views/ProductVariant.tsx +++ b/src/products/views/ProductVariant.tsx @@ -1,4 +1,5 @@ import placeholderImg from "@assets/images/placeholder255x255.png"; +import LeaveScreenDialog from "@saleor/components/LeaveScreenDialog"; import NotFoundPage from "@saleor/components/NotFoundPage"; import { WindowTitle } from "@saleor/components/WindowTitle"; import useNavigator from "@saleor/hooks/useNavigator"; @@ -13,6 +14,7 @@ import { usePrivateMetadataUpdate } from "@saleor/utils/metadata/updateMetadata"; import { useWarehouseList } from "@saleor/warehouses/queries"; +import { warehouseListPath } from "@saleor/warehouses/urls"; import React, { useEffect, useState } from "react"; import { useIntl } from "react-intl"; @@ -51,6 +53,7 @@ export const ProductVariant: React.FC = ({ productId, params }) => { + const { action } = params; const shop = useShop(); const navigate = useNavigator(); const notify = useNotifier(); @@ -78,7 +81,7 @@ export const ProductVariant: React.FC = ({ const [updateMetadata] = useMetadataUpdate({}); const [updatePrivateMetadata] = usePrivateMetadataUpdate({}); - const [openModal] = createDialogActionHandlers< + const [openModal, closeModal] = createDialogActionHandlers< ProductVariantEditUrlDialog, ProductVariantEditUrlQueryParams >( @@ -220,6 +223,7 @@ export const ProductVariant: React.FC = ({ navigate(productVariantEditUrl(productId, variantId)); }} onVariantReorder={handleVariantReorder} + onWarehouseConfigure={() => openModal("leave-screen")} /> = ({ open={params.action === "remove"} name={data?.productVariant?.name} /> + navigate(warehouseListPath)} + onClose={closeModal} + open={action === "leave-screen"} + confirmButtonState="default" + /> ); }; diff --git a/src/products/views/ProductVariantCreate.tsx b/src/products/views/ProductVariantCreate.tsx index 6d4df390d..b758ac83e 100644 --- a/src/products/views/ProductVariantCreate.tsx +++ b/src/products/views/ProductVariantCreate.tsx @@ -1,15 +1,18 @@ +import LeaveScreenDialog from "@saleor/components/LeaveScreenDialog"; import NotFoundPage from "@saleor/components/NotFoundPage"; import { WindowTitle } from "@saleor/components/WindowTitle"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import useShop from "@saleor/hooks/useShop"; import { commonMessages } from "@saleor/intl"; +import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler"; import { useMetadataUpdate, usePrivateMetadataUpdate } from "@saleor/utils/metadata/updateMetadata"; import { useWarehouseList } from "@saleor/warehouses/queries"; +import { warehouseListPath } from "@saleor/warehouses/urls"; import React from "react"; import { useIntl } from "react-intl"; @@ -22,16 +25,26 @@ import { useVariantCreateMutation } from "../mutations"; import { useProductVariantCreateQuery } from "../queries"; -import { productListUrl, productUrl, productVariantEditUrl } from "../urls"; +import { + productListUrl, + productUrl, + productVariantAddUrl, + ProductVariantAddUrlDialog, + ProductVariantAddUrlQueryParams, + productVariantEditUrl +} from "../urls"; import { createVariantReorderHandler } from "./ProductUpdate/handlers"; interface ProductVariantCreateProps { productId: string; + params: ProductVariantAddUrlQueryParams; } export const ProductVariant: React.FC = ({ - productId + productId, + params }) => { + const { action } = params; const navigate = useNavigator(); const notify = useNotifier(); const shop = useShop(); @@ -82,6 +95,11 @@ export const ProductVariant: React.FC = ({ reorderProductVariants({ variables }) ); + const [openModal, closeModal] = createDialogActionHandlers< + ProductVariantAddUrlDialog, + ProductVariantAddUrlQueryParams + >(navigate, params => productVariantAddUrl(productId, params), params); + const handleBack = () => navigate(productUrl(productId)); const handleCreate = async (formData: ProductVariantCreatePageSubmitData) => { const result = await variantCreate({ @@ -143,12 +161,19 @@ export const ProductVariant: React.FC = ({ onSubmit={handleSubmit} onVariantClick={handleVariantClick} onVariantReorder={handleVariantReorder} + onWarehouseConfigure={() => openModal("leave-screen")} saveButtonBarState={variantCreateResult.status} warehouses={ warehouses.data?.warehouses.edges.map(edge => edge.node) || [] } weightUnit={shop?.defaultWeightUnit} /> + navigate(warehouseListPath)} + onClose={closeModal} + open={action === "leave-screen"} + confirmButtonState="default" + /> ); }; diff --git a/src/storybook/stories/products/ProductCreatePage.tsx b/src/storybook/stories/products/ProductCreatePage.tsx index babd8504a..ef80d8076 100644 --- a/src/storybook/stories/products/ProductCreatePage.tsx +++ b/src/storybook/stories/products/ProductCreatePage.tsx @@ -37,6 +37,7 @@ storiesOf("Views / Products / Create product", module) warehouses={warehouseList} taxTypes={taxTypes} weightUnit="kg" + onWarehouseConfigure={() => undefined} /> )) .add("When loading", () => ( @@ -60,6 +61,7 @@ storiesOf("Views / Products / Create product", module) warehouses={undefined} taxTypes={taxTypes} weightUnit="kg" + onWarehouseConfigure={() => undefined} /> )) .add("form errors", () => ( @@ -89,5 +91,6 @@ storiesOf("Views / Products / Create product", module) warehouses={warehouseList} taxTypes={taxTypes} weightUnit="kg" + onWarehouseConfigure={() => undefined} /> )); diff --git a/src/storybook/stories/products/ProductUpdatePage.tsx b/src/storybook/stories/products/ProductUpdatePage.tsx index c44841a1b..980d68a84 100644 --- a/src/storybook/stories/products/ProductUpdatePage.tsx +++ b/src/storybook/stories/products/ProductUpdatePage.tsx @@ -39,6 +39,7 @@ const props: ProductUpdatePageProps = { onVariantReorder: () => undefined, onVariantShow: () => undefined, onVariantsAdd: () => undefined, + onWarehouseConfigure: () => undefined, placeholderImage, product, saveButtonBarState: "default", diff --git a/src/storybook/stories/products/ProductVariantCreatePage.tsx b/src/storybook/stories/products/ProductVariantCreatePage.tsx index d8578724d..d0fdbea77 100644 --- a/src/storybook/stories/products/ProductVariantCreatePage.tsx +++ b/src/storybook/stories/products/ProductVariantCreatePage.tsx @@ -26,6 +26,7 @@ storiesOf("Views / Products / Create product variant", module) onVariantReorder={() => undefined} saveButtonBarState="default" warehouses={warehouseList} + onWarehouseConfigure={() => undefined} /> )) .add("with errors", () => ( @@ -58,6 +59,7 @@ storiesOf("Views / Products / Create product variant", module) onVariantReorder={() => undefined} saveButtonBarState="default" warehouses={warehouseList} + onWarehouseConfigure={() => undefined} /> )) .add("when loading data", () => ( @@ -74,6 +76,7 @@ storiesOf("Views / Products / Create product variant", module) onVariantReorder={() => undefined} saveButtonBarState="default" warehouses={warehouseList} + onWarehouseConfigure={() => undefined} /> )) .add("add first variant", () => ( @@ -93,5 +96,6 @@ storiesOf("Views / Products / Create product variant", module) onVariantReorder={() => undefined} saveButtonBarState="default" warehouses={warehouseList} + onWarehouseConfigure={() => undefined} /> )); diff --git a/src/storybook/stories/products/ProductVariantPage.tsx b/src/storybook/stories/products/ProductVariantPage.tsx index 038c03372..a70095d78 100644 --- a/src/storybook/stories/products/ProductVariantPage.tsx +++ b/src/storybook/stories/products/ProductVariantPage.tsx @@ -28,6 +28,7 @@ storiesOf("Views / Products / Product variant details", module) onVariantReorder={() => undefined} saveButtonBarState="default" warehouses={warehouseList} + onWarehouseConfigure={() => undefined} /> )) .add("when loading data", () => ( @@ -47,6 +48,7 @@ storiesOf("Views / Products / Product variant details", module) onVariantReorder={() => undefined} saveButtonBarState="default" warehouses={warehouseList} + onWarehouseConfigure={() => undefined} /> )) .add("attribute errors", () => ( @@ -82,5 +84,6 @@ storiesOf("Views / Products / Product variant details", module) ...error }))} warehouses={warehouseList} + onWarehouseConfigure={() => undefined} /> ));