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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -17,6 +17,10 @@ import usePaginator, {
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import {
getById,
getByUnmatchingId
} from "@saleor/orders/components/OrderReturnPage/utils";
import useProductSearch from "@saleor/searches/useProductSearch"; import useProductSearch from "@saleor/searches/useProductSearch";
import DeleteShippingRateDialog from "@saleor/shipping/components/DeleteShippingRateDialog"; import DeleteShippingRateDialog from "@saleor/shipping/components/DeleteShippingRateDialog";
import ShippingMethodProductsAddDialog from "@saleor/shipping/components/ShippingMethodProductsAddDialog"; import ShippingMethodProductsAddDialog from "@saleor/shipping/components/ShippingMethodProductsAddDialog";
@ -43,7 +47,12 @@ import {
shippingWeightRatesEditUrl, shippingWeightRatesEditUrl,
shippingZoneUrl shippingZoneUrl
} from "@saleor/shipping/urls"; } 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 { MinMax } from "@saleor/types";
import { import {
PostalCodeRuleInclusionTypeEnum, PostalCodeRuleInclusionTypeEnum,
@ -81,53 +90,59 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
variables: { id, ...paginationState } variables: { id, ...paginationState }
}); });
const rate = data?.shippingZone?.shippingMethods?.find(getById(rateId));
const [openModal, closeModal] = createDialogActionHandlers< const [openModal, closeModal] = createDialogActionHandlers<
ShippingRateUrlDialog, ShippingRateUrlDialog,
ShippingRateUrlQueryParams ShippingRateUrlQueryParams
>(navigate, params => shippingWeightRatesEditUrl(id, rateId, params), params); >(navigate, params => shippingWeightRatesEditUrl(id, rateId, params), params);
const [codesToDelete, setCodesToDelete] = React.useState([]); const [state, dispatch] = React.useReducer(postalCodesReducer, {
const [havePostalCodesChanged, setHavePostalCodesChanged] = React.useState( codesToDelete: [],
false havePostalCodesChanged: false,
); inclusionType: rate?.postalCodeRules[0]?.inclusionType,
const [originalCodes, setOriginalCodes] = React.useState([]); originalCodes: [],
const [inclusionType, setInclusionType] = React.useState( postalCodeRules: rate?.postalCodeRules || []
PostalCodeRuleInclusionTypeEnum.EXCLUDE });
);
const postalCodeRulesLoaded =
!loading &&
!state.postalCodeRules?.length &&
!state.codesToDelete?.length &&
rate.postalCodeRules?.length;
if (postalCodeRulesLoaded) {
dispatch({ postalCodeRules: rate.postalCodeRules });
}
const onPostalCodeInclusionChange = ( const onPostalCodeInclusionChange = (
inclusion: PostalCodeRuleInclusionTypeEnum inclusion: PostalCodeRuleInclusionTypeEnum
) => { ) => {
setInclusionType(inclusion); dispatch({
setCodesToDelete( codesToDelete: rate.postalCodeRules.map(code => code.id),
rate.postalCodeRules havePostalCodesChanged: true,
.filter(code => code.id !== undefined) inclusionType: inclusion,
.map(code => code.id) postalCodeRules: []
); });
setHavePostalCodesChanged(true);
rate.postalCodeRules = [];
}; };
const onPostalCodeAssign = (rule: MinMax) => { const onPostalCodeAssign = (rule: MinMax) => {
if (!originalCodes.length) { if (!state.originalCodes.length) {
setOriginalCodes([...rate.postalCodeRules]); dispatch({ originalCodes: rate.postalCodeRules });
} }
if ( if (
rate.postalCodeRules.filter( state.postalCodeRules.filter(getPostalCodeRuleByMinMax(rule)).length > 0
item => item.start === rule.min && item.end === rule.max
).length > 0
) { ) {
closeModal(); closeModal();
return; return;
} }
const newCode = {
__typename: undefined, const newCode = getRuleObject(rule, state.inclusionType);
end: rule.max, dispatch({
id: undefined, havePostalCodesChanged: true,
inclusionType, postalCodeRules: [...state.postalCodeRules, newCode]
start: rule.min });
};
rate.postalCodeRules.push(newCode);
closeModal(); closeModal();
}; };
@ -137,10 +152,6 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
result: productsSearchOpts result: productsSearchOpts
} = useProductSearch({ variables: DEFAULT_INITIAL_SEARCH_DATA }); } = useProductSearch({ variables: DEFAULT_INITIAL_SEARCH_DATA });
const rate = data?.shippingZone?.shippingMethods.find(
rate => rate.id === rateId
);
const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions( const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions(
[] []
); );
@ -227,15 +238,14 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
data, data,
id, id,
rateId, rateId,
rate.postalCodeRules, state.postalCodeRules,
codesToDelete state.codesToDelete
) )
}); });
setCodesToDelete([]);
setHavePostalCodesChanged(false);
const errors = response.data.shippingPriceUpdate.errors; const errors = response.data.shippingPriceUpdate.errors;
if (errors.length === 0) { if (errors.length === 0) {
handleSuccess(); handleSuccess();
dispatch({ havePostalCodesChanged: false });
updateShippingMethodChannelListing({ updateShippingMethodChannelListing({
variables: getShippingMethodChannelVariables( variables: getShippingMethodChannelVariables(
rateId, rateId,
@ -251,14 +261,19 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
const onPostalCodeUnassign = code => { const onPostalCodeUnassign = code => {
if (code.id !== undefined) { if (code.id !== undefined) {
setCodesToDelete([...codesToDelete, code.id]); dispatch({
rate.postalCodeRules = rate.postalCodeRules.filter( codesToDelete: [...state.codesToDelete, code.id],
rule => rule.id !== code.id havePostalCodesChanged: true,
); postalCodeRules: state.postalCodeRules.filter(
getByUnmatchingId(code.id)
)
});
} else { } else {
rate.postalCodeRules = filterPostalCodes(rate.postalCodeRules, code); dispatch({
havePostalCodesChanged: true,
postalCodeRules: filterPostalCodes(state.postalCodeRules, code)
});
} }
setHavePostalCodesChanged(true);
}; };
const handleSubmit = createMetadataUpdateHandler( const handleSubmit = createMetadataUpdateHandler(
@ -346,7 +361,7 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
assignProductOpts?.status === "loading" assignProductOpts?.status === "loading"
} }
hasChannelChanged={shippingChannels?.length !== currentChannels?.length} hasChannelChanged={shippingChannels?.length !== currentChannels?.length}
havePostalCodesChanged={havePostalCodesChanged} havePostalCodesChanged={state.havePostalCodesChanged}
saveButtonBarState={updateShippingRateOpts.status} saveButtonBarState={updateShippingRateOpts.status}
onDelete={() => openModal("remove")} onDelete={() => openModal("remove")}
onSubmit={handleSubmit} onSubmit={handleSubmit}
@ -368,6 +383,7 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
toggleAll={toggleAll} toggleAll={toggleAll}
onNextPage={loadNextPage} onNextPage={loadNextPage}
onPreviousPage={loadPreviousPage} onPreviousPage={loadPreviousPage}
postalCodeRules={state.postalCodeRules}
pageInfo={pageInfo} pageInfo={pageInfo}
toolbar={ toolbar={
<Button color="primary" onClick={() => openModal("unassign-product")}> <Button color="primary" onClick={() => openModal("unassign-product")}>
@ -384,10 +400,7 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
<ShippingZonePostalCodeRangeDialog <ShippingZonePostalCodeRangeDialog
confirmButtonState={"default"} confirmButtonState={"default"}
onClose={closeModal} onClose={closeModal}
onSubmit={code => { onSubmit={code => onPostalCodeAssign(code)}
onPostalCodeAssign(code);
setHavePostalCodesChanged(true);
}}
open={params.action === "add-range"} 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( postalCodes.filter(
rule => rule =>
rule.start !== codeToFilterOut.start && rule.end !== codeToFilterOut.end 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 <div
class="MuiTypography-root-id MuiTypography-caption-id" class="MuiTypography-root-id MuiTypography-caption-id"
> >
3 postal code ranges 0 postal code ranges
</div> </div>
</th> </th>
<th <th
@ -206368,107 +206368,13 @@ exports[`Storyshots Views / Shipping / Shipping rate create price rate 1`] = `
> >
<td <td
class="MuiTableCell-root-id MuiTableCell-body-id" class="MuiTableCell-root-id MuiTableCell-body-id"
colspan="2"
> >
51-210 - 51-220 <div
</td> class="MuiTypography-root-id MuiTypography-body1-id MuiTypography-colorTextSecondary-id"
<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"
> >
<span This shipping rate has no postal codes assigned
class="MuiIconButton-label-id" </div>
>
<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>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -207580,7 +207486,7 @@ exports[`Storyshots Views / Shipping / Shipping rate create weight rate 1`] = `
<div <div
class="MuiTypography-root-id MuiTypography-caption-id" class="MuiTypography-root-id MuiTypography-caption-id"
> >
3 postal code ranges 0 postal code ranges
</div> </div>
</th> </th>
<th <th
@ -207623,107 +207529,13 @@ exports[`Storyshots Views / Shipping / Shipping rate create weight rate 1`] = `
> >
<td <td
class="MuiTableCell-root-id MuiTableCell-body-id" class="MuiTableCell-root-id MuiTableCell-body-id"
colspan="2"
> >
51-210 - 51-220 <div
</td> class="MuiTypography-root-id MuiTypography-body1-id MuiTypography-colorTextSecondary-id"
<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"
> >
<span This shipping rate has no postal codes assigned
class="MuiIconButton-label-id" </div>
>
<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>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -208933,11 +208745,11 @@ exports[`Storyshots Views / Shipping / Shipping rate loading 1`] = `
class="MuiTableCell-root-id MuiTableCell-head-id" class="MuiTableCell-root-id MuiTableCell-head-id"
scope="col" scope="col"
> >
<span <div
class="Skeleton-skeleton-id ShippingZonePostalCodes-skeleton-id" class="MuiTypography-root-id MuiTypography-caption-id"
> >
0 postal code ranges
</span> </div>
</th> </th>
<th <th
class="MuiTableCell-root-id MuiTableCell-head-id" class="MuiTableCell-root-id MuiTableCell-head-id"
@ -208979,39 +208791,13 @@ exports[`Storyshots Views / Shipping / Shipping rate loading 1`] = `
> >
<td <td
class="MuiTableCell-root-id MuiTableCell-body-id" class="MuiTableCell-root-id MuiTableCell-body-id"
colspan="2"
> >
<span <div
class="Skeleton-skeleton-id" class="MuiTypography-root-id MuiTypography-body1-id MuiTypography-colorTextSecondary-id"
> >
This shipping rate has no postal codes assigned
</span> </div>
</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>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -210223,7 +210009,7 @@ exports[`Storyshots Views / Shipping / Shipping rate update price rate 1`] = `
<div <div
class="MuiTypography-root-id MuiTypography-caption-id" class="MuiTypography-root-id MuiTypography-caption-id"
> >
3 postal code ranges 0 postal code ranges
</div> </div>
</th> </th>
<th <th
@ -210266,107 +210052,13 @@ exports[`Storyshots Views / Shipping / Shipping rate update price rate 1`] = `
> >
<td <td
class="MuiTableCell-root-id MuiTableCell-body-id" class="MuiTableCell-root-id MuiTableCell-body-id"
colspan="2"
> >
51-210 - 51-220 <div
</td> class="MuiTypography-root-id MuiTypography-body1-id MuiTypography-colorTextSecondary-id"
<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"
> >
<span This shipping rate has no postal codes assigned
class="MuiIconButton-label-id" </div>
>
<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>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -211562,7 +211254,7 @@ exports[`Storyshots Views / Shipping / Shipping rate update weight rate 1`] = `
<div <div
class="MuiTypography-root-id MuiTypography-caption-id" class="MuiTypography-root-id MuiTypography-caption-id"
> >
3 postal code ranges 0 postal code ranges
</div> </div>
</th> </th>
<th <th
@ -211605,107 +211297,13 @@ exports[`Storyshots Views / Shipping / Shipping rate update weight rate 1`] = `
> >
<td <td
class="MuiTableCell-root-id MuiTableCell-body-id" class="MuiTableCell-root-id MuiTableCell-body-id"
colspan="2"
> >
51-210 - 51-220 <div
</td> class="MuiTypography-root-id MuiTypography-body1-id MuiTypography-colorTextSecondary-id"
<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"
> >
<span This shipping rate has no postal codes assigned
class="MuiIconButton-label-id" </div>
>
<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>
</td> </td>
</tr> </tr>
</tbody> </tbody>