Add redirect on warehouse configuration action

This commit is contained in:
Dawid Tarasiuk 2020-09-21 18:29:50 +02:00
parent 6065c5ded6
commit 1aaa5c5c3a
14 changed files with 257 additions and 115 deletions

View file

@ -2,52 +2,54 @@ import Button from "@material-ui/core/Button";
import Dialog from "@material-ui/core/Dialog"; import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions"; import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent"; import DialogContent from "@material-ui/core/DialogContent";
import DialogTitle from "@material-ui/core/DialogTitle";
import { buttonMessages } from "@saleor/intl"; import { buttonMessages } from "@saleor/intl";
import React from "react"; import React from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";
import ConfirmButton, { ConfirmButtonTransitionState } from "../ConfirmButton"; import ConfirmButton, { ConfirmButtonTransitionState } from "../ConfirmButton";
import Form from "../Form";
export interface LeaveScreenDialogProps { export interface LeaveScreenDialogProps {
confirmButtonState: ConfirmButtonTransitionState; confirmButtonState: ConfirmButtonTransitionState;
open: boolean; open: boolean;
onClose: () => void; onClose: () => void;
onSubmit: () => void; onSaveChanges: () => void;
onRejectChanges: () => void;
} }
const LeaveScreenDialog: React.FC<LeaveScreenDialogProps> = ({ const LeaveScreenDialog: React.FC<LeaveScreenDialogProps> = ({
confirmButtonState, confirmButtonState,
onClose, onClose,
onSubmit, onSaveChanges,
onRejectChanges,
open open
}) => ( }) => (
<Dialog onClose={onClose} open={open} fullWidth maxWidth="sm"> <Dialog onClose={onClose} open={open} fullWidth maxWidth="sm">
<Form onSubmit={onSubmit}> <DialogTitle>
{({ submit }) => ( <FormattedMessage
<> defaultMessage="You're leaving this screen"
<DialogContent> description="leaving screen warning header"
<FormattedMessage />
defaultMessage="You're leaving this screen. Do you want to save previously made changes?" </DialogTitle>
description="leaving screen warning message" <DialogContent>
/> <FormattedMessage
</DialogContent> defaultMessage="Do you want to save previously made changes?"
<DialogActions> description="leaving screen warning message"
<Button onClick={onClose}> />
<FormattedMessage {...buttonMessages.cancel} /> </DialogContent>
</Button> <DialogActions>
<ConfirmButton <Button onClick={onRejectChanges}>
transitionState={confirmButtonState} <FormattedMessage {...buttonMessages.no} />
color="primary" </Button>
variant="contained" <ConfirmButton
onClick={submit} transitionState={confirmButtonState}
> color="primary"
<FormattedMessage {...buttonMessages.save} /> variant="contained"
</ConfirmButton> onClick={onSaveChanges}
</DialogActions> >
</> <FormattedMessage {...buttonMessages.yes} />
)} </ConfirmButton>
</Form> </DialogActions>
</Dialog> </Dialog>
); );
LeaveScreenDialog.displayName = "LeaveScreenDialog"; LeaveScreenDialog.displayName = "LeaveScreenDialog";

View file

@ -136,6 +136,10 @@ export const buttonMessages = defineMessages({
defaultMessage: "Next", defaultMessage: "Next",
description: "go to next step, button" description: "go to next step, button"
}, },
no: {
defaultMessage: "No",
description: "button"
},
ok: { ok: {
defaultMessage: "OK", defaultMessage: "OK",
description: "button" description: "button"
@ -163,6 +167,10 @@ export const buttonMessages = defineMessages({
undo: { undo: {
defaultMessage: "Undo", defaultMessage: "Undo",
description: "button" description: "button"
},
yes: {
defaultMessage: "Yes",
description: "button"
} }
}); });

View file

@ -5,6 +5,7 @@ import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import Form from "@saleor/components/Form"; import Form from "@saleor/components/Form";
import Grid from "@saleor/components/Grid"; import Grid from "@saleor/components/Grid";
import LeaveScreenDialog from "@saleor/components/LeaveScreenDialog";
import Metadata, { MetadataFormData } from "@saleor/components/Metadata"; import Metadata, { MetadataFormData } from "@saleor/components/Metadata";
import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField"; import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
@ -78,6 +79,8 @@ export interface ProductCreatePageSubmitData extends FormData {
stocks: ProductStockInput[]; stocks: ProductStockInput[];
} }
export type ProductCreatePageSubmitNextAction = "warehouse-configure";
interface ProductCreatePageProps { interface ProductCreatePageProps {
errors: ProductErrorFragment[]; errors: ProductErrorFragment[];
collections: SearchCollections_search_edges_node[]; collections: SearchCollections_search_edges_node[];
@ -98,12 +101,14 @@ interface ProductCreatePageProps {
weightUnit: string; weightUnit: string;
warehouses: SearchWarehouses_search_edges_node[]; warehouses: SearchWarehouses_search_edges_node[];
taxTypes: TaxTypeFragment[]; taxTypes: TaxTypeFragment[];
submitNextAction?: ProductCreatePageSubmitNextAction;
fetchCategories: (data: string) => void; fetchCategories: (data: string) => void;
fetchCollections: (data: string) => void; fetchCollections: (data: string) => void;
fetchProductTypes: (data: string) => void; fetchProductTypes: (data: string) => void;
onWarehouseConfigure: () => void;
onBack?(); onBack?();
onSubmit?(data: ProductCreatePageSubmitData); onSubmit?(data: ProductCreatePageSubmitData);
onSubmitReject?(nextAction?: ProductCreatePageSubmitNextAction);
setSubmitNextAction?(nextAction: ProductCreatePageSubmitNextAction);
} }
export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
@ -123,10 +128,12 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
warehouses, warehouses,
taxTypes, taxTypes,
onBack, onBack,
onWarehouseConfigure,
fetchProductTypes, fetchProductTypes,
weightUnit, weightUnit,
onSubmit onSubmit,
onSubmitReject,
submitNextAction,
setSubmitNextAction
}: ProductCreatePageProps) => { }: ProductCreatePageProps) => {
const intl = useIntl(); const intl = useIntl();
const localizeDate = useDateLocalize(); const localizeDate = useDateLocalize();
@ -323,7 +330,12 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
triggerChange(); triggerChange();
removeStock(id); removeStock(id);
}} }}
onWarehouseConfigure={onWarehouseConfigure} onWarehouseConfigure={() => {
setSubmitNextAction("warehouse-configure");
if (disabled || !onSubmit || !hasChanged) {
onSubmitReject("warehouse-configure");
}
}}
/> />
<CardSpacer /> <CardSpacer />
</> </>
@ -412,6 +424,17 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
state={saveButtonBarState} state={saveButtonBarState}
disabled={disabled || !onSubmit || !hasChanged} disabled={disabled || !onSubmit || !hasChanged}
/> />
<LeaveScreenDialog
onSaveChanges={() => {
submit();
}}
onRejectChanges={() => {
onSubmitReject("warehouse-configure");
}}
onClose={() => setSubmitNextAction(null)}
open={submitNextAction === "warehouse-configure"}
confirmButtonState={saveButtonBarState}
/>
</Container> </Container>
); );
}} }}

View file

@ -5,6 +5,7 @@ import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import Form from "@saleor/components/Form"; import Form from "@saleor/components/Form";
import Grid from "@saleor/components/Grid"; import Grid from "@saleor/components/Grid";
import LeaveScreenDialog from "@saleor/components/LeaveScreenDialog";
import Metadata from "@saleor/components/Metadata/Metadata"; import Metadata from "@saleor/components/Metadata/Metadata";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar"; import SaveButtonBar from "@saleor/components/SaveButtonBar";
@ -56,6 +57,8 @@ import ProductStocks, { ProductStockInput } from "../ProductStocks";
import ProductTaxes from "../ProductTaxes"; import ProductTaxes from "../ProductTaxes";
import ProductVariants from "../ProductVariants"; import ProductVariants from "../ProductVariants";
export type ProductUpdatePageSubmitNextAction = "warehouse-configure";
export interface ProductUpdatePageProps extends ListActions { export interface ProductUpdatePageProps extends ListActions {
defaultWeightUnit: string; defaultWeightUnit: string;
errors: ProductErrorFragment[]; errors: ProductErrorFragment[];
@ -72,6 +75,7 @@ export interface ProductUpdatePageProps extends ListActions {
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
warehouses: WarehouseFragment[]; warehouses: WarehouseFragment[];
taxTypes: TaxTypeFragment[]; taxTypes: TaxTypeFragment[];
submitNextAction?: ProductUpdatePageSubmitNextAction;
fetchCategories: (query: string) => void; fetchCategories: (query: string) => void;
fetchCollections: (query: string) => void; fetchCollections: (query: string) => void;
onVariantsAdd: () => void; onVariantsAdd: () => void;
@ -85,6 +89,8 @@ export interface ProductUpdatePageProps extends ListActions {
onImageUpload(file: File); onImageUpload(file: File);
onSeoClick?(); onSeoClick?();
onSubmit?(data: ProductUpdatePageSubmitData); onSubmit?(data: ProductUpdatePageSubmitData);
onSubmitReject?(nextAction?: ProductUpdatePageSubmitNextAction);
setSubmitNextAction?(nextAction: ProductUpdatePageSubmitNextAction);
onVariantAdd?(); onVariantAdd?();
onSetDefaultVariant(); onSetDefaultVariant();
onWarehouseConfigure(); onWarehouseConfigure();
@ -124,17 +130,19 @@ export const ProductUpdatePage: React.FC<ProductUpdatePageProps> = ({
onImageUpload, onImageUpload,
onSeoClick, onSeoClick,
onSubmit, onSubmit,
onSubmitReject,
onVariantAdd, onVariantAdd,
onVariantsAdd, onVariantsAdd,
onSetDefaultVariant, onSetDefaultVariant,
onVariantShow, onVariantShow,
onVariantReorder, onVariantReorder,
onWarehouseConfigure,
isChecked, isChecked,
selected, selected,
toggle, toggle,
toggleAll, toggleAll,
toolbar toolbar,
submitNextAction,
setSubmitNextAction
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const localizeDate = useDateLocalize(); const localizeDate = useDateLocalize();
@ -372,7 +380,12 @@ export const ProductUpdatePage: React.FC<ProductUpdatePageProps> = ({
triggerChange(); triggerChange();
removeStock(id); removeStock(id);
}} }}
onWarehouseConfigure={onWarehouseConfigure} onWarehouseConfigure={() => {
setSubmitNextAction("warehouse-configure");
if (disabled || !onSubmit || !hasChanged) {
onSubmitReject("warehouse-configure");
}
}}
/> />
</> </>
)} )}
@ -462,6 +475,17 @@ export const ProductUpdatePage: React.FC<ProductUpdatePageProps> = ({
state={saveButtonBarState} state={saveButtonBarState}
disabled={disabled || !hasChanged} disabled={disabled || !hasChanged}
/> />
<LeaveScreenDialog
onSaveChanges={() => {
submit();
}}
onRejectChanges={() => {
onSubmitReject("warehouse-configure");
}}
onClose={() => setSubmitNextAction(null)}
open={submitNextAction === "warehouse-configure"}
confirmButtonState={saveButtonBarState}
/>
</Container> </Container>
</> </>
); );

View file

@ -4,6 +4,7 @@ import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import Form from "@saleor/components/Form"; import Form from "@saleor/components/Form";
import Grid from "@saleor/components/Grid"; import Grid from "@saleor/components/Grid";
import LeaveScreenDialog from "@saleor/components/LeaveScreenDialog";
import Metadata, { MetadataFormData } from "@saleor/components/Metadata"; import Metadata, { MetadataFormData } from "@saleor/components/Metadata";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar"; import SaveButtonBar from "@saleor/components/SaveButtonBar";
@ -45,6 +46,8 @@ export interface ProductVariantCreatePageSubmitData
stocks: ProductStockInput[]; stocks: ProductStockInput[];
} }
export type ProductVariantCreatePageSubmitNextAction = "warehouse-configure";
interface ProductVariantCreatePageProps { interface ProductVariantCreatePageProps {
currencySymbol: string; currencySymbol: string;
disabled: boolean; disabled: boolean;
@ -54,11 +57,17 @@ interface ProductVariantCreatePageProps {
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
warehouses: SearchWarehouses_search_edges_node[]; warehouses: SearchWarehouses_search_edges_node[];
weightUnit: string; weightUnit: string;
submitNextAction?: ProductVariantCreatePageSubmitNextAction;
onBack: () => void; onBack: () => void;
onSubmit: (data: ProductVariantCreatePageSubmitData) => void; onSubmit: (data: ProductVariantCreatePageSubmitData) => void;
onSubmitReject?: (
nextAction?: ProductVariantCreatePageSubmitNextAction
) => void;
setSubmitNextAction?: (
nextAction: ProductVariantCreatePageSubmitNextAction
) => void;
onVariantClick: (variantId: string) => void; onVariantClick: (variantId: string) => void;
onVariantReorder: ReorderAction; onVariantReorder: ReorderAction;
onWarehouseConfigure: () => void;
} }
const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
@ -72,9 +81,11 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
weightUnit, weightUnit,
onBack, onBack,
onSubmit, onSubmit,
onSubmitReject,
onVariantClick, onVariantClick,
onVariantReorder, onVariantReorder,
onWarehouseConfigure submitNextAction,
setSubmitNextAction
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const attributeInput = React.useMemo( const attributeInput = React.useMemo(
@ -190,7 +201,12 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
triggerChange(); triggerChange();
removeStock(id); removeStock(id);
}} }}
onWarehouseConfigure={onWarehouseConfigure} onWarehouseConfigure={() => {
setSubmitNextAction("warehouse-configure");
if (disabled || !onSubmit || !hasChanged) {
onSubmitReject("warehouse-configure");
}
}}
/> />
<CardSpacer /> <CardSpacer />
<Metadata data={data} onChange={changeMetadata} /> <Metadata data={data} onChange={changeMetadata} />
@ -212,6 +228,17 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
onCancel={onBack} onCancel={onBack}
onSave={submit} onSave={submit}
/> />
<LeaveScreenDialog
onSaveChanges={() => {
submit();
}}
onRejectChanges={() => {
onSubmitReject("warehouse-configure");
}}
onClose={() => setSubmitNextAction(null)}
open={submitNextAction === "warehouse-configure"}
confirmButtonState={saveButtonBarState}
/>
</Container> </Container>
); );
}} }}

View file

@ -4,6 +4,7 @@ import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import Form from "@saleor/components/Form"; import Form from "@saleor/components/Form";
import Grid from "@saleor/components/Grid"; import Grid from "@saleor/components/Grid";
import LeaveScreenDialog from "@saleor/components/LeaveScreenDialog";
import { MetadataFormData } from "@saleor/components/Metadata"; import { MetadataFormData } from "@saleor/components/Metadata";
import Metadata from "@saleor/components/Metadata/Metadata"; import Metadata from "@saleor/components/Metadata/Metadata";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
@ -53,6 +54,8 @@ export interface ProductVariantPageSubmitData
removeStocks: string[]; removeStocks: string[];
} }
export type ProductVariantPageSubmitNextAction = "warehouse-configure";
interface ProductVariantPageProps { interface ProductVariantPageProps {
defaultWeightUnit: string; defaultWeightUnit: string;
variant?: ProductVariant; variant?: ProductVariant;
@ -62,11 +65,14 @@ interface ProductVariantPageProps {
placeholderImage?: string; placeholderImage?: string;
header: string; header: string;
warehouses: WarehouseFragment[]; warehouses: WarehouseFragment[];
submitNextAction?: ProductVariantPageSubmitNextAction;
onVariantReorder: ReorderAction; onVariantReorder: ReorderAction;
onAdd(); onAdd();
onBack(); onBack();
onDelete(); onDelete();
onSubmit(data: ProductVariantPageSubmitData); onSubmit(data: ProductVariantPageSubmitData);
onSubmitReject?(nextAction?: ProductVariantPageSubmitNextAction);
setSubmitNextAction?(nextAction: ProductVariantPageSubmitNextAction);
onImageSelect(id: string); onImageSelect(id: string);
onVariantClick(variantId: string); onVariantClick(variantId: string);
onSetDefaultVariant(); onSetDefaultVariant();
@ -87,10 +93,13 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
onDelete, onDelete,
onImageSelect, onImageSelect,
onSubmit, onSubmit,
onSubmitReject,
onVariantClick, onVariantClick,
onVariantReorder, onVariantReorder,
onSetDefaultVariant, onSetDefaultVariant,
onWarehouseConfigure onWarehouseConfigure,
submitNextAction,
setSubmitNextAction
}) => { }) => {
const attributeInput = React.useMemo( const attributeInput = React.useMemo(
() => getAttributeInputFromVariant(variant), () => getAttributeInputFromVariant(variant),
@ -266,7 +275,12 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
triggerChange(); triggerChange();
removeStock(id); removeStock(id);
}} }}
onWarehouseConfigure={onWarehouseConfigure} onWarehouseConfigure={() => {
setSubmitNextAction("warehouse-configure");
if (!onSubmit || !hasChanged) {
onSubmitReject("warehouse-configure");
}
}}
/> />
<CardSpacer /> <CardSpacer />
<Metadata data={data} onChange={changeMetadata} /> <Metadata data={data} onChange={changeMetadata} />
@ -279,6 +293,17 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
onDelete={onDelete} onDelete={onDelete}
onSave={submit} onSave={submit}
/> />
<LeaveScreenDialog
onSaveChanges={() => {
submit();
}}
onRejectChanges={() => {
onSubmitReject("warehouse-configure");
}}
onClose={() => setSubmitNextAction(null)}
open={submitNextAction === "warehouse-configure"}
confirmButtonState={saveButtonBarState}
/>
</> </>
); );
}} }}

View file

@ -1,4 +1,3 @@
import LeaveScreenDialog from "@saleor/components/LeaveScreenDialog";
import { WindowTitle } from "@saleor/components/WindowTitle"; import { WindowTitle } from "@saleor/components/WindowTitle";
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config"; import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
@ -22,28 +21,20 @@ import { useIntl } from "react-intl";
import { decimal, weight } from "../../misc"; import { decimal, weight } from "../../misc";
import ProductCreatePage, { import ProductCreatePage, {
ProductCreatePageSubmitData ProductCreatePageSubmitData,
ProductCreatePageSubmitNextAction
} from "../components/ProductCreatePage"; } from "../components/ProductCreatePage";
import { import {
useProductCreateMutation, useProductCreateMutation,
useProductSetAvailabilityForPurchase useProductSetAvailabilityForPurchase
} from "../mutations"; } from "../mutations";
import { import { ProductAddUrlQueryParams, productListUrl, productUrl } from "../urls";
productAddUrl,
ProductAddUrlDialog,
ProductAddUrlQueryParams,
productListUrl,
productUrl
} from "../urls";
interface ProductCreateViewProps { interface ProductCreateViewProps {
params: ProductAddUrlQueryParams; params: ProductAddUrlQueryParams;
} }
export const ProductCreateView: React.FC<ProductCreateViewProps> = ({ export const ProductCreateView: React.FC<ProductCreateViewProps> = ({}) => {
params
}) => {
const { action } = params;
const navigate = useNavigator(); const navigate = useNavigator();
const notify = useNotifier(); const notify = useNotifier();
const shop = useShop(); const shop = useShop();
@ -87,7 +78,7 @@ export const ProductCreateView: React.FC<ProductCreateViewProps> = ({
] = useProductSetAvailabilityForPurchase({ ] = useProductSetAvailabilityForPurchase({
onCompleted: data => { onCompleted: data => {
const errors = data?.productSetAvailabilityForPurchase?.errors; const errors = data?.productSetAvailabilityForPurchase?.errors;
if (errors?.length === 0) { if (errors?.length === 0 && !submitNextAction) {
navigate(productUrl(data.productSetAvailabilityForPurchase.product.id)); navigate(productUrl(data.productSetAvailabilityForPurchase.product.id));
} }
} }
@ -106,11 +97,6 @@ export const ProductCreateView: React.FC<ProductCreateViewProps> = ({
} }
}); });
const [openModal, closeModal] = createDialogActionHandlers<
ProductAddUrlDialog,
ProductAddUrlQueryParams
>(navigate, productAddUrl, params);
const handleCreate = async (formData: ProductCreatePageSubmitData) => { const handleCreate = async (formData: ProductCreatePageSubmitData) => {
const result = await productCreate({ const result = await productCreate({
variables: { variables: {
@ -171,6 +157,18 @@ export const ProductCreateView: React.FC<ProductCreateViewProps> = ({
updatePrivateMetadata updatePrivateMetadata
); );
const [submitNextAction, setSubmitNextAction] = React.useState<
ProductCreatePageSubmitNextAction
>(null);
const handleSubmitNextAction = (
nextAction?: ProductCreatePageSubmitNextAction
) => {
const action = nextAction || submitNextAction;
if (action === "warehouse-configure") {
navigate(warehouseListPath);
}
};
return ( return (
<> <>
<WindowTitle <WindowTitle
@ -200,7 +198,15 @@ export const ProductCreateView: React.FC<ProductCreateViewProps> = ({
edge => edge.node edge => edge.node
)} )}
onBack={handleBack} onBack={handleBack}
onSubmit={handleSubmit} onSubmit={async data => {
const errors = await handleSubmit(data);
if (errors?.length === 0) {
handleSubmitNextAction();
} else {
setSubmitNextAction(null);
}
}}
onSubmitReject={handleSubmitNextAction}
saveButtonBarState={productCreateOpts.status} saveButtonBarState={productCreateOpts.status}
fetchMoreCategories={{ fetchMoreCategories={{
hasMore: searchCategoryOpts.data?.search.pageInfo.hasNextPage, hasMore: searchCategoryOpts.data?.search.pageInfo.hasNextPage,
@ -217,19 +223,14 @@ export const ProductCreateView: React.FC<ProductCreateViewProps> = ({
loading: searchProductTypesOpts.loading, loading: searchProductTypesOpts.loading,
onFetchMore: loadMoreProductTypes onFetchMore: loadMoreProductTypes
}} }}
onWarehouseConfigure={() => openModal("leave-screen")} submitNextAction={submitNextAction}
setSubmitNextAction={setSubmitNextAction}
warehouses={ warehouses={
warehouses.data?.warehouses.edges.map(edge => edge.node) || [] warehouses.data?.warehouses.edges.map(edge => edge.node) || []
} }
taxTypes={taxTypes.data?.taxTypes || []} taxTypes={taxTypes.data?.taxTypes || []}
weightUnit={shop?.defaultWeightUnit} weightUnit={shop?.defaultWeightUnit}
/> />
<LeaveScreenDialog
onSubmit={() => navigate(warehouseListPath)}
onClose={closeModal}
open={action === "leave-screen"}
confirmButtonState="default"
/>
</> </>
); );
}; };

View file

@ -3,7 +3,6 @@ import DialogContentText from "@material-ui/core/DialogContentText";
import IconButton from "@material-ui/core/IconButton"; import IconButton from "@material-ui/core/IconButton";
import DeleteIcon from "@material-ui/icons/Delete"; import DeleteIcon from "@material-ui/icons/Delete";
import ActionDialog from "@saleor/components/ActionDialog"; import ActionDialog from "@saleor/components/ActionDialog";
import LeaveScreenDialog from "@saleor/components/LeaveScreenDialog";
import NotFoundPage from "@saleor/components/NotFoundPage"; import NotFoundPage from "@saleor/components/NotFoundPage";
import { WindowTitle } from "@saleor/components/WindowTitle"; import { WindowTitle } from "@saleor/components/WindowTitle";
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config"; import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
@ -39,7 +38,9 @@ import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
import { getMutationState, maybe } from "../../../misc"; import { getMutationState, maybe } from "../../../misc";
import ProductUpdatePage from "../../components/ProductUpdatePage"; import ProductUpdatePage, {
ProductUpdatePageSubmitNextAction
} from "../../components/ProductUpdatePage";
import { useProductDetails } from "../../queries"; import { useProductDetails } from "../../queries";
import { ProductImageCreateVariables } from "../../types/ProductImageCreate"; import { ProductImageCreateVariables } from "../../types/ProductImageCreate";
import { ProductUpdate as ProductUpdateMutationResult } from "../../types/ProductUpdate"; import { ProductUpdate as ProductUpdateMutationResult } from "../../types/ProductUpdate";
@ -66,7 +67,6 @@ interface ProductUpdateProps {
} }
export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => { export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
const { action } = params;
const navigate = useNavigator(); const navigate = useNavigator();
const notify = useNotifier(); const notify = useNotifier();
const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions( const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions(
@ -281,6 +281,18 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
null null
); );
const [submitNextAction, setSubmitNextAction] = React.useState<
ProductUpdatePageSubmitNextAction
>(null);
const handleSubmitNextAction = (
nextAction?: ProductUpdatePageSubmitNextAction
) => {
const action = nextAction || submitNextAction;
if (action === "warehouse-configure") {
navigate(warehouseListPath);
}
};
return ( return (
<> <>
<WindowTitle title={maybe(() => data.product.name)} /> <WindowTitle title={maybe(() => data.product.name)} />
@ -306,7 +318,15 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
onBack={handleBack} onBack={handleBack}
onDelete={() => openModal("remove")} onDelete={() => openModal("remove")}
onImageReorder={handleImageReorder} onImageReorder={handleImageReorder}
onSubmit={handleSubmit} onSubmit={async data => {
const errors = await handleSubmit(data);
if (errors?.length === 0) {
handleSubmitNextAction();
} else {
setSubmitNextAction(null);
}
}}
onSubmitReject={handleSubmitNextAction}
onVariantAdd={handleVariantAdd} onVariantAdd={handleVariantAdd}
onVariantsAdd={() => navigate(productVariantCreatorUrl(id))} onVariantsAdd={() => navigate(productVariantCreatorUrl(id))}
onVariantShow={variantId => () => onVariantShow={variantId => () =>
@ -315,7 +335,6 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
onImageUpload={handleImageUpload} onImageUpload={handleImageUpload}
onImageEdit={handleImageEdit} onImageEdit={handleImageEdit}
onImageDelete={handleImageDelete} onImageDelete={handleImageDelete}
onWarehouseConfigure={() => openModal("leave-screen")}
toolbar={ toolbar={
<IconButton <IconButton
color="primary" color="primary"
@ -346,6 +365,8 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
loading: searchCollectionsOpts.loading, loading: searchCollectionsOpts.loading,
onFetchMore: loadMoreCollections onFetchMore: loadMoreCollections
}} }}
submitNextAction={submitNextAction}
setSubmitNextAction={setSubmitNextAction}
/> />
<ActionDialog <ActionDialog
open={params.action === "remove"} open={params.action === "remove"}
@ -396,12 +417,6 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
/> />
</DialogContentText> </DialogContentText>
</ActionDialog> </ActionDialog>
<LeaveScreenDialog
onSubmit={() => navigate(warehouseListPath)}
onClose={closeModal}
open={action === "leave-screen"}
confirmButtonState="default"
/>
</> </>
); );
}; };

View file

@ -21,7 +21,8 @@ import { useIntl } from "react-intl";
import { decimal, weight } from "../../misc"; import { decimal, weight } from "../../misc";
import ProductVariantDeleteDialog from "../components/ProductVariantDeleteDialog"; import ProductVariantDeleteDialog from "../components/ProductVariantDeleteDialog";
import ProductVariantPage, { import ProductVariantPage, {
ProductVariantPageSubmitData ProductVariantPageSubmitData,
ProductVariantPageSubmitNextAction
} from "../components/ProductVariantPage"; } from "../components/ProductVariantPage";
import { import {
useProductVariantReorderMutation, useProductVariantReorderMutation,
@ -199,6 +200,18 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
variables => updatePrivateMetadata({ variables }) variables => updatePrivateMetadata({ variables })
); );
const [submitNextAction, setSubmitNextAction] = React.useState<
ProductVariantPageSubmitNextAction
>(null);
const handleSubmitNextAction = (
nextAction?: ProductVariantPageSubmitNextAction
) => {
const action = nextAction || submitNextAction;
if (action === "warehouse-configure") {
navigate(warehouseListPath);
}
};
return ( return (
<> <>
<WindowTitle title={data?.productVariant?.name} /> <WindowTitle title={data?.productVariant?.name} />
@ -218,12 +231,21 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
onBack={handleBack} onBack={handleBack}
onDelete={() => openModal("remove")} onDelete={() => openModal("remove")}
onImageSelect={handleImageSelect} onImageSelect={handleImageSelect}
onSubmit={handleSubmit} onSubmit={async data => {
const errors = await handleSubmit(data);
if (errors?.length === 0) {
handleSubmitNextAction();
} else {
setSubmitNextAction(null);
}
}}
onSubmitReject={handleSubmitNextAction}
onVariantClick={variantId => { onVariantClick={variantId => {
navigate(productVariantEditUrl(productId, variantId)); navigate(productVariantEditUrl(productId, variantId));
}} }}
onVariantReorder={handleVariantReorder} onVariantReorder={handleVariantReorder}
onWarehouseConfigure={() => openModal("leave-screen")} submitNextAction={submitNextAction}
setSubmitNextAction={setSubmitNextAction}
/> />
<ProductVariantDeleteDialog <ProductVariantDeleteDialog
confirmButtonState={deleteVariantOpts.status} confirmButtonState={deleteVariantOpts.status}
@ -239,7 +261,8 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
name={data?.productVariant?.name} name={data?.productVariant?.name}
/> />
<LeaveScreenDialog <LeaveScreenDialog
onSubmit={() => navigate(warehouseListPath)} onSaveChanges={() => navigate(warehouseListPath)}
onRejectChanges={() => navigate(warehouseListPath)}
onClose={closeModal} onClose={closeModal}
open={action === "leave-screen"} open={action === "leave-screen"}
confirmButtonState="default" confirmButtonState="default"

View file

@ -1,11 +1,9 @@
import LeaveScreenDialog from "@saleor/components/LeaveScreenDialog";
import NotFoundPage from "@saleor/components/NotFoundPage"; import NotFoundPage from "@saleor/components/NotFoundPage";
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 useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler"; import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler";
import { import {
useMetadataUpdate, useMetadataUpdate,
@ -18,7 +16,8 @@ import { useIntl } from "react-intl";
import { decimal, weight } from "../../misc"; import { decimal, weight } from "../../misc";
import ProductVariantCreatePage, { import ProductVariantCreatePage, {
ProductVariantCreatePageSubmitData ProductVariantCreatePageSubmitData,
ProductVariantCreatePageSubmitNextAction
} from "../components/ProductVariantCreatePage"; } from "../components/ProductVariantCreatePage";
import { import {
useProductVariantReorderMutation, useProductVariantReorderMutation,
@ -28,8 +27,6 @@ import { useProductVariantCreateQuery } from "../queries";
import { import {
productListUrl, productListUrl,
productUrl, productUrl,
productVariantAddUrl,
ProductVariantAddUrlDialog,
ProductVariantAddUrlQueryParams, ProductVariantAddUrlQueryParams,
productVariantEditUrl productVariantEditUrl
} from "../urls"; } from "../urls";
@ -41,10 +38,8 @@ interface ProductVariantCreateProps {
} }
export const ProductVariant: React.FC<ProductVariantCreateProps> = ({ export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
productId, productId
params
}) => { }) => {
const { action } = params;
const navigate = useNavigator(); const navigate = useNavigator();
const notify = useNotifier(); const notify = useNotifier();
const shop = useShop(); const shop = useShop();
@ -63,7 +58,7 @@ export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
const [variantCreate, variantCreateResult] = useVariantCreateMutation({ const [variantCreate, variantCreateResult] = useVariantCreateMutation({
onCompleted: data => { onCompleted: data => {
if (data.productVariantCreate.errors.length === 0) { if (data.productVariantCreate.errors.length === 0 && !submitNextAction) {
notify({ notify({
status: "success", status: "success",
text: intl.formatMessage(commonMessages.savedChanges) text: intl.formatMessage(commonMessages.savedChanges)
@ -95,11 +90,6 @@ export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
reorderProductVariants({ variables }) reorderProductVariants({ variables })
); );
const [openModal, closeModal] = createDialogActionHandlers<
ProductVariantAddUrlDialog,
ProductVariantAddUrlQueryParams
>(navigate, params => productVariantAddUrl(productId, params), params);
const handleBack = () => navigate(productUrl(productId)); const handleBack = () => navigate(productUrl(productId));
const handleCreate = async (formData: ProductVariantCreatePageSubmitData) => { const handleCreate = async (formData: ProductVariantCreatePageSubmitData) => {
const result = await variantCreate({ const result = await variantCreate({
@ -135,6 +125,18 @@ export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
const handleVariantClick = (id: string) => const handleVariantClick = (id: string) =>
navigate(productVariantEditUrl(productId, id)); navigate(productVariantEditUrl(productId, id));
const [submitNextAction, setSubmitNextAction] = React.useState<
ProductVariantCreatePageSubmitNextAction
>(null);
const handleSubmitNextAction = (
nextAction?: ProductVariantCreatePageSubmitNextAction
) => {
const action = nextAction || submitNextAction;
if (action === "warehouse-configure") {
navigate(warehouseListPath);
}
};
const disableForm = const disableForm =
productLoading || productLoading ||
variantCreateResult.loading || variantCreateResult.loading ||
@ -158,21 +160,24 @@ export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
})} })}
product={data?.product} product={data?.product}
onBack={handleBack} onBack={handleBack}
onSubmit={handleSubmit} onSubmit={async data => {
const errors = await handleSubmit(data);
if (errors?.length === 0) {
handleSubmitNextAction();
} else {
setSubmitNextAction(null);
}
}}
onSubmitReject={handleSubmitNextAction}
onVariantClick={handleVariantClick} onVariantClick={handleVariantClick}
onVariantReorder={handleVariantReorder} onVariantReorder={handleVariantReorder}
onWarehouseConfigure={() => openModal("leave-screen")}
saveButtonBarState={variantCreateResult.status} saveButtonBarState={variantCreateResult.status}
warehouses={ warehouses={
warehouses.data?.warehouses.edges.map(edge => edge.node) || [] warehouses.data?.warehouses.edges.map(edge => edge.node) || []
} }
weightUnit={shop?.defaultWeightUnit} weightUnit={shop?.defaultWeightUnit}
/> submitNextAction={submitNextAction}
<LeaveScreenDialog setSubmitNextAction={setSubmitNextAction}
onSubmit={() => navigate(warehouseListPath)}
onClose={closeModal}
open={action === "leave-screen"}
confirmButtonState="default"
/> />
</> </>
); );

View file

@ -37,7 +37,6 @@ storiesOf("Views / Products / Create product", module)
warehouses={warehouseList} warehouses={warehouseList}
taxTypes={taxTypes} taxTypes={taxTypes}
weightUnit="kg" weightUnit="kg"
onWarehouseConfigure={() => undefined}
/> />
)) ))
.add("When loading", () => ( .add("When loading", () => (
@ -61,7 +60,6 @@ storiesOf("Views / Products / Create product", module)
warehouses={undefined} warehouses={undefined}
taxTypes={taxTypes} taxTypes={taxTypes}
weightUnit="kg" weightUnit="kg"
onWarehouseConfigure={() => undefined}
/> />
)) ))
.add("form errors", () => ( .add("form errors", () => (
@ -91,6 +89,5 @@ storiesOf("Views / Products / Create product", module)
warehouses={warehouseList} warehouses={warehouseList}
taxTypes={taxTypes} taxTypes={taxTypes}
weightUnit="kg" weightUnit="kg"
onWarehouseConfigure={() => undefined}
/> />
)); ));

View file

@ -39,7 +39,6 @@ const props: ProductUpdatePageProps = {
onVariantReorder: () => undefined, onVariantReorder: () => undefined,
onVariantShow: () => undefined, onVariantShow: () => undefined,
onVariantsAdd: () => undefined, onVariantsAdd: () => undefined,
onWarehouseConfigure: () => undefined,
placeholderImage, placeholderImage,
product, product,
saveButtonBarState: "default", saveButtonBarState: "default",

View file

@ -26,7 +26,6 @@ storiesOf("Views / Products / Create product variant", module)
onVariantReorder={() => undefined} onVariantReorder={() => undefined}
saveButtonBarState="default" saveButtonBarState="default"
warehouses={warehouseList} warehouses={warehouseList}
onWarehouseConfigure={() => undefined}
/> />
)) ))
.add("with errors", () => ( .add("with errors", () => (
@ -59,7 +58,6 @@ storiesOf("Views / Products / Create product variant", module)
onVariantReorder={() => undefined} onVariantReorder={() => undefined}
saveButtonBarState="default" saveButtonBarState="default"
warehouses={warehouseList} warehouses={warehouseList}
onWarehouseConfigure={() => undefined}
/> />
)) ))
.add("when loading data", () => ( .add("when loading data", () => (
@ -76,7 +74,6 @@ storiesOf("Views / Products / Create product variant", module)
onVariantReorder={() => undefined} onVariantReorder={() => undefined}
saveButtonBarState="default" saveButtonBarState="default"
warehouses={warehouseList} warehouses={warehouseList}
onWarehouseConfigure={() => undefined}
/> />
)) ))
.add("add first variant", () => ( .add("add first variant", () => (
@ -96,6 +93,5 @@ storiesOf("Views / Products / Create product variant", module)
onVariantReorder={() => undefined} onVariantReorder={() => undefined}
saveButtonBarState="default" saveButtonBarState="default"
warehouses={warehouseList} warehouses={warehouseList}
onWarehouseConfigure={() => undefined}
/> />
)); ));

View file

@ -28,7 +28,6 @@ storiesOf("Views / Products / Product variant details", module)
onVariantReorder={() => undefined} onVariantReorder={() => undefined}
saveButtonBarState="default" saveButtonBarState="default"
warehouses={warehouseList} warehouses={warehouseList}
onWarehouseConfigure={() => undefined}
/> />
)) ))
.add("when loading data", () => ( .add("when loading data", () => (
@ -48,7 +47,6 @@ storiesOf("Views / Products / Product variant details", module)
onVariantReorder={() => undefined} onVariantReorder={() => undefined}
saveButtonBarState="default" saveButtonBarState="default"
warehouses={warehouseList} warehouses={warehouseList}
onWarehouseConfigure={() => undefined}
/> />
)) ))
.add("attribute errors", () => ( .add("attribute errors", () => (
@ -84,6 +82,5 @@ storiesOf("Views / Products / Product variant details", module)
...error ...error
}))} }))}
warehouses={warehouseList} warehouses={warehouseList}
onWarehouseConfigure={() => undefined}
/> />
)); ));