Refactor of postalCodes related components (#999)

* Refactor of postalCodes related components

* CR changes

* Simplify postal codes reducer

* Typing for newState in postal codes reducer
This commit is contained in:
Tomasz Szymański 2021-03-12 12:55:14 +01:00 committed by GitHub
parent bf9b7c5120
commit 88f51a1d31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 299 additions and 610 deletions

View file

@ -91,3 +91,7 @@ export const getParsedFulfiledLines = (
export const getById = (idToCompare: string) => (obj: { id: string }) =>
obj.id === idToCompare;
export const getByUnmatchingId = (idToCompare: string) => (obj: {
id: string;
}) => obj.id !== idToCompare;

View file

@ -24,7 +24,6 @@ import { FormattedMessage, useIntl } from "react-intl";
export interface ShippingZonePostalCodesProps {
disabled: boolean;
initialExpanded?: boolean;
initialInclusionType?: PostalCodeRuleInclusionTypeEnum;
postalCodes: ShippingMethodFragment_postalCodeRules[] | undefined;
onPostalCodeInclusionChange: (
inclusion: PostalCodeRuleInclusionTypeEnum
@ -64,7 +63,6 @@ const useStyles = makeStyles(
const ShippingZonePostalCodes: React.FC<ShippingZonePostalCodesProps> = ({
disabled,
initialExpanded = true,
initialInclusionType = PostalCodeRuleInclusionTypeEnum.EXCLUDE,
postalCodes,
onPostalCodeDelete,
onPostalCodeInclusionChange,
@ -75,6 +73,15 @@ const ShippingZonePostalCodes: React.FC<ShippingZonePostalCodesProps> = ({
const intl = useIntl();
const classes = useStyles({});
const getInclusionType = () => {
if (inclusionType) {
return inclusionType;
}
return (
postalCodes[0]?.inclusionType || PostalCodeRuleInclusionTypeEnum.EXCLUDE
);
};
const onInclusionRadioChange = (event: React.ChangeEvent<any>) => {
const value = event.target.value;
setInclusionType(value);
@ -93,9 +100,6 @@ const ShippingZonePostalCodes: React.FC<ShippingZonePostalCodesProps> = ({
return postalCodeRange.start;
};
const getInlcusionType = () =>
inclusionType === null ? initialInclusionType : inclusionType;
return (
<Card>
<CardTitle
@ -154,7 +158,7 @@ const ShippingZonePostalCodes: React.FC<ShippingZonePostalCodesProps> = ({
}
]}
name="includePostalCodes"
value={getInlcusionType()}
value={getInclusionType()}
onChange={onInclusionRadioChange}
/>
</CardContent>

View file

@ -91,12 +91,6 @@ export const ShippingZoneRatesCreatePage: React.FC<ShippingZoneRatesCreatePagePr
type: null
};
const postalCodeInclusionChange = (
inclusion: PostalCodeRuleInclusionTypeEnum
) => {
onPostalCodeInclusionChange(inclusion);
};
return (
<Form initial={initialForm} onSubmit={onSubmit}>
{({ change, data, hasChanged, submit, triggerChange }) => {
@ -166,7 +160,7 @@ export const ShippingZoneRatesCreatePage: React.FC<ShippingZoneRatesCreatePagePr
<ShippingZonePostalCodes
disabled={disabled}
onPostalCodeDelete={onPostalCodeUnassign}
onPostalCodeInclusionChange={postalCodeInclusionChange}
onPostalCodeInclusionChange={onPostalCodeInclusionChange}
onPostalCodeRangeAdd={onPostalCodeAssign}
postalCodes={postalCodes}
/>

View file

@ -56,6 +56,7 @@ const props: ShippingZoneRatesPageProps = {
onProductUnassign: () => undefined,
onSubmit: () => undefined,
openChannelsModal: () => undefined,
postalCodeRules: [],
rate: shippingZone.shippingMethods[0],
saveButtonBarState: "default",
selected: 0,

View file

@ -20,7 +20,10 @@ import PricingCard from "@saleor/shipping/components/PricingCard";
import ShippingMethodProducts from "@saleor/shipping/components/ShippingMethodProducts";
import ShippingRateInfo from "@saleor/shipping/components/ShippingRateInfo";
import { createChannelsChangeHandler } from "@saleor/shipping/handlers";
import { ShippingZone_shippingZone_shippingMethods } from "@saleor/shipping/types/ShippingZone";
import {
ShippingZone_shippingZone_shippingMethods,
ShippingZone_shippingZone_shippingMethods_postalCodeRules
} from "@saleor/shipping/types/ShippingZone";
import { ListActions, ListProps } from "@saleor/types";
import {
PostalCodeRuleInclusionTypeEnum,
@ -56,6 +59,7 @@ export interface ShippingZoneRatesPageProps
channelErrors: ShippingChannelsErrorFragment[];
errors: ShippingErrorFragment[];
saveButtonBarState: ConfirmButtonTransitionState;
postalCodeRules: ShippingZone_shippingZone_shippingMethods_postalCodeRules[];
onBack: () => void;
onDelete?: () => void;
onSubmit: (data: FormData) => void;
@ -91,6 +95,7 @@ export const ShippingZoneRatesPage: React.FC<ShippingZoneRatesPageProps> = ({
openChannelsModal,
rate,
saveButtonBarState,
postalCodeRules,
variant,
...listProps
}) => {
@ -108,14 +113,6 @@ export const ShippingZoneRatesPage: React.FC<ShippingZoneRatesPageProps> = ({
type: rate?.type || null
};
const postalCodesInclusionType = rate?.postalCodeRules[0]?.inclusionType;
const postalCodeInclusionChange = (
inclusion: PostalCodeRuleInclusionTypeEnum
) => {
onPostalCodeInclusionChange(inclusion);
};
const {
makeChangeHandler: makeMetadataChangeHandler
} = useMetadataChangeTrigger();
@ -181,10 +178,9 @@ export const ShippingZoneRatesPage: React.FC<ShippingZoneRatesPageProps> = ({
<ShippingZonePostalCodes
disabled={disabled}
onPostalCodeDelete={onPostalCodeUnassign}
onPostalCodeInclusionChange={postalCodeInclusionChange}
onPostalCodeInclusionChange={onPostalCodeInclusionChange}
onPostalCodeRangeAdd={onPostalCodeAssign}
postalCodes={rate?.postalCodeRules}
initialInclusionType={postalCodesInclusionType}
postalCodes={postalCodeRules}
/>
<CardSpacer />
<ShippingMethodProducts

View file

@ -14,7 +14,12 @@ import {
ShippingRateCreateUrlQueryParams,
shippingZoneUrl
} from "@saleor/shipping/urls";
import filterPostalCodes from "@saleor/shipping/views/utils";
import postalCodesReducer from "@saleor/shipping/views/reducer";
import {
filterPostalCodes,
getPostalCodeRuleByMinMax,
getRuleObject
} from "@saleor/shipping/views/utils";
import { MinMax } from "@saleor/types";
import {
PostalCodeRuleInclusionTypeEnum,
@ -36,11 +41,6 @@ export const PriceRatesCreate: React.FC<PriceRatesCreateProps> = ({
const navigate = useNavigator();
const intl = useIntl();
const [postalCodes, setPostalCodes] = React.useState([]);
const [radioInclusionType, setRadioInclusionType] = React.useState(
PostalCodeRuleInclusionTypeEnum.EXCLUDE
);
const { data: channelsData, loading: channelsLoading } = useChannelsList({});
const [openModal, closeModal] = createDialogActionHandlers<
@ -63,6 +63,14 @@ export const PriceRatesCreate: React.FC<PriceRatesCreateProps> = ({
toggleAllChannels
} = useChannels(allChannels, params?.action, { closeModal, openModal });
const [state, dispatch] = React.useReducer(postalCodesReducer, {
codesToDelete: [],
havePostalCodesChanged: false,
inclusionType: PostalCodeRuleInclusionTypeEnum.EXCLUDE,
originalCodes: [],
postalCodeRules: []
});
const {
channelErrors,
createShippingRate,
@ -71,33 +79,42 @@ export const PriceRatesCreate: React.FC<PriceRatesCreateProps> = ({
} = useShippingRateCreator(
id,
ShippingMethodTypeEnum.PRICE,
postalCodes,
radioInclusionType
state.postalCodeRules,
state.inclusionType
);
const handleBack = () => navigate(shippingZoneUrl(id));
const handlePostalCodeRangeAdd = (data: MinMax) => {
setPostalCodes(postalCodes => [
...postalCodes,
{
end: data.max,
start: data.min
}
]);
const onPostalCodeAssign = (rule: MinMax) => {
if (
state.postalCodeRules.filter(getPostalCodeRuleByMinMax(rule)).length > 0
) {
closeModal();
return;
}
const newCode = getRuleObject(rule, state.inclusionType);
dispatch({
havePostalCodesChanged: true,
postalCodeRules: [...state.postalCodeRules, newCode]
});
closeModal();
};
const onPostalCodeInclusionChange = (
inclusion: PostalCodeRuleInclusionTypeEnum
) => {
setRadioInclusionType(inclusion);
setPostalCodes([]);
dispatch({
inclusionType: inclusion,
postalCodeRules: []
});
};
const onPostalCodeUnassign = code => {
setPostalCodes(filterPostalCodes(postalCodes, code));
closeModal();
dispatch({
havePostalCodesChanged: true,
postalCodeRules: filterPostalCodes(state.postalCodeRules, code)
});
};
return (
@ -130,7 +147,7 @@ export const PriceRatesCreate: React.FC<PriceRatesCreateProps> = ({
onBack={handleBack}
errors={errors}
channelErrors={channelErrors}
postalCodes={postalCodes}
postalCodes={state.postalCodeRules}
openChannelsModal={handleChannelsModalOpen}
onChannelsChange={setCurrentChannels}
onPostalCodeAssign={() => openModal("add-range")}
@ -141,7 +158,7 @@ export const PriceRatesCreate: React.FC<PriceRatesCreateProps> = ({
<ShippingZonePostalCodeRangeDialog
confirmButtonState="default"
onClose={closeModal}
onSubmit={handlePostalCodeRangeAdd}
onSubmit={onPostalCodeAssign}
open={params.action === "add-range"}
/>
</>

View file

@ -17,6 +17,10 @@ import usePaginator, {
} from "@saleor/hooks/usePaginator";
import { sectionNames } from "@saleor/intl";
import { commonMessages } from "@saleor/intl";
import {
getById,
getByUnmatchingId
} from "@saleor/orders/components/OrderReturnPage/utils";
import useProductSearch from "@saleor/searches/useProductSearch";
import DeleteShippingRateDialog from "@saleor/shipping/components/DeleteShippingRateDialog";
import ShippingMethodProductsAddDialog from "@saleor/shipping/components/ShippingMethodProductsAddDialog";
@ -43,7 +47,12 @@ import {
ShippingRateUrlQueryParams,
shippingZoneUrl
} from "@saleor/shipping/urls";
import filterPostalCodes from "@saleor/shipping/views/utils";
import postalCodesReducer from "@saleor/shipping/views/reducer";
import {
filterPostalCodes,
getPostalCodeRuleByMinMax,
getRuleObject
} from "@saleor/shipping/views/utils";
import { MinMax } from "@saleor/types";
import {
PostalCodeRuleInclusionTypeEnum,
@ -80,6 +89,9 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
displayLoader: true,
variables: { id, ...paginationState }
});
const rate = data?.shippingZone?.shippingMethods?.find(getById(rateId));
const {
loadMore,
search: productsSearch,
@ -91,10 +103,6 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
ShippingRateUrlQueryParams
>(navigate, params => shippingPriceRatesEditUrl(id, rateId, params), params);
const rate = data?.shippingZone?.shippingMethods.find(
rate => rate.id === rateId
);
const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions(
[]
);
@ -174,26 +182,33 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
const [updateMetadata] = useMetadataUpdate({});
const [updatePrivateMetadata] = usePrivateMetadataUpdate({});
const [codesToDelete, setCodesToDelete] = React.useState([]);
const [havePostalCodesChanged, setHavePostalCodesChanged] = React.useState(
false
);
const [originalCodes, setOriginalCodes] = React.useState([]);
const [inclusionType, setInclusionType] = React.useState(
rate?.postalCodeRules[0]?.inclusionType
);
const [state, dispatch] = React.useReducer(postalCodesReducer, {
codesToDelete: [],
havePostalCodesChanged: false,
inclusionType: rate?.postalCodeRules[0]?.inclusionType,
originalCodes: [],
postalCodeRules: rate?.postalCodeRules || []
});
const postalCodeRulesLoaded =
!loading &&
!state.postalCodeRules?.length &&
!state.codesToDelete?.length &&
rate.postalCodeRules?.length;
if (postalCodeRulesLoaded) {
dispatch({ postalCodeRules: rate.postalCodeRules });
}
const onPostalCodeInclusionChange = (
inclusion: PostalCodeRuleInclusionTypeEnum
) => {
setInclusionType(inclusion);
setCodesToDelete(
rate.postalCodeRules
.filter(code => code.id !== undefined)
.map(code => code.id)
);
setHavePostalCodesChanged(true);
rate.postalCodeRules = [];
dispatch({
codesToDelete: rate.postalCodeRules.map(code => code.id),
havePostalCodesChanged: true,
inclusionType: inclusion,
postalCodeRules: []
});
};
const updateData = async (formData: FormData): Promise<unknown[]> => {
@ -202,15 +217,15 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
formData,
id,
rateId,
rate.postalCodeRules,
codesToDelete
state.postalCodeRules,
state.codesToDelete
)
});
setCodesToDelete([]);
setHavePostalCodesChanged(false);
dispatch({ codesToDelete: [] });
const errors = response.data.shippingPriceUpdate.errors;
if (errors.length === 0) {
handleSuccess();
dispatch({ havePostalCodesChanged: false });
updateShippingMethodChannelListing({
variables: getShippingMethodChannelVariables(
rateId,
@ -244,38 +259,40 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
};
const onPostalCodeAssign = (rule: MinMax) => {
if (!originalCodes.length) {
setOriginalCodes([...rate.postalCodeRules]);
if (!state.originalCodes.length) {
dispatch({ originalCodes: rate.postalCodeRules });
}
if (
rate.postalCodeRules.filter(
item => item.start === rule.min && item.end === rule.max
).length > 0
state.postalCodeRules.filter(getPostalCodeRuleByMinMax(rule)).length > 0
) {
closeModal();
return;
}
const newCode = {
__typename: undefined,
end: rule.max,
id: undefined,
inclusionType,
start: rule.min
};
rate.postalCodeRules.push(newCode);
const newCode = getRuleObject(rule, state.inclusionType);
dispatch({
havePostalCodesChanged: true,
postalCodeRules: [...state.postalCodeRules, newCode]
});
closeModal();
};
const onPostalCodeUnassign = code => {
if (code.id !== undefined) {
setCodesToDelete([...codesToDelete, code.id]);
rate.postalCodeRules = rate.postalCodeRules.filter(
rule => rule.id !== code.id
);
dispatch({
codesToDelete: [...state.codesToDelete, code.id],
havePostalCodesChanged: true,
postalCodeRules: state.postalCodeRules.filter(
getByUnmatchingId(code.id)
)
});
} else {
rate.postalCodeRules = filterPostalCodes(rate.postalCodeRules, code);
dispatch({
havePostalCodesChanged: true,
postalCodeRules: filterPostalCodes(state.postalCodeRules, code)
});
}
setHavePostalCodesChanged(true);
};
const handleBack = () => navigate(shippingZoneUrl(id));
@ -344,7 +361,7 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
assignProductOpts?.status === "loading"
}
hasChannelChanged={shippingChannels?.length !== currentChannels?.length}
havePostalCodesChanged={havePostalCodesChanged}
havePostalCodesChanged={state.havePostalCodesChanged}
saveButtonBarState={updateShippingRateOpts.status}
onDelete={() => openModal("remove")}
onSubmit={handleSubmit}
@ -378,14 +395,12 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
onPostalCodeInclusionChange={onPostalCodeInclusionChange}
onPostalCodeAssign={() => openModal("add-range")}
onPostalCodeUnassign={onPostalCodeUnassign}
postalCodeRules={state.postalCodeRules}
/>
<ShippingZonePostalCodeRangeDialog
confirmButtonState={"default"}
onClose={closeModal}
onSubmit={code => {
onPostalCodeAssign(code);
setHavePostalCodesChanged(true);
}}
onSubmit={code => onPostalCodeAssign(code)}
open={params.action === "add-range"}
/>
</>

View file

@ -9,6 +9,7 @@ import useNotifier from "@saleor/hooks/useNotifier";
import { createPaginationState } from "@saleor/hooks/usePaginator";
import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl";
import { getById } from "@saleor/orders/components/OrderReturnPage/utils";
import useWarehouseSearch from "@saleor/searches/useWarehouseSearch";
import DeleteShippingRateDialog from "@saleor/shipping/components/DeleteShippingRateDialog";
import ShippingZoneAddWarehouseDialog from "@saleor/shipping/components/ShippingZoneAddWarehouseDialog";
@ -78,9 +79,7 @@ const ShippingZoneDetails: React.FC<ShippingZoneDetailsProps> = ({
ShippingZoneUrlDialog,
ShippingZoneUrlQueryParams
>(navigate, params => shippingZoneUrl(id, params), params);
const rate = data?.shippingZone?.shippingMethods?.find(
rate => rate.id === params.id
);
const rate = data?.shippingZone?.shippingMethods?.find(getById(params.id));
const [deleteShippingRate, deleteShippingRateOpts] = useShippingRateDelete({
onCompleted: data => {

View file

@ -17,7 +17,12 @@ import {
shippingWeightRatesUrl,
shippingZoneUrl
} from "@saleor/shipping/urls";
import filterPostalCodes from "@saleor/shipping/views/utils";
import postalCodesReducer from "@saleor/shipping/views/reducer";
import {
filterPostalCodes,
getPostalCodeRuleByMinMax,
getRuleObject
} from "@saleor/shipping/views/utils";
import { MinMax } from "@saleor/types";
import {
PostalCodeRuleInclusionTypeEnum,
@ -39,11 +44,6 @@ export const WeightRatesCreate: React.FC<WeightRatesCreateProps> = ({
const navigate = useNavigator();
const intl = useIntl();
const [postalCodes, setPostalCodes] = React.useState([]);
const [radioInclusionType, setRadioInclusionType] = React.useState(
PostalCodeRuleInclusionTypeEnum.EXCLUDE
);
const { data: channelsData, loading: channelsLoading } = useChannelsList({});
const [openModal, closeModal] = createDialogActionHandlers<
@ -67,6 +67,14 @@ export const WeightRatesCreate: React.FC<WeightRatesCreateProps> = ({
toggleAllChannels
} = useChannels(shippingChannels, params?.action, { closeModal, openModal });
const [state, dispatch] = React.useReducer(postalCodesReducer, {
codesToDelete: [],
havePostalCodesChanged: false,
inclusionType: PostalCodeRuleInclusionTypeEnum.EXCLUDE,
originalCodes: [],
postalCodeRules: []
});
const {
channelErrors,
createShippingRate,
@ -75,36 +83,42 @@ export const WeightRatesCreate: React.FC<WeightRatesCreateProps> = ({
} = useShippingRateCreator(
id,
ShippingMethodTypeEnum.WEIGHT,
postalCodes,
radioInclusionType
state.postalCodeRules,
state.inclusionType
);
const handleBack = () => navigate(shippingZoneUrl(id));
const handlePostalCodeRangeAdd = (data: MinMax) => {
setPostalCodes(postalCodes => [
...postalCodes,
{
__typename: "ShippingMethodPostalCodeRule",
end: data.max,
id: postalCodes.length.toString(),
inclusionType: postalCodes?.[0]?.inclusionType,
start: data.min
}
]);
const onPostalCodeAssign = (rule: MinMax) => {
if (
state.postalCodeRules.filter(getPostalCodeRuleByMinMax(rule)).length > 0
) {
closeModal();
return;
}
const newCode = getRuleObject(rule, state.inclusionType);
dispatch({
havePostalCodesChanged: true,
postalCodeRules: [...state.postalCodeRules, newCode]
});
closeModal();
};
const onPostalCodeInclusionChange = (
inclusion: PostalCodeRuleInclusionTypeEnum
) => {
setRadioInclusionType(inclusion);
setPostalCodes([]);
dispatch({
inclusionType: inclusion,
postalCodeRules: []
});
};
const onPostalCodeUnassign = code => {
setPostalCodes(filterPostalCodes(postalCodes, code));
closeModal();
dispatch({
havePostalCodesChanged: true,
postalCodeRules: filterPostalCodes(state.postalCodeRules, code)
});
};
return (
@ -136,7 +150,7 @@ export const WeightRatesCreate: React.FC<WeightRatesCreateProps> = ({
onBack={handleBack}
errors={errors}
channelErrors={channelErrors}
postalCodes={postalCodes}
postalCodes={state.postalCodeRules}
openChannelsModal={handleChannelsModalOpen}
onChannelsChange={setCurrentChannels}
onPostalCodeAssign={() => openModal("add-range")}
@ -147,7 +161,7 @@ export const WeightRatesCreate: React.FC<WeightRatesCreateProps> = ({
<ShippingZonePostalCodeRangeDialog
confirmButtonState="default"
onClose={closeModal}
onSubmit={handlePostalCodeRangeAdd}
onSubmit={onPostalCodeAssign}
open={params.action === "add-range"}
/>
</>

View file

@ -17,6 +17,10 @@ import usePaginator, {
} from "@saleor/hooks/usePaginator";
import { sectionNames } from "@saleor/intl";
import { commonMessages } from "@saleor/intl";
import {
getById,
getByUnmatchingId
} from "@saleor/orders/components/OrderReturnPage/utils";
import useProductSearch from "@saleor/searches/useProductSearch";
import DeleteShippingRateDialog from "@saleor/shipping/components/DeleteShippingRateDialog";
import ShippingMethodProductsAddDialog from "@saleor/shipping/components/ShippingMethodProductsAddDialog";
@ -43,7 +47,12 @@ import {
shippingWeightRatesEditUrl,
shippingZoneUrl
} from "@saleor/shipping/urls";
import filterPostalCodes from "@saleor/shipping/views/utils";
import postalCodesReducer from "@saleor/shipping/views/reducer";
import {
filterPostalCodes,
getPostalCodeRuleByMinMax,
getRuleObject
} from "@saleor/shipping/views/utils";
import { MinMax } from "@saleor/types";
import {
PostalCodeRuleInclusionTypeEnum,
@ -81,53 +90,59 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
variables: { id, ...paginationState }
});
const rate = data?.shippingZone?.shippingMethods?.find(getById(rateId));
const [openModal, closeModal] = createDialogActionHandlers<
ShippingRateUrlDialog,
ShippingRateUrlQueryParams
>(navigate, params => shippingWeightRatesEditUrl(id, rateId, params), params);
const [codesToDelete, setCodesToDelete] = React.useState([]);
const [havePostalCodesChanged, setHavePostalCodesChanged] = React.useState(
false
);
const [originalCodes, setOriginalCodes] = React.useState([]);
const [inclusionType, setInclusionType] = React.useState(
PostalCodeRuleInclusionTypeEnum.EXCLUDE
);
const [state, dispatch] = React.useReducer(postalCodesReducer, {
codesToDelete: [],
havePostalCodesChanged: false,
inclusionType: rate?.postalCodeRules[0]?.inclusionType,
originalCodes: [],
postalCodeRules: rate?.postalCodeRules || []
});
const postalCodeRulesLoaded =
!loading &&
!state.postalCodeRules?.length &&
!state.codesToDelete?.length &&
rate.postalCodeRules?.length;
if (postalCodeRulesLoaded) {
dispatch({ postalCodeRules: rate.postalCodeRules });
}
const onPostalCodeInclusionChange = (
inclusion: PostalCodeRuleInclusionTypeEnum
) => {
setInclusionType(inclusion);
setCodesToDelete(
rate.postalCodeRules
.filter(code => code.id !== undefined)
.map(code => code.id)
);
setHavePostalCodesChanged(true);
rate.postalCodeRules = [];
dispatch({
codesToDelete: rate.postalCodeRules.map(code => code.id),
havePostalCodesChanged: true,
inclusionType: inclusion,
postalCodeRules: []
});
};
const onPostalCodeAssign = (rule: MinMax) => {
if (!originalCodes.length) {
setOriginalCodes([...rate.postalCodeRules]);
if (!state.originalCodes.length) {
dispatch({ originalCodes: rate.postalCodeRules });
}
if (
rate.postalCodeRules.filter(
item => item.start === rule.min && item.end === rule.max
).length > 0
state.postalCodeRules.filter(getPostalCodeRuleByMinMax(rule)).length > 0
) {
closeModal();
return;
}
const newCode = {
__typename: undefined,
end: rule.max,
id: undefined,
inclusionType,
start: rule.min
};
rate.postalCodeRules.push(newCode);
const newCode = getRuleObject(rule, state.inclusionType);
dispatch({
havePostalCodesChanged: true,
postalCodeRules: [...state.postalCodeRules, newCode]
});
closeModal();
};
@ -137,10 +152,6 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
result: productsSearchOpts
} = useProductSearch({ variables: DEFAULT_INITIAL_SEARCH_DATA });
const rate = data?.shippingZone?.shippingMethods.find(
rate => rate.id === rateId
);
const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions(
[]
);
@ -227,15 +238,14 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
data,
id,
rateId,
rate.postalCodeRules,
codesToDelete
state.postalCodeRules,
state.codesToDelete
)
});
setCodesToDelete([]);
setHavePostalCodesChanged(false);
const errors = response.data.shippingPriceUpdate.errors;
if (errors.length === 0) {
handleSuccess();
dispatch({ havePostalCodesChanged: false });
updateShippingMethodChannelListing({
variables: getShippingMethodChannelVariables(
rateId,
@ -251,14 +261,19 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
const onPostalCodeUnassign = code => {
if (code.id !== undefined) {
setCodesToDelete([...codesToDelete, code.id]);
rate.postalCodeRules = rate.postalCodeRules.filter(
rule => rule.id !== code.id
);
dispatch({
codesToDelete: [...state.codesToDelete, code.id],
havePostalCodesChanged: true,
postalCodeRules: state.postalCodeRules.filter(
getByUnmatchingId(code.id)
)
});
} else {
rate.postalCodeRules = filterPostalCodes(rate.postalCodeRules, code);
dispatch({
havePostalCodesChanged: true,
postalCodeRules: filterPostalCodes(state.postalCodeRules, code)
});
}
setHavePostalCodesChanged(true);
};
const handleSubmit = createMetadataUpdateHandler(
@ -346,7 +361,7 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
assignProductOpts?.status === "loading"
}
hasChannelChanged={shippingChannels?.length !== currentChannels?.length}
havePostalCodesChanged={havePostalCodesChanged}
havePostalCodesChanged={state.havePostalCodesChanged}
saveButtonBarState={updateShippingRateOpts.status}
onDelete={() => openModal("remove")}
onSubmit={handleSubmit}
@ -368,6 +383,7 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
toggleAll={toggleAll}
onNextPage={loadNextPage}
onPreviousPage={loadPreviousPage}
postalCodeRules={state.postalCodeRules}
pageInfo={pageInfo}
toolbar={
<Button color="primary" onClick={() => openModal("unassign-product")}>
@ -384,10 +400,7 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
<ShippingZonePostalCodeRangeDialog
confirmButtonState={"default"}
onClose={closeModal}
onSubmit={code => {
onPostalCodeAssign(code);
setHavePostalCodesChanged(true);
}}
onSubmit={code => onPostalCodeAssign(code)}
open={params.action === "add-range"}
/>
</>

View file

@ -0,0 +1,19 @@
import { ShippingZone_shippingZone_shippingMethods_postalCodeRules } from "@saleor/shipping/types/ShippingZone";
import { PostalCodeRuleInclusionTypeEnum } from "@saleor/types/globalTypes";
export interface PostalCodesState {
codesToDelete?: string[];
havePostalCodesChanged?: boolean;
inclusionType?: PostalCodeRuleInclusionTypeEnum;
originalCodes?: ShippingZone_shippingZone_shippingMethods_postalCodeRules[];
postalCodeRules?: ShippingZone_shippingZone_shippingMethods_postalCodeRules[];
}
function postalCodesReducer(
prevState: PostalCodesState,
newState: PostalCodesState
) {
return { ...prevState, ...newState };
}
export default postalCodesReducer;

View file

@ -1,7 +1,22 @@
const filterPostalCodes = (postalCodes, codeToFilterOut) =>
import { MinMax } from "@saleor/types";
import { PostalCodeRuleInclusionTypeEnum } from "@saleor/types/globalTypes";
export const filterPostalCodes = (postalCodes, codeToFilterOut) =>
postalCodes.filter(
rule =>
rule.start !== codeToFilterOut.start && rule.end !== codeToFilterOut.end
);
export default filterPostalCodes;
export const getPostalCodeRuleByMinMax = ({ min, max }) => ({ start, end }) =>
start === min && end === max;
export const getRuleObject = (
rule: MinMax,
inclusionType: PostalCodeRuleInclusionTypeEnum
) => ({
__typename: undefined,
end: rule.max,
id: undefined,
inclusionType,
start: rule.min
});

View file

@ -206325,7 +206325,7 @@ exports[`Storyshots Views / Shipping / Shipping rate create price rate 1`] = `
<div
class="MuiTypography-root-id MuiTypography-caption-id"
>
3 postal code ranges
0 postal code ranges
</div>
</th>
<th
@ -206368,107 +206368,13 @@ exports[`Storyshots Views / Shipping / Shipping rate create price rate 1`] = `
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
colspan="2"
>
51-210 - 51-220
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
<button
class="MuiButtonBase-root-id MuiIconButton-root-id MuiIconButton-colorPrimary-id"
data-test="delete-postal-code"
data-test-id="1"
tabindex="0"
type="button"
<div
class="MuiTypography-root-id MuiTypography-body1-id MuiTypography-colorTextSecondary-id"
>
<span
class="MuiIconButton-label-id"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
/>
</svg>
</span>
</button>
</td>
</tr>
<tr
class="MuiTableRow-root-id"
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
51-235 - 51-240
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
<button
class="MuiButtonBase-root-id MuiIconButton-root-id MuiIconButton-colorPrimary-id"
data-test="delete-postal-code"
data-test-id="2"
tabindex="0"
type="button"
>
<span
class="MuiIconButton-label-id"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
/>
</svg>
</span>
</button>
</td>
</tr>
<tr
class="MuiTableRow-root-id"
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
51-274
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
<button
class="MuiButtonBase-root-id MuiIconButton-root-id MuiIconButton-colorPrimary-id"
data-test="delete-postal-code"
data-test-id="2"
tabindex="0"
type="button"
>
<span
class="MuiIconButton-label-id"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
/>
</svg>
</span>
</button>
This shipping rate has no postal codes assigned
</div>
</td>
</tr>
</tbody>
@ -207580,7 +207486,7 @@ exports[`Storyshots Views / Shipping / Shipping rate create weight rate 1`] = `
<div
class="MuiTypography-root-id MuiTypography-caption-id"
>
3 postal code ranges
0 postal code ranges
</div>
</th>
<th
@ -207623,107 +207529,13 @@ exports[`Storyshots Views / Shipping / Shipping rate create weight rate 1`] = `
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
colspan="2"
>
51-210 - 51-220
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
<button
class="MuiButtonBase-root-id MuiIconButton-root-id MuiIconButton-colorPrimary-id"
data-test="delete-postal-code"
data-test-id="1"
tabindex="0"
type="button"
<div
class="MuiTypography-root-id MuiTypography-body1-id MuiTypography-colorTextSecondary-id"
>
<span
class="MuiIconButton-label-id"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
/>
</svg>
</span>
</button>
</td>
</tr>
<tr
class="MuiTableRow-root-id"
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
51-235 - 51-240
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
<button
class="MuiButtonBase-root-id MuiIconButton-root-id MuiIconButton-colorPrimary-id"
data-test="delete-postal-code"
data-test-id="2"
tabindex="0"
type="button"
>
<span
class="MuiIconButton-label-id"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
/>
</svg>
</span>
</button>
</td>
</tr>
<tr
class="MuiTableRow-root-id"
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
51-274
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
<button
class="MuiButtonBase-root-id MuiIconButton-root-id MuiIconButton-colorPrimary-id"
data-test="delete-postal-code"
data-test-id="2"
tabindex="0"
type="button"
>
<span
class="MuiIconButton-label-id"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
/>
</svg>
</span>
</button>
This shipping rate has no postal codes assigned
</div>
</td>
</tr>
</tbody>
@ -208933,11 +208745,11 @@ exports[`Storyshots Views / Shipping / Shipping rate loading 1`] = `
class="MuiTableCell-root-id MuiTableCell-head-id"
scope="col"
>
<span
class="Skeleton-skeleton-id ShippingZonePostalCodes-skeleton-id"
<div
class="MuiTypography-root-id MuiTypography-caption-id"
>
</span>
0 postal code ranges
</div>
</th>
<th
class="MuiTableCell-root-id MuiTableCell-head-id"
@ -208979,39 +208791,13 @@ exports[`Storyshots Views / Shipping / Shipping rate loading 1`] = `
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
colspan="2"
>
<span
class="Skeleton-skeleton-id"
<div
class="MuiTypography-root-id MuiTypography-body1-id MuiTypography-colorTextSecondary-id"
>
</span>
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
<button
class="MuiButtonBase-root-id MuiIconButton-root-id MuiIconButton-colorPrimary-id MuiIconButton-disabled-id MuiButtonBase-disabled-id"
data-test="delete-postal-code"
disabled=""
tabindex="-1"
type="button"
>
<span
class="MuiIconButton-label-id"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
/>
</svg>
</span>
</button>
This shipping rate has no postal codes assigned
</div>
</td>
</tr>
</tbody>
@ -210223,7 +210009,7 @@ exports[`Storyshots Views / Shipping / Shipping rate update price rate 1`] = `
<div
class="MuiTypography-root-id MuiTypography-caption-id"
>
3 postal code ranges
0 postal code ranges
</div>
</th>
<th
@ -210266,107 +210052,13 @@ exports[`Storyshots Views / Shipping / Shipping rate update price rate 1`] = `
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
colspan="2"
>
51-210 - 51-220
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
<button
class="MuiButtonBase-root-id MuiIconButton-root-id MuiIconButton-colorPrimary-id"
data-test="delete-postal-code"
data-test-id="1"
tabindex="0"
type="button"
<div
class="MuiTypography-root-id MuiTypography-body1-id MuiTypography-colorTextSecondary-id"
>
<span
class="MuiIconButton-label-id"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
/>
</svg>
</span>
</button>
</td>
</tr>
<tr
class="MuiTableRow-root-id"
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
51-235 - 51-240
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
<button
class="MuiButtonBase-root-id MuiIconButton-root-id MuiIconButton-colorPrimary-id"
data-test="delete-postal-code"
data-test-id="2"
tabindex="0"
type="button"
>
<span
class="MuiIconButton-label-id"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
/>
</svg>
</span>
</button>
</td>
</tr>
<tr
class="MuiTableRow-root-id"
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
51-274
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
<button
class="MuiButtonBase-root-id MuiIconButton-root-id MuiIconButton-colorPrimary-id"
data-test="delete-postal-code"
data-test-id="2"
tabindex="0"
type="button"
>
<span
class="MuiIconButton-label-id"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
/>
</svg>
</span>
</button>
This shipping rate has no postal codes assigned
</div>
</td>
</tr>
</tbody>
@ -211562,7 +211254,7 @@ exports[`Storyshots Views / Shipping / Shipping rate update weight rate 1`] = `
<div
class="MuiTypography-root-id MuiTypography-caption-id"
>
3 postal code ranges
0 postal code ranges
</div>
</th>
<th
@ -211605,107 +211297,13 @@ exports[`Storyshots Views / Shipping / Shipping rate update weight rate 1`] = `
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
colspan="2"
>
51-210 - 51-220
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
<button
class="MuiButtonBase-root-id MuiIconButton-root-id MuiIconButton-colorPrimary-id"
data-test="delete-postal-code"
data-test-id="1"
tabindex="0"
type="button"
<div
class="MuiTypography-root-id MuiTypography-body1-id MuiTypography-colorTextSecondary-id"
>
<span
class="MuiIconButton-label-id"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
/>
</svg>
</span>
</button>
</td>
</tr>
<tr
class="MuiTableRow-root-id"
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
51-235 - 51-240
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
<button
class="MuiButtonBase-root-id MuiIconButton-root-id MuiIconButton-colorPrimary-id"
data-test="delete-postal-code"
data-test-id="2"
tabindex="0"
type="button"
>
<span
class="MuiIconButton-label-id"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
/>
</svg>
</span>
</button>
</td>
</tr>
<tr
class="MuiTableRow-root-id"
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
51-274
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
<button
class="MuiButtonBase-root-id MuiIconButton-root-id MuiIconButton-colorPrimary-id"
data-test="delete-postal-code"
data-test-id="2"
tabindex="0"
type="button"
>
<span
class="MuiIconButton-label-id"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
/>
</svg>
</span>
</button>
This shipping rate has no postal codes assigned
</div>
</td>
</tr>
</tbody>