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,9 +121,10 @@ 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
: shippingZone.default
? intl.formatMessage({ ? intl.formatMessage({
defaultMessage: defaultMessage:
"This is default shipping zone, which means that it covers all of the countries which are not assigned to other shipping zones" "This is default shipping zone, which means that it covers all of the countries which are not assigned to other shipping zones"
@ -132,8 +132,7 @@ const ShippingZoneDetailsPage: React.FC<ShippingZoneDetailsPageProps> = ({
: intl.formatMessage({ : intl.formatMessage({
defaultMessage: defaultMessage:
"Currently, there are no countries assigned to this shipping zone" "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,8 +144,9 @@ const ShippingZoneDetails: React.FC<ShippingZoneDetailsProps> = ({
} }
}); });
const handleSubmit = (data: FormData) => { const handleSubmit = async (data: FormData) => {
updateShippingZone({ try {
const updateResult = await updateShippingZone({
variables: { variables: {
id, id,
input: { input: {
@ -153,12 +154,35 @@ const ShippingZoneDetails: React.FC<ShippingZoneDetailsProps> = ({
} }
} }
}); });
assignToWarehouse({ const updateErrors = updateResult.data.shippingZoneUpdate.errors;
if (updateErrors.length === 0) {
const assignResult = await assignToWarehouse({
variables: { variables: {
shippingZoneId: id, shippingZoneId: id,
warehouseId: data.warehouses[0] 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) {
notify({
text: intl.formatMessage(commonMessages.somethingWentWrong)
});
}
}; };
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;
}