From 3827204f134fa77e9c3dd846532ab8ec3f86d2cb Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Thu, 15 Jan 2026 09:47:11 +0700 Subject: [PATCH 1/2] chore: make basePath nullable --- src/components/input/SelectInput.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/input/SelectInput.tsx b/src/components/input/SelectInput.tsx index 8d5b9170..9cc9fda5 100644 --- a/src/components/input/SelectInput.tsx +++ b/src/components/input/SelectInput.tsx @@ -325,7 +325,7 @@ const SelectInput = (props: SelectInputProps) => { }; const useSelect = ( - basePath: string, + basePath: string | null, valueKey: keyof T | string, labelKey: keyof T | string, searchKey: string = 'search', @@ -354,7 +354,7 @@ const useSelect = ( [limitKey]: String(limit), }).toString(); - return `${basePath}?${qs}`; + return basePath ? `${basePath}?${qs}` : null; }; const { From c75563491f904105340fce4113de0180797ccab2 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Thu, 15 Jan 2026 09:48:02 +0700 Subject: [PATCH 2/2] feat: implement lazy loading in SelectInput --- .../pages/closing/ClosingsTable.tsx | 2 + .../form/InventoryAdjustmentForm.tsx | 112 +++++++----------- .../inventory/movement/form/MovementForm.tsx | 53 ++++----- .../report/DailyMarketingReportContent.tsx | 8 ++ .../report/expense/ReportExpenseTable.tsx | 86 ++++++++++---- .../report/finance/tab/CustomerPaymentTab.tsx | 4 + .../report/finance/tab/DebtSupplierTab.tsx | 15 ++- .../ProductionResultContent.tsx | 8 ++ .../report/sale/tab/HppPerKandangTab.tsx | 34 ++++-- 9 files changed, 182 insertions(+), 140 deletions(-) diff --git a/src/components/pages/closing/ClosingsTable.tsx b/src/components/pages/closing/ClosingsTable.tsx index 0cacb549..ec334104 100644 --- a/src/components/pages/closing/ClosingsTable.tsx +++ b/src/components/pages/closing/ClosingsTable.tsx @@ -163,6 +163,7 @@ const ClosingsTable = () => { setInputValue: setLocationInputValue, options: locationOptions, isLoadingOptions: isLoadingLocationOptions, + loadMore: loadMoreLocations, } = useSelect(LocationApi.basePath, 'id', 'name'); const [selectedLocation, setSelectedLocation] = useState( @@ -228,6 +229,7 @@ const ClosingsTable = () => { value={selectedLocation} onChange={locationChangeHandler} onInputChange={setLocationInputValue} + onMenuScrollToBottom={loadMoreLocations} isClearable className={{ wrapper: 'col-span-12 sm:col-span-6', diff --git a/src/components/pages/inventory/adjustment/form/InventoryAdjustmentForm.tsx b/src/components/pages/inventory/adjustment/form/InventoryAdjustmentForm.tsx index c1fc25da..3bae393d 100644 --- a/src/components/pages/inventory/adjustment/form/InventoryAdjustmentForm.tsx +++ b/src/components/pages/inventory/adjustment/form/InventoryAdjustmentForm.tsx @@ -1,6 +1,6 @@ 'use client'; -import { isResponseError, isResponseSuccess } from '@/lib/api-helper'; +import { isResponseError } from '@/lib/api-helper'; import { InventoryAdjustmentApi } from '@/services/api/inventory'; import { CreateInventoryAdjustmentPayload, @@ -22,12 +22,18 @@ import { } from '@/services/api/master-data'; import Button from '@/components/Button'; import { Icon } from '@iconify/react'; -import SelectInput, { OptionType } from '@/components/input/SelectInput'; +import SelectInput, { + OptionType, + useSelect, +} from '@/components/input/SelectInput'; import TextInput from '@/components/input/TextInput'; import { RadioGroup } from '@/components/input/RadioInput'; import TextArea from '@/components/input/TextArea'; import { useFormikErrorList } from '@/services/hooks/useFormikErrorList'; import AlertErrorList from '@/components/helper/form/FormErrors'; +import { ProductCategory } from '@/types/api/master-data/product-category'; +import { Product } from '@/types/api/master-data/product'; +import { Warehouse } from '@/types/api/master-data/warehouse'; interface InventoryAdjustmentFormProps { type?: 'add' | 'edit' | 'detail'; @@ -44,10 +50,7 @@ const InventoryAdjustmentForm = ({ InventoryAdjustmentFormErrorMessage, setInventoryAdjustmentFormErrorMessage, ] = useState(''); - const [selectedProductCategories, setSelectedProductCategories] = - useState(''); const [disabledProduct, setDisabledProduct] = useState(true); - const [optionsProduct, setOptionsProduct] = useState([]); const [quantityLabel, setQuantityLabel] = useState('Tambah Stok'); // Submit Handler @@ -108,45 +111,30 @@ const InventoryAdjustmentForm = ({ }); // Fetch Data - const productCategoriesUrl = `${ - ProductCategoryApi.basePath - }?${new URLSearchParams({ - search: '', - }).toString()}`; - const { data: productCategories, isLoading: isLoadingProductCategories } = - useSWR(productCategoriesUrl, ProductCategoryApi.getAllFetcher); + const { + setInputValue: setProductCategoryInputValue, + options: productCategoryOptions, + isLoadingOptions: isLoadingProductCategoryOptions, + loadMore: loadMoreProductCategories, + } = useSelect(ProductCategoryApi.basePath, 'id', 'name'); - const productUrl = `${ProductApi.basePath}?${new URLSearchParams({ - search: '', - product_category_id: selectedProductCategories, - }).toString()}`; - const { data: products, isLoading: isLoadingProducts } = useSWR( - productUrl, - ProductApi.getAllFetcher - ); + const { + setInputValue: setProductInputValue, + options: productOptions, + isLoadingOptions: isLoadingProductOptions, + loadMore: loadMoreProducts, + } = useSelect(ProductApi.basePath, 'id', 'name', 'search', { + product_category_id: formik.values.product_category_id + ? String(formik.values.product_category_id) + : '', + }); - const warehouseUrl = `${WarehouseApi.basePath}?${new URLSearchParams({ - search: '', - limit: '100', - }).toString()}`; - const { data: warehouses, isLoading: isLoadingWarehouses } = useSWR( - warehouseUrl, - WarehouseApi.getAllFetcher - ); - - // Map Data to Options - const optionsProductCategory = isResponseSuccess(productCategories) - ? productCategories?.data.map((productCategory) => ({ - value: productCategory.id, - label: productCategory.name, - })) - : []; - const optionsWarehouse = isResponseSuccess(warehouses) - ? warehouses?.data.map((warehouse) => ({ - value: warehouse.id, - label: warehouse.name, - })) - : []; + const { + setInputValue: setWarehouseInputValue, + options: warehouseOptions, + isLoadingOptions: isLoadingWarehouseOptions, + loadMore: loadMoreWarehouses, + } = useSelect(WarehouseApi.basePath, 'id', 'name'); // Options Handler const productCategoryChangeHandler = ( @@ -157,7 +145,6 @@ const InventoryAdjustmentForm = ({ formik.setFieldValue('product_category', val); - setSelectedProductCategories((val as OptionType)?.value as string); const disabled = (val as OptionType)?.value == null; setDisabledProduct(disabled); formik.setFieldValue('product_id', 0); @@ -193,9 +180,6 @@ const InventoryAdjustmentForm = ({ // Effect useEffect(() => { if (initialValues?.product_warehouse?.product?.id) { - setSelectedProductCategories( - String(initialValues.product_warehouse.product.id) - ); setDisabledProduct(false); formik.setFieldValue( 'product_id', @@ -219,25 +203,10 @@ const InventoryAdjustmentForm = ({ ); formik.setFieldValue('note', initialValues.note); } - }, [ - formik, - initialValues, - setQuantityLabel, - setDisabledProduct, - setSelectedProductCategories, - ]); + }, [formik, initialValues, setQuantityLabel, setDisabledProduct]); useEffect(() => { formikSetValues(formikInitialValues as InventoryAdjustmentFormValues); }, [formikSetValues, formikInitialValues]); - useEffect(() => { - if (isResponseSuccess(products)) { - const options = products.data.map((p) => ({ - value: p.id, - label: p.name, - })); - setOptionsProduct(options); - } - }, [products]); // Utils Function const formatNumber = (value: string) => { @@ -282,9 +251,10 @@ const InventoryAdjustmentForm = ({ label='Kategori Produk' value={formik.values.product_category as OptionType} onChange={productCategoryChangeHandler} - onInputChange={setSelectedProductCategories} - options={optionsProductCategory} - isLoading={isLoadingProductCategories} + onInputChange={setProductCategoryInputValue} + options={productCategoryOptions} + onMenuScrollToBottom={loadMoreProductCategories} + isLoading={isLoadingProductCategoryOptions} isError={ formik.touched.product_category && Boolean(formik.errors.product_category) @@ -300,8 +270,10 @@ const InventoryAdjustmentForm = ({ label='Produk' value={formik.values.product as OptionType} onChange={productChangeHandler} - options={optionsProduct} - isLoading={isLoadingProducts} + onInputChange={setProductInputValue} + options={productOptions} + onMenuScrollToBottom={loadMoreProducts} + isLoading={isLoadingProductOptions} isError={formik.touched.product && Boolean(formik.errors.product)} errorMessage={formik.errors.product as string} isDisabled={type === 'detail' || disabledProduct} @@ -314,8 +286,10 @@ const InventoryAdjustmentForm = ({ label='Warehouse' value={formik.values.warehouse as OptionType} onChange={warehouseChangeHandler} - options={optionsWarehouse} - isLoading={isLoadingWarehouses} + onInputChange={setWarehouseInputValue} + options={warehouseOptions} + onMenuScrollToBottom={loadMoreWarehouses} + isLoading={isLoadingWarehouseOptions} isError={ formik.touched.warehouse && Boolean(formik.errors.warehouse) } diff --git a/src/components/pages/inventory/movement/form/MovementForm.tsx b/src/components/pages/inventory/movement/form/MovementForm.tsx index d9aef6cd..40e08c5d 100644 --- a/src/components/pages/inventory/movement/form/MovementForm.tsx +++ b/src/components/pages/inventory/movement/form/MovementForm.tsx @@ -38,6 +38,8 @@ import Card from '@/components/Card'; import { S3_PUBLIC_BASE_URL } from '@/config/constant'; import { getUniqueFormikErrors } from '@/lib/formik-helper'; import AlertErrorList from '@/components/helper/form/FormErrors'; +import { Warehouse } from '@/types/api/master-data/warehouse'; +import { ProductWarehouse } from '@/types/api/inventory/product-warehouse'; interface MovementFormProps { type?: 'add' | 'edit' | 'detail'; @@ -49,10 +51,6 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { // ===== STATE MANAGEMENT ===== const [movementFormErrorMessage, setMovementFormErrorMessage] = useState(''); - const [ - productWarehouseSelectInputValue, - setProductWarehouseSelectInputValue, - ] = useState(''); const [selectedProducts, setSelectedProducts] = useState([]); const [selectedDeliveries, setSelectedDeliveries] = useState([]); const [formErrorList, setFormErrorList] = useState([]); @@ -93,10 +91,11 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { // ===== USE SELECT HOOKS ===== const { - inputValue: warehouseSelectInputValue, setInputValue: setWarehouseSelectInputValue, isLoadingOptions: isLoadingWarehouses, - } = useSelect(WarehouseApi.basePath, 'id', 'name', 'search'); + loadMore: loadMoreWarehouses, + rawData: warehouses, + } = useSelect(WarehouseApi.basePath, 'id', 'name', 'search'); // ===== SELECT INPUT DATA ===== const { @@ -107,12 +106,6 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { category: 'BOP', }); - const warehousesUrl = `${WarehouseApi.basePath}?${new URLSearchParams({ search: warehouseSelectInputValue }).toString()}`; - const { data: warehouses } = useSWR( - warehousesUrl, - WarehouseApi.getAllFetcher - ); - // ===== DATA PROCESSING ===== const warehouseStockMap = useMemo(() => { if (!isResponseSuccess(allProductWarehouses)) return new Map(); @@ -269,25 +262,22 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { }); // ===== PRODUCT WAREHOUSE FETCHING (after form initialization) ===== - const getProductWarehousesUrl = useCallback(() => { - const productWarehouseParams = new URLSearchParams({ - search: productWarehouseSelectInputValue, - }); - if (formik.values.source_warehouse_id) { - productWarehouseParams.append( - 'warehouse_id', - formik.values.source_warehouse_id.toString() - ); + const { + setInputValue: setProductWarehouseSelectInputValue, + isLoadingOptions: isLoadingProductWarehouses, + loadMore: loadMoreProductWarehouses, + rawData: productWarehouses, + } = useSelect( + formik.values.source_warehouse_id ? ProductWarehouseApi.basePath : null, + 'id', + 'name', + 'search', + { + warehouse_id: formik.values.source_warehouse_id + ? formik.values.source_warehouse_id.toString() + : '', } - return `${ProductWarehouseApi.basePath}?${productWarehouseParams.toString()}`; - }, [formik.values.source_warehouse_id, productWarehouseSelectInputValue]); - - const productWarehousesUrl = getProductWarehousesUrl(); - const { data: productWarehouses, isLoading: isLoadingProductWarehouses } = - useSWR( - formik.values.source_warehouse_id ? productWarehousesUrl : null, - ProductWarehouseApi.getAllFetcher - ); + ); const productWarehouseOptions = isResponseSuccess(productWarehouses) ? productWarehouses?.data.map((pw) => ({ @@ -1006,6 +996,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { }} options={warehouseOptions} onInputChange={setWarehouseSelectInputValue} + onMenuScrollToBottom={loadMoreWarehouses} isLoading={isLoadingWarehouses} isError={ formik.touched.source_warehouse_id && @@ -1104,6 +1095,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { options={warehouseOptions} onInputChange={setWarehouseSelectInputValue} isLoading={isLoadingWarehouses} + onMenuScrollToBottom={loadMoreWarehouses} isError={ formik.touched.destination_warehouse_id && Boolean(formik.errors.destination_warehouse_id) @@ -1263,6 +1255,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => { }} options={productWarehouseOptions} onInputChange={setProductWarehouseSelectInputValue} + onMenuScrollToBottom={loadMoreProductWarehouses} isLoading={isLoadingProductWarehouses} isDisabled={ type === 'detail' || diff --git a/src/components/pages/report/DailyMarketingReportContent.tsx b/src/components/pages/report/DailyMarketingReportContent.tsx index d17df01e..01c360d0 100644 --- a/src/components/pages/report/DailyMarketingReportContent.tsx +++ b/src/components/pages/report/DailyMarketingReportContent.tsx @@ -87,6 +87,7 @@ const DailyMarketingReportContent = () => { setInputValue: setAreaInputValue, options: areaOptions, isLoadingOptions: isLoadingAreaOptions, + loadMore: loadMoreAreas, } = useSelect(AreaApi.basePath, 'id', 'name'); const areaChangeHandler = (val: OptionType | OptionType[] | null) => { @@ -101,6 +102,7 @@ const DailyMarketingReportContent = () => { setInputValue: setLocationInputValue, options: locationOptions, isLoadingOptions: isLoadingLocationOptions, + loadMore: loadMoreLocations, } = useSelect(LocationApi.basePath, 'id', 'name'); const locationChangeHandler = (val: OptionType | OptionType[] | null) => { @@ -118,6 +120,7 @@ const DailyMarketingReportContent = () => { setInputValue: setWarehouseInputValue, options: warehouseOptions, isLoadingOptions: isLoadingWarehouseOptions, + loadMore: loadMoreWarehouses, } = useSelect(WarehouseApi.basePath, 'id', 'name'); const warehouseChangeHandler = (val: OptionType | OptionType[] | null) => { @@ -135,6 +138,7 @@ const DailyMarketingReportContent = () => { setInputValue: setCustomerInputValue, options: customerOptions, isLoadingOptions: isLoadingCustomerOptions, + loadMore: loadMoreCustomers, } = useSelect(CustomerApi.basePath, 'id', 'name'); const customerChangeHandler = (val: OptionType | OptionType[] | null) => { @@ -298,6 +302,7 @@ const DailyMarketingReportContent = () => { value={selectedArea} onChange={areaChangeHandler} onInputChange={setAreaInputValue} + onMenuScrollToBottom={loadMoreAreas} isClearable className={{ wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4', @@ -312,6 +317,7 @@ const DailyMarketingReportContent = () => { value={selectedLocation} onChange={locationChangeHandler} onInputChange={setLocationInputValue} + onMenuScrollToBottom={loadMoreLocations} isClearable className={{ wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4', @@ -326,6 +332,7 @@ const DailyMarketingReportContent = () => { value={selectedWarehouse} onChange={warehouseChangeHandler} onInputChange={setWarehouseInputValue} + onMenuScrollToBottom={loadMoreWarehouses} isClearable className={{ wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4', @@ -340,6 +347,7 @@ const DailyMarketingReportContent = () => { value={selectedCustomer} onChange={customerChangeHandler} onInputChange={setCustomerInputValue} + onMenuScrollToBottom={loadMoreCustomers} isClearable className={{ wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4', diff --git a/src/components/pages/report/expense/ReportExpenseTable.tsx b/src/components/pages/report/expense/ReportExpenseTable.tsx index c34072a2..c809c153 100644 --- a/src/components/pages/report/expense/ReportExpenseTable.tsx +++ b/src/components/pages/report/expense/ReportExpenseTable.tsx @@ -26,6 +26,15 @@ import MenuItem from '@/components/menu/MenuItem'; import * as XLSX from 'xlsx'; import { generateReportExpensePDF } from './pdf/ReportExpenseExport'; import toast from 'react-hot-toast'; +import { + KandangApi, + LocationApi, + NonstockApi, + SupplierApi, +} from '@/services/api/master-data'; +import { Supplier } from '@/types/api/master-data/supplier'; +import { Kandang } from '@/types/api/master-data/kandang'; +import { Nonstock } from '@/types/api/master-data/nonstock'; const ReportExpenseTable = () => { // ===== STATE MANAGEMENT ===== @@ -64,16 +73,33 @@ const ReportExpenseTable = () => { }); // ===== SELECT OPTIONS ===== - const { options: optionsLocation, isLoadingOptions: isLoadingLocation } = - useSelect(`/master-data/locations`, 'id', 'name'); - const { options: optionsSupplier, isLoadingOptions: isLoadingSupplier } = - useSelect(`/master-data/suppliers`, 'id', 'name'); - const { options: optionsKandang, isLoadingOptions: isLoadingKandang } = - useSelect(`/master-data/kandangs`, 'id', 'name', '', { - location_id: filterState.location_id, - }); - const { options: optionsNonstock, isLoadingOptions: isLoadingNonstock } = - useSelect(`/master-data/nonstocks`, 'id', 'name'); + const { + setInputValue: setLocationInputValue, + options: locationOptions, + isLoadingOptions: isLoadingLocationOptions, + loadMore: loadMoreLocations, + } = useSelect(LocationApi.basePath, 'id', 'name'); + + const { + setInputValue: setSupplierInputValue, + options: supplierOptions, + isLoadingOptions: isLoadingSupplierOptions, + loadMore: loadMoreSuppliers, + } = useSelect(SupplierApi.basePath, 'id', 'name'); + + const { + setInputValue: setKandangInputValue, + options: kandangOptions, + isLoadingOptions: isLoadingKandangOptions, + loadMore: loadMoreKandangs, + } = useSelect(KandangApi.basePath, 'id', 'name'); + + const { + setInputValue: setNonstockInputValue, + options: nonstockOptions, + isLoadingOptions: isLoadingNonstockOptions, + loadMore: loadMoreNonstocks, + } = useSelect(NonstockApi.basePath, 'id', 'name'); const categoryOptions = useMemo( () => [ @@ -86,31 +112,31 @@ const ReportExpenseTable = () => { // Mendapatkan value option select dari filter state const selectedLocation = useMemo( () => - optionsLocation.find( + locationOptions.find( (opt) => String(opt.value) === filterState.location_id ) || null, - [optionsLocation, filterState.location_id] + [locationOptions, filterState.location_id] ); const selectedSupplier = useMemo( () => - optionsSupplier.find( + supplierOptions.find( (opt) => String(opt.value) === filterState.supplier_id ) || null, - [optionsSupplier, filterState.supplier_id] + [supplierOptions, filterState.supplier_id] ); const selectedKandang = useMemo( () => - optionsKandang.find( + kandangOptions.find( (opt) => String(opt.value) === filterState.kandang_id ) || null, - [optionsKandang, filterState.kandang_id] + [kandangOptions, filterState.kandang_id] ); const selectedNonstock = useMemo( () => - optionsNonstock.find( + nonstockOptions.find( (opt) => String(opt.value) === filterState.nonstock_id ) || null, - [optionsNonstock, filterState.nonstock_id] + [nonstockOptions, filterState.nonstock_id] ); const selectedCategory = useMemo( () => @@ -756,38 +782,46 @@ const ReportExpenseTable = () => { { const { options: customerOptions, + setInputValue: setCustomerInputValue, isLoadingOptions: isLoadingCustomers, loadMore: loadMoreCustomers, hasMore: hasMoreCustomers, @@ -62,6 +63,7 @@ const CustomerPaymentTab = () => { const { options: salesOptions, + setInputValue: setSalesInputValue, isLoadingOptions: isLoadingSales, loadMore: loadMoreSales, hasMore: hasMoreSales, @@ -654,6 +656,7 @@ const CustomerPaymentTab = () => { Array.isArray(val) ? val : val ? [val] : [] ); }} + onInputChange={setCustomerInputValue} isLoading={isLoadingCustomers} isClearable onMenuScrollToBottom={loadMoreCustomers} @@ -670,6 +673,7 @@ const CustomerPaymentTab = () => { onChange={(val) => { setFilterSales(Array.isArray(val) ? val : val ? [val] : []); }} + onInputChange={setSalesInputValue} isLoading={isLoadingSales} isClearable onMenuScrollToBottom={loadMoreSales} diff --git a/src/components/pages/report/finance/tab/DebtSupplierTab.tsx b/src/components/pages/report/finance/tab/DebtSupplierTab.tsx index 2214ecd6..a2607e2b 100644 --- a/src/components/pages/report/finance/tab/DebtSupplierTab.tsx +++ b/src/components/pages/report/finance/tab/DebtSupplierTab.tsx @@ -33,6 +33,7 @@ import { } from '@/components/pages/report/finance/filter/DebtSupplierFilter'; import { getFilledFormikValuesCount } from '@/lib/formik-helper'; import ButtonFilter from '@/components/helper/ButtonFilter'; +import { Supplier } from '@/types/api/master-data/supplier'; const DebtSupplierTab = () => { // ===== STATE MANAGEMENT ===== @@ -51,10 +52,12 @@ const DebtSupplierTab = () => { const filterModal = useModal(); - const { options: supplierOptions, isLoadingOptions: isLoadingSuppliers } = - useSelect(SupplierApi.basePath, 'id', 'name', '', { - limit: 'limit', - }); + const { + setInputValue: setSupplierInputValue, + options: supplierOptions, + isLoadingOptions: isLoadingSupplierOptions, + loadMore: loadMoreSuppliers, + } = useSelect(SupplierApi.basePath, 'id', 'name'); const dataTypeOptions = useMemo( () => [ @@ -610,7 +613,9 @@ const DebtSupplierTab = () => { Array.isArray(val) ? val : val ? [val] : null ); }} - isLoading={isLoadingSuppliers} + onInputChange={setSupplierInputValue} + onMenuScrollToBottom={loadMoreSuppliers} + isLoading={isLoadingSupplierOptions} isClearable className={{ wrapper: 'w-full' }} isError={ diff --git a/src/components/pages/report/production-result/ProductionResultContent.tsx b/src/components/pages/report/production-result/ProductionResultContent.tsx index ae6f744b..7820ff53 100644 --- a/src/components/pages/report/production-result/ProductionResultContent.tsx +++ b/src/components/pages/report/production-result/ProductionResultContent.tsx @@ -62,6 +62,7 @@ const ProductionResultContent = () => { setInputValue: setAreaInputValue, options: areaOptions, isLoadingOptions: isLoadingAreaOptions, + loadMore: loadMoreAreas, } = useSelect(AreaApi.basePath, 'id', 'name'); const areaChangeHandler = (val: OptionType | OptionType[] | null) => { @@ -78,6 +79,7 @@ const ProductionResultContent = () => { setInputValue: setLocationInputValue, options: locationOptions, isLoadingOptions: isLoadingLocationOptions, + loadMore: loadMoreLocations, } = useSelect(LocationApi.basePath, 'id', 'name', 'search', { area_id: selectedArea ? ((selectedArea as OptionType).value as string) : '', }); @@ -94,6 +96,7 @@ const ProductionResultContent = () => { setInputValue: setProjectFlockInputValue, options: projectFlockOptions, isLoadingOptions: isLoadingProjectFlockOptions, + loadMore: loadMoreProjectFlocks, } = useSelect( ProjectFlockApi.basePath, 'id', @@ -120,6 +123,7 @@ const ProductionResultContent = () => { setInputValue: setProjectFlockKandangInputValue, options: projectFlockKandangOptions, isLoadingOptions: isLoadingProjectFlockKandangOptions, + loadMore: loadMoreProjectFlockKandangs, } = useSelect( ProjectFlockKandangApi.basePath, 'id', @@ -235,6 +239,7 @@ const ProductionResultContent = () => { value={selectedArea} onChange={areaChangeHandler} onInputChange={setAreaInputValue} + onMenuScrollToBottom={loadMoreAreas} isClearable className={{ wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4', @@ -251,6 +256,7 @@ const ProductionResultContent = () => { value={selectedLocation} onChange={locationChangeHandler} onInputChange={setLocationInputValue} + onMenuScrollToBottom={loadMoreLocations} isClearable isDisabled={!selectedArea} className={{ @@ -270,6 +276,7 @@ const ProductionResultContent = () => { value={selectedProjectFlock} onChange={projectFlockChangeHandler} onInputChange={setProjectFlockInputValue} + onMenuScrollToBottom={loadMoreProjectFlocks} isClearable isDisabled={!selectedArea || !selectedLocation} className={{ @@ -289,6 +296,7 @@ const ProductionResultContent = () => { value={selectedProjectFlockKandang} onChange={projectFlockKandangChangeHandler} onInputChange={setProjectFlockKandangInputValue} + onMenuScrollToBottom={loadMoreProjectFlockKandangs} isClearable isDisabled={!selectedProjectFlock} className={{ diff --git a/src/components/pages/report/sale/tab/HppPerKandangTab.tsx b/src/components/pages/report/sale/tab/HppPerKandangTab.tsx index 7d6f0951..eda88d8c 100644 --- a/src/components/pages/report/sale/tab/HppPerKandangTab.tsx +++ b/src/components/pages/report/sale/tab/HppPerKandangTab.tsx @@ -58,18 +58,26 @@ const HppPerKandangTab = () => { }, }); - const { options: areaOptions, isLoadingOptions: isLoadingAreas } = useSelect( - AreaApi.basePath, - 'id', - 'name', - 'search' - ); + const { + setInputValue: setAreaInputValue, + options: areaOptions, + isLoadingOptions: isLoadingAreas, + loadMore: loadMoreAreas, + } = useSelect(AreaApi.basePath, 'id', 'name', 'search'); - const { options: locationOptions, isLoadingOptions: isLoadingLocations } = - useSelect(LocationApi.basePath, 'id', 'name', 'search'); + const { + setInputValue: setLocationInputValue, + options: locationOptions, + isLoadingOptions: isLoadingLocations, + loadMore: loadMoreLocations, + } = useSelect(LocationApi.basePath, 'id', 'name', 'search'); - const { options: kandangOptions, isLoadingOptions: isLoadingKandangs } = - useSelect(KandangApi.basePath, 'id', 'name', 'search'); + const { + setInputValue: setKandangInputValue, + options: kandangOptions, + isLoadingOptions: isLoadingKandangs, + loadMore: loadMoreKandangs, + } = useSelect(KandangApi.basePath, 'id', 'name', 'search'); const showUnrecordedOptions: OptionType[] = [ { value: 'false', label: 'Sembunyikan' }, @@ -810,6 +818,8 @@ const HppPerKandangTab = () => { .includes(String(opt.value)) )} onChange={areaChangeHandler} + onInputChange={setAreaInputValue} + onMenuScrollToBottom={loadMoreAreas} isLoading={isLoadingAreas} isClearable /> @@ -824,6 +834,8 @@ const HppPerKandangTab = () => { .includes(String(opt.value)) )} onChange={locationChangeHandler} + onInputChange={setLocationInputValue} + onMenuScrollToBottom={loadMoreLocations} isLoading={isLoadingLocations} isClearable /> @@ -838,6 +850,8 @@ const HppPerKandangTab = () => { .includes(String(opt.value)) )} onChange={kandangChangeHandler} + onInputChange={setKandangInputValue} + onMenuScrollToBottom={loadMoreKandangs} isLoading={isLoadingKandangs} isClearable />