feat: enhance product filtering in ProductSelect component

This commit is contained in:
2025-09-05 04:42:00 +03:00
parent b08f921c1c
commit 7a052f7422
2 changed files with 203 additions and 297 deletions

View File

@@ -10,8 +10,10 @@ import getRenderOptions from "./utils/getRenderOptions.tsx";
type RestProps = {
clientId: number;
};
const MAX_PRODUCTS = 200;
type Props = Omit<ObjectSelectProps<ProductSchema>, "data"> & RestProps;
const ProductSelect: FC<Props> = (props: Props) => {
const [searchValue, setSearchValue] = useState("");
const [debounced] = useDebouncedValue(searchValue, 500);
@@ -22,11 +24,22 @@ const ProductSelect: FC<Props> = (props: Props) => {
itemsPerPage: MAX_PRODUCTS,
});
const restProps = omit(props, ["clientId"]);
const optionsFilter: OptionsFilter = ({ options }) => options;
const filterProducts = (searchFilter: string): ProductSchema[] => {
searchFilter = searchFilter.toLowerCase().trim();
if (!searchFilter) return products;
const filteredByName = products.filter((v) => v.name.toLowerCase().includes(searchFilter));
const filteredByBarcodes = products.filter((v) => v.barcodes?.some(barcode => barcode.toLowerCase().includes(searchFilter)));
const filteredByArticle = products.filter((v) => v.article == searchFilter);
const uniqueProducts = new Set([...filteredByName, ...filteredByBarcodes, ...filteredByArticle]);
return Array.from(uniqueProducts).sort((a, b) => a.id - b.id);
};
const optionsFilter: OptionsFilter = ({ search }) => {
return filterProducts(search).map(product => ({ label: product.name, value: product.id.toString() }));
};
const setSearchValueImpl = (value: string) => {
const names = products.map(product => product.name);
if (names.includes(value)) return;
value = value.toLowerCase().trim();
if (!value) return;
if (filterProducts(value)) return;
setSearchValue(value);
};

View File

@@ -10,262 +10,110 @@
import { createFileRoute } from '@tanstack/react-router'
// Import Routes
import { Route as rootRouteImport } from './routes/__root'
import { Route as LeadsDealIdRouteImport } from './routes/leads.$dealId'
import { Route as DealsDealIdRouteImport } from './routes/deals.$dealId'
import { Route as rootRoute } from './routes/__root'
import { Route as LeadsDealIdImport } from './routes/leads.$dealId'
import { Route as DealsDealIdImport } from './routes/deals.$dealId'
const TestLazyRouteImport = createFileRoute('/test')()
const StatisticsLazyRouteImport = createFileRoute('/statistics')()
const Shipping_warehousesLazyRouteImport = createFileRoute(
'/shipping_warehouses',
)()
const ServicesLazyRouteImport = createFileRoute('/services')()
const ResiduesLazyRouteImport = createFileRoute('/residues')()
const ReceiptLazyRouteImport = createFileRoute('/receipt')()
const ProductsLazyRouteImport = createFileRoute('/products')()
const MarketplacesLazyRouteImport = createFileRoute('/marketplaces')()
const LoginLazyRouteImport = createFileRoute('/login')()
const LeadsLazyRouteImport = createFileRoute('/leads')()
const ClientsLazyRouteImport = createFileRoute('/clients')()
const BarcodeLazyRouteImport = createFileRoute('/barcode')()
const AdminLazyRouteImport = createFileRoute('/admin')()
const IndexLazyRouteImport = createFileRoute('/')()
// Create Virtual Routes
const TestLazyImport = createFileRoute('/test')()
const StatisticsLazyImport = createFileRoute('/statistics')()
const ShippingwarehousesLazyImport = createFileRoute('/shipping_warehouses')()
const ServicesLazyImport = createFileRoute('/services')()
const ResiduesLazyImport = createFileRoute('/residues')()
const ReceiptLazyImport = createFileRoute('/receipt')()
const ProductsLazyImport = createFileRoute('/products')()
const MarketplacesLazyImport = createFileRoute('/marketplaces')()
const LoginLazyImport = createFileRoute('/login')()
const LeadsLazyImport = createFileRoute('/leads')()
const ClientsLazyImport = createFileRoute('/clients')()
const BarcodeLazyImport = createFileRoute('/barcode')()
const AdminLazyImport = createFileRoute('/admin')()
const IndexLazyImport = createFileRoute('/')()
// Create/Update Routes
const TestLazyRoute = TestLazyImport.update({
const TestLazyRoute = TestLazyRouteImport.update({
id: '/test',
path: '/test',
getParentRoute: () => rootRoute,
getParentRoute: () => rootRouteImport,
} as any).lazy(() => import('./routes/test.lazy').then((d) => d.Route))
const StatisticsLazyRoute = StatisticsLazyImport.update({
const StatisticsLazyRoute = StatisticsLazyRouteImport.update({
id: '/statistics',
path: '/statistics',
getParentRoute: () => rootRoute,
getParentRoute: () => rootRouteImport,
} as any).lazy(() => import('./routes/statistics.lazy').then((d) => d.Route))
const ShippingwarehousesLazyRoute = ShippingwarehousesLazyImport.update({
const Shipping_warehousesLazyRoute = Shipping_warehousesLazyRouteImport.update({
id: '/shipping_warehouses',
path: '/shipping_warehouses',
getParentRoute: () => rootRoute,
getParentRoute: () => rootRouteImport,
} as any).lazy(() =>
import('./routes/shipping_warehouses.lazy').then((d) => d.Route),
)
const ServicesLazyRoute = ServicesLazyImport.update({
const ServicesLazyRoute = ServicesLazyRouteImport.update({
id: '/services',
path: '/services',
getParentRoute: () => rootRoute,
getParentRoute: () => rootRouteImport,
} as any).lazy(() => import('./routes/services.lazy').then((d) => d.Route))
const ResiduesLazyRoute = ResiduesLazyImport.update({
const ResiduesLazyRoute = ResiduesLazyRouteImport.update({
id: '/residues',
path: '/residues',
getParentRoute: () => rootRoute,
getParentRoute: () => rootRouteImport,
} as any).lazy(() => import('./routes/residues.lazy').then((d) => d.Route))
const ReceiptLazyRoute = ReceiptLazyImport.update({
const ReceiptLazyRoute = ReceiptLazyRouteImport.update({
id: '/receipt',
path: '/receipt',
getParentRoute: () => rootRoute,
getParentRoute: () => rootRouteImport,
} as any).lazy(() => import('./routes/receipt.lazy').then((d) => d.Route))
const ProductsLazyRoute = ProductsLazyImport.update({
const ProductsLazyRoute = ProductsLazyRouteImport.update({
id: '/products',
path: '/products',
getParentRoute: () => rootRoute,
getParentRoute: () => rootRouteImport,
} as any).lazy(() => import('./routes/products.lazy').then((d) => d.Route))
const MarketplacesLazyRoute = MarketplacesLazyImport.update({
const MarketplacesLazyRoute = MarketplacesLazyRouteImport.update({
id: '/marketplaces',
path: '/marketplaces',
getParentRoute: () => rootRoute,
getParentRoute: () => rootRouteImport,
} as any).lazy(() => import('./routes/marketplaces.lazy').then((d) => d.Route))
const LoginLazyRoute = LoginLazyImport.update({
const LoginLazyRoute = LoginLazyRouteImport.update({
id: '/login',
path: '/login',
getParentRoute: () => rootRoute,
getParentRoute: () => rootRouteImport,
} as any).lazy(() => import('./routes/login.lazy').then((d) => d.Route))
const LeadsLazyRoute = LeadsLazyImport.update({
const LeadsLazyRoute = LeadsLazyRouteImport.update({
id: '/leads',
path: '/leads',
getParentRoute: () => rootRoute,
getParentRoute: () => rootRouteImport,
} as any).lazy(() => import('./routes/leads.lazy').then((d) => d.Route))
const ClientsLazyRoute = ClientsLazyImport.update({
const ClientsLazyRoute = ClientsLazyRouteImport.update({
id: '/clients',
path: '/clients',
getParentRoute: () => rootRoute,
getParentRoute: () => rootRouteImport,
} as any).lazy(() => import('./routes/clients.lazy').then((d) => d.Route))
const BarcodeLazyRoute = BarcodeLazyImport.update({
const BarcodeLazyRoute = BarcodeLazyRouteImport.update({
id: '/barcode',
path: '/barcode',
getParentRoute: () => rootRoute,
getParentRoute: () => rootRouteImport,
} as any).lazy(() => import('./routes/barcode.lazy').then((d) => d.Route))
const AdminLazyRoute = AdminLazyImport.update({
const AdminLazyRoute = AdminLazyRouteImport.update({
id: '/admin',
path: '/admin',
getParentRoute: () => rootRoute,
getParentRoute: () => rootRouteImport,
} as any).lazy(() => import('./routes/admin.lazy').then((d) => d.Route))
const IndexLazyRoute = IndexLazyImport.update({
const IndexLazyRoute = IndexLazyRouteImport.update({
id: '/',
path: '/',
getParentRoute: () => rootRoute,
getParentRoute: () => rootRouteImport,
} as any).lazy(() => import('./routes/index.lazy').then((d) => d.Route))
const LeadsDealIdRoute = LeadsDealIdImport.update({
const LeadsDealIdRoute = LeadsDealIdRouteImport.update({
id: '/$dealId',
path: '/$dealId',
getParentRoute: () => LeadsLazyRoute,
} as any)
const DealsDealIdRoute = DealsDealIdImport.update({
const DealsDealIdRoute = DealsDealIdRouteImport.update({
id: '/deals/$dealId',
path: '/deals/$dealId',
getParentRoute: () => rootRoute,
getParentRoute: () => rootRouteImport,
} as any)
// Populate the FileRoutesByPath interface
declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/': {
id: '/'
path: '/'
fullPath: '/'
preLoaderRoute: typeof IndexLazyImport
parentRoute: typeof rootRoute
}
'/admin': {
id: '/admin'
path: '/admin'
fullPath: '/admin'
preLoaderRoute: typeof AdminLazyImport
parentRoute: typeof rootRoute
}
'/barcode': {
id: '/barcode'
path: '/barcode'
fullPath: '/barcode'
preLoaderRoute: typeof BarcodeLazyImport
parentRoute: typeof rootRoute
}
'/clients': {
id: '/clients'
path: '/clients'
fullPath: '/clients'
preLoaderRoute: typeof ClientsLazyImport
parentRoute: typeof rootRoute
}
'/leads': {
id: '/leads'
path: '/leads'
fullPath: '/leads'
preLoaderRoute: typeof LeadsLazyImport
parentRoute: typeof rootRoute
}
'/login': {
id: '/login'
path: '/login'
fullPath: '/login'
preLoaderRoute: typeof LoginLazyImport
parentRoute: typeof rootRoute
}
'/marketplaces': {
id: '/marketplaces'
path: '/marketplaces'
fullPath: '/marketplaces'
preLoaderRoute: typeof MarketplacesLazyImport
parentRoute: typeof rootRoute
}
'/products': {
id: '/products'
path: '/products'
fullPath: '/products'
preLoaderRoute: typeof ProductsLazyImport
parentRoute: typeof rootRoute
}
'/receipt': {
id: '/receipt'
path: '/receipt'
fullPath: '/receipt'
preLoaderRoute: typeof ReceiptLazyImport
parentRoute: typeof rootRoute
}
'/residues': {
id: '/residues'
path: '/residues'
fullPath: '/residues'
preLoaderRoute: typeof ResiduesLazyImport
parentRoute: typeof rootRoute
}
'/services': {
id: '/services'
path: '/services'
fullPath: '/services'
preLoaderRoute: typeof ServicesLazyImport
parentRoute: typeof rootRoute
}
'/shipping_warehouses': {
id: '/shipping_warehouses'
path: '/shipping_warehouses'
fullPath: '/shipping_warehouses'
preLoaderRoute: typeof ShippingwarehousesLazyImport
parentRoute: typeof rootRoute
}
'/statistics': {
id: '/statistics'
path: '/statistics'
fullPath: '/statistics'
preLoaderRoute: typeof StatisticsLazyImport
parentRoute: typeof rootRoute
}
'/test': {
id: '/test'
path: '/test'
fullPath: '/test'
preLoaderRoute: typeof TestLazyImport
parentRoute: typeof rootRoute
}
'/deals/$dealId': {
id: '/deals/$dealId'
path: '/deals/$dealId'
fullPath: '/deals/$dealId'
preLoaderRoute: typeof DealsDealIdImport
parentRoute: typeof rootRoute
}
'/leads/$dealId': {
id: '/leads/$dealId'
path: '/$dealId'
fullPath: '/leads/$dealId'
preLoaderRoute: typeof LeadsDealIdImport
parentRoute: typeof LeadsLazyImport
}
}
}
// Create and export the route tree
interface LeadsLazyRouteChildren {
LeadsDealIdRoute: typeof LeadsDealIdRoute
}
const LeadsLazyRouteChildren: LeadsLazyRouteChildren = {
LeadsDealIdRoute: LeadsDealIdRoute,
}
const LeadsLazyRouteWithChildren = LeadsLazyRoute._addFileChildren(
LeadsLazyRouteChildren,
)
export interface FileRoutesByFullPath {
'/': typeof IndexLazyRoute
'/admin': typeof AdminLazyRoute
@@ -278,13 +126,12 @@ export interface FileRoutesByFullPath {
'/receipt': typeof ReceiptLazyRoute
'/residues': typeof ResiduesLazyRoute
'/services': typeof ServicesLazyRoute
'/shipping_warehouses': typeof ShippingwarehousesLazyRoute
'/shipping_warehouses': typeof Shipping_warehousesLazyRoute
'/statistics': typeof StatisticsLazyRoute
'/test': typeof TestLazyRoute
'/deals/$dealId': typeof DealsDealIdRoute
'/leads/$dealId': typeof LeadsDealIdRoute
}
export interface FileRoutesByTo {
'/': typeof IndexLazyRoute
'/admin': typeof AdminLazyRoute
@@ -297,15 +144,14 @@ export interface FileRoutesByTo {
'/receipt': typeof ReceiptLazyRoute
'/residues': typeof ResiduesLazyRoute
'/services': typeof ServicesLazyRoute
'/shipping_warehouses': typeof ShippingwarehousesLazyRoute
'/shipping_warehouses': typeof Shipping_warehousesLazyRoute
'/statistics': typeof StatisticsLazyRoute
'/test': typeof TestLazyRoute
'/deals/$dealId': typeof DealsDealIdRoute
'/leads/$dealId': typeof LeadsDealIdRoute
}
export interface FileRoutesById {
__root__: typeof rootRoute
__root__: typeof rootRouteImport
'/': typeof IndexLazyRoute
'/admin': typeof AdminLazyRoute
'/barcode': typeof BarcodeLazyRoute
@@ -317,13 +163,12 @@ export interface FileRoutesById {
'/receipt': typeof ReceiptLazyRoute
'/residues': typeof ResiduesLazyRoute
'/services': typeof ServicesLazyRoute
'/shipping_warehouses': typeof ShippingwarehousesLazyRoute
'/shipping_warehouses': typeof Shipping_warehousesLazyRoute
'/statistics': typeof StatisticsLazyRoute
'/test': typeof TestLazyRoute
'/deals/$dealId': typeof DealsDealIdRoute
'/leads/$dealId': typeof LeadsDealIdRoute
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths:
@@ -381,7 +226,6 @@ export interface FileRouteTypes {
| '/leads/$dealId'
fileRoutesById: FileRoutesById
}
export interface RootRouteChildren {
IndexLazyRoute: typeof IndexLazyRoute
AdminLazyRoute: typeof AdminLazyRoute
@@ -394,12 +238,141 @@ export interface RootRouteChildren {
ReceiptLazyRoute: typeof ReceiptLazyRoute
ResiduesLazyRoute: typeof ResiduesLazyRoute
ServicesLazyRoute: typeof ServicesLazyRoute
ShippingwarehousesLazyRoute: typeof ShippingwarehousesLazyRoute
Shipping_warehousesLazyRoute: typeof Shipping_warehousesLazyRoute
StatisticsLazyRoute: typeof StatisticsLazyRoute
TestLazyRoute: typeof TestLazyRoute
DealsDealIdRoute: typeof DealsDealIdRoute
}
declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/test': {
id: '/test'
path: '/test'
fullPath: '/test'
preLoaderRoute: typeof TestLazyRouteImport
parentRoute: typeof rootRouteImport
}
'/statistics': {
id: '/statistics'
path: '/statistics'
fullPath: '/statistics'
preLoaderRoute: typeof StatisticsLazyRouteImport
parentRoute: typeof rootRouteImport
}
'/shipping_warehouses': {
id: '/shipping_warehouses'
path: '/shipping_warehouses'
fullPath: '/shipping_warehouses'
preLoaderRoute: typeof Shipping_warehousesLazyRouteImport
parentRoute: typeof rootRouteImport
}
'/services': {
id: '/services'
path: '/services'
fullPath: '/services'
preLoaderRoute: typeof ServicesLazyRouteImport
parentRoute: typeof rootRouteImport
}
'/residues': {
id: '/residues'
path: '/residues'
fullPath: '/residues'
preLoaderRoute: typeof ResiduesLazyRouteImport
parentRoute: typeof rootRouteImport
}
'/receipt': {
id: '/receipt'
path: '/receipt'
fullPath: '/receipt'
preLoaderRoute: typeof ReceiptLazyRouteImport
parentRoute: typeof rootRouteImport
}
'/products': {
id: '/products'
path: '/products'
fullPath: '/products'
preLoaderRoute: typeof ProductsLazyRouteImport
parentRoute: typeof rootRouteImport
}
'/marketplaces': {
id: '/marketplaces'
path: '/marketplaces'
fullPath: '/marketplaces'
preLoaderRoute: typeof MarketplacesLazyRouteImport
parentRoute: typeof rootRouteImport
}
'/login': {
id: '/login'
path: '/login'
fullPath: '/login'
preLoaderRoute: typeof LoginLazyRouteImport
parentRoute: typeof rootRouteImport
}
'/leads': {
id: '/leads'
path: '/leads'
fullPath: '/leads'
preLoaderRoute: typeof LeadsLazyRouteImport
parentRoute: typeof rootRouteImport
}
'/clients': {
id: '/clients'
path: '/clients'
fullPath: '/clients'
preLoaderRoute: typeof ClientsLazyRouteImport
parentRoute: typeof rootRouteImport
}
'/barcode': {
id: '/barcode'
path: '/barcode'
fullPath: '/barcode'
preLoaderRoute: typeof BarcodeLazyRouteImport
parentRoute: typeof rootRouteImport
}
'/admin': {
id: '/admin'
path: '/admin'
fullPath: '/admin'
preLoaderRoute: typeof AdminLazyRouteImport
parentRoute: typeof rootRouteImport
}
'/': {
id: '/'
path: '/'
fullPath: '/'
preLoaderRoute: typeof IndexLazyRouteImport
parentRoute: typeof rootRouteImport
}
'/leads/$dealId': {
id: '/leads/$dealId'
path: '/$dealId'
fullPath: '/leads/$dealId'
preLoaderRoute: typeof LeadsDealIdRouteImport
parentRoute: typeof LeadsLazyRoute
}
'/deals/$dealId': {
id: '/deals/$dealId'
path: '/deals/$dealId'
fullPath: '/deals/$dealId'
preLoaderRoute: typeof DealsDealIdRouteImport
parentRoute: typeof rootRouteImport
}
}
}
interface LeadsLazyRouteChildren {
LeadsDealIdRoute: typeof LeadsDealIdRoute
}
const LeadsLazyRouteChildren: LeadsLazyRouteChildren = {
LeadsDealIdRoute: LeadsDealIdRoute,
}
const LeadsLazyRouteWithChildren = LeadsLazyRoute._addFileChildren(
LeadsLazyRouteChildren,
)
const rootRouteChildren: RootRouteChildren = {
IndexLazyRoute: IndexLazyRoute,
AdminLazyRoute: AdminLazyRoute,
@@ -412,91 +385,11 @@ const rootRouteChildren: RootRouteChildren = {
ReceiptLazyRoute: ReceiptLazyRoute,
ResiduesLazyRoute: ResiduesLazyRoute,
ServicesLazyRoute: ServicesLazyRoute,
ShippingwarehousesLazyRoute: ShippingwarehousesLazyRoute,
Shipping_warehousesLazyRoute: Shipping_warehousesLazyRoute,
StatisticsLazyRoute: StatisticsLazyRoute,
TestLazyRoute: TestLazyRoute,
DealsDealIdRoute: DealsDealIdRoute,
}
export const routeTree = rootRoute
export const routeTree = rootRouteImport
._addFileChildren(rootRouteChildren)
._addFileTypes<FileRouteTypes>()
/* ROUTE_MANIFEST_START
{
"routes": {
"__root__": {
"filePath": "__root.tsx",
"children": [
"/",
"/admin",
"/barcode",
"/clients",
"/leads",
"/login",
"/marketplaces",
"/products",
"/receipt",
"/residues",
"/services",
"/shipping_warehouses",
"/statistics",
"/test",
"/deals/$dealId"
]
},
"/": {
"filePath": "index.lazy.tsx"
},
"/admin": {
"filePath": "admin.lazy.tsx"
},
"/barcode": {
"filePath": "barcode.lazy.tsx"
},
"/clients": {
"filePath": "clients.lazy.tsx"
},
"/leads": {
"filePath": "leads.lazy.tsx",
"children": [
"/leads/$dealId"
]
},
"/login": {
"filePath": "login.lazy.tsx"
},
"/marketplaces": {
"filePath": "marketplaces.lazy.tsx"
},
"/products": {
"filePath": "products.lazy.tsx"
},
"/receipt": {
"filePath": "receipt.lazy.tsx"
},
"/residues": {
"filePath": "residues.lazy.tsx"
},
"/services": {
"filePath": "services.lazy.tsx"
},
"/shipping_warehouses": {
"filePath": "shipping_warehouses.lazy.tsx"
},
"/statistics": {
"filePath": "statistics.lazy.tsx"
},
"/test": {
"filePath": "test.lazy.tsx"
},
"/deals/$dealId": {
"filePath": "deals.$dealId.tsx"
},
"/leads/$dealId": {
"filePath": "leads.$dealId.tsx",
"parent": "/leads"
}
}
}
ROUTE_MANIFEST_END */