Add zip code exclusion (#877)
* Clean up stories * Add missing props * Add zip codes section (#861) * Add zip code listing * Add list wrapping * Update snapshots * Set up API data * Fix lgtm warning * Update snapshots * Run Actions on all PR * Checks on PR * Test envs on PR * Cleanup action on PR * Update messages Co-authored-by: Krzysztof Wolski <krzysztof.k.wolski@gmail.com> * Add zip code range dialog * Fix path management * Use query params to handle modal actions * Allow zip codes to be assigned to shipping method * Make params optional * Fix types * Add zip code deletion (#871) * Add zip code range dialog * Fix path management * Use query params to handle modal actions * Allow zip codes to be assigned to shipping method * Make params optional * Fix types * Clean up urls * Add zip code range delete action * Update snapshots and messages * Update testing and changelog * Update schema * Simplify code * Refresh zip code list after assigning them * Update view after zip code deletion * Update types and snapshots * Update snapshots * Fix error message, checkbox default value (#880) * Fix error message, checkbox default value * Update snapshots * Use price instead of weight variant * Update schema and types * Hide exclude/include zip codes section * Update stories Co-authored-by: Krzysztof Wolski <krzysztof.k.wolski@gmail.com> Co-authored-by: Tomasz Szymański <lime129@gmail.com>
This commit is contained in:
parent
eb351b396a
commit
e55805a79d
41 changed files with 6588 additions and 2979 deletions
1
.github/workflows/test-env-cleanup.yml
vendored
1
.github/workflows/test-env-cleanup.yml
vendored
|
@ -4,7 +4,6 @@ name: TEST-ENV-CLEANUP
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
types: [closed]
|
types: [closed]
|
||||||
branches: ["*"]
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
6
.github/workflows/test-env-deploy.yml
vendored
6
.github/workflows/test-env-deploy.yml
vendored
|
@ -1,11 +1,7 @@
|
||||||
name: TEST-ENV-DEPLOYMENT
|
name: TEST-ENV-DEPLOYMENT
|
||||||
# Build and deploy test instance for every pull request
|
# Build and deploy test instance for every pull request
|
||||||
|
|
||||||
on:
|
on: [pull_request]
|
||||||
pull_request:
|
|
||||||
# trigger on "edited" to update instance when configuration changes in PR description
|
|
||||||
types: [opened, reopened, synchronize]
|
|
||||||
branches: ["*"]
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
|
|
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
|
@ -1,8 +1,6 @@
|
||||||
name: QA
|
name: QA
|
||||||
|
|
||||||
on:
|
on: [pull_request]
|
||||||
pull_request:
|
|
||||||
branches: ["*"]
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-lock:
|
check-lock:
|
||||||
|
|
|
@ -8,6 +8,7 @@ All notable, unreleased changes to this project will be documented in this file.
|
||||||
- Add Page Types - #807 by @orzechdev
|
- Add Page Types - #807 by @orzechdev
|
||||||
- Add shipping methods to translation section - #864 by @marekchoinski
|
- Add shipping methods to translation section - #864 by @marekchoinski
|
||||||
- New Miscellaneous and Product refunds - #870 by @orzechdev
|
- New Miscellaneous and Product refunds - #870 by @orzechdev
|
||||||
|
- Add zip code exclusion - #877 by @dominik-zeglen
|
||||||
|
|
||||||
# 2.11.1
|
# 2.11.1
|
||||||
|
|
||||||
|
|
|
@ -5292,9 +5292,9 @@
|
||||||
"context": "channels discount info",
|
"context": "channels discount info",
|
||||||
"string": "Channels that don’t have assigned discounts will use their parent channel to define the price. Price will be converted to channel’s currency"
|
"string": "Channels that don’t have assigned discounts will use their parent channel to define the price. Price will be converted to channel’s currency"
|
||||||
},
|
},
|
||||||
"src_dot_shipping_dot_components_dot_OrderValue_dot_2946165345": {
|
"src_dot_shipping_dot_components_dot_OrderValue_dot_3989471564": {
|
||||||
"context": "card title",
|
"context": "card title",
|
||||||
"string": "Order value"
|
"string": "Order Value"
|
||||||
},
|
},
|
||||||
"src_dot_shipping_dot_components_dot_OrderValue_dot_4226393146": {
|
"src_dot_shipping_dot_components_dot_OrderValue_dot_4226393146": {
|
||||||
"context": "price rates info",
|
"context": "price rates info",
|
||||||
|
@ -5319,13 +5319,13 @@
|
||||||
"context": "info text",
|
"context": "info text",
|
||||||
"string": "This rate will apply to all orders"
|
"string": "This rate will apply to all orders"
|
||||||
},
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_OrderWeight_dot_2211490913": {
|
||||||
|
"context": "card title",
|
||||||
|
"string": "Order Weight"
|
||||||
|
},
|
||||||
"src_dot_shipping_dot_components_dot_OrderWeight_dot_2935375344": {
|
"src_dot_shipping_dot_components_dot_OrderWeight_dot_2935375344": {
|
||||||
"string": "Min. Order Weight"
|
"string": "Min. Order Weight"
|
||||||
},
|
},
|
||||||
"src_dot_shipping_dot_components_dot_OrderWeight_dot_3721863048": {
|
|
||||||
"context": "card title",
|
|
||||||
"string": "Order weight"
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_OrderWeight_dot_882649212": {
|
"src_dot_shipping_dot_components_dot_OrderWeight_dot_882649212": {
|
||||||
"context": "checkbox label",
|
"context": "checkbox label",
|
||||||
"string": "There are no value limits"
|
"string": "There are no value limits"
|
||||||
|
@ -5349,6 +5349,13 @@
|
||||||
"context": "column title",
|
"context": "column title",
|
||||||
"string": "Channel name"
|
"string": "Channel name"
|
||||||
},
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingRateZipCodeRangeRemoveDialog_dot_1083561409": {
|
||||||
|
"string": "Are you sure you want to remove this ZIP-code rule?"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingRateZipCodeRangeRemoveDialog_dot_2944856644": {
|
||||||
|
"context": "header",
|
||||||
|
"string": "Remove ZIP-codes from Shipping Rate"
|
||||||
|
},
|
||||||
"src_dot_shipping_dot_components_dot_ShippingWeightUnitForm_dot_2863708228": {
|
"src_dot_shipping_dot_components_dot_ShippingWeightUnitForm_dot_2863708228": {
|
||||||
"string": "This unit will be used as default shipping weight"
|
"string": "This unit will be used as default shipping weight"
|
||||||
},
|
},
|
||||||
|
@ -5477,6 +5484,54 @@
|
||||||
"context": "input placeholder",
|
"context": "input placeholder",
|
||||||
"string": "Select Warehouse"
|
"string": "Select Warehouse"
|
||||||
},
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodeRangeDialog_dot_1938537617": {
|
||||||
|
"string": "Please provide range of ZIP codes you want to add to the include/exclude list."
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodeRangeDialog_dot_3099331554": {
|
||||||
|
"context": "add zip code range, button",
|
||||||
|
"string": "Add"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodeRangeDialog_dot_3529644799": {
|
||||||
|
"context": "range input label",
|
||||||
|
"string": "Zip Codes (Start)"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodeRangeDialog_dot_4196919717": {
|
||||||
|
"context": "dialog header",
|
||||||
|
"string": "Add ZIP-Codes"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodeRangeDialog_dot_551327109": {
|
||||||
|
"context": "range input label",
|
||||||
|
"string": "Zip Codes (End)"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_1462092303": {
|
||||||
|
"string": "Added ZIP-codes will be excluded from using this delivery methods. If none are added all ZIP-Codes will be able to use that shipping rate"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_1605967697": {
|
||||||
|
"context": "action",
|
||||||
|
"string": "Exclude ZIP-codes"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_2728850129": {
|
||||||
|
"string": "Only added ZIP-codes will be able to use this shipping rate"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_2850315665": {
|
||||||
|
"context": "number of zip code ranges",
|
||||||
|
"string": "{number} ZIP-Code ranges"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_3795380518": {
|
||||||
|
"context": "button",
|
||||||
|
"string": "Add ZIP-Code range"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_4288715411": {
|
||||||
|
"string": "This shipping rate has no ZIP-codes assigned"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_529495587": {
|
||||||
|
"context": "postal codes, header",
|
||||||
|
"string": "ZIP-Codes"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_671838332": {
|
||||||
|
"context": "action",
|
||||||
|
"string": "Include ZIP-codes"
|
||||||
|
},
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZonesListPage_dot_1325966144": {
|
"src_dot_shipping_dot_components_dot_ShippingZonesListPage_dot_1325966144": {
|
||||||
"context": "header",
|
"context": "header",
|
||||||
"string": "Shipping"
|
"string": "Shipping"
|
||||||
|
@ -5525,6 +5580,10 @@
|
||||||
"src_dot_shipping_dot_views_dot_PriceRatesCreate_dot_3823295269": {
|
"src_dot_shipping_dot_views_dot_PriceRatesCreate_dot_3823295269": {
|
||||||
"string": "Manage Channel Availability"
|
"string": "Manage Channel Availability"
|
||||||
},
|
},
|
||||||
|
"src_dot_shipping_dot_views_dot_PriceRatesUpdate_dot_2710215007": {
|
||||||
|
"context": "zip code range add error text",
|
||||||
|
"string": "Cannot add specified zip codes range."
|
||||||
|
},
|
||||||
"src_dot_shipping_dot_views_dot_PriceRatesUpdate_dot_3823295269": {
|
"src_dot_shipping_dot_views_dot_PriceRatesUpdate_dot_3823295269": {
|
||||||
"string": "Manage Channel Availability"
|
"string": "Manage Channel Availability"
|
||||||
},
|
},
|
||||||
|
@ -5543,6 +5602,10 @@
|
||||||
"src_dot_shipping_dot_views_dot_WeightRatesCreate_dot_3014453080": {
|
"src_dot_shipping_dot_views_dot_WeightRatesCreate_dot_3014453080": {
|
||||||
"string": "Manage Channels Availability"
|
"string": "Manage Channels Availability"
|
||||||
},
|
},
|
||||||
|
"src_dot_shipping_dot_views_dot_WeightRatesUpdate_dot_2710215007": {
|
||||||
|
"context": "zip code range add error text",
|
||||||
|
"string": "Cannot add specified zip codes range."
|
||||||
|
},
|
||||||
"src_dot_shipping_dot_views_dot_WeightRatesUpdate_dot_3014453080": {
|
"src_dot_shipping_dot_views_dot_WeightRatesUpdate_dot_3014453080": {
|
||||||
"string": "Manage Channels Availability"
|
"string": "Manage Channels Availability"
|
||||||
},
|
},
|
||||||
|
|
|
@ -2565,11 +2565,15 @@ type Mutation {
|
||||||
shopAddressUpdate(input: AddressInput): ShopAddressUpdate
|
shopAddressUpdate(input: AddressInput): ShopAddressUpdate
|
||||||
orderSettingsUpdate(input: OrderSettingsUpdateInput!): OrderSettingsUpdate
|
orderSettingsUpdate(input: OrderSettingsUpdateInput!): OrderSettingsUpdate
|
||||||
shippingMethodChannelListingUpdate(id: ID!, input: ShippingMethodChannelListingInput!): ShippingMethodChannelListingUpdate
|
shippingMethodChannelListingUpdate(id: ID!, input: ShippingMethodChannelListingInput!): ShippingMethodChannelListingUpdate
|
||||||
|
shippingMethodZipCodeRulesCreate(input: ShippingZipCodeRulesCreateInput!, shippingMethodId: ID!): ShippingZipCodeRulesCreate
|
||||||
|
shippingMethodZipCodeRulesDelete(id: ID!): ShippingZipCodeRulesDelete
|
||||||
shippingPriceCreate(input: ShippingPriceInput!): ShippingPriceCreate
|
shippingPriceCreate(input: ShippingPriceInput!): ShippingPriceCreate
|
||||||
shippingPriceDelete(id: ID!): ShippingPriceDelete
|
shippingPriceDelete(id: ID!): ShippingPriceDelete
|
||||||
shippingPriceBulkDelete(ids: [ID]!): ShippingPriceBulkDelete
|
shippingPriceBulkDelete(ids: [ID]!): ShippingPriceBulkDelete
|
||||||
shippingPriceUpdate(id: ID!, input: ShippingPriceInput!): ShippingPriceUpdate
|
shippingPriceUpdate(id: ID!, input: ShippingPriceInput!): ShippingPriceUpdate
|
||||||
shippingPriceTranslate(id: ID!, input: NameTranslationInput!, languageCode: LanguageCodeEnum!): ShippingPriceTranslate
|
shippingPriceTranslate(id: ID!, input: NameTranslationInput!, languageCode: LanguageCodeEnum!): ShippingPriceTranslate
|
||||||
|
shippingPriceExcludeProducts(id: ID!, input: ShippingPriceExcludeProductsInput!): ShippingPriceExcludeProducts
|
||||||
|
shippingPriceRemoveProductFromExclude(id: ID!, products: [ID]!): ShippingPriceRemoveProductFromExclude
|
||||||
shippingZoneCreate(input: ShippingZoneCreateInput!): ShippingZoneCreate
|
shippingZoneCreate(input: ShippingZoneCreateInput!): ShippingZoneCreate
|
||||||
shippingZoneDelete(id: ID!): ShippingZoneDelete
|
shippingZoneDelete(id: ID!): ShippingZoneDelete
|
||||||
shippingZoneBulkDelete(ids: [ID]!): ShippingZoneBulkDelete
|
shippingZoneBulkDelete(ids: [ID]!): ShippingZoneBulkDelete
|
||||||
|
@ -2856,7 +2860,6 @@ type Order implements Node & ObjectWithMetadata {
|
||||||
totalBalance: Money!
|
totalBalance: Money!
|
||||||
userEmail: String
|
userEmail: String
|
||||||
isShippingRequired: Boolean!
|
isShippingRequired: Boolean!
|
||||||
linesAvailableForRefund: [OrderLineAvailableForRefund]!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum OrderAction {
|
enum OrderAction {
|
||||||
|
@ -3097,11 +3100,6 @@ type OrderLine implements Node {
|
||||||
allocations: [Allocation!]
|
allocations: [Allocation!]
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrderLineAvailableForRefund {
|
|
||||||
quantity: Int
|
|
||||||
orderLine: OrderLine
|
|
||||||
}
|
|
||||||
|
|
||||||
input OrderLineCreateInput {
|
input OrderLineCreateInput {
|
||||||
quantity: Int!
|
quantity: Int!
|
||||||
variantId: ID!
|
variantId: ID!
|
||||||
|
@ -3124,19 +3122,18 @@ type OrderRefund {
|
||||||
}
|
}
|
||||||
|
|
||||||
input OrderRefundFulfillmentLineInput {
|
input OrderRefundFulfillmentLineInput {
|
||||||
fulfillmentLineId: ID
|
fulfillmentLineId: ID!
|
||||||
quantity: Int!
|
quantity: Int!
|
||||||
}
|
}
|
||||||
|
|
||||||
input OrderRefundLineInput {
|
input OrderRefundLineInput {
|
||||||
orderLineId: ID
|
orderLineId: ID!
|
||||||
quantity: Int!
|
quantity: Int!
|
||||||
}
|
}
|
||||||
|
|
||||||
input OrderRefundProductsInput {
|
input OrderRefundProductsInput {
|
||||||
orderLines: [OrderRefundLineInput!]
|
orderLines: [OrderRefundLineInput!]
|
||||||
fulfillmentLines: [OrderRefundFulfillmentLineInput!]
|
fulfillmentLines: [OrderRefundFulfillmentLineInput!]
|
||||||
notifyCustomer: Boolean
|
|
||||||
amountToRefund: PositiveDecimal
|
amountToRefund: PositiveDecimal
|
||||||
includeShippingCosts: Boolean = false
|
includeShippingCosts: Boolean = false
|
||||||
}
|
}
|
||||||
|
@ -4656,6 +4653,8 @@ type ShippingMethod implements Node & ObjectWithMetadata {
|
||||||
price: Money
|
price: Money
|
||||||
maximumOrderPrice: Money
|
maximumOrderPrice: Money
|
||||||
minimumOrderPrice: Money
|
minimumOrderPrice: Money
|
||||||
|
zipCodeRules: [ShippingMethodZipCodeRule]
|
||||||
|
excludedProducts(before: String, after: String, first: Int, last: Int): ProductCountableConnection
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShippingMethodChannelListing implements Node {
|
type ShippingMethodChannelListing implements Node {
|
||||||
|
@ -4702,6 +4701,12 @@ enum ShippingMethodTypeEnum {
|
||||||
WEIGHT
|
WEIGHT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ShippingMethodZipCodeRule implements Node {
|
||||||
|
start: String
|
||||||
|
end: String
|
||||||
|
id: ID!
|
||||||
|
}
|
||||||
|
|
||||||
type ShippingPriceBulkDelete {
|
type ShippingPriceBulkDelete {
|
||||||
errors: [Error!]! @deprecated(reason: "Use typed errors with error codes. This field will be removed after 2020-07-31.")
|
errors: [Error!]! @deprecated(reason: "Use typed errors with error codes. This field will be removed after 2020-07-31.")
|
||||||
count: Int!
|
count: Int!
|
||||||
|
@ -4722,6 +4727,16 @@ type ShippingPriceDelete {
|
||||||
shippingErrors: [ShippingError!]!
|
shippingErrors: [ShippingError!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ShippingPriceExcludeProducts {
|
||||||
|
errors: [Error!]! @deprecated(reason: "Use typed errors with error codes. This field will be removed after 2020-07-31.")
|
||||||
|
shippingMethod: ShippingMethod
|
||||||
|
shippingErrors: [ShippingError!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
input ShippingPriceExcludeProductsInput {
|
||||||
|
products: [ID]!
|
||||||
|
}
|
||||||
|
|
||||||
input ShippingPriceInput {
|
input ShippingPriceInput {
|
||||||
name: String
|
name: String
|
||||||
minimumOrderWeight: WeightScalar
|
minimumOrderWeight: WeightScalar
|
||||||
|
@ -4730,6 +4745,12 @@ input ShippingPriceInput {
|
||||||
shippingZone: ID
|
shippingZone: ID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ShippingPriceRemoveProductFromExclude {
|
||||||
|
errors: [Error!]! @deprecated(reason: "Use typed errors with error codes. This field will be removed after 2020-07-31.")
|
||||||
|
shippingMethod: ShippingMethod
|
||||||
|
shippingErrors: [ShippingError!]!
|
||||||
|
}
|
||||||
|
|
||||||
type ShippingPriceTranslate {
|
type ShippingPriceTranslate {
|
||||||
errors: [Error!]! @deprecated(reason: "Use typed errors with error codes. This field will be removed after 2020-07-31.")
|
errors: [Error!]! @deprecated(reason: "Use typed errors with error codes. This field will be removed after 2020-07-31.")
|
||||||
translationErrors: [TranslationError!]!
|
translationErrors: [TranslationError!]!
|
||||||
|
@ -4743,6 +4764,29 @@ type ShippingPriceUpdate {
|
||||||
shippingErrors: [ShippingError!]!
|
shippingErrors: [ShippingError!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ShippingZipCodeRulesCreate {
|
||||||
|
errors: [Error!]! @deprecated(reason: "Use typed errors with error codes. This field will be removed after 2020-07-31.")
|
||||||
|
zipCodeRules: [ShippingMethodZipCodeRule]
|
||||||
|
shippingMethod: ShippingMethod
|
||||||
|
shippingErrors: [ShippingError!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
input ShippingZipCodeRulesCreateInput {
|
||||||
|
zipCodeRules: [ShippingZipCodeRulesCreateInputRange]!
|
||||||
|
}
|
||||||
|
|
||||||
|
input ShippingZipCodeRulesCreateInputRange {
|
||||||
|
start: String!
|
||||||
|
end: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShippingZipCodeRulesDelete {
|
||||||
|
errors: [Error!]! @deprecated(reason: "Use typed errors with error codes. This field will be removed after 2020-07-31.")
|
||||||
|
shippingMethod: ShippingMethod
|
||||||
|
shippingErrors: [ShippingError!]!
|
||||||
|
shippingMethodZipCodeRule: ShippingMethodZipCodeRule
|
||||||
|
}
|
||||||
|
|
||||||
type ShippingZone implements Node & ObjectWithMetadata {
|
type ShippingZone implements Node & ObjectWithMetadata {
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
|
@ -4807,6 +4851,7 @@ input ShippingZoneUpdateInput {
|
||||||
|
|
||||||
type Shop {
|
type Shop {
|
||||||
availablePaymentGateways(currency: String): [PaymentGateway!]!
|
availablePaymentGateways(currency: String): [PaymentGateway!]!
|
||||||
|
availableShippingMethods(channel: String!, address: AddressInput): [ShippingMethod]
|
||||||
geolocalization: Geolocalization
|
geolocalization: Geolocalization
|
||||||
authorizationKeys: [AuthorizationKey]!
|
authorizationKeys: [AuthorizationKey]!
|
||||||
countries(languageCode: LanguageCodeEnum): [CountryDisplay!]!
|
countries(languageCode: LanguageCodeEnum): [CountryDisplay!]!
|
||||||
|
|
|
@ -12,6 +12,11 @@ import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
theme => ({
|
theme => ({
|
||||||
|
alignTop: {
|
||||||
|
alignSelf: "baseline",
|
||||||
|
position: "relative",
|
||||||
|
top: -6
|
||||||
|
},
|
||||||
formLabel: {
|
formLabel: {
|
||||||
marginBottom: theme.spacing(1)
|
marginBottom: theme.spacing(1)
|
||||||
},
|
},
|
||||||
|
@ -51,6 +56,7 @@ export interface RadioGroupFieldChoice<
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RadioGroupFieldProps {
|
interface RadioGroupFieldProps {
|
||||||
|
alignTop?: boolean;
|
||||||
choices: RadioGroupFieldChoice[];
|
choices: RadioGroupFieldChoice[];
|
||||||
className?: string;
|
className?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
@ -65,6 +71,7 @@ interface RadioGroupFieldProps {
|
||||||
|
|
||||||
export const RadioGroupField: React.FC<RadioGroupFieldProps> = props => {
|
export const RadioGroupField: React.FC<RadioGroupFieldProps> = props => {
|
||||||
const {
|
const {
|
||||||
|
alignTop,
|
||||||
className,
|
className,
|
||||||
disabled,
|
disabled,
|
||||||
error,
|
error,
|
||||||
|
@ -107,7 +114,14 @@ export const RadioGroupField: React.FC<RadioGroupFieldProps> = props => {
|
||||||
[classes.radioLabel]: variant !== "inline",
|
[classes.radioLabel]: variant !== "inline",
|
||||||
[classes.radioLabelInline]: variant === "inline"
|
[classes.radioLabelInline]: variant === "inline"
|
||||||
})}
|
})}
|
||||||
control={<Radio color="primary" />}
|
control={
|
||||||
|
<Radio
|
||||||
|
className={classNames({
|
||||||
|
[classes.alignTop]: alignTop
|
||||||
|
})}
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
}
|
||||||
label={choice.label}
|
label={choice.label}
|
||||||
key={choice.value}
|
key={choice.value}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -11,10 +11,22 @@ export const shippingZoneFragment = gql`
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const shippingMethodWithZipCodesFragment = gql`
|
||||||
|
fragment ShippingMethodWithZipCodesFragment on ShippingMethod {
|
||||||
|
id
|
||||||
|
zipCodeRules {
|
||||||
|
id
|
||||||
|
start
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
export const shippingMethodFragment = gql`
|
export const shippingMethodFragment = gql`
|
||||||
${fragmentMoney}
|
${fragmentMoney}
|
||||||
|
${shippingMethodWithZipCodesFragment}
|
||||||
fragment ShippingMethodFragment on ShippingMethod {
|
fragment ShippingMethodFragment on ShippingMethod {
|
||||||
id
|
...ShippingMethodWithZipCodesFragment
|
||||||
minimumOrderWeight {
|
minimumOrderWeight {
|
||||||
unit
|
unit
|
||||||
value
|
value
|
||||||
|
|
|
@ -8,6 +8,13 @@ import { WeightUnitsEnum, ShippingMethodTypeEnum } from "./../../types/globalTyp
|
||||||
// GraphQL fragment: ShippingMethodFragment
|
// GraphQL fragment: ShippingMethodFragment
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
|
export interface ShippingMethodFragment_zipCodeRules {
|
||||||
|
__typename: "ShippingMethodZipCodeRule";
|
||||||
|
id: string;
|
||||||
|
start: string | null;
|
||||||
|
end: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ShippingMethodFragment_minimumOrderWeight {
|
export interface ShippingMethodFragment_minimumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: WeightUnitsEnum;
|
unit: WeightUnitsEnum;
|
||||||
|
@ -57,6 +64,7 @@ export interface ShippingMethodFragment_channelListings {
|
||||||
export interface ShippingMethodFragment {
|
export interface ShippingMethodFragment {
|
||||||
__typename: "ShippingMethod";
|
__typename: "ShippingMethod";
|
||||||
id: string;
|
id: string;
|
||||||
|
zipCodeRules: (ShippingMethodFragment_zipCodeRules | null)[] | null;
|
||||||
minimumOrderWeight: ShippingMethodFragment_minimumOrderWeight | null;
|
minimumOrderWeight: ShippingMethodFragment_minimumOrderWeight | null;
|
||||||
maximumOrderWeight: ShippingMethodFragment_maximumOrderWeight | null;
|
maximumOrderWeight: ShippingMethodFragment_maximumOrderWeight | null;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
20
src/fragments/types/ShippingMethodWithZipCodesFragment.ts
Normal file
20
src/fragments/types/ShippingMethodWithZipCodesFragment.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL fragment: ShippingMethodWithZipCodesFragment
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface ShippingMethodWithZipCodesFragment_zipCodeRules {
|
||||||
|
__typename: "ShippingMethodZipCodeRule";
|
||||||
|
id: string;
|
||||||
|
start: string | null;
|
||||||
|
end: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShippingMethodWithZipCodesFragment {
|
||||||
|
__typename: "ShippingMethod";
|
||||||
|
id: string;
|
||||||
|
zipCodeRules: (ShippingMethodWithZipCodesFragment_zipCodeRules | null)[] | null;
|
||||||
|
}
|
|
@ -14,6 +14,13 @@ export interface ShippingZoneDetailsFragment_countries {
|
||||||
country: string;
|
country: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ShippingZoneDetailsFragment_shippingMethods_zipCodeRules {
|
||||||
|
__typename: "ShippingMethodZipCodeRule";
|
||||||
|
id: string;
|
||||||
|
start: string | null;
|
||||||
|
end: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ShippingZoneDetailsFragment_shippingMethods_minimumOrderWeight {
|
export interface ShippingZoneDetailsFragment_shippingMethods_minimumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: WeightUnitsEnum;
|
unit: WeightUnitsEnum;
|
||||||
|
@ -63,6 +70,7 @@ export interface ShippingZoneDetailsFragment_shippingMethods_channelListings {
|
||||||
export interface ShippingZoneDetailsFragment_shippingMethods {
|
export interface ShippingZoneDetailsFragment_shippingMethods {
|
||||||
__typename: "ShippingMethod";
|
__typename: "ShippingMethod";
|
||||||
id: string;
|
id: string;
|
||||||
|
zipCodeRules: (ShippingZoneDetailsFragment_shippingMethods_zipCodeRules | null)[] | null;
|
||||||
minimumOrderWeight: ShippingZoneDetailsFragment_shippingMethods_minimumOrderWeight | null;
|
minimumOrderWeight: ShippingZoneDetailsFragment_shippingMethods_minimumOrderWeight | null;
|
||||||
maximumOrderWeight: ShippingZoneDetailsFragment_shippingMethods_maximumOrderWeight | null;
|
maximumOrderWeight: ShippingZoneDetailsFragment_shippingMethods_maximumOrderWeight | null;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
15
src/misc.ts
15
src/misc.ts
|
@ -264,15 +264,18 @@ export function getMutationState(
|
||||||
interface SaleorMutationResult {
|
interface SaleorMutationResult {
|
||||||
errors?: UserError[];
|
errors?: UserError[];
|
||||||
}
|
}
|
||||||
|
export function getMutationErrors<
|
||||||
|
TData extends Record<string, SaleorMutationResult>
|
||||||
|
>(data: TData): UserError[] {
|
||||||
|
return Object.values(data).reduce(
|
||||||
|
(acc: UserError[], mut) => [...acc, ...maybe(() => mut.errors, [])],
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
}
|
||||||
export function getMutationStatus<
|
export function getMutationStatus<
|
||||||
TData extends Record<string, SaleorMutationResult | any>
|
TData extends Record<string, SaleorMutationResult | any>
|
||||||
>(opts: MutationResult<TData>): ConfirmButtonTransitionState {
|
>(opts: MutationResult<TData>): ConfirmButtonTransitionState {
|
||||||
const errors = opts.data
|
const errors = opts.data ? getMutationErrors(opts.data) : [];
|
||||||
? Object.values(opts.data).reduce(
|
|
||||||
(acc: UserError[], mut) => [...acc, ...maybe(() => mut.errors, [])],
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
: [];
|
|
||||||
|
|
||||||
return getMutationState(opts.called, opts.loading, errors);
|
return getMutationState(opts.called, opts.loading, errors);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ export const OrderValue: React.FC<OrderValueProps> = ({
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
defaultMessage: "Order value",
|
defaultMessage: "Order Value",
|
||||||
description: "card title"
|
description: "card title"
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -40,7 +40,7 @@ export const OrderWeight: React.FC<OrderWeightProps> = ({
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
defaultMessage: "Order weight",
|
defaultMessage: "Order Weight",
|
||||||
description: "card title"
|
description: "card title"
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
import DialogContentText from "@material-ui/core/DialogContentText";
|
||||||
|
import ActionDialog from "@saleor/components/ActionDialog";
|
||||||
|
import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
|
||||||
|
import { DialogProps } from "@saleor/types";
|
||||||
|
import React from "react";
|
||||||
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
|
export interface ShippingRateZipCodeRangeRemoveDialogProps extends DialogProps {
|
||||||
|
confirmButtonState: ConfirmButtonTransitionState;
|
||||||
|
onConfirm: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ShippingRateZipCodeRangeRemoveDialog: React.FC<ShippingRateZipCodeRangeRemoveDialogProps> = ({
|
||||||
|
confirmButtonState,
|
||||||
|
open,
|
||||||
|
onClose,
|
||||||
|
onConfirm
|
||||||
|
}) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ActionDialog
|
||||||
|
confirmButtonState={confirmButtonState}
|
||||||
|
open={open}
|
||||||
|
onClose={onClose}
|
||||||
|
onConfirm={onConfirm}
|
||||||
|
title={intl.formatMessage({
|
||||||
|
defaultMessage: "Remove ZIP-codes from Shipping Rate",
|
||||||
|
description: "header"
|
||||||
|
})}
|
||||||
|
variant="delete"
|
||||||
|
>
|
||||||
|
<DialogContentText>
|
||||||
|
<FormattedMessage defaultMessage="Are you sure you want to remove this ZIP-code rule?" />
|
||||||
|
</DialogContentText>
|
||||||
|
</ActionDialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ShippingRateZipCodeRangeRemoveDialog.displayName =
|
||||||
|
"ShippingRateZipCodeRangeRemoveDialog";
|
||||||
|
export default ShippingRateZipCodeRangeRemoveDialog;
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./ShippingRateZipCodeRangeRemoveDialog";
|
||||||
|
export { default } from "./ShippingRateZipCodeRangeRemoveDialog";
|
|
@ -47,37 +47,58 @@ const props: ShippingZoneRatesPageProps = {
|
||||||
onChannelsChange: () => undefined,
|
onChannelsChange: () => undefined,
|
||||||
onDelete: () => undefined,
|
onDelete: () => undefined,
|
||||||
onSubmit: () => undefined,
|
onSubmit: () => undefined,
|
||||||
|
onZipCodeAssign: () => undefined,
|
||||||
|
onZipCodeUnassign: () => undefined,
|
||||||
openChannelsModal: () => undefined,
|
openChannelsModal: () => undefined,
|
||||||
|
rate: null,
|
||||||
saveButtonBarState: "default",
|
saveButtonBarState: "default",
|
||||||
shippingChannels: defaultChannels,
|
shippingChannels: defaultChannels,
|
||||||
variant: ShippingMethodTypeEnum.PRICE
|
variant: ShippingMethodTypeEnum.PRICE,
|
||||||
|
zipCodes: [
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: "51-200",
|
||||||
|
id: "1",
|
||||||
|
start: "51-220"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: "31-101",
|
||||||
|
id: "1",
|
||||||
|
start: "44-205"
|
||||||
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("Shipping / ShippingZoneRates page", module)
|
storiesOf("Views / Shipping / Shipping rate", module)
|
||||||
.addDecorator(Decorator)
|
.addDecorator(Decorator)
|
||||||
.add("default price", () => <ShippingZoneRatesPage {...props} />)
|
.add("create price rate", () => <ShippingZoneRatesPage {...props} />)
|
||||||
|
.add("create weight rate", () => (
|
||||||
|
<ShippingZoneRatesPage {...props} variant={ShippingMethodTypeEnum.WEIGHT} />
|
||||||
|
))
|
||||||
.add("loading", () => (
|
.add("loading", () => (
|
||||||
<ShippingZoneRatesPage
|
<ShippingZoneRatesPage
|
||||||
{...props}
|
{...props}
|
||||||
disabled={true}
|
disabled={true}
|
||||||
|
rate={undefined}
|
||||||
saveButtonBarState={"loading"}
|
saveButtonBarState={"loading"}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
.add("update price", () => (
|
.add("update price rate", () => (
|
||||||
<ShippingZoneRatesPage
|
<ShippingZoneRatesPage
|
||||||
{...props}
|
{...props}
|
||||||
shippingChannels={channels}
|
shippingChannels={channels}
|
||||||
rate={shippingZone.shippingMethods[2]}
|
rate={shippingZone.shippingMethods[2]}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
.add("default weight", () => (
|
.add("update weight rate", () => (
|
||||||
<ShippingZoneRatesPage {...props} variant={ShippingMethodTypeEnum.WEIGHT} />
|
|
||||||
))
|
|
||||||
.add("update weight", () => (
|
|
||||||
<ShippingZoneRatesPage
|
<ShippingZoneRatesPage
|
||||||
{...props}
|
{...props}
|
||||||
shippingChannels={channels}
|
shippingChannels={channels}
|
||||||
rate={shippingZone.shippingMethods[0]}
|
rate={shippingZone.shippingMethods[0]}
|
||||||
variant={ShippingMethodTypeEnum.WEIGHT}
|
variant={ShippingMethodTypeEnum.WEIGHT}
|
||||||
/>
|
/>
|
||||||
|
))
|
||||||
|
.add("no zip codes", () => (
|
||||||
|
<ShippingZoneRatesPage {...props} zipCodes={[]} />
|
||||||
));
|
));
|
||||||
|
|
|
@ -10,19 +10,27 @@ import PageHeader from "@saleor/components/PageHeader";
|
||||||
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
||||||
import { ShippingChannelsErrorFragment } from "@saleor/fragments/types/ShippingChannelsErrorFragment";
|
import { ShippingChannelsErrorFragment } from "@saleor/fragments/types/ShippingChannelsErrorFragment";
|
||||||
import { ShippingErrorFragment } from "@saleor/fragments/types/ShippingErrorFragment";
|
import { ShippingErrorFragment } from "@saleor/fragments/types/ShippingErrorFragment";
|
||||||
|
import {
|
||||||
|
ShippingMethodFragment,
|
||||||
|
ShippingMethodFragment_zipCodeRules
|
||||||
|
} from "@saleor/fragments/types/ShippingMethodFragment";
|
||||||
import { validatePrice } from "@saleor/products/utils/validation";
|
import { validatePrice } from "@saleor/products/utils/validation";
|
||||||
import OrderValue from "@saleor/shipping/components/OrderValue";
|
import OrderValue from "@saleor/shipping/components/OrderValue";
|
||||||
import OrderWeight from "@saleor/shipping/components/OrderWeight";
|
import OrderWeight from "@saleor/shipping/components/OrderWeight";
|
||||||
import PricingCard from "@saleor/shipping/components/PricingCard";
|
import PricingCard from "@saleor/shipping/components/PricingCard";
|
||||||
import ShippingZoneInfo from "@saleor/shipping/components/ShippingZoneInfo";
|
import ShippingZoneInfo from "@saleor/shipping/components/ShippingZoneInfo";
|
||||||
import { createChannelsChangeHandler } from "@saleor/shipping/handlers";
|
import { createChannelsChangeHandler } from "@saleor/shipping/handlers";
|
||||||
import { ShippingZone_shippingZone_shippingMethods } from "@saleor/shipping/types/ShippingZone";
|
|
||||||
import { ShippingMethodTypeEnum } from "@saleor/types/globalTypes";
|
import { ShippingMethodTypeEnum } from "@saleor/types/globalTypes";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
|
import ShippingZoneZipCodes, {
|
||||||
|
ZipCodeInclusion
|
||||||
|
} from "../ShippingZoneZipCodes";
|
||||||
|
|
||||||
export interface FormData {
|
export interface FormData {
|
||||||
channelListings: ChannelShippingData[];
|
channelListings: ChannelShippingData[];
|
||||||
|
includeZipCodes: ZipCodeInclusion;
|
||||||
name: string;
|
name: string;
|
||||||
noLimits: boolean;
|
noLimits: boolean;
|
||||||
minValue: string;
|
minValue: string;
|
||||||
|
@ -35,13 +43,16 @@ export interface ShippingZoneRatesPageProps {
|
||||||
shippingChannels: ChannelShippingData[];
|
shippingChannels: ChannelShippingData[];
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
hasChannelChanged?: boolean;
|
hasChannelChanged?: boolean;
|
||||||
rate?: ShippingZone_shippingZone_shippingMethods;
|
rate: ShippingMethodFragment | null;
|
||||||
|
zipCodes?: ShippingMethodFragment_zipCodeRules[];
|
||||||
channelErrors: ShippingChannelsErrorFragment[];
|
channelErrors: ShippingChannelsErrorFragment[];
|
||||||
errors: ShippingErrorFragment[];
|
errors: ShippingErrorFragment[];
|
||||||
saveButtonBarState: ConfirmButtonTransitionState;
|
saveButtonBarState: ConfirmButtonTransitionState;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
onDelete?: () => void;
|
onDelete?: () => void;
|
||||||
onSubmit: (data: FormData) => void;
|
onSubmit: (data: FormData) => void;
|
||||||
|
onZipCodeAssign: () => void;
|
||||||
|
onZipCodeUnassign: (id: string) => void;
|
||||||
onChannelsChange: (data: ChannelShippingData[]) => void;
|
onChannelsChange: (data: ChannelShippingData[]) => void;
|
||||||
openChannelsModal: () => void;
|
openChannelsModal: () => void;
|
||||||
variant: ShippingMethodTypeEnum;
|
variant: ShippingMethodTypeEnum;
|
||||||
|
@ -58,15 +69,19 @@ export const ShippingZoneRatesPage: React.FC<ShippingZoneRatesPageProps> = ({
|
||||||
onDelete,
|
onDelete,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onChannelsChange,
|
onChannelsChange,
|
||||||
|
onZipCodeAssign,
|
||||||
|
onZipCodeUnassign,
|
||||||
openChannelsModal,
|
openChannelsModal,
|
||||||
rate,
|
rate,
|
||||||
saveButtonBarState,
|
saveButtonBarState,
|
||||||
variant
|
variant,
|
||||||
|
zipCodes
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const isPriceVariant = variant === ShippingMethodTypeEnum.PRICE;
|
const isPriceVariant = variant === ShippingMethodTypeEnum.PRICE;
|
||||||
const initialForm: FormData = {
|
const initialForm: FormData = {
|
||||||
channelListings: shippingChannels,
|
channelListings: shippingChannels,
|
||||||
|
includeZipCodes: ZipCodeInclusion.Exclude,
|
||||||
maxValue: rate?.maximumOrderWeight?.value.toString() || "",
|
maxValue: rate?.maximumOrderWeight?.value.toString() || "",
|
||||||
minValue: rate?.minimumOrderWeight?.value.toString() || "",
|
minValue: rate?.minimumOrderWeight?.value.toString() || "",
|
||||||
name: rate?.name || "",
|
name: rate?.name || "",
|
||||||
|
@ -74,6 +89,8 @@ export const ShippingZoneRatesPage: React.FC<ShippingZoneRatesPageProps> = ({
|
||||||
type: rate?.type || null
|
type: rate?.type || null
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const rateExists = rate !== null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form initial={initialForm} onSubmit={onSubmit}>
|
<Form initial={initialForm} onSubmit={onSubmit}>
|
||||||
{({ change, data, hasChanged, submit, triggerChange }) => {
|
{({ change, data, hasChanged, submit, triggerChange }) => {
|
||||||
|
@ -141,6 +158,14 @@ export const ShippingZoneRatesPage: React.FC<ShippingZoneRatesPageProps> = ({
|
||||||
errors={channelErrors}
|
errors={channelErrors}
|
||||||
/>
|
/>
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
|
<ShippingZoneZipCodes
|
||||||
|
data={data}
|
||||||
|
disabled={disabled}
|
||||||
|
onZipCodeDelete={onZipCodeUnassign}
|
||||||
|
onZipCodeInclusionChange={() => undefined}
|
||||||
|
onZipCodeRangeAdd={onZipCodeAssign}
|
||||||
|
zipCodes={rateExists ? rate?.zipCodeRules : zipCodes}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<ChannelsAvailability
|
<ChannelsAvailability
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
import Decorator from "@saleor/storybook/Decorator";
|
||||||
|
import { storiesOf } from "@storybook/react";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import ShippingZoneZipCodeRangeDialog from "./ShippingZoneZipCodeRangeDialog";
|
||||||
|
|
||||||
|
storiesOf("Shipping / Add zip code range", module)
|
||||||
|
.addDecorator(Decorator)
|
||||||
|
.add("default", () => (
|
||||||
|
<ShippingZoneZipCodeRangeDialog
|
||||||
|
confirmButtonState="default"
|
||||||
|
open={true}
|
||||||
|
onClose={() => undefined}
|
||||||
|
onSubmit={() => undefined}
|
||||||
|
/>
|
||||||
|
));
|
|
@ -0,0 +1,109 @@
|
||||||
|
import Button from "@material-ui/core/Button";
|
||||||
|
import Dialog from "@material-ui/core/Dialog";
|
||||||
|
import DialogActions from "@material-ui/core/DialogActions";
|
||||||
|
import DialogContent from "@material-ui/core/DialogContent";
|
||||||
|
import DialogTitle from "@material-ui/core/DialogTitle";
|
||||||
|
import makeStyles from "@material-ui/core/styles/makeStyles";
|
||||||
|
import TextField from "@material-ui/core/TextField";
|
||||||
|
import Typography from "@material-ui/core/Typography";
|
||||||
|
import ConfirmButton, {
|
||||||
|
ConfirmButtonTransitionState
|
||||||
|
} from "@saleor/components/ConfirmButton";
|
||||||
|
import Form from "@saleor/components/Form";
|
||||||
|
import Grid from "@saleor/components/Grid";
|
||||||
|
import { buttonMessages, commonMessages } from "@saleor/intl";
|
||||||
|
import { DialogProps, MinMax } from "@saleor/types";
|
||||||
|
import React from "react";
|
||||||
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
|
export interface ShippingZoneZipCodeRangeDialogProps extends DialogProps {
|
||||||
|
confirmButtonState: ConfirmButtonTransitionState;
|
||||||
|
onSubmit: (range: MinMax) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const useStyles = makeStyles(
|
||||||
|
theme => ({
|
||||||
|
info: {
|
||||||
|
marginBottom: theme.spacing(2)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
name: "ShippingZoneZipCodeRangeDialog"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const ShippingZoneZipCodeRangeDialog: React.FC<ShippingZoneZipCodeRangeDialogProps> = ({
|
||||||
|
confirmButtonState,
|
||||||
|
open,
|
||||||
|
onClose,
|
||||||
|
onSubmit
|
||||||
|
}) => {
|
||||||
|
const classes = useStyles({});
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const initial: MinMax = {
|
||||||
|
max: "",
|
||||||
|
min: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={open}>
|
||||||
|
<DialogTitle>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Add ZIP-Codes"
|
||||||
|
description="dialog header"
|
||||||
|
/>
|
||||||
|
</DialogTitle>
|
||||||
|
<Form initial={initial} onSubmit={onSubmit}>
|
||||||
|
{({ change, data, hasChanged }) => (
|
||||||
|
<>
|
||||||
|
<DialogContent>
|
||||||
|
<Typography className={classes.info}>
|
||||||
|
<FormattedMessage defaultMessage="Please provide range of ZIP codes you want to add to the include/exclude list." />
|
||||||
|
</Typography>
|
||||||
|
<Grid variant="uniform">
|
||||||
|
<TextField
|
||||||
|
label={intl.formatMessage({
|
||||||
|
defaultMessage: "Zip Codes (Start)",
|
||||||
|
description: "range input label"
|
||||||
|
})}
|
||||||
|
name="min"
|
||||||
|
value={data.min}
|
||||||
|
onChange={change}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
label={intl.formatMessage({
|
||||||
|
defaultMessage: "Zip Codes (End)",
|
||||||
|
description: "range input label"
|
||||||
|
})}
|
||||||
|
name="max"
|
||||||
|
helperText={intl.formatMessage(commonMessages.optionalField)}
|
||||||
|
value={data.max}
|
||||||
|
onChange={change}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={onClose}>
|
||||||
|
<FormattedMessage {...buttonMessages.back} />
|
||||||
|
</Button>
|
||||||
|
<ConfirmButton
|
||||||
|
disabled={!hasChanged || !data.min}
|
||||||
|
transitionState={confirmButtonState}
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Add"
|
||||||
|
description="add zip code range, button"
|
||||||
|
/>
|
||||||
|
</ConfirmButton>
|
||||||
|
</DialogActions>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Form>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ShippingZoneZipCodeRangeDialog.displayName = "ShippingZoneZipCodeRangeDialog";
|
||||||
|
export default ShippingZoneZipCodeRangeDialog;
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./ShippingZoneZipCodeRangeDialog";
|
||||||
|
export { default } from "./ShippingZoneZipCodeRangeDialog";
|
|
@ -0,0 +1,233 @@
|
||||||
|
import Button from "@material-ui/core/Button";
|
||||||
|
import Card from "@material-ui/core/Card";
|
||||||
|
import CardContent from "@material-ui/core/CardContent";
|
||||||
|
import IconButton from "@material-ui/core/IconButton";
|
||||||
|
import makeStyles from "@material-ui/core/styles/makeStyles";
|
||||||
|
import TableBody from "@material-ui/core/TableBody";
|
||||||
|
import TableCell from "@material-ui/core/TableCell";
|
||||||
|
import TableHead from "@material-ui/core/TableHead";
|
||||||
|
import TableRow from "@material-ui/core/TableRow";
|
||||||
|
import Typography from "@material-ui/core/Typography";
|
||||||
|
import DeleteIcon from "@material-ui/icons/Delete";
|
||||||
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
|
import RadioGroupField from "@saleor/components/RadioGroupField";
|
||||||
|
import ResponsiveTable from "@saleor/components/ResponsiveTable";
|
||||||
|
import Skeleton from "@saleor/components/Skeleton";
|
||||||
|
import { ShippingMethodFragment_zipCodeRules } from "@saleor/fragments/types/ShippingMethodFragment";
|
||||||
|
import { FormChange } from "@saleor/hooks/useForm";
|
||||||
|
import ArrowDropdown from "@saleor/icons/ArrowDropdown";
|
||||||
|
import { renderCollection } from "@saleor/misc";
|
||||||
|
import classNames from "classnames";
|
||||||
|
import React from "react";
|
||||||
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
|
export enum ZipCodeInclusion {
|
||||||
|
Include,
|
||||||
|
Exclude
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShippingZoneZipCodesProps {
|
||||||
|
data: Record<"includeZipCodes", ZipCodeInclusion>;
|
||||||
|
disabled: boolean;
|
||||||
|
initialExpanded?: boolean;
|
||||||
|
zipCodes: ShippingMethodFragment_zipCodeRules[] | undefined;
|
||||||
|
onZipCodeInclusionChange: FormChange;
|
||||||
|
onZipCodeDelete: (id: string) => void;
|
||||||
|
onZipCodeRangeAdd: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const useStyles = makeStyles(
|
||||||
|
theme => ({
|
||||||
|
arrow: {
|
||||||
|
transition: theme.transitions.create("transform")
|
||||||
|
},
|
||||||
|
arrowRotate: {
|
||||||
|
transform: "scale(-1)"
|
||||||
|
},
|
||||||
|
colAction: {
|
||||||
|
width: 80
|
||||||
|
},
|
||||||
|
colCode: {},
|
||||||
|
hide: {
|
||||||
|
display: "none"
|
||||||
|
},
|
||||||
|
option: {
|
||||||
|
marginBottom: theme.spacing(2),
|
||||||
|
width: 400
|
||||||
|
},
|
||||||
|
radioContainer: {
|
||||||
|
paddingBottom: 0
|
||||||
|
},
|
||||||
|
skeleton: {
|
||||||
|
width: 80
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
name: "ShippingZoneZipCodes"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const ShippingZoneZipCodes: React.FC<ShippingZoneZipCodesProps> = ({
|
||||||
|
data,
|
||||||
|
disabled,
|
||||||
|
initialExpanded,
|
||||||
|
zipCodes,
|
||||||
|
onZipCodeDelete,
|
||||||
|
onZipCodeInclusionChange,
|
||||||
|
onZipCodeRangeAdd
|
||||||
|
}) => {
|
||||||
|
const [expanded, setExpanded] = React.useState(initialExpanded);
|
||||||
|
const intl = useIntl();
|
||||||
|
const classes = useStyles({});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<CardTitle
|
||||||
|
title={intl.formatMessage({
|
||||||
|
defaultMessage: "ZIP-Codes",
|
||||||
|
description: "postal codes, header"
|
||||||
|
})}
|
||||||
|
toolbar={
|
||||||
|
<Button
|
||||||
|
color="primary"
|
||||||
|
onClick={onZipCodeRangeAdd}
|
||||||
|
data-test="add-zip-code-range"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Add ZIP-Code range"
|
||||||
|
description="button"
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<CardContent className={classNames(classes.radioContainer, classes.hide)}>
|
||||||
|
<RadioGroupField
|
||||||
|
alignTop
|
||||||
|
choices={[
|
||||||
|
{
|
||||||
|
disabled: true,
|
||||||
|
label: (
|
||||||
|
<div className={classes.option}>
|
||||||
|
<Typography color="textSecondary" variant="body1">
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Exclude ZIP-codes"
|
||||||
|
description="action"
|
||||||
|
/>
|
||||||
|
</Typography>
|
||||||
|
<Typography color="textSecondary" variant="caption">
|
||||||
|
<FormattedMessage defaultMessage="Added ZIP-codes will be excluded from using this delivery methods. If none are added all ZIP-Codes will be able to use that shipping rate" />
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: ZipCodeInclusion.Exclude
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: (
|
||||||
|
<div className={classes.option}>
|
||||||
|
<Typography variant="body1">
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Include ZIP-codes"
|
||||||
|
description="action"
|
||||||
|
/>
|
||||||
|
</Typography>
|
||||||
|
<Typography color="textSecondary" variant="caption">
|
||||||
|
<FormattedMessage defaultMessage="Only added ZIP-codes will be able to use this shipping rate" />
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: ZipCodeInclusion.Include
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
name="includeZipCodes"
|
||||||
|
value={data.includeZipCodes}
|
||||||
|
onChange={onZipCodeInclusionChange}
|
||||||
|
/>
|
||||||
|
</CardContent>
|
||||||
|
<ResponsiveTable>
|
||||||
|
<colgroup>
|
||||||
|
<col />
|
||||||
|
<col className={classes.colAction} />
|
||||||
|
</colgroup>
|
||||||
|
{zipCodes === undefined ||
|
||||||
|
(zipCodes.length > 0 && (
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell>
|
||||||
|
{zipCodes === undefined ? (
|
||||||
|
<Skeleton className={classes.skeleton} />
|
||||||
|
) : (
|
||||||
|
<Typography variant="caption">
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="{number} ZIP-Code ranges"
|
||||||
|
description="number of zip code ranges"
|
||||||
|
values={{
|
||||||
|
number: zipCodes.length
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<IconButton onClick={() => setExpanded(!expanded)}>
|
||||||
|
<ArrowDropdown
|
||||||
|
className={classNames(classes.arrow, {
|
||||||
|
[classes.arrowRotate]: expanded
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</IconButton>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
))}
|
||||||
|
{expanded && (
|
||||||
|
<TableBody>
|
||||||
|
{renderCollection(
|
||||||
|
zipCodes,
|
||||||
|
zipCodeRange => (
|
||||||
|
<TableRow key={zipCodeRange?.id}>
|
||||||
|
<TableCell>
|
||||||
|
{zipCodeRange?.start ? (
|
||||||
|
zipCodeRange?.end ? (
|
||||||
|
`${zipCodeRange.start} - ${zipCodeRange.end}`
|
||||||
|
) : (
|
||||||
|
zipCodeRange.start
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<Skeleton />
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<IconButton
|
||||||
|
disabled={disabled}
|
||||||
|
color="primary"
|
||||||
|
onClick={() => onZipCodeDelete(zipCodeRange.id)}
|
||||||
|
data-test="delete-zip-code"
|
||||||
|
data-test-id={zipCodeRange?.id}
|
||||||
|
>
|
||||||
|
<DeleteIcon />
|
||||||
|
</IconButton>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
),
|
||||||
|
() => (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={2}>
|
||||||
|
<Typography color="textSecondary">
|
||||||
|
<FormattedMessage defaultMessage="This shipping rate has no ZIP-codes assigned" />
|
||||||
|
</Typography>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
)}
|
||||||
|
</ResponsiveTable>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ShippingZoneZipCodes.displayName = "ShippingZoneZipCodes";
|
||||||
|
ShippingZoneZipCodes.defaultProps = {
|
||||||
|
initialExpanded: true
|
||||||
|
};
|
||||||
|
export default ShippingZoneZipCodes;
|
2
src/shipping/components/ShippingZoneZipCodes/index.ts
Normal file
2
src/shipping/components/ShippingZoneZipCodes/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./ShippingZoneZipCodes";
|
||||||
|
export { default } from "./ShippingZoneZipCodes";
|
|
@ -1589,7 +1589,27 @@ export const shippingZone: ShippingZoneDetailsFragment = {
|
||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
name: "DB Schenker",
|
name: "DB Schenker",
|
||||||
type: ShippingMethodTypeEnum.WEIGHT
|
type: ShippingMethodTypeEnum.WEIGHT,
|
||||||
|
zipCodeRules: [
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: "51-220",
|
||||||
|
id: "1",
|
||||||
|
start: "51-210"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: "51-240",
|
||||||
|
id: "2",
|
||||||
|
start: "51-235"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: null,
|
||||||
|
id: "2",
|
||||||
|
start: "51-274"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
__typename: "ShippingMethod",
|
__typename: "ShippingMethod",
|
||||||
|
@ -1602,7 +1622,27 @@ export const shippingZone: ShippingZoneDetailsFragment = {
|
||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
name: "Registred priority",
|
name: "Registred priority",
|
||||||
type: ShippingMethodTypeEnum.WEIGHT
|
type: ShippingMethodTypeEnum.WEIGHT,
|
||||||
|
zipCodeRules: [
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: "51-220",
|
||||||
|
id: "1",
|
||||||
|
start: "51-210"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: "51-240",
|
||||||
|
id: "2",
|
||||||
|
start: "51-235"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: null,
|
||||||
|
id: "2",
|
||||||
|
start: "51-274"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
__typename: "ShippingMethod",
|
__typename: "ShippingMethod",
|
||||||
|
@ -1614,9 +1654,28 @@ export const shippingZone: ShippingZoneDetailsFragment = {
|
||||||
unit: WeightUnitsEnum.KG,
|
unit: WeightUnitsEnum.KG,
|
||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
|
|
||||||
name: "UPS",
|
name: "UPS",
|
||||||
type: ShippingMethodTypeEnum.PRICE
|
type: ShippingMethodTypeEnum.PRICE,
|
||||||
|
zipCodeRules: [
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: "51-220",
|
||||||
|
id: "1",
|
||||||
|
start: "51-210"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: "51-240",
|
||||||
|
id: "2",
|
||||||
|
start: "51-235"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: null,
|
||||||
|
id: "2",
|
||||||
|
start: "51-274"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
__typename: "ShippingMethod",
|
__typename: "ShippingMethod",
|
||||||
|
@ -1629,7 +1688,27 @@ export const shippingZone: ShippingZoneDetailsFragment = {
|
||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
name: "DHL",
|
name: "DHL",
|
||||||
type: ShippingMethodTypeEnum.PRICE
|
type: ShippingMethodTypeEnum.PRICE,
|
||||||
|
zipCodeRules: [
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: "51-220",
|
||||||
|
id: "1",
|
||||||
|
start: "51-210"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: "51-240",
|
||||||
|
id: "2",
|
||||||
|
start: "51-235"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: null,
|
||||||
|
id: "2",
|
||||||
|
start: "51-274"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
warehouses: [
|
warehouses: [
|
||||||
|
|
|
@ -1,10 +1,24 @@
|
||||||
import { ChannelShippingData } from "@saleor/channels/utils";
|
import { ChannelShippingData } from "@saleor/channels/utils";
|
||||||
|
import { ShippingMethodFragment_zipCodeRules } from "@saleor/fragments/types/ShippingMethodFragment";
|
||||||
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
|
import useNotifier from "@saleor/hooks/useNotifier";
|
||||||
|
import { commonMessages } from "@saleor/intl";
|
||||||
|
import { getMutationErrors, getMutationState } from "@saleor/misc";
|
||||||
import { FormData as ShippingZoneRatesPageFormData } from "@saleor/shipping/components/ShippingZoneRatesPage";
|
import { FormData as ShippingZoneRatesPageFormData } from "@saleor/shipping/components/ShippingZoneRatesPage";
|
||||||
import { CreateShippingRateVariables } from "@saleor/shipping/types/CreateShippingRate";
|
import { CreateShippingRateVariables } from "@saleor/shipping/types/CreateShippingRate";
|
||||||
import { ShippingMethodChannelListingUpdateVariables } from "@saleor/shipping/types/ShippingMethodChannelListingUpdate";
|
import { ShippingMethodChannelListingUpdateVariables } from "@saleor/shipping/types/ShippingMethodChannelListingUpdate";
|
||||||
import { UpdateShippingRateVariables } from "@saleor/shipping/types/UpdateShippingRate";
|
import { UpdateShippingRateVariables } from "@saleor/shipping/types/UpdateShippingRate";
|
||||||
import { ShippingMethodTypeEnum } from "@saleor/types/globalTypes";
|
import { ShippingMethodTypeEnum } from "@saleor/types/globalTypes";
|
||||||
import { diff } from "fast-array-diff";
|
import { diff } from "fast-array-diff";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
import {
|
||||||
|
useShippingMethodChannelListingUpdate,
|
||||||
|
useShippingMethodZipCodeRangeAssign,
|
||||||
|
useShippingRateCreate,
|
||||||
|
useShippingRateDelete
|
||||||
|
} from "./mutations";
|
||||||
|
import { shippingPriceRatesEditUrl, shippingWeightRatesEditUrl } from "./urls";
|
||||||
|
|
||||||
export const createChannelsChangeHandler = (
|
export const createChannelsChangeHandler = (
|
||||||
selectedChannels: ChannelShippingData[],
|
selectedChannels: ChannelShippingData[],
|
||||||
|
@ -122,3 +136,109 @@ export function getShippingMethodChannelVariables(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useShippingRateCreator(
|
||||||
|
shippingZoneId: string,
|
||||||
|
type: ShippingMethodTypeEnum,
|
||||||
|
zipCodes: ShippingMethodFragment_zipCodeRules[]
|
||||||
|
) {
|
||||||
|
const intl = useIntl();
|
||||||
|
const notify = useNotifier();
|
||||||
|
const navigate = useNavigator();
|
||||||
|
const [
|
||||||
|
createBaseShippingRate,
|
||||||
|
createBaseShippingRateOpts
|
||||||
|
] = useShippingRateCreate({});
|
||||||
|
const [
|
||||||
|
assignZipCodeRules,
|
||||||
|
assignZipCodeRulesOpts
|
||||||
|
] = useShippingMethodZipCodeRangeAssign({});
|
||||||
|
const [
|
||||||
|
updateShippingMethodChannelListing,
|
||||||
|
updateShippingMethodChannelListingOpts
|
||||||
|
] = useShippingMethodChannelListingUpdate({});
|
||||||
|
const [deleteShippingRate] = useShippingRateDelete({});
|
||||||
|
|
||||||
|
const getVariables =
|
||||||
|
type === ShippingMethodTypeEnum.PRICE
|
||||||
|
? getCreateShippingPriceRateVariables
|
||||||
|
: getCreateShippingWeightRateVariables;
|
||||||
|
const getUrl =
|
||||||
|
type === ShippingMethodTypeEnum.PRICE
|
||||||
|
? shippingPriceRatesEditUrl
|
||||||
|
: shippingWeightRatesEditUrl;
|
||||||
|
|
||||||
|
const createShippingRate = async (data: ShippingZoneRatesPageFormData) => {
|
||||||
|
const response = await createBaseShippingRate({
|
||||||
|
variables: getVariables(data, shippingZoneId)
|
||||||
|
});
|
||||||
|
|
||||||
|
const createErrors = response.data.shippingPriceCreate.errors;
|
||||||
|
if (createErrors.length === 0) {
|
||||||
|
const rateId = response.data.shippingPriceCreate.shippingMethod.id;
|
||||||
|
|
||||||
|
const mutationResults = await Promise.all([
|
||||||
|
updateShippingMethodChannelListing({
|
||||||
|
variables: getShippingMethodChannelVariables(
|
||||||
|
rateId,
|
||||||
|
data.noLimits,
|
||||||
|
data.channelListings
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
assignZipCodeRules({
|
||||||
|
variables: {
|
||||||
|
id: rateId,
|
||||||
|
input: {
|
||||||
|
zipCodeRules: zipCodes.map(zipCodeRule => ({
|
||||||
|
end: zipCodeRule.end || null,
|
||||||
|
start: zipCodeRule.start
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (
|
||||||
|
mutationResults.find(
|
||||||
|
result => getMutationErrors(result.data as any).length > 0
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
deleteShippingRate({
|
||||||
|
variables: {
|
||||||
|
id: rateId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
notify({
|
||||||
|
status: "success",
|
||||||
|
text: intl.formatMessage(commonMessages.savedChanges)
|
||||||
|
});
|
||||||
|
navigate(getUrl(shippingZoneId, rateId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const called =
|
||||||
|
createBaseShippingRateOpts.called ||
|
||||||
|
updateShippingMethodChannelListingOpts.called ||
|
||||||
|
assignZipCodeRulesOpts.called;
|
||||||
|
const loading =
|
||||||
|
createBaseShippingRateOpts.loading ||
|
||||||
|
updateShippingMethodChannelListingOpts.loading ||
|
||||||
|
assignZipCodeRulesOpts.loading;
|
||||||
|
const errors = [
|
||||||
|
...(createBaseShippingRateOpts.data?.shippingPriceCreate.errors || []),
|
||||||
|
...(assignZipCodeRulesOpts.data?.shippingMethodZipCodeRulesCreate.errors ||
|
||||||
|
[])
|
||||||
|
];
|
||||||
|
const channelErrors =
|
||||||
|
updateShippingMethodChannelListingOpts.data
|
||||||
|
?.shippingMethodChannelListingUpdate.errors || [];
|
||||||
|
|
||||||
|
return {
|
||||||
|
channelErrors,
|
||||||
|
createShippingRate,
|
||||||
|
errors,
|
||||||
|
status: getMutationState(called, loading, [...errors, ...channelErrors])
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -6,10 +6,12 @@ import { Route, RouteComponentProps, Switch } from "react-router-dom";
|
||||||
|
|
||||||
import { WindowTitle } from "../components/WindowTitle";
|
import { WindowTitle } from "../components/WindowTitle";
|
||||||
import {
|
import {
|
||||||
shippingPriceRatesEditUrl,
|
shippingPriceRatesEditPath,
|
||||||
shippingPriceRatesUrl,
|
shippingPriceRatesPath,
|
||||||
shippingWeightRatesEditUrl,
|
ShippingRateCreateUrlQueryParams,
|
||||||
shippingWeightRatesUrl,
|
ShippingRateUrlQueryParams,
|
||||||
|
shippingWeightRatesEditPath,
|
||||||
|
shippingWeightRatesPath,
|
||||||
shippingZoneAddPath,
|
shippingZoneAddPath,
|
||||||
shippingZonePath,
|
shippingZonePath,
|
||||||
shippingZonesListPath,
|
shippingZonesListPath,
|
||||||
|
@ -48,31 +50,63 @@ const ShippingZoneDetails: React.FC<RouteComponentProps<
|
||||||
|
|
||||||
const PriceRatesCreate: React.FC<RouteComponentProps<{ id: string }>> = ({
|
const PriceRatesCreate: React.FC<RouteComponentProps<{ id: string }>> = ({
|
||||||
match
|
match
|
||||||
}) => <PriceRatesCreateComponent id={decodeURIComponent(match.params.id)} />;
|
}) => {
|
||||||
|
const qs = parseQs(location.search.substr(1));
|
||||||
|
const params: ShippingRateCreateUrlQueryParams = qs;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PriceRatesCreateComponent
|
||||||
|
id={decodeURIComponent(match.params.id)}
|
||||||
|
params={params}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const WeightRatesCreate: React.FC<RouteComponentProps<{ id: string }>> = ({
|
const WeightRatesCreate: React.FC<RouteComponentProps<{ id: string }>> = ({
|
||||||
match
|
match
|
||||||
}) => <WeightRatesCreateComponent id={decodeURIComponent(match.params.id)} />;
|
}) => {
|
||||||
|
const qs = parseQs(location.search.substr(1));
|
||||||
|
const params: ShippingRateCreateUrlQueryParams = qs;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<WeightRatesCreateComponent
|
||||||
|
id={decodeURIComponent(match.params.id)}
|
||||||
|
params={params}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const WeightRatesUpdate: React.FC<RouteComponentProps<{
|
const WeightRatesUpdate: React.FC<RouteComponentProps<{
|
||||||
id: string;
|
id: string;
|
||||||
rateId: string;
|
rateId: string;
|
||||||
}>> = ({ match }) => (
|
}>> = ({ match }) => {
|
||||||
<WeightRatesUpdateComponent
|
const qs = parseQs(location.search.substr(1));
|
||||||
id={decodeURIComponent(match.params.id)}
|
const params: ShippingRateUrlQueryParams = qs;
|
||||||
rateId={decodeURIComponent(match.params.rateId)}
|
|
||||||
/>
|
return (
|
||||||
);
|
<WeightRatesUpdateComponent
|
||||||
|
id={decodeURIComponent(match.params.id)}
|
||||||
|
rateId={decodeURIComponent(match.params.rateId)}
|
||||||
|
params={params}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const PriceRatesUpdate: React.FC<RouteComponentProps<{
|
const PriceRatesUpdate: React.FC<RouteComponentProps<{
|
||||||
id: string;
|
id: string;
|
||||||
rateId: string;
|
rateId: string;
|
||||||
}>> = ({ match }) => (
|
}>> = ({ match }) => {
|
||||||
<PriceRatesUpdateComponent
|
const qs = parseQs(location.search.substr(1));
|
||||||
id={decodeURIComponent(match.params.id)}
|
const params: ShippingRateUrlQueryParams = qs;
|
||||||
rateId={decodeURIComponent(match.params.rateId)}
|
|
||||||
/>
|
return (
|
||||||
);
|
<PriceRatesUpdateComponent
|
||||||
|
id={decodeURIComponent(match.params.id)}
|
||||||
|
rateId={decodeURIComponent(match.params.rateId)}
|
||||||
|
params={params}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const ShippingRouter: React.FC = () => {
|
export const ShippingRouter: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
@ -97,19 +131,19 @@ export const ShippingRouter: React.FC = () => {
|
||||||
component={ShippingZoneDetails}
|
component={ShippingZoneDetails}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={shippingPriceRatesUrl(":id")}
|
path={shippingPriceRatesPath(":id")}
|
||||||
component={PriceRatesCreate}
|
component={PriceRatesCreate}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={shippingWeightRatesUrl(":id")}
|
path={shippingWeightRatesPath(":id")}
|
||||||
component={WeightRatesCreate}
|
component={WeightRatesCreate}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={shippingWeightRatesEditUrl(":id", ":rateId")}
|
path={shippingWeightRatesEditPath(":id", ":rateId")}
|
||||||
component={WeightRatesUpdate}
|
component={WeightRatesUpdate}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={shippingPriceRatesEditUrl(":id", ":rateId")}
|
path={shippingPriceRatesEditPath(":id", ":rateId")}
|
||||||
component={PriceRatesUpdate}
|
component={PriceRatesUpdate}
|
||||||
/>
|
/>
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
} from "@saleor/fragments/errors";
|
} from "@saleor/fragments/errors";
|
||||||
import {
|
import {
|
||||||
shippingMethodFragment,
|
shippingMethodFragment,
|
||||||
|
shippingMethodWithZipCodesFragment,
|
||||||
shippingZoneDetailsFragment
|
shippingZoneDetailsFragment
|
||||||
} from "@saleor/fragments/shipping";
|
} from "@saleor/fragments/shipping";
|
||||||
import { countryFragment } from "@saleor/fragments/taxes";
|
import { countryFragment } from "@saleor/fragments/taxes";
|
||||||
|
@ -38,6 +39,14 @@ import {
|
||||||
ShippingMethodChannelListingUpdate,
|
ShippingMethodChannelListingUpdate,
|
||||||
ShippingMethodChannelListingUpdateVariables
|
ShippingMethodChannelListingUpdateVariables
|
||||||
} from "./types/ShippingMethodChannelListingUpdate";
|
} from "./types/ShippingMethodChannelListingUpdate";
|
||||||
|
import {
|
||||||
|
ShippingMethodZipCodeRangeAssign,
|
||||||
|
ShippingMethodZipCodeRangeAssignVariables
|
||||||
|
} from "./types/ShippingMethodZipCodeRangeAssign";
|
||||||
|
import {
|
||||||
|
ShippingMethodZipCodeRangeUnassign,
|
||||||
|
ShippingMethodZipCodeRangeUnassignVariables
|
||||||
|
} from "./types/ShippingMethodZipCodeRangeUnassign";
|
||||||
import {
|
import {
|
||||||
UpdateDefaultWeightUnit,
|
UpdateDefaultWeightUnit,
|
||||||
UpdateDefaultWeightUnitVariables
|
UpdateDefaultWeightUnitVariables
|
||||||
|
@ -245,3 +254,46 @@ export const useShippingMethodChannelListingUpdate = makeMutation<
|
||||||
ShippingMethodChannelListingUpdate,
|
ShippingMethodChannelListingUpdate,
|
||||||
ShippingMethodChannelListingUpdateVariables
|
ShippingMethodChannelListingUpdateVariables
|
||||||
>(shippingMethodChannelListingUpdate);
|
>(shippingMethodChannelListingUpdate);
|
||||||
|
|
||||||
|
export const shippingMethodZipCodeRangeAssign = gql`
|
||||||
|
${shippingChannelsErrorFragment}
|
||||||
|
${shippingMethodWithZipCodesFragment}
|
||||||
|
mutation ShippingMethodZipCodeRangeAssign(
|
||||||
|
$id: ID!
|
||||||
|
$input: ShippingZipCodeRulesCreateInput!
|
||||||
|
) {
|
||||||
|
shippingMethodZipCodeRulesCreate(shippingMethodId: $id, input: $input) {
|
||||||
|
errors: shippingErrors {
|
||||||
|
...ShippingChannelsErrorFragment
|
||||||
|
}
|
||||||
|
shippingMethod {
|
||||||
|
...ShippingMethodWithZipCodesFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const useShippingMethodZipCodeRangeAssign = makeMutation<
|
||||||
|
ShippingMethodZipCodeRangeAssign,
|
||||||
|
ShippingMethodZipCodeRangeAssignVariables
|
||||||
|
>(shippingMethodZipCodeRangeAssign);
|
||||||
|
|
||||||
|
export const shippingMethodZipCodeRulesDelete = gql`
|
||||||
|
${shippingChannelsErrorFragment}
|
||||||
|
${shippingMethodWithZipCodesFragment}
|
||||||
|
mutation ShippingMethodZipCodeRangeUnassign($id: ID!) {
|
||||||
|
shippingMethodZipCodeRulesDelete(id: $id) {
|
||||||
|
errors: shippingErrors {
|
||||||
|
...ShippingChannelsErrorFragment
|
||||||
|
}
|
||||||
|
shippingMethod {
|
||||||
|
...ShippingMethodWithZipCodesFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const useShippingMethodZipCodeRangeUnassign = makeMutation<
|
||||||
|
ShippingMethodZipCodeRangeUnassign,
|
||||||
|
ShippingMethodZipCodeRangeUnassignVariables
|
||||||
|
>(shippingMethodZipCodeRulesDelete);
|
||||||
|
|
|
@ -20,6 +20,13 @@ export interface CreateShippingRate_shippingPriceCreate_shippingZone_countries {
|
||||||
country: string;
|
country: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CreateShippingRate_shippingPriceCreate_shippingZone_shippingMethods_zipCodeRules {
|
||||||
|
__typename: "ShippingMethodZipCodeRule";
|
||||||
|
id: string;
|
||||||
|
start: string | null;
|
||||||
|
end: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CreateShippingRate_shippingPriceCreate_shippingZone_shippingMethods_minimumOrderWeight {
|
export interface CreateShippingRate_shippingPriceCreate_shippingZone_shippingMethods_minimumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: WeightUnitsEnum;
|
unit: WeightUnitsEnum;
|
||||||
|
@ -69,6 +76,7 @@ export interface CreateShippingRate_shippingPriceCreate_shippingZone_shippingMet
|
||||||
export interface CreateShippingRate_shippingPriceCreate_shippingZone_shippingMethods {
|
export interface CreateShippingRate_shippingPriceCreate_shippingZone_shippingMethods {
|
||||||
__typename: "ShippingMethod";
|
__typename: "ShippingMethod";
|
||||||
id: string;
|
id: string;
|
||||||
|
zipCodeRules: (CreateShippingRate_shippingPriceCreate_shippingZone_shippingMethods_zipCodeRules | null)[] | null;
|
||||||
minimumOrderWeight: CreateShippingRate_shippingPriceCreate_shippingZone_shippingMethods_minimumOrderWeight | null;
|
minimumOrderWeight: CreateShippingRate_shippingPriceCreate_shippingZone_shippingMethods_minimumOrderWeight | null;
|
||||||
maximumOrderWeight: CreateShippingRate_shippingPriceCreate_shippingZone_shippingMethods_maximumOrderWeight | null;
|
maximumOrderWeight: CreateShippingRate_shippingPriceCreate_shippingZone_shippingMethods_maximumOrderWeight | null;
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -92,6 +100,13 @@ export interface CreateShippingRate_shippingPriceCreate_shippingZone {
|
||||||
warehouses: (CreateShippingRate_shippingPriceCreate_shippingZone_warehouses | null)[] | null;
|
warehouses: (CreateShippingRate_shippingPriceCreate_shippingZone_warehouses | null)[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CreateShippingRate_shippingPriceCreate_shippingMethod_zipCodeRules {
|
||||||
|
__typename: "ShippingMethodZipCodeRule";
|
||||||
|
id: string;
|
||||||
|
start: string | null;
|
||||||
|
end: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CreateShippingRate_shippingPriceCreate_shippingMethod_minimumOrderWeight {
|
export interface CreateShippingRate_shippingPriceCreate_shippingMethod_minimumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: WeightUnitsEnum;
|
unit: WeightUnitsEnum;
|
||||||
|
@ -141,6 +156,7 @@ export interface CreateShippingRate_shippingPriceCreate_shippingMethod_channelLi
|
||||||
export interface CreateShippingRate_shippingPriceCreate_shippingMethod {
|
export interface CreateShippingRate_shippingPriceCreate_shippingMethod {
|
||||||
__typename: "ShippingMethod";
|
__typename: "ShippingMethod";
|
||||||
id: string;
|
id: string;
|
||||||
|
zipCodeRules: (CreateShippingRate_shippingPriceCreate_shippingMethod_zipCodeRules | null)[] | null;
|
||||||
minimumOrderWeight: CreateShippingRate_shippingPriceCreate_shippingMethod_minimumOrderWeight | null;
|
minimumOrderWeight: CreateShippingRate_shippingPriceCreate_shippingMethod_minimumOrderWeight | null;
|
||||||
maximumOrderWeight: CreateShippingRate_shippingPriceCreate_shippingMethod_maximumOrderWeight | null;
|
maximumOrderWeight: CreateShippingRate_shippingPriceCreate_shippingMethod_maximumOrderWeight | null;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
@ -20,6 +20,13 @@ export interface DeleteShippingRate_shippingPriceDelete_shippingZone_countries {
|
||||||
country: string;
|
country: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMethods_zipCodeRules {
|
||||||
|
__typename: "ShippingMethodZipCodeRule";
|
||||||
|
id: string;
|
||||||
|
start: string | null;
|
||||||
|
end: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMethods_minimumOrderWeight {
|
export interface DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMethods_minimumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: WeightUnitsEnum;
|
unit: WeightUnitsEnum;
|
||||||
|
@ -69,6 +76,7 @@ export interface DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMet
|
||||||
export interface DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMethods {
|
export interface DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMethods {
|
||||||
__typename: "ShippingMethod";
|
__typename: "ShippingMethod";
|
||||||
id: string;
|
id: string;
|
||||||
|
zipCodeRules: (DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMethods_zipCodeRules | null)[] | null;
|
||||||
minimumOrderWeight: DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMethods_minimumOrderWeight | null;
|
minimumOrderWeight: DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMethods_minimumOrderWeight | null;
|
||||||
maximumOrderWeight: DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMethods_maximumOrderWeight | null;
|
maximumOrderWeight: DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMethods_maximumOrderWeight | null;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
@ -8,6 +8,13 @@ import { ShippingMethodChannelListingInput, WeightUnitsEnum, ShippingMethodTypeE
|
||||||
// GraphQL mutation operation: ShippingMethodChannelListingUpdate
|
// GraphQL mutation operation: ShippingMethodChannelListingUpdate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
|
export interface ShippingMethodChannelListingUpdate_shippingMethodChannelListingUpdate_shippingMethod_zipCodeRules {
|
||||||
|
__typename: "ShippingMethodZipCodeRule";
|
||||||
|
id: string;
|
||||||
|
start: string | null;
|
||||||
|
end: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ShippingMethodChannelListingUpdate_shippingMethodChannelListingUpdate_shippingMethod_minimumOrderWeight {
|
export interface ShippingMethodChannelListingUpdate_shippingMethodChannelListingUpdate_shippingMethod_minimumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: WeightUnitsEnum;
|
unit: WeightUnitsEnum;
|
||||||
|
@ -57,6 +64,7 @@ export interface ShippingMethodChannelListingUpdate_shippingMethodChannelListing
|
||||||
export interface ShippingMethodChannelListingUpdate_shippingMethodChannelListingUpdate_shippingMethod {
|
export interface ShippingMethodChannelListingUpdate_shippingMethodChannelListingUpdate_shippingMethod {
|
||||||
__typename: "ShippingMethod";
|
__typename: "ShippingMethod";
|
||||||
id: string;
|
id: string;
|
||||||
|
zipCodeRules: (ShippingMethodChannelListingUpdate_shippingMethodChannelListingUpdate_shippingMethod_zipCodeRules | null)[] | null;
|
||||||
minimumOrderWeight: ShippingMethodChannelListingUpdate_shippingMethodChannelListingUpdate_shippingMethod_minimumOrderWeight | null;
|
minimumOrderWeight: ShippingMethodChannelListingUpdate_shippingMethodChannelListingUpdate_shippingMethod_minimumOrderWeight | null;
|
||||||
maximumOrderWeight: ShippingMethodChannelListingUpdate_shippingMethodChannelListingUpdate_shippingMethod_maximumOrderWeight | null;
|
maximumOrderWeight: ShippingMethodChannelListingUpdate_shippingMethodChannelListingUpdate_shippingMethod_maximumOrderWeight | null;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
44
src/shipping/types/ShippingMethodZipCodeRangeAssign.ts
Normal file
44
src/shipping/types/ShippingMethodZipCodeRangeAssign.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { ShippingZipCodeRulesCreateInput, ShippingErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL mutation operation: ShippingMethodZipCodeRangeAssign
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface ShippingMethodZipCodeRangeAssign_shippingMethodZipCodeRulesCreate_errors {
|
||||||
|
__typename: "ShippingError";
|
||||||
|
code: ShippingErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
channels: string[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShippingMethodZipCodeRangeAssign_shippingMethodZipCodeRulesCreate_shippingMethod_zipCodeRules {
|
||||||
|
__typename: "ShippingMethodZipCodeRule";
|
||||||
|
id: string;
|
||||||
|
start: string | null;
|
||||||
|
end: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShippingMethodZipCodeRangeAssign_shippingMethodZipCodeRulesCreate_shippingMethod {
|
||||||
|
__typename: "ShippingMethod";
|
||||||
|
id: string;
|
||||||
|
zipCodeRules: (ShippingMethodZipCodeRangeAssign_shippingMethodZipCodeRulesCreate_shippingMethod_zipCodeRules | null)[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShippingMethodZipCodeRangeAssign_shippingMethodZipCodeRulesCreate {
|
||||||
|
__typename: "ShippingZipCodeRulesCreate";
|
||||||
|
errors: ShippingMethodZipCodeRangeAssign_shippingMethodZipCodeRulesCreate_errors[];
|
||||||
|
shippingMethod: ShippingMethodZipCodeRangeAssign_shippingMethodZipCodeRulesCreate_shippingMethod | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShippingMethodZipCodeRangeAssign {
|
||||||
|
shippingMethodZipCodeRulesCreate: ShippingMethodZipCodeRangeAssign_shippingMethodZipCodeRulesCreate | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShippingMethodZipCodeRangeAssignVariables {
|
||||||
|
id: string;
|
||||||
|
input: ShippingZipCodeRulesCreateInput;
|
||||||
|
}
|
43
src/shipping/types/ShippingMethodZipCodeRangeUnassign.ts
Normal file
43
src/shipping/types/ShippingMethodZipCodeRangeUnassign.ts
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { ShippingErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL mutation operation: ShippingMethodZipCodeRangeUnassign
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface ShippingMethodZipCodeRangeUnassign_shippingMethodZipCodeRulesDelete_errors {
|
||||||
|
__typename: "ShippingError";
|
||||||
|
code: ShippingErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
channels: string[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShippingMethodZipCodeRangeUnassign_shippingMethodZipCodeRulesDelete_shippingMethod_zipCodeRules {
|
||||||
|
__typename: "ShippingMethodZipCodeRule";
|
||||||
|
id: string;
|
||||||
|
start: string | null;
|
||||||
|
end: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShippingMethodZipCodeRangeUnassign_shippingMethodZipCodeRulesDelete_shippingMethod {
|
||||||
|
__typename: "ShippingMethod";
|
||||||
|
id: string;
|
||||||
|
zipCodeRules: (ShippingMethodZipCodeRangeUnassign_shippingMethodZipCodeRulesDelete_shippingMethod_zipCodeRules | null)[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShippingMethodZipCodeRangeUnassign_shippingMethodZipCodeRulesDelete {
|
||||||
|
__typename: "ShippingZipCodeRulesDelete";
|
||||||
|
errors: ShippingMethodZipCodeRangeUnassign_shippingMethodZipCodeRulesDelete_errors[];
|
||||||
|
shippingMethod: ShippingMethodZipCodeRangeUnassign_shippingMethodZipCodeRulesDelete_shippingMethod | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShippingMethodZipCodeRangeUnassign {
|
||||||
|
shippingMethodZipCodeRulesDelete: ShippingMethodZipCodeRangeUnassign_shippingMethodZipCodeRulesDelete | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShippingMethodZipCodeRangeUnassignVariables {
|
||||||
|
id: string;
|
||||||
|
}
|
|
@ -14,6 +14,13 @@ export interface ShippingZone_shippingZone_countries {
|
||||||
country: string;
|
country: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ShippingZone_shippingZone_shippingMethods_zipCodeRules {
|
||||||
|
__typename: "ShippingMethodZipCodeRule";
|
||||||
|
id: string;
|
||||||
|
start: string | null;
|
||||||
|
end: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ShippingZone_shippingZone_shippingMethods_minimumOrderWeight {
|
export interface ShippingZone_shippingZone_shippingMethods_minimumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: WeightUnitsEnum;
|
unit: WeightUnitsEnum;
|
||||||
|
@ -63,6 +70,7 @@ export interface ShippingZone_shippingZone_shippingMethods_channelListings {
|
||||||
export interface ShippingZone_shippingZone_shippingMethods {
|
export interface ShippingZone_shippingZone_shippingMethods {
|
||||||
__typename: "ShippingMethod";
|
__typename: "ShippingMethod";
|
||||||
id: string;
|
id: string;
|
||||||
|
zipCodeRules: (ShippingZone_shippingZone_shippingMethods_zipCodeRules | null)[] | null;
|
||||||
minimumOrderWeight: ShippingZone_shippingZone_shippingMethods_minimumOrderWeight | null;
|
minimumOrderWeight: ShippingZone_shippingZone_shippingMethods_minimumOrderWeight | null;
|
||||||
maximumOrderWeight: ShippingZone_shippingZone_shippingMethods_maximumOrderWeight | null;
|
maximumOrderWeight: ShippingZone_shippingZone_shippingMethods_maximumOrderWeight | null;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
@ -14,6 +14,13 @@ export interface UpdateShippingRate_shippingPriceUpdate_errors {
|
||||||
field: string | null;
|
field: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UpdateShippingRate_shippingPriceUpdate_shippingMethod_zipCodeRules {
|
||||||
|
__typename: "ShippingMethodZipCodeRule";
|
||||||
|
id: string;
|
||||||
|
start: string | null;
|
||||||
|
end: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface UpdateShippingRate_shippingPriceUpdate_shippingMethod_minimumOrderWeight {
|
export interface UpdateShippingRate_shippingPriceUpdate_shippingMethod_minimumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: WeightUnitsEnum;
|
unit: WeightUnitsEnum;
|
||||||
|
@ -63,6 +70,7 @@ export interface UpdateShippingRate_shippingPriceUpdate_shippingMethod_channelLi
|
||||||
export interface UpdateShippingRate_shippingPriceUpdate_shippingMethod {
|
export interface UpdateShippingRate_shippingPriceUpdate_shippingMethod {
|
||||||
__typename: "ShippingMethod";
|
__typename: "ShippingMethod";
|
||||||
id: string;
|
id: string;
|
||||||
|
zipCodeRules: (UpdateShippingRate_shippingPriceUpdate_shippingMethod_zipCodeRules | null)[] | null;
|
||||||
minimumOrderWeight: UpdateShippingRate_shippingPriceUpdate_shippingMethod_minimumOrderWeight | null;
|
minimumOrderWeight: UpdateShippingRate_shippingPriceUpdate_shippingMethod_minimumOrderWeight | null;
|
||||||
maximumOrderWeight: UpdateShippingRate_shippingPriceUpdate_shippingMethod_maximumOrderWeight | null;
|
maximumOrderWeight: UpdateShippingRate_shippingPriceUpdate_shippingMethod_maximumOrderWeight | null;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
@ -36,22 +36,58 @@ export const shippingZoneUrl = (
|
||||||
params?: ShippingZoneUrlQueryParams
|
params?: ShippingZoneUrlQueryParams
|
||||||
) => shippingZonePath(encodeURIComponent(id)) + "?" + stringifyQs(params);
|
) => shippingZonePath(encodeURIComponent(id)) + "?" + stringifyQs(params);
|
||||||
|
|
||||||
export const shippingPriceRatesUrl = (id: string) =>
|
type ZipCodeRangeActions = "add-range" | "remove-range";
|
||||||
|
export type ShippingRateUrlDialog = ZipCodeRangeActions | "remove";
|
||||||
|
export type ShippingRateUrlQueryParams = Dialog<ShippingRateUrlDialog> &
|
||||||
|
SingleAction;
|
||||||
|
export type ShippingRateCreateUrlDialog = ZipCodeRangeActions;
|
||||||
|
export type ShippingRateCreateUrlQueryParams = Dialog<
|
||||||
|
ShippingRateCreateUrlDialog
|
||||||
|
> &
|
||||||
|
SingleAction;
|
||||||
|
|
||||||
|
export const shippingPriceRatesPath = (id: string) =>
|
||||||
urlJoin(shippingZonePath(id), "price", "add");
|
urlJoin(shippingZonePath(id), "price", "add");
|
||||||
|
export const shippingPriceRatesUrl = (
|
||||||
|
id: string,
|
||||||
|
params?: ShippingRateCreateUrlQueryParams
|
||||||
|
) => shippingPriceRatesPath(encodeURIComponent(id)) + "?" + stringifyQs(params);
|
||||||
|
|
||||||
export const shippingWeightRatesUrl = (id: string) =>
|
export const shippingWeightRatesPath = (id: string) =>
|
||||||
urlJoin(shippingZonePath(id), "weight", "add");
|
urlJoin(shippingZonePath(id), "weight", "add");
|
||||||
|
export const shippingWeightRatesUrl = (
|
||||||
|
id: string,
|
||||||
|
params?: ShippingRateCreateUrlQueryParams
|
||||||
|
) =>
|
||||||
|
shippingWeightRatesPath(encodeURIComponent(id)) + "?" + stringifyQs(params);
|
||||||
|
|
||||||
export const shippingWeightRatesEditUrl = (id: string, rateId: string) =>
|
export const shippingPriceRatesEditPath = (id: string, rateId: string) =>
|
||||||
urlJoin(shippingZonePath(id), "weight", rateId);
|
|
||||||
|
|
||||||
export const shippingPriceRatesEditUrl = (id: string, rateId: string) =>
|
|
||||||
urlJoin(shippingZonePath(id), "price", rateId);
|
urlJoin(shippingZonePath(id), "price", rateId);
|
||||||
|
export const shippingPriceRatesEditUrl = (
|
||||||
|
id: string,
|
||||||
|
rateId: string,
|
||||||
|
params?: ShippingRateUrlQueryParams
|
||||||
|
) =>
|
||||||
|
shippingPriceRatesEditPath(
|
||||||
|
encodeURIComponent(id),
|
||||||
|
encodeURIComponent(rateId)
|
||||||
|
) +
|
||||||
|
"?" +
|
||||||
|
stringifyQs(params);
|
||||||
|
|
||||||
|
export const shippingWeightRatesEditPath = (id: string, rateId: string) =>
|
||||||
|
urlJoin(shippingZonePath(id), "weight", rateId);
|
||||||
|
export const shippingWeightRatesEditUrl = (
|
||||||
|
id: string,
|
||||||
|
rateId: string,
|
||||||
|
params?: ShippingRateUrlQueryParams
|
||||||
|
) =>
|
||||||
|
shippingWeightRatesEditPath(
|
||||||
|
encodeURIComponent(id),
|
||||||
|
encodeURIComponent(rateId)
|
||||||
|
) +
|
||||||
|
"?" +
|
||||||
|
stringifyQs(params);
|
||||||
|
|
||||||
export const shippingZoneAddPath = urlJoin(shippingZonesListPath, "add");
|
export const shippingZoneAddPath = urlJoin(shippingZonesListPath, "add");
|
||||||
export const shippingZoneAddUrl = shippingZoneAddPath;
|
export const shippingZoneAddUrl = shippingZoneAddPath + "?";
|
||||||
export const shippingPriceRatesAddPath = urlJoin(
|
|
||||||
shippingZonesListPath,
|
|
||||||
"price",
|
|
||||||
"add"
|
|
||||||
);
|
|
||||||
|
|
|
@ -2,57 +2,49 @@ import { useChannelsList } from "@saleor/channels/queries";
|
||||||
import { createSortedShippingChannels } from "@saleor/channels/utils";
|
import { createSortedShippingChannels } from "@saleor/channels/utils";
|
||||||
import ChannelsAvailabilityDialog from "@saleor/components/ChannelsAvailabilityDialog";
|
import ChannelsAvailabilityDialog from "@saleor/components/ChannelsAvailabilityDialog";
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
|
import { ShippingMethodFragment_zipCodeRules } from "@saleor/fragments/types/ShippingMethodFragment";
|
||||||
import useChannels from "@saleor/hooks/useChannels";
|
import useChannels from "@saleor/hooks/useChannels";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
import useNotifier from "@saleor/hooks/useNotifier";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { commonMessages, sectionNames } from "@saleor/intl";
|
import ShippingRateZipCodeRangeRemoveDialog from "@saleor/shipping/components/ShippingRateZipCodeRangeRemoveDialog";
|
||||||
import { FormData } from "@saleor/shipping/components/ShippingZoneRatesPage";
|
|
||||||
import ShippingZoneRatesPage from "@saleor/shipping/components/ShippingZoneRatesPage";
|
import ShippingZoneRatesPage from "@saleor/shipping/components/ShippingZoneRatesPage";
|
||||||
|
import ShippingZoneZipCodeRangeDialog from "@saleor/shipping/components/ShippingZoneZipCodeRangeDialog";
|
||||||
|
import { useShippingRateCreator } from "@saleor/shipping/handlers";
|
||||||
import {
|
import {
|
||||||
getCreateShippingPriceRateVariables,
|
shippingPriceRatesUrl,
|
||||||
getShippingMethodChannelVariables
|
ShippingRateCreateUrlDialog,
|
||||||
} from "@saleor/shipping/handlers";
|
ShippingRateCreateUrlQueryParams,
|
||||||
import { useShippingMethodChannelListingUpdate } from "@saleor/shipping/mutations";
|
|
||||||
import { useShippingRateCreate } from "@saleor/shipping/mutations";
|
|
||||||
import {
|
|
||||||
shippingPriceRatesEditUrl,
|
|
||||||
shippingZoneUrl
|
shippingZoneUrl
|
||||||
} from "@saleor/shipping/urls";
|
} from "@saleor/shipping/urls";
|
||||||
|
import { MinMax } from "@saleor/types";
|
||||||
import { ShippingMethodTypeEnum } from "@saleor/types/globalTypes";
|
import { ShippingMethodTypeEnum } from "@saleor/types/globalTypes";
|
||||||
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
|
import { remove } from "@saleor/utils/lists";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
export interface PriceRatesCreateProps {
|
export interface PriceRatesCreateProps {
|
||||||
id: string;
|
id: string;
|
||||||
|
params: ShippingRateCreateUrlQueryParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PriceRatesCreate: React.FC<PriceRatesCreateProps> = ({ id }) => {
|
export const PriceRatesCreate: React.FC<PriceRatesCreateProps> = ({
|
||||||
|
id,
|
||||||
|
params
|
||||||
|
}) => {
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
const notify = useNotifier();
|
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const [zipCodes, setZipCodes] = React.useState<
|
||||||
|
ShippingMethodFragment_zipCodeRules[]
|
||||||
|
>([]);
|
||||||
|
|
||||||
const { data: channelsData, loading: channelsLoading } = useChannelsList({});
|
const { data: channelsData, loading: channelsLoading } = useChannelsList({});
|
||||||
|
|
||||||
const [
|
const [openModal, closeModal] = createDialogActionHandlers<
|
||||||
updateShippingMethodChannelListing,
|
ShippingRateCreateUrlDialog,
|
||||||
updateShippingMethodChannelListingOpts
|
ShippingRateCreateUrlQueryParams
|
||||||
] = useShippingMethodChannelListingUpdate({
|
>(navigate, params => shippingPriceRatesUrl(id, params), params);
|
||||||
onCompleted: data => {
|
|
||||||
const errors = data.shippingMethodChannelListingUpdate.errors;
|
|
||||||
if (errors.length === 0) {
|
|
||||||
notify({
|
|
||||||
status: "success",
|
|
||||||
text: intl.formatMessage(commonMessages.savedChanges)
|
|
||||||
});
|
|
||||||
navigate(
|
|
||||||
shippingPriceRatesEditUrl(
|
|
||||||
id,
|
|
||||||
data.shippingMethodChannelListingUpdate.shippingMethod.id
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const allChannels = createSortedShippingChannels(channelsData?.channels);
|
const allChannels = createSortedShippingChannels(channelsData?.channels);
|
||||||
|
|
||||||
|
@ -69,27 +61,38 @@ export const PriceRatesCreate: React.FC<PriceRatesCreateProps> = ({ id }) => {
|
||||||
toggleAllChannels
|
toggleAllChannels
|
||||||
} = useChannels(allChannels);
|
} = useChannels(allChannels);
|
||||||
|
|
||||||
const [createShippingRate, createShippingRateOpts] = useShippingRateCreate(
|
const {
|
||||||
{}
|
channelErrors,
|
||||||
);
|
createShippingRate,
|
||||||
|
errors,
|
||||||
|
status
|
||||||
|
} = useShippingRateCreator(id, ShippingMethodTypeEnum.PRICE, zipCodes);
|
||||||
|
|
||||||
const handleSubmit = async (data: FormData) => {
|
|
||||||
const response = await createShippingRate({
|
|
||||||
variables: getCreateShippingPriceRateVariables(data, id)
|
|
||||||
});
|
|
||||||
const errors = response.data.shippingPriceCreate.errors;
|
|
||||||
if (errors.length === 0) {
|
|
||||||
updateShippingMethodChannelListing({
|
|
||||||
variables: getShippingMethodChannelVariables(
|
|
||||||
response.data.shippingPriceCreate.shippingMethod.id,
|
|
||||||
data.noLimits,
|
|
||||||
data.channelListings
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const handleBack = () => navigate(shippingZoneUrl(id));
|
const handleBack = () => navigate(shippingZoneUrl(id));
|
||||||
|
|
||||||
|
const handleZipCodeRangeAdd = (data: MinMax) => {
|
||||||
|
setZipCodes(zipCodes => [
|
||||||
|
...zipCodes,
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: data.max,
|
||||||
|
id: zipCodes.length.toString(),
|
||||||
|
start: data.min
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
closeModal();
|
||||||
|
};
|
||||||
|
const handleZipCodeRangeDelete = (id: string) => {
|
||||||
|
setZipCodes(zipCodes =>
|
||||||
|
remove(
|
||||||
|
zipCodes.find(zipCode => zipCode.id === id),
|
||||||
|
zipCodes,
|
||||||
|
(a, b) => a.id === b.id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
closeModal();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<WindowTitle title={intl.formatMessage(sectionNames.shipping)} />
|
<WindowTitle title={intl.formatMessage(sectionNames.shipping)} />
|
||||||
|
@ -114,23 +117,36 @@ export const PriceRatesCreate: React.FC<PriceRatesCreateProps> = ({ id }) => {
|
||||||
<ShippingZoneRatesPage
|
<ShippingZoneRatesPage
|
||||||
allChannelsCount={allChannels?.length}
|
allChannelsCount={allChannels?.length}
|
||||||
shippingChannels={currentChannels}
|
shippingChannels={currentChannels}
|
||||||
disabled={
|
disabled={channelsLoading || status === "loading"}
|
||||||
channelsLoading ||
|
saveButtonBarState={status}
|
||||||
createShippingRateOpts?.status === "loading" ||
|
onSubmit={createShippingRate}
|
||||||
updateShippingMethodChannelListingOpts?.status === "loading"
|
|
||||||
}
|
|
||||||
saveButtonBarState={createShippingRateOpts?.status}
|
|
||||||
onSubmit={handleSubmit}
|
|
||||||
onBack={handleBack}
|
onBack={handleBack}
|
||||||
errors={createShippingRateOpts.data?.shippingPriceCreate.errors || []}
|
errors={errors}
|
||||||
channelErrors={
|
channelErrors={channelErrors}
|
||||||
updateShippingMethodChannelListingOpts?.data
|
rate={null}
|
||||||
?.shippingMethodChannelListingUpdate?.errors || []
|
zipCodes={zipCodes}
|
||||||
}
|
|
||||||
openChannelsModal={handleChannelsModalOpen}
|
openChannelsModal={handleChannelsModalOpen}
|
||||||
onChannelsChange={setCurrentChannels}
|
onChannelsChange={setCurrentChannels}
|
||||||
|
onZipCodeAssign={() => openModal("add-range")}
|
||||||
|
onZipCodeUnassign={id =>
|
||||||
|
openModal("remove-range", {
|
||||||
|
id
|
||||||
|
})
|
||||||
|
}
|
||||||
variant={ShippingMethodTypeEnum.PRICE}
|
variant={ShippingMethodTypeEnum.PRICE}
|
||||||
/>
|
/>
|
||||||
|
<ShippingZoneZipCodeRangeDialog
|
||||||
|
confirmButtonState="default"
|
||||||
|
onClose={closeModal}
|
||||||
|
onSubmit={handleZipCodeRangeAdd}
|
||||||
|
open={params.action === "add-range"}
|
||||||
|
/>
|
||||||
|
<ShippingRateZipCodeRangeRemoveDialog
|
||||||
|
confirmButtonState="default"
|
||||||
|
onClose={closeModal}
|
||||||
|
onConfirm={() => handleZipCodeRangeDelete(params.id)}
|
||||||
|
open={params.action === "remove-range"}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,32 +11,46 @@ import useNotifier from "@saleor/hooks/useNotifier";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import DeleteShippingRateDialog from "@saleor/shipping/components/DeleteShippingRateDialog";
|
import DeleteShippingRateDialog from "@saleor/shipping/components/DeleteShippingRateDialog";
|
||||||
|
import ShippingRateZipCodeRangeRemoveDialog from "@saleor/shipping/components/ShippingRateZipCodeRangeRemoveDialog";
|
||||||
import ShippingZoneRatesPage, {
|
import ShippingZoneRatesPage, {
|
||||||
FormData
|
FormData
|
||||||
} from "@saleor/shipping/components/ShippingZoneRatesPage";
|
} from "@saleor/shipping/components/ShippingZoneRatesPage";
|
||||||
|
import ShippingZoneZipCodeRangeDialog from "@saleor/shipping/components/ShippingZoneZipCodeRangeDialog";
|
||||||
import {
|
import {
|
||||||
getShippingMethodChannelVariables,
|
getShippingMethodChannelVariables,
|
||||||
getUpdateShippingPriceRateVariables
|
getUpdateShippingPriceRateVariables
|
||||||
} from "@saleor/shipping/handlers";
|
} from "@saleor/shipping/handlers";
|
||||||
import { useShippingMethodChannelListingUpdate } from "@saleor/shipping/mutations";
|
import {
|
||||||
|
useShippingMethodChannelListingUpdate,
|
||||||
|
useShippingMethodZipCodeRangeAssign,
|
||||||
|
useShippingMethodZipCodeRangeUnassign
|
||||||
|
} from "@saleor/shipping/mutations";
|
||||||
import {
|
import {
|
||||||
useShippingRateDelete,
|
useShippingRateDelete,
|
||||||
useShippingRateUpdate
|
useShippingRateUpdate
|
||||||
} from "@saleor/shipping/mutations";
|
} from "@saleor/shipping/mutations";
|
||||||
import { useShippingZone } from "@saleor/shipping/queries";
|
import { useShippingZone } from "@saleor/shipping/queries";
|
||||||
import { shippingZoneUrl } from "@saleor/shipping/urls";
|
import {
|
||||||
|
shippingPriceRatesEditUrl,
|
||||||
|
ShippingRateUrlDialog,
|
||||||
|
ShippingRateUrlQueryParams,
|
||||||
|
shippingZoneUrl
|
||||||
|
} from "@saleor/shipping/urls";
|
||||||
import { ShippingMethodTypeEnum } from "@saleor/types/globalTypes";
|
import { ShippingMethodTypeEnum } from "@saleor/types/globalTypes";
|
||||||
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
export interface PriceRatesUpdateProps {
|
export interface PriceRatesUpdateProps {
|
||||||
id: string;
|
id: string;
|
||||||
rateId: string;
|
rateId: string;
|
||||||
|
params: ShippingRateUrlQueryParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
|
export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
|
||||||
id,
|
id,
|
||||||
rateId
|
rateId,
|
||||||
|
params
|
||||||
}) => {
|
}) => {
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
const notify = useNotifier();
|
const notify = useNotifier();
|
||||||
|
@ -47,6 +61,11 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
|
||||||
variables: { id }
|
variables: { id }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [openModal, closeModal] = createDialogActionHandlers<
|
||||||
|
ShippingRateUrlDialog,
|
||||||
|
ShippingRateUrlQueryParams
|
||||||
|
>(navigate, params => shippingPriceRatesEditUrl(id, rateId, params), params);
|
||||||
|
|
||||||
const rate = data?.shippingZone?.shippingMethods.find(
|
const rate = data?.shippingZone?.shippingMethods.find(
|
||||||
rate => rate.id === rateId
|
rate => rate.id === rateId
|
||||||
);
|
);
|
||||||
|
@ -57,6 +76,43 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
|
||||||
updateShippingMethodChannelListingOpts
|
updateShippingMethodChannelListingOpts
|
||||||
] = useShippingMethodChannelListingUpdate({});
|
] = useShippingMethodChannelListingUpdate({});
|
||||||
|
|
||||||
|
const [
|
||||||
|
assignZipCodeRange,
|
||||||
|
assignZipCodeRangeOpts
|
||||||
|
] = useShippingMethodZipCodeRangeAssign({
|
||||||
|
onCompleted: data => {
|
||||||
|
if (data.shippingMethodZipCodeRulesCreate.errors.length === 0) {
|
||||||
|
notify({
|
||||||
|
status: "success",
|
||||||
|
text: intl.formatMessage(commonMessages.savedChanges)
|
||||||
|
});
|
||||||
|
closeModal();
|
||||||
|
} else {
|
||||||
|
notify({
|
||||||
|
status: "error",
|
||||||
|
text: intl.formatMessage({
|
||||||
|
defaultMessage: "Cannot add specified zip codes range.",
|
||||||
|
description: "zip code range add error text"
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const [
|
||||||
|
unassignZipCodeRange,
|
||||||
|
unassignZipCodeRangeOpts
|
||||||
|
] = useShippingMethodZipCodeRangeUnassign({
|
||||||
|
onCompleted: data => {
|
||||||
|
if (data.shippingMethodZipCodeRulesDelete.errors.length === 0) {
|
||||||
|
notify({
|
||||||
|
status: "success",
|
||||||
|
text: intl.formatMessage(commonMessages.savedChanges)
|
||||||
|
});
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const shippingChannels = createShippingChannelsFromRate(
|
const shippingChannels = createShippingChannelsFromRate(
|
||||||
rate?.channelListings
|
rate?.channelListings
|
||||||
);
|
);
|
||||||
|
@ -75,8 +131,6 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
|
||||||
toggleAllChannels
|
toggleAllChannels
|
||||||
} = useChannels(shippingChannels);
|
} = useChannels(shippingChannels);
|
||||||
|
|
||||||
const [openModal, setOpenModal] = React.useState(false);
|
|
||||||
|
|
||||||
const [updateShippingRate, updateShippingRateOpts] = useShippingRateUpdate(
|
const [updateShippingRate, updateShippingRateOpts] = useShippingRateUpdate(
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
@ -96,7 +150,6 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleDelete = () => setOpenModal(true);
|
|
||||||
const handleSubmit = async (formData: FormData) => {
|
const handleSubmit = async (formData: FormData) => {
|
||||||
const response = await updateShippingRate({
|
const response = await updateShippingRate({
|
||||||
variables: getUpdateShippingPriceRateVariables(formData, id, rateId)
|
variables: getUpdateShippingPriceRateVariables(formData, id, rateId)
|
||||||
|
@ -139,7 +192,7 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
|
||||||
)}
|
)}
|
||||||
<DeleteShippingRateDialog
|
<DeleteShippingRateDialog
|
||||||
confirmButtonState={deleteShippingRateOpts.status}
|
confirmButtonState={deleteShippingRateOpts.status}
|
||||||
onClose={() => setOpenModal(false)}
|
onClose={closeModal}
|
||||||
handleConfirm={() =>
|
handleConfirm={() =>
|
||||||
deleteShippingRate({
|
deleteShippingRate({
|
||||||
variables: {
|
variables: {
|
||||||
|
@ -147,7 +200,7 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
open={openModal}
|
open={params.action === "remove"}
|
||||||
name={rate?.name}
|
name={rate?.name}
|
||||||
/>
|
/>
|
||||||
<ShippingZoneRatesPage
|
<ShippingZoneRatesPage
|
||||||
|
@ -160,7 +213,7 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
|
||||||
}
|
}
|
||||||
hasChannelChanged={shippingChannels?.length !== currentChannels?.length}
|
hasChannelChanged={shippingChannels?.length !== currentChannels?.length}
|
||||||
saveButtonBarState={updateShippingRateOpts.status}
|
saveButtonBarState={updateShippingRateOpts.status}
|
||||||
onDelete={handleDelete}
|
onDelete={() => openModal("remove")}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
onBack={handleBack}
|
onBack={handleBack}
|
||||||
rate={rate}
|
rate={rate}
|
||||||
|
@ -172,6 +225,44 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
|
||||||
openChannelsModal={handleChannelsModalOpen}
|
openChannelsModal={handleChannelsModalOpen}
|
||||||
onChannelsChange={setCurrentChannels}
|
onChannelsChange={setCurrentChannels}
|
||||||
variant={ShippingMethodTypeEnum.PRICE}
|
variant={ShippingMethodTypeEnum.PRICE}
|
||||||
|
onZipCodeAssign={() => openModal("add-range")}
|
||||||
|
onZipCodeUnassign={id =>
|
||||||
|
openModal("remove-range", {
|
||||||
|
id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<ShippingZoneZipCodeRangeDialog
|
||||||
|
confirmButtonState={assignZipCodeRangeOpts.status}
|
||||||
|
onClose={closeModal}
|
||||||
|
onSubmit={data =>
|
||||||
|
assignZipCodeRange({
|
||||||
|
variables: {
|
||||||
|
id: rateId,
|
||||||
|
input: {
|
||||||
|
zipCodeRules: [
|
||||||
|
{
|
||||||
|
end: data.max || null,
|
||||||
|
start: data.min
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
open={params.action === "add-range"}
|
||||||
|
/>
|
||||||
|
<ShippingRateZipCodeRangeRemoveDialog
|
||||||
|
confirmButtonState={unassignZipCodeRangeOpts.status}
|
||||||
|
onClose={closeModal}
|
||||||
|
onConfirm={() =>
|
||||||
|
unassignZipCodeRange({
|
||||||
|
variables: {
|
||||||
|
id: params.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
open={params.action === "remove-range"}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,57 +5,49 @@ import {
|
||||||
} from "@saleor/channels/utils";
|
} from "@saleor/channels/utils";
|
||||||
import ChannelsAvailabilityDialog from "@saleor/components/ChannelsAvailabilityDialog";
|
import ChannelsAvailabilityDialog from "@saleor/components/ChannelsAvailabilityDialog";
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
|
import { ShippingMethodFragment_zipCodeRules } from "@saleor/fragments/types/ShippingMethodFragment";
|
||||||
import useChannels from "@saleor/hooks/useChannels";
|
import useChannels from "@saleor/hooks/useChannels";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
import useNotifier from "@saleor/hooks/useNotifier";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { commonMessages, sectionNames } from "@saleor/intl";
|
import ShippingRateZipCodeRangeRemoveDialog from "@saleor/shipping/components/ShippingRateZipCodeRangeRemoveDialog";
|
||||||
import { FormData } from "@saleor/shipping/components/ShippingZoneRatesPage";
|
|
||||||
import ShippingZoneRatesPage from "@saleor/shipping/components/ShippingZoneRatesPage";
|
import ShippingZoneRatesPage from "@saleor/shipping/components/ShippingZoneRatesPage";
|
||||||
|
import ShippingZoneZipCodeRangeDialog from "@saleor/shipping/components/ShippingZoneZipCodeRangeDialog";
|
||||||
|
import { useShippingRateCreator } from "@saleor/shipping/handlers";
|
||||||
import {
|
import {
|
||||||
getCreateShippingWeightRateVariables,
|
ShippingRateCreateUrlDialog,
|
||||||
getShippingMethodChannelVariables
|
ShippingRateCreateUrlQueryParams,
|
||||||
} from "@saleor/shipping/handlers";
|
shippingWeightRatesUrl,
|
||||||
import { useShippingMethodChannelListingUpdate } from "@saleor/shipping/mutations";
|
|
||||||
import { useShippingRateCreate } from "@saleor/shipping/mutations";
|
|
||||||
import {
|
|
||||||
shippingWeightRatesEditUrl,
|
|
||||||
shippingZoneUrl
|
shippingZoneUrl
|
||||||
} from "@saleor/shipping/urls";
|
} from "@saleor/shipping/urls";
|
||||||
|
import { MinMax } from "@saleor/types";
|
||||||
import { ShippingMethodTypeEnum } from "@saleor/types/globalTypes";
|
import { ShippingMethodTypeEnum } from "@saleor/types/globalTypes";
|
||||||
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
|
import { remove } from "@saleor/utils/lists";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
export interface WeightRatesCreateProps {
|
export interface WeightRatesCreateProps {
|
||||||
id: string;
|
id: string;
|
||||||
|
params: ShippingRateCreateUrlQueryParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WeightRatesCreate: React.FC<WeightRatesCreateProps> = ({ id }) => {
|
export const WeightRatesCreate: React.FC<WeightRatesCreateProps> = ({
|
||||||
|
id,
|
||||||
|
params
|
||||||
|
}) => {
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
const notify = useNotifier();
|
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const [zipCodes, setZipCodes] = React.useState<
|
||||||
|
ShippingMethodFragment_zipCodeRules[]
|
||||||
|
>([]);
|
||||||
|
|
||||||
const { data: channelsData, loading: channelsLoading } = useChannelsList({});
|
const { data: channelsData, loading: channelsLoading } = useChannelsList({});
|
||||||
|
|
||||||
const [
|
const [openModal, closeModal] = createDialogActionHandlers<
|
||||||
updateShippingMethodChannelListing,
|
ShippingRateCreateUrlDialog,
|
||||||
updateShippingMethodChannelListingOpts
|
ShippingRateCreateUrlQueryParams
|
||||||
] = useShippingMethodChannelListingUpdate({
|
>(navigate, params => shippingWeightRatesUrl(id, params), params);
|
||||||
onCompleted: data => {
|
|
||||||
const errors = data.shippingMethodChannelListingUpdate.errors;
|
|
||||||
if (errors.length === 0) {
|
|
||||||
notify({
|
|
||||||
status: "success",
|
|
||||||
text: intl.formatMessage(commonMessages.savedChanges)
|
|
||||||
});
|
|
||||||
navigate(
|
|
||||||
shippingWeightRatesEditUrl(
|
|
||||||
id,
|
|
||||||
data.shippingMethodChannelListingUpdate.shippingMethod.id
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const shippingChannels = createShippingChannels(channelsData?.channels);
|
const shippingChannels = createShippingChannels(channelsData?.channels);
|
||||||
const allChannels = createSortedShippingChannels(channelsData?.channels);
|
const allChannels = createSortedShippingChannels(channelsData?.channels);
|
||||||
|
@ -73,28 +65,38 @@ export const WeightRatesCreate: React.FC<WeightRatesCreateProps> = ({ id }) => {
|
||||||
toggleAllChannels
|
toggleAllChannels
|
||||||
} = useChannels(shippingChannels);
|
} = useChannels(shippingChannels);
|
||||||
|
|
||||||
const [createShippingRate, createShippingRateOpts] = useShippingRateCreate(
|
const {
|
||||||
{}
|
channelErrors,
|
||||||
);
|
createShippingRate,
|
||||||
|
errors,
|
||||||
const handleSubmit = async (data: FormData) => {
|
status
|
||||||
const response = await createShippingRate({
|
} = useShippingRateCreator(id, ShippingMethodTypeEnum.WEIGHT, zipCodes);
|
||||||
variables: getCreateShippingWeightRateVariables(data, id)
|
|
||||||
});
|
|
||||||
const errors = response.data.shippingPriceCreate.errors;
|
|
||||||
if (errors.length === 0) {
|
|
||||||
updateShippingMethodChannelListing({
|
|
||||||
variables: getShippingMethodChannelVariables(
|
|
||||||
response.data.shippingPriceCreate.shippingMethod.id,
|
|
||||||
data.noLimits,
|
|
||||||
data.channelListings
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleBack = () => navigate(shippingZoneUrl(id));
|
const handleBack = () => navigate(shippingZoneUrl(id));
|
||||||
|
|
||||||
|
const handleZipCodeRangeAdd = (data: MinMax) => {
|
||||||
|
setZipCodes(zipCodes => [
|
||||||
|
...zipCodes,
|
||||||
|
{
|
||||||
|
__typename: "ShippingMethodZipCodeRule",
|
||||||
|
end: data.max,
|
||||||
|
id: zipCodes.length.toString(),
|
||||||
|
start: data.min
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
closeModal();
|
||||||
|
};
|
||||||
|
const handleZipCodeRangeDelete = (id: string) => {
|
||||||
|
setZipCodes(zipCodes =>
|
||||||
|
remove(
|
||||||
|
zipCodes.find(zipCode => zipCode.id === id),
|
||||||
|
zipCodes,
|
||||||
|
(a, b) => a.id === b.id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
closeModal();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<WindowTitle title={intl.formatMessage(sectionNames.shipping)} />
|
<WindowTitle title={intl.formatMessage(sectionNames.shipping)} />
|
||||||
|
@ -118,23 +120,36 @@ export const WeightRatesCreate: React.FC<WeightRatesCreateProps> = ({ id }) => {
|
||||||
<ShippingZoneRatesPage
|
<ShippingZoneRatesPage
|
||||||
allChannelsCount={allChannels?.length}
|
allChannelsCount={allChannels?.length}
|
||||||
shippingChannels={currentChannels}
|
shippingChannels={currentChannels}
|
||||||
disabled={
|
disabled={channelsLoading || status === "loading"}
|
||||||
channelsLoading ||
|
saveButtonBarState={status}
|
||||||
createShippingRateOpts?.status === "loading" ||
|
onSubmit={createShippingRate}
|
||||||
updateShippingMethodChannelListingOpts?.status === "loading"
|
|
||||||
}
|
|
||||||
saveButtonBarState={createShippingRateOpts?.status}
|
|
||||||
onSubmit={handleSubmit}
|
|
||||||
onBack={handleBack}
|
onBack={handleBack}
|
||||||
errors={createShippingRateOpts.data?.shippingPriceCreate.errors || []}
|
errors={errors}
|
||||||
channelErrors={
|
channelErrors={channelErrors}
|
||||||
updateShippingMethodChannelListingOpts?.data
|
rate={null}
|
||||||
?.shippingMethodChannelListingUpdate?.errors || []
|
zipCodes={zipCodes}
|
||||||
}
|
|
||||||
openChannelsModal={handleChannelsModalOpen}
|
openChannelsModal={handleChannelsModalOpen}
|
||||||
onChannelsChange={setCurrentChannels}
|
onChannelsChange={setCurrentChannels}
|
||||||
|
onZipCodeAssign={() => openModal("add-range")}
|
||||||
|
onZipCodeUnassign={id =>
|
||||||
|
openModal("remove-range", {
|
||||||
|
id
|
||||||
|
})
|
||||||
|
}
|
||||||
variant={ShippingMethodTypeEnum.WEIGHT}
|
variant={ShippingMethodTypeEnum.WEIGHT}
|
||||||
/>
|
/>
|
||||||
|
<ShippingZoneZipCodeRangeDialog
|
||||||
|
confirmButtonState="default"
|
||||||
|
onClose={closeModal}
|
||||||
|
onSubmit={handleZipCodeRangeAdd}
|
||||||
|
open={params.action === "add-range"}
|
||||||
|
/>
|
||||||
|
<ShippingRateZipCodeRangeRemoveDialog
|
||||||
|
confirmButtonState="default"
|
||||||
|
onClose={closeModal}
|
||||||
|
onConfirm={() => handleZipCodeRangeDelete(params.id)}
|
||||||
|
open={params.action === "remove-range"}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,32 +11,44 @@ import useNotifier from "@saleor/hooks/useNotifier";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import DeleteShippingRateDialog from "@saleor/shipping/components/DeleteShippingRateDialog";
|
import DeleteShippingRateDialog from "@saleor/shipping/components/DeleteShippingRateDialog";
|
||||||
|
import ShippingRateZipCodeRangeRemoveDialog from "@saleor/shipping/components/ShippingRateZipCodeRangeRemoveDialog";
|
||||||
import ShippingZoneRatesPage, {
|
import ShippingZoneRatesPage, {
|
||||||
FormData
|
FormData
|
||||||
} from "@saleor/shipping/components/ShippingZoneRatesPage";
|
} from "@saleor/shipping/components/ShippingZoneRatesPage";
|
||||||
|
import ShippingZoneZipCodeRangeDialog from "@saleor/shipping/components/ShippingZoneZipCodeRangeDialog";
|
||||||
import {
|
import {
|
||||||
getShippingMethodChannelVariables,
|
getShippingMethodChannelVariables,
|
||||||
getUpdateShippingWeightRateVariables
|
getUpdateShippingWeightRateVariables
|
||||||
} from "@saleor/shipping/handlers";
|
} from "@saleor/shipping/handlers";
|
||||||
import {
|
import {
|
||||||
|
useShippingMethodZipCodeRangeAssign,
|
||||||
|
useShippingMethodZipCodeRangeUnassign,
|
||||||
useShippingRateDelete,
|
useShippingRateDelete,
|
||||||
useShippingRateUpdate
|
useShippingRateUpdate
|
||||||
} from "@saleor/shipping/mutations";
|
} from "@saleor/shipping/mutations";
|
||||||
import { useShippingMethodChannelListingUpdate } from "@saleor/shipping/mutations";
|
import { useShippingMethodChannelListingUpdate } from "@saleor/shipping/mutations";
|
||||||
import { useShippingZone } from "@saleor/shipping/queries";
|
import { useShippingZone } from "@saleor/shipping/queries";
|
||||||
import { shippingZoneUrl } from "@saleor/shipping/urls";
|
import {
|
||||||
|
ShippingRateUrlDialog,
|
||||||
|
ShippingRateUrlQueryParams,
|
||||||
|
shippingWeightRatesEditUrl,
|
||||||
|
shippingZoneUrl
|
||||||
|
} from "@saleor/shipping/urls";
|
||||||
import { ShippingMethodTypeEnum } from "@saleor/types/globalTypes";
|
import { ShippingMethodTypeEnum } from "@saleor/types/globalTypes";
|
||||||
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
export interface WeightRatesUpdateProps {
|
export interface WeightRatesUpdateProps {
|
||||||
id: string;
|
id: string;
|
||||||
rateId: string;
|
rateId: string;
|
||||||
|
params: ShippingRateUrlQueryParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
|
export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
|
||||||
id,
|
id,
|
||||||
rateId
|
rateId,
|
||||||
|
params
|
||||||
}) => {
|
}) => {
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
const notify = useNotifier();
|
const notify = useNotifier();
|
||||||
|
@ -47,6 +59,11 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
|
||||||
variables: { id }
|
variables: { id }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [openModal, closeModal] = createDialogActionHandlers<
|
||||||
|
ShippingRateUrlDialog,
|
||||||
|
ShippingRateUrlQueryParams
|
||||||
|
>(navigate, params => shippingWeightRatesEditUrl(id, rateId, params), params);
|
||||||
|
|
||||||
const rate = data?.shippingZone?.shippingMethods.find(
|
const rate = data?.shippingZone?.shippingMethods.find(
|
||||||
rate => rate.id === rateId
|
rate => rate.id === rateId
|
||||||
);
|
);
|
||||||
|
@ -74,8 +91,6 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
|
||||||
toggleAllChannels
|
toggleAllChannels
|
||||||
} = useChannels(shippingChannels);
|
} = useChannels(shippingChannels);
|
||||||
|
|
||||||
const [openModal, setOpenModal] = React.useState(false);
|
|
||||||
|
|
||||||
const [updateShippingRate, updateShippingRateOpts] = useShippingRateUpdate(
|
const [updateShippingRate, updateShippingRateOpts] = useShippingRateUpdate(
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
@ -96,7 +111,43 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleDelete = () => setOpenModal(true);
|
const [
|
||||||
|
assignZipCodeRange,
|
||||||
|
assignZipCodeRangeOpts
|
||||||
|
] = useShippingMethodZipCodeRangeAssign({
|
||||||
|
onCompleted: data => {
|
||||||
|
if (data.shippingMethodZipCodeRulesCreate.errors.length === 0) {
|
||||||
|
notify({
|
||||||
|
status: "success",
|
||||||
|
text: intl.formatMessage(commonMessages.savedChanges)
|
||||||
|
});
|
||||||
|
closeModal();
|
||||||
|
} else {
|
||||||
|
notify({
|
||||||
|
status: "error",
|
||||||
|
text: intl.formatMessage({
|
||||||
|
defaultMessage: "Cannot add specified zip codes range.",
|
||||||
|
description: "zip code range add error text"
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const [
|
||||||
|
unassignZipCodeRange,
|
||||||
|
unassignZipCodeRangeOpts
|
||||||
|
] = useShippingMethodZipCodeRangeUnassign({
|
||||||
|
onCompleted: data => {
|
||||||
|
if (data.shippingMethodZipCodeRulesDelete.errors.length === 0) {
|
||||||
|
notify({
|
||||||
|
status: "success",
|
||||||
|
text: intl.formatMessage(commonMessages.savedChanges)
|
||||||
|
});
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const handleSubmit = async (data: FormData) => {
|
const handleSubmit = async (data: FormData) => {
|
||||||
const response = await updateShippingRate({
|
const response = await updateShippingRate({
|
||||||
variables: getUpdateShippingWeightRateVariables(data, id, rateId)
|
variables: getUpdateShippingWeightRateVariables(data, id, rateId)
|
||||||
|
@ -139,7 +190,7 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
|
||||||
)}
|
)}
|
||||||
<DeleteShippingRateDialog
|
<DeleteShippingRateDialog
|
||||||
confirmButtonState={deleteShippingRateOpts.status}
|
confirmButtonState={deleteShippingRateOpts.status}
|
||||||
onClose={() => setOpenModal(false)}
|
onClose={closeModal}
|
||||||
handleConfirm={() =>
|
handleConfirm={() =>
|
||||||
deleteShippingRate({
|
deleteShippingRate({
|
||||||
variables: {
|
variables: {
|
||||||
|
@ -147,7 +198,7 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
open={openModal}
|
open={params.action === "remove"}
|
||||||
name={rate?.name}
|
name={rate?.name}
|
||||||
/>
|
/>
|
||||||
<ShippingZoneRatesPage
|
<ShippingZoneRatesPage
|
||||||
|
@ -160,7 +211,7 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
|
||||||
}
|
}
|
||||||
hasChannelChanged={shippingChannels?.length !== currentChannels?.length}
|
hasChannelChanged={shippingChannels?.length !== currentChannels?.length}
|
||||||
saveButtonBarState={updateShippingRateOpts.status}
|
saveButtonBarState={updateShippingRateOpts.status}
|
||||||
onDelete={handleDelete}
|
onDelete={() => openModal("remove")}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
onBack={handleBack}
|
onBack={handleBack}
|
||||||
rate={rate}
|
rate={rate}
|
||||||
|
@ -172,6 +223,44 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
|
||||||
openChannelsModal={handleChannelsModalOpen}
|
openChannelsModal={handleChannelsModalOpen}
|
||||||
onChannelsChange={setCurrentChannels}
|
onChannelsChange={setCurrentChannels}
|
||||||
variant={ShippingMethodTypeEnum.WEIGHT}
|
variant={ShippingMethodTypeEnum.WEIGHT}
|
||||||
|
onZipCodeAssign={() => openModal("add-range")}
|
||||||
|
onZipCodeUnassign={id =>
|
||||||
|
openModal("remove-range", {
|
||||||
|
id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<ShippingZoneZipCodeRangeDialog
|
||||||
|
confirmButtonState={assignZipCodeRangeOpts.status}
|
||||||
|
onClose={closeModal}
|
||||||
|
onSubmit={data =>
|
||||||
|
assignZipCodeRange({
|
||||||
|
variables: {
|
||||||
|
id: rateId,
|
||||||
|
input: {
|
||||||
|
zipCodeRules: [
|
||||||
|
{
|
||||||
|
end: data.max || null,
|
||||||
|
start: data.min
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
open={params.action === "add-range"}
|
||||||
|
/>
|
||||||
|
<ShippingRateZipCodeRangeRemoveDialog
|
||||||
|
confirmButtonState={unassignZipCodeRangeOpts.status}
|
||||||
|
onClose={closeModal}
|
||||||
|
onConfirm={() =>
|
||||||
|
unassignZipCodeRange({
|
||||||
|
variables: {
|
||||||
|
id: params.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
open={params.action === "remove-range"}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1357,19 +1357,18 @@ export interface OrderLineInput {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OrderRefundFulfillmentLineInput {
|
export interface OrderRefundFulfillmentLineInput {
|
||||||
fulfillmentLineId?: string | null;
|
fulfillmentLineId: string;
|
||||||
quantity: number;
|
quantity: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OrderRefundLineInput {
|
export interface OrderRefundLineInput {
|
||||||
orderLineId?: string | null;
|
orderLineId: string;
|
||||||
quantity: number;
|
quantity: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OrderRefundProductsInput {
|
export interface OrderRefundProductsInput {
|
||||||
orderLines?: OrderRefundLineInput[] | null;
|
orderLines?: OrderRefundLineInput[] | null;
|
||||||
fulfillmentLines?: OrderRefundFulfillmentLineInput[] | null;
|
fulfillmentLines?: OrderRefundFulfillmentLineInput[] | null;
|
||||||
notifyCustomer?: boolean | null;
|
|
||||||
amountToRefund?: any | null;
|
amountToRefund?: any | null;
|
||||||
includeShippingCosts?: boolean | null;
|
includeShippingCosts?: boolean | null;
|
||||||
}
|
}
|
||||||
|
@ -1698,6 +1697,15 @@ export interface ShippingPriceInput {
|
||||||
shippingZone?: string | null;
|
shippingZone?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ShippingZipCodeRulesCreateInput {
|
||||||
|
zipCodeRules: (ShippingZipCodeRulesCreateInputRange | null)[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShippingZipCodeRulesCreateInputRange {
|
||||||
|
start: string;
|
||||||
|
end?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ShippingZoneCreateInput {
|
export interface ShippingZoneCreateInput {
|
||||||
name?: string | null;
|
name?: string | null;
|
||||||
countries?: (string | null)[] | null;
|
countries?: (string | null)[] | null;
|
||||||
|
|
Loading…
Reference in a new issue