From 0a4e20e8886e64391227940848886ef808ead80d Mon Sep 17 00:00:00 2001 From: AlexSserb Date: Fri, 31 Jan 2025 20:18:01 +0400 Subject: [PATCH] feat: searchable product select and department select --- .../ProductSelect/ProductSelect.tsx | 137 +----------------- .../ProductSelect/utils/getRenderOptions.tsx | 50 +++++++ .../components/DepartmentSelect.tsx | 1 + .../components/ShippingProductSelect.tsx | 40 +++++ .../modals/ShippingProductModal.tsx | 33 +++-- .../ShippingTab/types/ShippingProductData.tsx | 14 +- .../ShippingTab/utils/getRestProducts.tsx | 7 +- 7 files changed, 126 insertions(+), 156 deletions(-) create mode 100644 src/components/ProductSelect/utils/getRenderOptions.tsx create mode 100644 src/pages/LeadsPage/tabs/ShippingTab/components/ShippingProductSelect.tsx diff --git a/src/components/ProductSelect/ProductSelect.tsx b/src/components/ProductSelect/ProductSelect.tsx index 4ad6796..cae05b4 100644 --- a/src/components/ProductSelect/ProductSelect.tsx +++ b/src/components/ProductSelect/ProductSelect.tsx @@ -2,21 +2,10 @@ import { ProductSchema } from "../../client"; import { FC, useState } from "react"; import useProductsList from "../../pages/ProductsPage/hooks/useProductsList.tsx"; import { omit } from "lodash"; -import ObjectSelect, { - ObjectSelectProps, -} from "../ObjectSelect/ObjectSelect.tsx"; -import { - ComboboxItem, - Image, - Loader, - OptionsFilter, - rem, - SelectProps, - Text, - Tooltip, -} from "@mantine/core"; -import { getProductFields } from "../../types/utils.ts"; +import ObjectSelect, { ObjectSelectProps } from "../ObjectSelect/ObjectSelect.tsx"; +import { Loader, OptionsFilter } from "@mantine/core"; import { useDebouncedValue } from "@mantine/hooks"; +import getRenderOptions from "./utils/getRenderOptions.tsx"; type RestProps = { clientId: number; @@ -33,68 +22,8 @@ const ProductSelect: FC = (props: Props) => { itemsPerPage: MAX_PRODUCTS, }); const restProps = omit(props, ["clientId"]); - const renderOption: SelectProps["renderOption"] = item => { - const product = products.find( - product => product.id == parseInt(item.option.value) - ); - if (!product) return item.option.label; - const productFields = getProductFields(product); - const imageUrl = - product.images && product.images[0] - ? product.images[0].imageUrl - : undefined; - return ( - - {productFields - .map(([key, value]) => { - return `${key.toString()}: ${value.toString()}`; - }) - .join("\n")} - {imageUrl && ( - {product.name} - )} - - }> -
- {product.name} -
- {product.barcodes && ( - {product.barcodes[0]} - )} -
-
- ); - }; - const optionsFilter: OptionsFilter = ({ options, search }) => { - return options; - const filtered = (options as ComboboxItem[]).filter(option => { - const product = products.find( - product => product.id == parseInt(option.value) - ); - if (!product) return true; - return ( - product.name.toLowerCase().includes(search.toLowerCase()) || - product.barcodes.some(value => - value.toLowerCase().includes(search.toLowerCase()) - ) || - product.article?.toLowerCase() === search.toLowerCase() - ); - }); - filtered.sort((a, b) => a.label.localeCompare(b.label)); - return filtered.length > MAX_PRODUCTS - ? filtered.slice(0, MAX_PRODUCTS) - : filtered; - }; + const optionsFilter: OptionsFilter = ({ options }) => options; const setSearchValueImpl = (value: string) => { const names = products.map(product => product.name); if (names.includes(value)) return; @@ -103,14 +32,13 @@ const ProductSelect: FC = (props: Props) => { return ( ) : null } onSearchChange={setSearchValueImpl} - renderOption={renderOption} + renderOption={getRenderOptions(products)} searchable {...restProps} data={products} @@ -118,58 +46,5 @@ const ProductSelect: FC = (props: Props) => { /> ); }; + export default ProductSelect; -// type ControlledValueProps = { -// value: ProductSchema; -// onChange: (value: ProductSchema) => void; -// } -// type RestProps = { -// defaultValue?: ProductSchema; -// onChange: (value: ProductSchema) => void; -// clientId: number; -// } -// type Props = (RestProps & Partial) & Omit; -// -// const ProductSelect: FC = (props) => { -// const isControlled = 'value' in props; -// const [intertalValue, setInternalValue] = useState(props.defaultValue); -// const value = isControlled ? props.value : intertalValue -// -// const {products} = useProductsList({clientId: props.clientId}); -// -// -// const data = useMemo(() => products.reduce((acc, product) => { -// acc.push({ -// label: product.name, -// value: product.id.toString() -// }); -// return acc; -// }, [] as { label: string, value: string }[]), [products]); -// -// const handleOnChange = (event: string | null) => { -// if (!event) return; -// const product = products.find(product => parseInt(event) == product.id); -// if (!product) return; -// if (isControlled) { -// props.onChange(product); -// return; -// } -// setInternalValue(product); -// } -// useEffect(() => { -// if (isControlled || !intertalValue) return; -// props.onChange(intertalValue); -// }, [intertalValue]); -// const restProps = omit(props, ['clientId']) -// return ( -// {getRestQuantityText()} diff --git a/src/pages/LeadsPage/tabs/ShippingTab/types/ShippingProductData.tsx b/src/pages/LeadsPage/tabs/ShippingTab/types/ShippingProductData.tsx index 1acfea9..5c1944f 100644 --- a/src/pages/LeadsPage/tabs/ShippingTab/types/ShippingProductData.tsx +++ b/src/pages/LeadsPage/tabs/ShippingTab/types/ShippingProductData.tsx @@ -1,13 +1,13 @@ -import { CreateShippingProductSchema, UpdateBoxSchema, UpdateShippingProductSchema } from "../../../../../client"; +import { + CreateShippingProductSchema, + ProductSchema, + UpdateBoxSchema, + UpdateShippingProductSchema, +} from "../../../../../client"; export type ShippingModalForm = { quantity: number; - productId?: number | null; -} - -export type ShippingProductOption = { - value: string; - label: string; + product?: ProductSchema | null; } export type ShippingData = diff --git a/src/pages/LeadsPage/tabs/ShippingTab/utils/getRestProducts.tsx b/src/pages/LeadsPage/tabs/ShippingTab/utils/getRestProducts.tsx index 4088e0b..dc87e00 100644 --- a/src/pages/LeadsPage/tabs/ShippingTab/utils/getRestProducts.tsx +++ b/src/pages/LeadsPage/tabs/ShippingTab/utils/getRestProducts.tsx @@ -1,4 +1,3 @@ -import { ShippingProductOption } from "../types/ShippingProductData.tsx"; import { DealProductSchema, DealSchema, ProductSchema } from "../../../../../client"; type UnaccountedValues = { @@ -61,11 +60,11 @@ const getRestProducts = ({ } }); - const restProductsSelectData: ShippingProductOption[] = []; + const restProductsSelectData: ProductSchema[] = []; restProducts.forEach( - (restProduct, id) => { - restProductsSelectData.push({ value: String(id), label: restProduct.product.name }); + (restProduct) => { + restProductsSelectData.push(restProduct.product); }, );