Fix assigning shipping zone to warehouse

This commit is contained in:
dominik-zeglen 2020-03-19 13:44:54 +01:00
parent 220f77c20a
commit 0805ff052d
8 changed files with 103 additions and 80 deletions

View file

@ -110,13 +110,14 @@ const useStyles = makeStyles(
function getChoiceIndex( function getChoiceIndex(
index: number, index: number,
emptyValue: boolean, emptyValue: boolean,
customValue: boolean customValue: boolean,
add: boolean
) { ) {
let choiceIndex = index; let choiceIndex = index;
if (emptyValue) { if (emptyValue) {
choiceIndex += 1; choiceIndex += 1;
} }
if (customValue) { if (customValue || add) {
choiceIndex += 2; choiceIndex += 2;
} }
@ -222,7 +223,8 @@ const SingleAutocompleteSelectFieldContent: React.FC<SingleAutocompleteSelectFie
const choiceIndex = getChoiceIndex( const choiceIndex = getChoiceIndex(
index, index,
emptyOption, emptyOption,
!!add || displayCustomValue displayCustomValue,
!!add
); );
return ( return (

View file

@ -11,10 +11,10 @@ import Grid from "@saleor/components/Grid";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar"; import SaveButtonBar from "@saleor/components/SaveButtonBar";
import { ShippingErrorFragment } from "@saleor/shipping/types/ShippingErrorFragment"; import { ShippingErrorFragment } from "@saleor/shipping/types/ShippingErrorFragment";
import createMultiAutocompleteSelectHandler from "@saleor/utils/handlers/multiAutocompleteSelectChangeHandler"; import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField"; import { SingleAutocompleteChoiceType } from "@saleor/components/SingleAutocompleteSelectField";
import useStateFromProps from "@saleor/hooks/useStateFromProps"; import useStateFromProps from "@saleor/hooks/useStateFromProps";
import { maybe } from "../../../misc"; import { getStringOrPlaceholder } from "../../../misc";
import { FetchMoreProps, SearchProps } from "../../../types"; import { FetchMoreProps, SearchProps } from "../../../types";
import { ShippingMethodTypeEnum } from "../../../types/globalTypes"; import { ShippingMethodTypeEnum } from "../../../types/globalTypes";
import { import {
@ -27,7 +27,7 @@ import ShippingZoneWarehouses from "../ShippingZoneWarehouses";
export interface FormData { export interface FormData {
name: string; name: string;
warehouses: string[]; warehouse: string;
} }
export interface ShippingZoneDetailsPageProps export interface ShippingZoneDetailsPageProps
@ -53,7 +53,7 @@ export interface ShippingZoneDetailsPageProps
function warehouseToChoice( function warehouseToChoice(
warehouse: Record<"id" | "name", string> warehouse: Record<"id" | "name", string>
): MultiAutocompleteChoiceType { ): SingleAutocompleteChoiceType {
return { return {
label: warehouse.name, label: warehouse.name,
value: warehouse.id value: warehouse.id
@ -86,10 +86,10 @@ const ShippingZoneDetailsPage: React.FC<ShippingZoneDetailsPageProps> = ({
const initialForm: FormData = { const initialForm: FormData = {
name: shippingZone?.name || "", name: shippingZone?.name || "",
warehouses: shippingZone?.warehouses.map(warehouse => warehouse.id) || [] warehouse: shippingZone?.warehouses[0]?.id || null
}; };
const [warehouseDisplayValues, setWarehouseDisplayValues] = useStateFromProps( const [warehouseDisplayValue, setWarehouseDisplayValue] = useStateFromProps(
shippingZone?.warehouses.map(warehouseToChoice) || [] shippingZone?.warehouses[0]?.name || ""
); );
const warehouseChoices = warehouses.map(warehouseToChoice); const warehouseChoices = warehouses.map(warehouseToChoice);
@ -97,10 +97,9 @@ const ShippingZoneDetailsPage: React.FC<ShippingZoneDetailsPageProps> = ({
return ( return (
<Form initial={initialForm} onSubmit={onSubmit}> <Form initial={initialForm} onSubmit={onSubmit}>
{({ change, data, hasChanged, submit }) => { {({ change, data, hasChanged, submit }) => {
const handleWarehouseChange = createMultiAutocompleteSelectHandler( const handleWarehouseChange = createSingleAutocompleteSelectHandler(
change, change,
setWarehouseDisplayValues, setWarehouseDisplayValue,
warehouseDisplayValues,
warehouseChoices warehouseChoices
); );
@ -122,18 +121,18 @@ const ShippingZoneDetailsPage: React.FC<ShippingZoneDetailsPageProps> = ({
<CountryList <CountryList
countries={shippingZone?.countries} countries={shippingZone?.countries}
disabled={disabled} disabled={disabled}
emptyText={maybe( emptyText={getStringOrPlaceholder(
() => shippingZone?.default === undefined
shippingZone.default ? undefined
? intl.formatMessage({ : shippingZone.default
defaultMessage: ? intl.formatMessage({
"This is default shipping zone, which means that it covers all of the countries which are not assigned to other shipping zones" defaultMessage:
}) "This is default shipping zone, which means that it covers all of the countries which are not assigned to other shipping zones"
: intl.formatMessage({ })
defaultMessage: : intl.formatMessage({
"Currently, there are no countries assigned to this shipping zone" defaultMessage:
}), "Currently, there are no countries assigned to this shipping zone"
"..." })
)} )}
onCountryAssign={onCountryAdd} onCountryAssign={onCountryAdd}
onCountryUnassign={onCountryRemove} onCountryUnassign={onCountryRemove}
@ -167,7 +166,7 @@ const ShippingZoneDetailsPage: React.FC<ShippingZoneDetailsPageProps> = ({
<div> <div>
<ShippingZoneWarehouses <ShippingZoneWarehouses
data={data} data={data}
displayValue={warehouseDisplayValues} displayValue={warehouseDisplayValue}
hasMore={hasMore} hasMore={hasMore}
loading={loading} loading={loading}
onChange={handleWarehouseChange} onChange={handleWarehouseChange}

View file

@ -6,17 +6,17 @@ import { useIntl } from "react-intl";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import { FetchMoreProps, SearchProps } from "@saleor/types"; import { FetchMoreProps, SearchProps } from "@saleor/types";
import { FormChange } from "@saleor/hooks/useForm"; import { FormChange } from "@saleor/hooks/useForm";
import MultiAutocompleteSelectField, { import SingleAutocompleteSelectField, {
MultiAutocompleteChoiceType SingleAutocompleteChoiceType
} from "@saleor/components/MultiAutocompleteSelectField"; } from "@saleor/components/SingleAutocompleteSelectField";
interface ShippingZoneWarehousesFormData { interface ShippingZoneWarehousesFormData {
warehouses: string[]; warehouse: string;
} }
interface ShippingZonewWarehousesProps extends FetchMoreProps, SearchProps { interface ShippingZonewWarehousesProps extends FetchMoreProps, SearchProps {
data: ShippingZoneWarehousesFormData; data: ShippingZoneWarehousesFormData;
displayValue: MultiAutocompleteChoiceType[]; displayValue: string;
warehouses: MultiAutocompleteChoiceType[]; warehouses: SingleAutocompleteChoiceType[];
onChange: FormChange; onChange: FormChange;
onWarehouseAdd: () => void; onWarehouseAdd: () => void;
} }
@ -44,7 +44,7 @@ export const ShippingZoneWarehouses: React.FC<ShippingZonewWarehousesProps> = pr
})} })}
/> />
<CardContent> <CardContent>
<MultiAutocompleteSelectField <SingleAutocompleteSelectField
add={{ add={{
label: intl.formatMessage({ label: intl.formatMessage({
defaultMessage: "Add New Warehouse", defaultMessage: "Add New Warehouse",
@ -53,7 +53,7 @@ export const ShippingZoneWarehouses: React.FC<ShippingZonewWarehousesProps> = pr
onClick: onWarehouseAdd onClick: onWarehouseAdd
}} }}
choices={warehouses} choices={warehouses}
displayValues={displayValue} displayValue={displayValue}
fetchChoices={onSearchChange} fetchChoices={onSearchChange}
hasMore={hasMore} hasMore={hasMore}
helperText={intl.formatMessage({ helperText={intl.formatMessage({
@ -66,14 +66,14 @@ export const ShippingZoneWarehouses: React.FC<ShippingZonewWarehousesProps> = pr
id: "shippingZoneWarehouses.autocomplete.label" id: "shippingZoneWarehouses.autocomplete.label"
})} })}
loading={loading} loading={loading}
name="warehouses" name="warehouse"
onChange={onChange} onChange={onChange}
onFetchMore={onFetchMore} onFetchMore={onFetchMore}
placeholder={intl.formatMessage({ placeholder={intl.formatMessage({
defaultMessage: "Select Warehouse", defaultMessage: "Select Warehouse",
description: "input placeholder" description: "input placeholder"
})} })}
value={data.warehouses} value={data.warehouse}
/> />
</CardContent> </CardContent>
</Card> </Card>

View file

@ -1,6 +1,7 @@
import gql from "graphql-tag"; import gql from "graphql-tag";
import makeMutation from "@saleor/hooks/makeMutation"; import makeMutation from "@saleor/hooks/makeMutation";
import { warehouseErrorFragment } from "@saleor/warehouses/mutations";
import { countryFragment } from "../taxes/queries"; import { countryFragment } from "../taxes/queries";
import { shippingMethodFragment, shippingZoneDetailsFragment } from "./queries"; import { shippingMethodFragment, shippingZoneDetailsFragment } from "./queries";
import { import {
@ -43,10 +44,6 @@ import {
AssignShippingZoneToWarehouse, AssignShippingZoneToWarehouse,
AssignShippingZoneToWarehouseVariables AssignShippingZoneToWarehouseVariables
} from "./types/AssignShippingZoneToWarehouse"; } from "./types/AssignShippingZoneToWarehouse";
import {
UnassignShippingZoneToWarehouse,
UnassignShippingZoneToWarehouseVariables
} from "./types/UnassignShippingZoneToWarehouse";
export const shippingErrorFragment = gql` export const shippingErrorFragment = gql`
fragment ShippingErrorFragment on ShippingError { fragment ShippingErrorFragment on ShippingError {
@ -224,6 +221,7 @@ export const useShippingRateBulkDelete = makeMutation<
>(bulkDeleteShippingRate); >(bulkDeleteShippingRate);
const assignShippingZoneToWarehouse = gql` const assignShippingZoneToWarehouse = gql`
${warehouseErrorFragment}
mutation AssignShippingZoneToWarehouse( mutation AssignShippingZoneToWarehouse(
$warehouseId: ID! $warehouseId: ID!
$shippingZoneId: ID! $shippingZoneId: ID!
@ -232,9 +230,8 @@ const assignShippingZoneToWarehouse = gql`
id: $warehouseId id: $warehouseId
shippingZoneIds: [$shippingZoneId] shippingZoneIds: [$shippingZoneId]
) { ) {
warehouseErrors { errors: warehouseErrors {
code ...WarehouseErrorFragment
field
} }
} }
} }
@ -243,24 +240,3 @@ export const useAssignShippingZoneToWarehouse = makeMutation<
AssignShippingZoneToWarehouse, AssignShippingZoneToWarehouse,
AssignShippingZoneToWarehouseVariables AssignShippingZoneToWarehouseVariables
>(assignShippingZoneToWarehouse); >(assignShippingZoneToWarehouse);
const unassignShippingZoneToWarehouse = gql`
mutation UnassignShippingZoneToWarehouse(
$warehouseId: ID!
$shippingZoneId: ID!
) {
unassignWarehouseShippingZone(
id: $warehouseId
shippingZoneIds: [$shippingZoneId]
) {
warehouseErrors {
code
field
}
}
}
`;
export const useUnassignShippingZoneToWarehouse = makeMutation<
UnassignShippingZoneToWarehouse,
UnassignShippingZoneToWarehouseVariables
>(unassignShippingZoneToWarehouse);

View file

@ -8,7 +8,7 @@ import { WarehouseErrorCode } from "./../../types/globalTypes";
// GraphQL mutation operation: AssignShippingZoneToWarehouse // GraphQL mutation operation: AssignShippingZoneToWarehouse
// ==================================================== // ====================================================
export interface AssignShippingZoneToWarehouse_assignWarehouseShippingZone_warehouseErrors { export interface AssignShippingZoneToWarehouse_assignWarehouseShippingZone_errors {
__typename: "WarehouseError"; __typename: "WarehouseError";
code: WarehouseErrorCode; code: WarehouseErrorCode;
field: string | null; field: string | null;
@ -16,7 +16,7 @@ export interface AssignShippingZoneToWarehouse_assignWarehouseShippingZone_wareh
export interface AssignShippingZoneToWarehouse_assignWarehouseShippingZone { export interface AssignShippingZoneToWarehouse_assignWarehouseShippingZone {
__typename: "WarehouseShippingZoneAssign"; __typename: "WarehouseShippingZoneAssign";
warehouseErrors: AssignShippingZoneToWarehouse_assignWarehouseShippingZone_warehouseErrors[]; errors: AssignShippingZoneToWarehouse_assignWarehouseShippingZone_errors[];
} }
export interface AssignShippingZoneToWarehouse { export interface AssignShippingZoneToWarehouse {

View file

@ -144,21 +144,45 @@ const ShippingZoneDetails: React.FC<ShippingZoneDetailsProps> = ({
} }
}); });
const handleSubmit = (data: FormData) => { const handleSubmit = async (data: FormData) => {
updateShippingZone({ try {
variables: { const updateResult = await updateShippingZone({
id, variables: {
input: { id,
name: data.name input: {
name: data.name
}
} }
});
const updateErrors = updateResult.data.shippingZoneUpdate.errors;
if (updateErrors.length === 0) {
const assignResult = await assignToWarehouse({
variables: {
shippingZoneId: id,
warehouseId: data.warehouse
}
});
const assignErrors =
assignResult.data.assignWarehouseShippingZone.errors;
if (assignErrors.length === 0) {
notify({
text: intl.formatMessage(commonMessages.savedChanges)
});
} else {
throw new Error(
`Assigning to warehouse failed: ${assignErrors[0].code}`
);
}
} else {
throw new Error(`Updating failed: ${updateErrors[0].message}`);
} }
}); } catch (err) {
assignToWarehouse({ notify({
variables: { text: intl.formatMessage(commonMessages.somethingWentWrong)
shippingZoneId: id, });
warehouseId: data.warehouses[0] }
}
});
}; };
if (data?.shippingZone === null) { if (data?.shippingZone === null) {

View file

@ -15,6 +15,13 @@ import {
} from "./types/WarehouseDelete"; } from "./types/WarehouseDelete";
import { warehouseDetailsFragment } from "./queries"; import { warehouseDetailsFragment } from "./queries";
export const warehouseErrorFragment = gql`
fragment WarehouseErrorFragment on WarehouseError {
code
field
}
`;
const deleteWarehouse = gql` const deleteWarehouse = gql`
mutation WarehouseDelete($id: ID!) { mutation WarehouseDelete($id: ID!) {
deleteWarehouse(id: $id) { deleteWarehouse(id: $id) {

View file

@ -0,0 +1,15 @@
/* tslint:disable */
/* eslint-disable */
// This file was automatically generated and should not be edited.
import { WarehouseErrorCode } from "./../../types/globalTypes";
// ====================================================
// GraphQL fragment: WarehouseErrorFragment
// ====================================================
export interface WarehouseErrorFragment {
__typename: "WarehouseError";
code: WarehouseErrorCode;
field: string | null;
}