fix(dashboard,medusa,types): allow searching for promotion rule options (#12028)
* fix: allow searching for promotion rule options * fix: allow searching for promotion rule options * add changeset * cleanup
This commit is contained in:
committed by
GitHub
parent
6d8390a529
commit
3dba58785f
7
.changeset/gold-pigs-glow.md
Normal file
7
.changeset/gold-pigs-glow.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@medusajs/dashboard": patch
|
||||
"@medusajs/types": patch
|
||||
"@medusajs/medusa": patch
|
||||
---
|
||||
|
||||
fix(dashboard,medusa,types): allow searching for promotion rule options
|
||||
@@ -197,7 +197,7 @@ const ComboboxImpl = <T extends Value = string>(
|
||||
const showTag = hasValue && isArrayValue
|
||||
const showSelected = showTag && !searchValue && !open
|
||||
|
||||
const hideInput = !isArrayValue && !open
|
||||
const hideInput = !isArrayValue && hasValue && !open
|
||||
const selectedLabel = options.find((o) => o.value === selectedValues)?.label
|
||||
|
||||
const hidePlaceholder = showSelected || open
|
||||
|
||||
@@ -28,6 +28,7 @@ export const useComboboxData = <
|
||||
defaultValue,
|
||||
defaultValueKey,
|
||||
pageSize = 10,
|
||||
enabled = true,
|
||||
}: {
|
||||
queryKey: QueryKey
|
||||
queryFn: (params: TParams) => Promise<TResponse>
|
||||
@@ -35,6 +36,7 @@ export const useComboboxData = <
|
||||
defaultValueKey?: keyof TParams
|
||||
defaultValue?: string | string[]
|
||||
pageSize?: number
|
||||
enabled?: boolean
|
||||
}) => {
|
||||
const { searchValue, onSearchValueChange, query } = useDebouncedSearch()
|
||||
|
||||
@@ -47,7 +49,7 @@ export const useComboboxData = <
|
||||
limit: Array.isArray(defaultValue) ? defaultValue.length : 1,
|
||||
} as TParams)
|
||||
},
|
||||
enabled: !!defaultValue,
|
||||
enabled: !!defaultValue && enabled,
|
||||
})
|
||||
|
||||
const { data, ...rest } = useInfiniteQuery({
|
||||
@@ -65,6 +67,7 @@ export const useComboboxData = <
|
||||
return moreItemsExist ? lastPage.offset + lastPage.limit : undefined
|
||||
},
|
||||
placeholderData: keepPreviousData,
|
||||
enabled: enabled,
|
||||
})
|
||||
|
||||
const options = data?.pages.flatMap((page) => getOptions(page)) ?? []
|
||||
@@ -74,7 +77,8 @@ export const useComboboxData = <
|
||||
* If there are no options and the query is empty, then the combobox should be disabled,
|
||||
* as there is no data to search for.
|
||||
*/
|
||||
const disabled = !rest.isPending && !options.length && !searchValue
|
||||
const disabled =
|
||||
(!rest.isPending && !options.length && !searchValue) || !enabled
|
||||
|
||||
// make sure that the default value is included in the options
|
||||
if (defaultValue && defaultOptions.length && !searchValue) {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { RuleAttributeOptionsResponse, StoreDTO } from "@medusajs/types"
|
||||
import { Input, Select } from "@medusajs/ui"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { Input } from "@medusajs/ui"
|
||||
import { useWatch } from "react-hook-form"
|
||||
import { Form } from "../../../../../../components/common/form"
|
||||
import { Combobox } from "../../../../../../components/inputs/combobox"
|
||||
import { usePromotionRuleValues } from "../../../../../../hooks/api/promotions"
|
||||
import { useStore } from "../../../../../../hooks/api/store"
|
||||
import { useComboboxData } from "../../../../../../hooks/use-combobox-data"
|
||||
import { sdk } from "../../../../../../lib/client"
|
||||
|
||||
type RuleValueFormFieldType = {
|
||||
form: any
|
||||
@@ -16,11 +17,11 @@ type RuleValueFormFieldType = {
|
||||
name: string
|
||||
operator: string
|
||||
fieldRule: any
|
||||
attributes: RuleAttributeOptionsResponse[]
|
||||
attributes: HttpTypes.AdminRuleAttributeOption[]
|
||||
ruleType: "rules" | "target-rules" | "buy-rules"
|
||||
}
|
||||
|
||||
const buildFilters = (attribute?: string, store?: StoreDTO) => {
|
||||
const buildFilters = (attribute?: string, store?: HttpTypes.AdminStore) => {
|
||||
if (!attribute || !store) {
|
||||
return {}
|
||||
}
|
||||
@@ -49,17 +50,25 @@ export const RuleValueFormField = ({
|
||||
)
|
||||
|
||||
const { store, isLoading: isStoreLoading } = useStore()
|
||||
const { values: options = [] } = usePromotionRuleValues(
|
||||
ruleType,
|
||||
attribute?.id!,
|
||||
buildFilters(attribute?.id, store),
|
||||
{
|
||||
enabled:
|
||||
!!attribute?.id &&
|
||||
["select", "multiselect"].includes(attribute.field_type) &&
|
||||
!isStoreLoading,
|
||||
}
|
||||
)
|
||||
|
||||
const comboboxData = useComboboxData({
|
||||
queryFn: async (params) => {
|
||||
return await sdk.admin.promotion.listRuleValues(
|
||||
ruleType,
|
||||
attribute?.id!,
|
||||
{
|
||||
...params,
|
||||
...buildFilters(attribute?.id, store!),
|
||||
}
|
||||
)
|
||||
},
|
||||
enabled:
|
||||
!!attribute?.id &&
|
||||
["select", "multiselect"].includes(attribute.field_type) &&
|
||||
!isStoreLoading,
|
||||
getOptions: (data) => data.values,
|
||||
queryKey: ["rule-value-options", ruleType, attribute?.id],
|
||||
})
|
||||
|
||||
const watchOperator = useWatch({
|
||||
control: form.control,
|
||||
@@ -103,54 +112,21 @@ export const RuleValueFormField = ({
|
||||
<Form.ErrorMessage />
|
||||
</Form.Item>
|
||||
)
|
||||
} else if (watchOperator === "eq") {
|
||||
return (
|
||||
<Form.Item className="basis-1/2">
|
||||
<Form.Control>
|
||||
<Select
|
||||
{...field}
|
||||
value={
|
||||
Array.isArray(field.value) ? field.value[0] : field.value
|
||||
}
|
||||
onValueChange={onChange}
|
||||
disabled={!fieldRule.attribute}
|
||||
>
|
||||
<Select.Trigger ref={ref} className="bg-ui-bg-base">
|
||||
<Select.Value placeholder="Select Value" />
|
||||
</Select.Trigger>
|
||||
|
||||
<Select.Content>
|
||||
{options?.map((option, i) => (
|
||||
<Select.Item
|
||||
key={`${identifier}-value-option-${i}`}
|
||||
value={option.value}
|
||||
>
|
||||
<span className="text-ui-fg-subtle">
|
||||
{option.label}
|
||||
</span>
|
||||
</Select.Item>
|
||||
))}
|
||||
</Select.Content>
|
||||
</Select>
|
||||
</Form.Control>
|
||||
<Form.ErrorMessage />
|
||||
</Form.Item>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<Form.Item className="basis-1/2">
|
||||
<Form.Control>
|
||||
<Combobox
|
||||
{...field}
|
||||
{...comboboxData}
|
||||
multiple={watchOperator !== "eq"}
|
||||
ref={ref}
|
||||
placeholder="Select Values"
|
||||
options={options}
|
||||
placeholder={
|
||||
watchOperator === "eq" ? "Select Value" : "Select Values"
|
||||
}
|
||||
onChange={onChange}
|
||||
className="bg-ui-bg-base"
|
||||
disabled={!fieldRule.attribute}
|
||||
/>
|
||||
</Form.Control>
|
||||
|
||||
<Form.ErrorMessage />
|
||||
</Form.Item>
|
||||
)
|
||||
|
||||
@@ -61,12 +61,12 @@ export interface RuleValueOptionsResponse {
|
||||
/**
|
||||
* @experimental
|
||||
*/
|
||||
export type AdminRuleValueOptionsListResponse = {
|
||||
export type AdminRuleValueOptionsListResponse = PaginatedResponse<{
|
||||
/**
|
||||
* The list of rule value options.
|
||||
*/
|
||||
values: AdminRuleValueOption[]
|
||||
}
|
||||
}>
|
||||
|
||||
export type AdminPromotionRuleBatchResponse = BatchResponse<AdminPromotionRule>
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/framework/utils"
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "@medusajs/framework/http"
|
||||
import { HttpTypes } from "@medusajs/framework/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/framework/utils"
|
||||
import {
|
||||
ruleQueryConfigurations,
|
||||
validateRuleAttribute,
|
||||
validateRuleType,
|
||||
} from "../../../utils"
|
||||
import { AdminGetPromotionRuleParamsType } from "../../../validators"
|
||||
import { HttpTypes } from "@medusajs/framework/types"
|
||||
|
||||
/*
|
||||
This endpoint returns all the potential values for rules (promotion rules, target rules and buy rules)
|
||||
@@ -49,7 +49,7 @@ export const GET = async (
|
||||
applicationMethodType,
|
||||
})
|
||||
|
||||
const { rows } = await remoteQuery(
|
||||
const { rows, metadata } = await remoteQuery(
|
||||
remoteQueryObjectFromString({
|
||||
entryPoint: queryConfig.entryPoint,
|
||||
variables: {
|
||||
@@ -67,5 +67,8 @@ export const GET = async (
|
||||
|
||||
res.json({
|
||||
values,
|
||||
count: metadata.count,
|
||||
offset: metadata.skip,
|
||||
limit: metadata.take,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user