fix(admin-ui): Prevent oversized product request in Price List domain (#5535)
* fix(admin-ui): Prevent oversized product request in Price List domain * add changeset
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/admin-ui": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix(admin-ui): Fix issue were Price List domain would fetch all products on initial load"
|
||||||
@@ -59,11 +59,11 @@ const PriceListEdit = () => {
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
<PriceListGeneralSection
|
<PriceListGeneralSection
|
||||||
key={`${price_list.updated_at}`}
|
key={`gs_${price_list.id}_${price_list.updated_at}`}
|
||||||
priceList={price_list}
|
priceList={price_list}
|
||||||
/>
|
/>
|
||||||
<PriceListPricesSection
|
<PriceListPricesSection
|
||||||
key={`${price_list.updated_at}`}
|
key={`ps_${price_list.id}_${price_list.updated_at}`}
|
||||||
priceList={price_list}
|
priceList={price_list}
|
||||||
/>
|
/>
|
||||||
{getWidgets("price_list.details.after").map((w, i) => {
|
{getWidgets("price_list.details.after").map((w, i) => {
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
usePrompt,
|
usePrompt,
|
||||||
} from "@medusajs/ui"
|
} from "@medusajs/ui"
|
||||||
|
import { useAdminCreatePriceListPrices } from "medusa-react"
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import { useForm } from "react-hook-form"
|
import { useForm } from "react-hook-form"
|
||||||
import * as z from "zod"
|
|
||||||
import { useAdminCreatePriceListPrices } from "medusa-react"
|
|
||||||
import { useTranslation } from "react-i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
|
import * as z from "zod"
|
||||||
|
|
||||||
import { Form } from "../../../../components/helpers/form"
|
import { Form } from "../../../../components/helpers/form"
|
||||||
import useNotification from "../../../../hooks/use-notification"
|
import useNotification from "../../../../hooks/use-notification"
|
||||||
@@ -621,52 +621,68 @@ const AddProductsModal = ({
|
|||||||
productIds={productIds}
|
productIds={productIds}
|
||||||
/>
|
/>
|
||||||
</ProgressTabs.Content>
|
</ProgressTabs.Content>
|
||||||
{isLoading ? (
|
<ProgressTabs.Content
|
||||||
<div className="flex h-full w-full items-center justify-center">
|
value={Tab.PRICES}
|
||||||
<Spinner className="text-ui-fg-subtle animate-spin" />
|
className="h-full w-full"
|
||||||
</div>
|
>
|
||||||
) : isError || isNotFound ? (
|
{isLoading ? (
|
||||||
<div className="flex h-full w-full items-center justify-center">
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
<div className="text-ui-fg-subtle flex items-center gap-x-2">
|
<Spinner className="text-ui-fg-subtle animate-spin" />
|
||||||
<ExclamationCircle />
|
|
||||||
<Text>
|
|
||||||
{t(
|
|
||||||
"price-list-add-products-modal-error",
|
|
||||||
"An error occurred while preparing the form. Reload the page and try again. If the issue persists, try again later."
|
|
||||||
)}
|
|
||||||
</Text>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
) : isError || isNotFound ? (
|
||||||
) : (
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
<React.Fragment>
|
<div className="text-ui-fg-subtle flex items-center gap-x-2">
|
||||||
<ProgressTabs.Content
|
<ExclamationCircle />
|
||||||
value={Tab.PRICES}
|
<Text>
|
||||||
className="h-full w-full"
|
{t(
|
||||||
>
|
"price-list-add-products-modal-error",
|
||||||
<PriceListPricesForm
|
"An error occurred while preparing the form. Reload the page and try again. If the issue persists, try again later."
|
||||||
setProduct={onSetProduct}
|
)}
|
||||||
form={nestedForm(form, "prices")}
|
</Text>
|
||||||
productIds={selectedIds}
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<PriceListPricesForm
|
||||||
|
setProduct={onSetProduct}
|
||||||
|
form={nestedForm(form, "prices")}
|
||||||
|
productIds={selectedIds}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</ProgressTabs.Content>
|
||||||
|
{product && (
|
||||||
|
<ProgressTabs.Content
|
||||||
|
value={Tab.EDIT}
|
||||||
|
className="h-full w-full"
|
||||||
|
>
|
||||||
|
{isLoading ? (
|
||||||
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
|
<Spinner className="text-ui-fg-subtle animate-spin" />
|
||||||
|
</div>
|
||||||
|
) : isError || isNotFound ? (
|
||||||
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
|
<div className="text-ui-fg-subtle flex items-center gap-x-2">
|
||||||
|
<ExclamationCircle />
|
||||||
|
<Text>
|
||||||
|
{t(
|
||||||
|
"price-list-add-products-modal-error",
|
||||||
|
"An error occurred while preparing the form. Reload the page and try again. If the issue persists, try again later."
|
||||||
|
)}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<PriceListProductPricesForm
|
||||||
|
product={product}
|
||||||
|
currencies={currencies}
|
||||||
|
regions={regions}
|
||||||
|
control={editControl}
|
||||||
|
priceListTaxInclusive={priceList.includes_tax}
|
||||||
|
taxInclEnabled={isTaxInclPricesEnabled}
|
||||||
|
setValue={setEditValue}
|
||||||
|
getValues={getEditValues}
|
||||||
/>
|
/>
|
||||||
</ProgressTabs.Content>
|
|
||||||
{product && (
|
|
||||||
<ProgressTabs.Content
|
|
||||||
value={Tab.EDIT}
|
|
||||||
className="h-full w-full"
|
|
||||||
>
|
|
||||||
<PriceListProductPricesForm
|
|
||||||
product={product}
|
|
||||||
currencies={currencies}
|
|
||||||
regions={regions}
|
|
||||||
control={editControl}
|
|
||||||
priceListTaxInclusive={priceList.includes_tax}
|
|
||||||
taxInclEnabled={isTaxInclPricesEnabled}
|
|
||||||
setValue={setEditValue}
|
|
||||||
getValues={getEditValues}
|
|
||||||
/>
|
|
||||||
</ProgressTabs.Content>
|
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</ProgressTabs.Content>
|
||||||
)}
|
)}
|
||||||
</Form>
|
</Form>
|
||||||
</FocusModal.Body>
|
</FocusModal.Body>
|
||||||
|
|||||||
+2
-2
@@ -5,11 +5,11 @@ import { useAdminProducts } from "medusa-react"
|
|||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
|
|
||||||
import { useTranslation } from "react-i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
|
import { Form } from "../../../../components/helpers/form"
|
||||||
import { useDebounce } from "../../../../hooks/use-debounce"
|
import { useDebounce } from "../../../../hooks/use-debounce"
|
||||||
import { NestedForm } from "../../../../utils/nested-form"
|
import { NestedForm } from "../../../../utils/nested-form"
|
||||||
import { ProductFilter, ProductFilterMenu } from "../../components"
|
import { ProductFilter, ProductFilterMenu } from "../../components"
|
||||||
import { PriceListPricesSchema } from "./types"
|
import { PriceListPricesSchema } from "./types"
|
||||||
import { Form } from "../../../../components/helpers/form"
|
|
||||||
|
|
||||||
type PriceListPricesFormProps = {
|
type PriceListPricesFormProps = {
|
||||||
form: NestedForm<PriceListPricesSchema>
|
form: NestedForm<PriceListPricesSchema>
|
||||||
@@ -46,13 +46,13 @@ const PriceListPricesForm = ({
|
|||||||
{
|
{
|
||||||
id: productIds,
|
id: productIds,
|
||||||
q: debouncedQuery,
|
q: debouncedQuery,
|
||||||
limit: productIds?.length,
|
|
||||||
price_list_id: priceListId ? [priceListId] : undefined,
|
price_list_id: priceListId ? [priceListId] : undefined,
|
||||||
...filters,
|
...filters,
|
||||||
expand: "variants.prices",
|
expand: "variants.prices",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
keepPreviousData: true,
|
keepPreviousData: true,
|
||||||
|
enabled: !!productIds?.length,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+12
-4
@@ -5,11 +5,17 @@ import * as React from "react"
|
|||||||
type UsePricesFormDataProps = {
|
type UsePricesFormDataProps = {
|
||||||
priceList?: PriceList
|
priceList?: PriceList
|
||||||
productIds: string[]
|
productIds: string[]
|
||||||
|
enable?: {
|
||||||
|
products?: boolean
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const usePricesFormData = ({
|
const usePricesFormData = ({
|
||||||
priceList,
|
priceList,
|
||||||
productIds,
|
productIds,
|
||||||
|
enable = {
|
||||||
|
products: true,
|
||||||
|
},
|
||||||
}: UsePricesFormDataProps) => {
|
}: UsePricesFormDataProps) => {
|
||||||
const {
|
const {
|
||||||
products,
|
products,
|
||||||
@@ -18,11 +24,11 @@ const usePricesFormData = ({
|
|||||||
} = useAdminProducts(
|
} = useAdminProducts(
|
||||||
{
|
{
|
||||||
id: productIds,
|
id: productIds,
|
||||||
limit: productIds?.length,
|
|
||||||
price_list_id: priceList ? [priceList.id] : undefined,
|
price_list_id: priceList ? [priceList.id] : undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
keepPreviousData: true,
|
keepPreviousData: true,
|
||||||
|
enabled: !!productIds?.length && enable.products,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -53,9 +59,11 @@ const usePricesFormData = ({
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const isLoading = isLoadingProducts || isLoadingStore || isLoadingRegions
|
const isLoading =
|
||||||
const isError = isErrorProducts || isStoreError || isErrorRegions
|
(enable.products && isLoadingProducts) || isLoadingStore || isLoadingRegions
|
||||||
const isNotFound = !products || !regions || !currencies
|
const isError =
|
||||||
|
(enable.products && isErrorProducts) || isStoreError || isErrorRegions
|
||||||
|
const isNotFound = (enable.products && !products) || !regions || !currencies
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isError,
|
isError,
|
||||||
|
|||||||
+1
-1
@@ -280,7 +280,7 @@ const PriceListProductsForm = ({
|
|||||||
|
|
||||||
const { products, count, isLoading, isError } = useAdminProducts(
|
const { products, count, isLoading, isError } = useAdminProducts(
|
||||||
{
|
{
|
||||||
limit: PAGE_SIZE,
|
limit: 20,
|
||||||
offset,
|
offset,
|
||||||
expand: "variants,sales_channels,collection",
|
expand: "variants,sales_channels,collection",
|
||||||
q: debouncedQuery,
|
q: debouncedQuery,
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import * as React from "react"
|
|||||||
import { useForm, useWatch } from "react-hook-form"
|
import { useForm, useWatch } from "react-hook-form"
|
||||||
import * as z from "zod"
|
import * as z from "zod"
|
||||||
|
|
||||||
import { ExclamationCircle, Spinner } from "@medusajs/icons"
|
|
||||||
import { Product } from "@medusajs/medusa"
|
import { Product } from "@medusajs/medusa"
|
||||||
import { useAdminCreatePriceList } from "medusa-react"
|
import { useAdminCreatePriceList } from "medusa-react"
|
||||||
import { Form } from "../../../components/helpers/form"
|
import { Form } from "../../../components/helpers/form"
|
||||||
@@ -41,6 +40,7 @@ import {
|
|||||||
type PriceListProductPricesSchema,
|
type PriceListProductPricesSchema,
|
||||||
} from "../forms/price-list-product-prices-form"
|
} from "../forms/price-list-product-prices-form"
|
||||||
|
|
||||||
|
import { ExclamationCircle, Spinner } from "@medusajs/icons"
|
||||||
import { useTranslation } from "react-i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
import {
|
import {
|
||||||
PriceListProductsForm,
|
PriceListProductsForm,
|
||||||
@@ -159,6 +159,9 @@ const PriceListNew = () => {
|
|||||||
const { isLoading, isError, isNotFound, regions, currencies } =
|
const { isLoading, isError, isNotFound, regions, currencies } =
|
||||||
usePricesFormData({
|
usePricesFormData({
|
||||||
productIds: selectedIds,
|
productIds: selectedIds,
|
||||||
|
enable: {
|
||||||
|
products: false,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const onCloseModal = React.useCallback(() => {
|
const onCloseModal = React.useCallback(() => {
|
||||||
@@ -690,52 +693,69 @@ const PriceListNew = () => {
|
|||||||
>
|
>
|
||||||
<PriceListProductsForm form={nestedForm(form, "products")} />
|
<PriceListProductsForm form={nestedForm(form, "products")} />
|
||||||
</ProgressTabs.Content>
|
</ProgressTabs.Content>
|
||||||
{isLoading ? (
|
|
||||||
<div className="flex h-full w-full items-center justify-center">
|
<ProgressTabs.Content
|
||||||
<Spinner className="text-ui-fg-subtle animate-spin" />
|
value={Tab.PRICES}
|
||||||
</div>
|
className="h-full w-full"
|
||||||
) : isError || isNotFound ? (
|
>
|
||||||
<div className="flex h-full w-full items-center justify-center">
|
{isLoading ? (
|
||||||
<div className="text-ui-fg-subtle flex items-center gap-x-2">
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
<ExclamationCircle />
|
<Spinner className="text-ui-fg-subtle animate-spin" />
|
||||||
<Text>
|
|
||||||
{t(
|
|
||||||
"price-list-new-form-error-loading-products",
|
|
||||||
"An error occurred while preparing the form. Reload the page and try again. If the issue persists, try again later."
|
|
||||||
)}
|
|
||||||
</Text>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
) : isError || isNotFound ? (
|
||||||
) : (
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
<React.Fragment>
|
<div className="text-ui-fg-subtle flex items-center gap-x-2">
|
||||||
<ProgressTabs.Content
|
<ExclamationCircle />
|
||||||
value={Tab.PRICES}
|
<Text>
|
||||||
className="h-full w-full"
|
{t(
|
||||||
>
|
"price-list-new-form-error-loading-products",
|
||||||
<PriceListPricesForm
|
"An error occurred while preparing the form. Reload the page and try again. If the issue persists, try again later."
|
||||||
setProduct={onSetProduct}
|
)}
|
||||||
form={nestedForm(form, "prices")}
|
</Text>
|
||||||
productIds={selectedIds}
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<PriceListPricesForm
|
||||||
|
setProduct={onSetProduct}
|
||||||
|
form={nestedForm(form, "prices")}
|
||||||
|
productIds={selectedIds}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</ProgressTabs.Content>
|
||||||
|
{product && (
|
||||||
|
<ProgressTabs.Content
|
||||||
|
value={Tab.EDIT}
|
||||||
|
className="h-full w-full"
|
||||||
|
>
|
||||||
|
{isLoading ? (
|
||||||
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
|
<Spinner className="text-ui-fg-subtle animate-spin" />
|
||||||
|
</div>
|
||||||
|
) : isError || isNotFound ? (
|
||||||
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
|
<div className="text-ui-fg-subtle flex items-center gap-x-2">
|
||||||
|
<ExclamationCircle />
|
||||||
|
<Text>
|
||||||
|
{t(
|
||||||
|
"price-list-new-form-error-loading-products",
|
||||||
|
"An error occurred while preparing the form. Reload the page and try again. If the issue persists, try again later."
|
||||||
|
)}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<PriceListProductPricesForm
|
||||||
|
priceListTaxInclusive={taxToggleState}
|
||||||
|
taxInclEnabled={isTaxInclPricesEnabled}
|
||||||
|
product={product}
|
||||||
|
currencies={currencies}
|
||||||
|
regions={regions}
|
||||||
|
control={editControl}
|
||||||
|
getValues={getEditValues}
|
||||||
|
setValue={setEditValue}
|
||||||
/>
|
/>
|
||||||
</ProgressTabs.Content>
|
|
||||||
{product && (
|
|
||||||
<ProgressTabs.Content
|
|
||||||
value={Tab.EDIT}
|
|
||||||
className="h-full w-full"
|
|
||||||
>
|
|
||||||
<PriceListProductPricesForm
|
|
||||||
priceListTaxInclusive={taxToggleState}
|
|
||||||
taxInclEnabled={isTaxInclPricesEnabled}
|
|
||||||
product={product}
|
|
||||||
currencies={currencies}
|
|
||||||
regions={regions}
|
|
||||||
control={editControl}
|
|
||||||
getValues={getEditValues}
|
|
||||||
setValue={setEditValue}
|
|
||||||
/>
|
|
||||||
</ProgressTabs.Content>
|
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</ProgressTabs.Content>
|
||||||
)}
|
)}
|
||||||
</Form>
|
</Form>
|
||||||
</FocusModal.Body>
|
</FocusModal.Body>
|
||||||
|
|||||||
Reference in New Issue
Block a user