feat(dashboard, core-flows): associate shipping option to type (#13226)

* feat(dashboard, core-flows): allow associating shipping option type to a shipping option

* edit as well

* fix translation schema

* fix some tests

* changeset

* add new test to update shipping option type

* add new test to create shipping option with shipping option type

* pr comments

* pr comments

* rename variable

* make zod great again
This commit is contained in:
William Bouchard
2025-08-19 11:02:36 -04:00
committed by GitHub
parent b1ee204369
commit 67d3660abf
18 changed files with 525 additions and 42 deletions

View File

@@ -6308,6 +6308,9 @@
"profile": {
"type": "string"
},
"type": {
"type": "string"
},
"fulfillmentOption": {
"type": "string"
}
@@ -6318,6 +6321,7 @@
"enableInStore",
"provider",
"profile",
"type",
"fulfillmentOption"
],
"additionalProperties": false

View File

@@ -1683,6 +1683,7 @@
},
"provider": "Fulfillment provider",
"profile": "Shipping profile",
"type": "Shipping option type",
"fulfillmentOption": "Fulfillment option"
}
},

View File

@@ -10,10 +10,7 @@ import { Combobox } from "../../../../../components/inputs/combobox"
import { useComboboxData } from "../../../../../hooks/use-combobox-data"
import { sdk } from "../../../../../lib/client"
import { formatProvider } from "../../../../../lib/format-provider"
import {
FulfillmentSetType,
ShippingOptionPriceType,
} from "../../../common/constants"
import { FulfillmentSetType, ShippingOptionPriceType, } from "../../../common/constants"
import { CreateShippingOptionSchema } from "./schema"
type CreateShippingOptionDetailsFormProps = {
@@ -49,6 +46,16 @@ export const CreateShippingOptionDetailsForm = ({
})),
})
const shippingOptionTypes = useComboboxData({
queryFn: (params) => sdk.admin.shippingOptionType.list(params),
queryKey: ["shipping_option_types"],
getOptions: (data) =>
data.shipping_option_types.map((type) => ({
label: type.label,
value: type.id,
})),
})
const fulfillmentProviders = useComboboxData({
queryFn: (params) =>
sdk.admin.fulfillmentProvider.list({
@@ -170,6 +177,31 @@ export const CreateShippingOptionDetailsForm = ({
)
}}
/>
<Form.Field
control={form.control}
name="shipping_option_type_id"
render={({ field }) => {
return (
<Form.Item>
<Form.Label>
{t("stockLocations.shippingOptions.fields.type")}
</Form.Label>
<Form.Control>
<Combobox
{...field}
options={shippingOptionTypes.options}
searchValue={shippingOptionTypes.searchValue}
onSearchValueChange={
shippingOptionTypes.onSearchValueChange
}
disabled={shippingOptionTypes.disabled}
/>
</Form.Control>
<Form.ErrorMessage />
</Form.Item>
)
}}
/>
</div>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">

View File

@@ -167,12 +167,7 @@ export function CreateShippingOptionsForm({
operator: "eq",
},
],
type: {
// TODO: FETCH TYPES
label: "Type label",
description: "Type description",
code: "type-code",
},
type_id: data.shipping_option_type_id,
},
{
onSuccess: ({ shipping_option }) => {

View File

@@ -13,6 +13,7 @@ export const CreateShippingOptionDetailsSchema = z.object({
shipping_profile_id: z.string().min(1),
provider_id: z.string().min(1),
fulfillment_option_id: z.string().min(1),
shipping_option_type_id: z.string().min(1),
})
export const ShippingOptionConditionalPriceSchema = z.object({

View File

@@ -31,6 +31,7 @@ const EditShippingOptionSchema = zod.object({
price_type: zod.nativeEnum(ShippingOptionPriceType),
enabled_in_store: zod.boolean().optional(),
shipping_profile_id: zod.string(),
shipping_option_type_id: zod.string(),
})
export const EditShippingOptionForm = ({
@@ -54,12 +55,23 @@ export const EditShippingOptionForm = ({
defaultValue: shippingOption.shipping_profile_id,
})
const shippingOptionTypes = useComboboxData({
queryFn: (params) => sdk.admin.shippingOptionType.list(params),
queryKey: ["shipping_option_types"],
getOptions: (data) =>
data.shipping_option_types.map((type) => ({
label: type.label,
value: type.id,
})),
})
const form = useForm<zod.infer<typeof EditShippingOptionSchema>>({
defaultValues: {
name: shippingOption.name,
price_type: shippingOption.price_type as ShippingOptionPriceType,
enabled_in_store: isOptionEnabledInStore(shippingOption),
shipping_profile_id: shippingOption.shipping_profile_id,
shipping_option_type_id: shippingOption.type.id,
},
resolver: zodResolver(EditShippingOptionSchema),
})
@@ -92,6 +104,7 @@ export const EditShippingOptionForm = ({
price_type: values.price_type,
shipping_profile_id: values.shipping_profile_id,
rules,
type_id: values.shipping_option_type_id,
},
{
onSuccess: ({ shipping_option }) => {
@@ -111,7 +124,10 @@ export const EditShippingOptionForm = ({
return (
<RouteDrawer.Form form={form}>
<KeyboundForm onSubmit={handleSubmit} className="flex flex-1 flex-col overflow-hidden">
<KeyboundForm
onSubmit={handleSubmit}
className="flex flex-1 flex-col overflow-hidden"
>
<RouteDrawer.Body className="overflow-y-auto">
<div className="flex flex-col gap-y-8">
<div className="flex flex-col gap-y-8">
@@ -200,6 +216,32 @@ export const EditShippingOptionForm = ({
)
}}
/>
<Form.Field
control={form.control}
name="shipping_option_type_id"
render={({ field }) => {
return (
<Form.Item>
<Form.Label>
{t("stockLocations.shippingOptions.fields.type")}
</Form.Label>
<Form.Control>
<Combobox
{...field}
options={shippingOptionTypes.options}
searchValue={shippingOptionTypes.searchValue}
onSearchValueChange={
shippingOptionTypes.onSearchValueChange
}
disabled={shippingOptionTypes.disabled}
/>
</Form.Control>
<Form.ErrorMessage />
</Form.Item>
)
}}
/>
</div>
<Divider />