feat: implement lazy loading in SelectInput component in master data form

This commit is contained in:
ValdiANS
2026-01-14 11:36:57 +07:00
parent 8d7adbbd27
commit 54e05b7150
6 changed files with 115 additions and 180 deletions
@@ -9,7 +9,10 @@ import useSWR from 'swr';
import { Icon } from '@iconify/react';
import Button from '@/components/Button';
import TextInput from '@/components/input/TextInput';
import SelectInput, { OptionType } from '@/components/input/SelectInput';
import SelectInput, {
OptionType,
useSelect,
} from '@/components/input/SelectInput';
import { useModal } from '@/components/Modal';
import ConfirmationModal from '@/components/modal/ConfirmationModal';
import RequirePermission from '@/components/helper/RequirePermission';
@@ -31,6 +34,7 @@ import { UserApi } from '@/services/api/user';
import NumberInput from '@/components/input/NumberInput';
import { useFormikErrorList } from '@/services/hooks/useFormikErrorList';
import AlertErrorList from '@/components/helper/form/FormErrors';
import { User } from '@/types/api/api-general';
interface KandangFormProps {
type?: 'add' | 'edit' | 'detail';
@@ -128,23 +132,12 @@ const KandangForm = ({ type = 'add', initialValues }: KandangFormProps) => {
const { setValues: formikSetValues } = formik;
// location
const [locationSelectInputValue, setLocationSelectInputValue] = useState('');
const locationsUrl = `${LocationApi.basePath}?${new URLSearchParams({
search: locationSelectInputValue ?? '',
}).toString()}`;
const { data: locations, isLoading: isLoadingLocations } = useSWR(
locationsUrl,
LocationApi.getAllFetcher
);
const locationOptions = isResponseSuccess(locations)
? locations?.data.map((location) => ({
value: location.id,
label: location.name,
}))
: [];
const {
setInputValue: setLocationSelectInputValue,
options: locationOptions,
isLoadingOptions: isLoadingLocationOptions,
loadMore: loadMoreLocations,
} = useSelect<Location>(LocationApi.basePath, 'id', 'name');
const locationChangeHandler = (val: OptionType | OptionType[] | null) => {
formik.setFieldTouched('location', true);
@@ -155,23 +148,12 @@ const KandangForm = ({ type = 'add', initialValues }: KandangFormProps) => {
};
// PIC
const [picSelectInputValue, setPicSelectInputValue] = useState('');
const picsUrl = `${UserApi.basePath}?${new URLSearchParams({
search: picSelectInputValue ?? '',
}).toString()}`;
const { data: pics, isLoading: isLoadingPics } = useSWR(
picsUrl,
LocationApi.getAllFetcher
);
const picOptions = isResponseSuccess(pics)
? pics?.data.map((pic) => ({
value: pic.id,
label: pic.name,
}))
: [];
const {
setInputValue: setPicSelectInputValue,
options: picOptions,
isLoadingOptions: isLoadingPicOptions,
loadMore: loadMorePics,
} = useSelect<User>(UserApi.basePath, 'id', 'name');
const picChangeHandler = (val: OptionType | OptionType[] | null) => {
formik.setFieldTouched('pic', true);
@@ -249,7 +231,8 @@ const KandangForm = ({ type = 'add', initialValues }: KandangFormProps) => {
onChange={locationChangeHandler}
options={locationOptions}
onInputChange={setLocationSelectInputValue}
isLoading={isLoadingLocations}
onMenuScrollToBottom={loadMoreLocations}
isLoading={isLoadingLocationOptions}
isError={
formik.touched.locationId && Boolean(formik.errors.locationId)
}
@@ -280,7 +263,8 @@ const KandangForm = ({ type = 'add', initialValues }: KandangFormProps) => {
onChange={picChangeHandler}
options={picOptions}
onInputChange={setPicSelectInputValue}
isLoading={isLoadingPics}
onMenuScrollToBottom={loadMorePics}
isLoading={isLoadingPicOptions}
isError={formik.touched.picId && Boolean(formik.errors.picId)}
errorMessage={formik.errors.picId as string}
isDisabled={type === 'detail'}