fix(FE): implement lazy loading select button on project flock index

This commit is contained in:
randy-ar
2026-01-15 16:53:39 +07:00
parent e349b9dfa4
commit 73100aa1ce
@@ -5,7 +5,10 @@ import Button from '@/components/Button';
import FloatingActionsButton from '@/components/FloatingActionsButton'; import FloatingActionsButton from '@/components/FloatingActionsButton';
import CheckboxInput from '@/components/input/CheckboxInput'; import CheckboxInput from '@/components/input/CheckboxInput';
import DebouncedTextInput from '@/components/input/DebouncedTextInput'; import DebouncedTextInput from '@/components/input/DebouncedTextInput';
import SelectInput, { OptionType } from '@/components/input/SelectInput'; import SelectInput, {
OptionType,
useSelect,
} from '@/components/input/SelectInput';
import { useModal } from '@/components/Modal'; import { useModal } from '@/components/Modal';
import ConfirmationModal from '@/components/modal/ConfirmationModal'; import ConfirmationModal from '@/components/modal/ConfirmationModal';
import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes'; import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes';
@@ -59,9 +62,6 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
const selectedRowIds = Object.keys(rowSelection) const selectedRowIds = Object.keys(rowSelection)
.filter((id) => rowSelection[id]) .filter((id) => rowSelection[id])
.map((id) => parseInt(id)); .map((id) => parseInt(id));
const [locationSelectInputValue, setLocationSelectInputValue] = useState('');
const [areaSelectInputValue, setAreaSelectInputValue] = useState('');
const [kandangSelectInputValue, setKandangSelectInputValue] = useState('');
const [selectedArea, setSelectedArea] = useState<OptionType | null>(null); const [selectedArea, setSelectedArea] = useState<OptionType | null>(null);
const [selectedLocation, setSelectedLocation] = useState<OptionType | null>( const [selectedLocation, setSelectedLocation] = useState<OptionType | null>(
null null
@@ -90,55 +90,25 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
{ revalidateOnMount: true } { revalidateOnMount: true }
); );
const areaUrl = `${AreaApi.basePath}?${new URLSearchParams({ // ===== Fetch Data Select =====
search: areaSelectInputValue, const {
limit: '100', options: optionsArea,
}).toString()}`; isLoadingOptions: isLoadingArea,
const { data: areas, isLoading: isLoadingAreas } = useSWR( setInputValue: setAreaSelectInputValue,
areaUrl, loadMore: loadMoreArea,
AreaApi.getAllFetcher } = useSelect(AreaApi.basePath, 'id', 'name');
); const {
options: optionsLocation,
const locationUrl = `${LocationApi.basePath}?${new URLSearchParams({ isLoadingOptions: isLoadingLocation,
search: locationSelectInputValue, setInputValue: setLocationSelectInputValue,
area_id: selectedArea != null ? selectedArea.value.toString() : '', loadMore: loadMoreLocation,
limit: '100', } = useSelect(LocationApi.basePath, 'id', 'name');
}).toString()}`; const {
const { data: locations, isLoading: isLoadingLocations } = useSWR( options: optionsKandang,
locationUrl, isLoadingOptions: isLoadingKandang,
LocationApi.getAllFetcher setInputValue: setKandangSelectInputValue,
); loadMore: loadMoreKandang,
} = useSelect(KandangApi.basePath, 'id', 'name');
const kandangUrl = `${KandangApi.basePath}?${new URLSearchParams({
search: kandangSelectInputValue,
location_id:
selectedLocation != null ? selectedLocation.value.toString() : '',
limit: '100',
}).toString()}`;
const { data: kandangs, isLoading: isLoadingKandang } = useSWR(
kandangUrl,
KandangApi.getAllFetcher
);
// ===== Data to Options Mapping ======
const optionsArea = isResponseSuccess(areas)
? areas?.data.map((area) => ({
value: area.id,
label: area.name,
}))
: [];
const optionsKandang = isResponseSuccess(kandangs)
? kandangs?.data.map((kandang) => ({
value: kandang.id,
label: kandang.name,
}))
: [];
const optionsLocation = isResponseSuccess(locations)
? locations?.data.map((location) => ({
value: location.id,
label: location.name,
}))
: [];
// ====== HANDLER ====== // ====== HANDLER ======
const confirmationModalDeleteClickHandler = async () => { const confirmationModalDeleteClickHandler = async () => {
@@ -385,7 +355,7 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
<SelectInput <SelectInput
label='Area' label='Area'
options={optionsArea} options={optionsArea}
isLoading={isLoadingAreas} isLoading={isLoadingArea}
value={selectedArea} value={selectedArea}
onChange={(val) => { onChange={(val) => {
setSelectedArea(val as OptionType); setSelectedArea(val as OptionType);
@@ -395,12 +365,13 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
); );
}} }}
onInputChange={setAreaSelectInputValue} onInputChange={setAreaSelectInputValue}
onMenuScrollToBottom={loadMoreArea}
isClearable isClearable
/> />
<SelectInput <SelectInput
label='Lokasi' label='Lokasi'
options={optionsLocation} options={optionsLocation}
isLoading={isLoadingLocations} isLoading={isLoadingLocation}
value={selectedLocation} value={selectedLocation}
onChange={(val) => { onChange={(val) => {
setSelectedLocation(val as OptionType); setSelectedLocation(val as OptionType);
@@ -410,6 +381,7 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
); );
}} }}
onInputChange={setLocationSelectInputValue} onInputChange={setLocationSelectInputValue}
onMenuScrollToBottom={loadMoreLocation}
isClearable isClearable
/> />
<SelectInput <SelectInput
@@ -425,6 +397,7 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
); );
}} }}
onInputChange={setKandangSelectInputValue} onInputChange={setKandangSelectInputValue}
onMenuScrollToBottom={loadMoreKandang}
isClearable isClearable
/> />
<DebouncedTextInput <DebouncedTextInput