diff --git a/.changeset/gold-pigs-glow.md b/.changeset/gold-pigs-glow.md new file mode 100644 index 0000000000..6f2a3c81bb --- /dev/null +++ b/.changeset/gold-pigs-glow.md @@ -0,0 +1,7 @@ +--- +"@medusajs/dashboard": patch +"@medusajs/types": patch +"@medusajs/medusa": patch +--- + +fix(dashboard,medusa,types): allow searching for promotion rule options diff --git a/packages/admin/dashboard/src/components/inputs/combobox/combobox.tsx b/packages/admin/dashboard/src/components/inputs/combobox/combobox.tsx index a8eeb128b8..f1747de7d1 100644 --- a/packages/admin/dashboard/src/components/inputs/combobox/combobox.tsx +++ b/packages/admin/dashboard/src/components/inputs/combobox/combobox.tsx @@ -197,7 +197,7 @@ const ComboboxImpl = ( 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 diff --git a/packages/admin/dashboard/src/hooks/use-combobox-data.tsx b/packages/admin/dashboard/src/hooks/use-combobox-data.tsx index 1488dec0c7..46e45f8cc0 100644 --- a/packages/admin/dashboard/src/hooks/use-combobox-data.tsx +++ b/packages/admin/dashboard/src/hooks/use-combobox-data.tsx @@ -28,6 +28,7 @@ export const useComboboxData = < defaultValue, defaultValueKey, pageSize = 10, + enabled = true, }: { queryKey: QueryKey queryFn: (params: TParams) => Promise @@ -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) { diff --git a/packages/admin/dashboard/src/routes/promotions/common/edit-rules/components/rule-value-form-field/rule-value-form-field.tsx b/packages/admin/dashboard/src/routes/promotions/common/edit-rules/components/rule-value-form-field/rule-value-form-field.tsx index a86618fb7c..21b7ea8e5b 100644 --- a/packages/admin/dashboard/src/routes/promotions/common/edit-rules/components/rule-value-form-field/rule-value-form-field.tsx +++ b/packages/admin/dashboard/src/routes/promotions/common/edit-rules/components/rule-value-form-field/rule-value-form-field.tsx @@ -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 = ({ ) - } else if (watchOperator === "eq") { - return ( - - - - - - - ) } else { return ( - ) diff --git a/packages/core/types/src/http/promotion/admin/responses.ts b/packages/core/types/src/http/promotion/admin/responses.ts index 23a6c9d082..41edd98085 100644 --- a/packages/core/types/src/http/promotion/admin/responses.ts +++ b/packages/core/types/src/http/promotion/admin/responses.ts @@ -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 diff --git a/packages/medusa/src/api/admin/promotions/rule-value-options/[rule_type]/[rule_attribute_id]/route.ts b/packages/medusa/src/api/admin/promotions/rule-value-options/[rule_type]/[rule_attribute_id]/route.ts index 98dcf3f709..7b34ae6062 100644 --- a/packages/medusa/src/api/admin/promotions/rule-value-options/[rule_type]/[rule_attribute_id]/route.ts +++ b/packages/medusa/src/api/admin/promotions/rule-value-options/[rule_type]/[rule_attribute_id]/route.ts @@ -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, }) }