From c385c42c8f17d71dc0e1e411e0e1c86607394e71 Mon Sep 17 00:00:00 2001 From: rstubryan Date: Tue, 30 Dec 2025 10:17:46 +0700 Subject: [PATCH] feat(FE-316): Support multi-select filters in UniformityTable --- .../pages/uniformity/UniformityTable.tsx | 77 +++++++++++-------- src/services/api/uniformity.ts | 14 ++-- 2 files changed, 52 insertions(+), 39 deletions(-) diff --git a/src/components/pages/uniformity/UniformityTable.tsx b/src/components/pages/uniformity/UniformityTable.tsx index 2b23c009..205d6966 100644 --- a/src/components/pages/uniformity/UniformityTable.tsx +++ b/src/components/pages/uniformity/UniformityTable.tsx @@ -185,10 +185,11 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => { const filterModal = useModal(); // ===== FILTER STATE ===== - const [filterLocation, setFilterLocation] = useState(null); - const [filterProjectFlock, setFilterProjectFlock] = - useState(null); - const [filterKandang, setFilterKandang] = useState(null); + const [filterLocation, setFilterLocation] = useState([]); + const [filterProjectFlock, setFilterProjectFlock] = useState( + [] + ); + const [filterKandang, setFilterKandang] = useState([]); const [filterStartDate, setFilterStartDate] = useState(''); const [filterEndDate, setFilterEndDate] = useState(''); const [projectFlockSearchValue, setProjectFlockSearchValue] = useState(''); @@ -205,8 +206,9 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => { search: projectFlockSearchValue || '', limit: '100', }); - if (filterLocation) { - params.append('location_id', filterLocation.value.toString()); + if (filterLocation.length > 0) { + const locationIds = filterLocation.map((loc) => loc.value).join(','); + params.append('location_id', locationIds); } return `${ProjectFlockApi.basePath}?${params.toString()}`; }, [projectFlockSearchValue, filterLocation]); @@ -243,20 +245,21 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => { const filterKandangOptions = useMemo(() => { let options: OptionType[] = []; - if (filterProjectFlock && filterProjectFlocksDataList) { - const selectedProjectFlockData = filterProjectFlocksDataList.find( - (pf) => pf.id === filterProjectFlock.value - ); + if (filterProjectFlock.length > 0 && filterProjectFlocksDataList) { + const selectedProjectFlockIds = filterProjectFlock.map((pf) => pf.value); - if (selectedProjectFlockData?.kandangs) { - const kandangOpts = selectedProjectFlockData.kandangs.map( - (kandang: Kandang) => ({ + filterProjectFlocksDataList.forEach((projectFlock) => { + if ( + selectedProjectFlockIds.includes(projectFlock.id) && + projectFlock.kandangs + ) { + const kandangOpts = projectFlock.kandangs.map((kandang: Kandang) => ({ value: kandang.id, label: kandang.name || '', - }) - ); - options = options.concat(kandangOpts); - } + })); + options = options.concat(kandangOpts); + } + }); } return options; @@ -267,17 +270,17 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => { const basePath = UniformityApi.basePath; const queryParams = new URLSearchParams(); - if (filterLocation) { - queryParams.append('location_id', filterLocation.value.toString()); + if (filterLocation.length > 0) { + const locationIds = filterLocation.map((loc) => loc.value).join(','); + queryParams.append('location_id', locationIds); } - if (filterProjectFlock) { - queryParams.append( - 'project_flock_id', - filterProjectFlock.value.toString() - ); + if (filterProjectFlock.length > 0) { + const flockIds = filterProjectFlock.map((pf) => pf.value).join(','); + queryParams.append('project_flock_id', flockIds); } - if (filterKandang) { - queryParams.append('kandang_id', filterKandang.value.toString()); + if (filterKandang.length > 0) { + const kandangIds = filterKandang.map((k) => k.value).join(','); + queryParams.append('kandang_id', kandangIds); } if (filterStartDate) { queryParams.append('start_date', filterStartDate); @@ -315,29 +318,32 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => { // ===== FILTER HANDLERS ===== const handleFilterLocationChange = useCallback( (val: OptionType | OptionType[] | null) => { - setFilterLocation(val as OptionType | null); + const arr = Array.isArray(val) ? val : val ? [val] : []; + setFilterLocation(arr); }, [] ); const handleFilterProjectFlockChange = useCallback( (val: OptionType | OptionType[] | null) => { - setFilterProjectFlock(val as OptionType | null); + const arr = Array.isArray(val) ? val : val ? [val] : []; + setFilterProjectFlock(arr); }, [] ); const handleFilterKandangChange = useCallback( (val: OptionType | OptionType[] | null) => { - setFilterKandang(val as OptionType | null); + const arr = Array.isArray(val) ? val : val ? [val] : []; + setFilterKandang(arr); }, [] ); const handleResetFilters = useCallback(() => { - setFilterLocation(null); - setFilterProjectFlock(null); - setFilterKandang(null); + setFilterLocation([]); + setFilterProjectFlock([]); + setFilterKandang([]); setFilterStartDate(''); setFilterEndDate(''); }, []); @@ -893,6 +899,7 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => { onInputChange={setFilterLocationInputValue} isLoading={isLoadingFilterLocations} isClearable + isMulti className={{ wrapper: 'w-full' }} /> @@ -904,8 +911,9 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => { options={filterProjectFlockOptions} onInputChange={setProjectFlockSearchValue} isLoading={isLoadingFilterProjectFlocks} - isDisabled={!filterLocation} + isDisabled={filterLocation.length === 0} isClearable + isMulti className={{ wrapper: 'w-full' }} /> @@ -915,8 +923,9 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => { value={filterKandang} onChange={handleFilterKandangChange} options={filterKandangOptions} - isDisabled={!filterProjectFlock} + isDisabled={filterProjectFlock.length === 0} isClearable + isMulti className={{ wrapper: 'w-full' }} /> diff --git a/src/services/api/uniformity.ts b/src/services/api/uniformity.ts index b12ea5d7..59161734 100644 --- a/src/services/api/uniformity.ts +++ b/src/services/api/uniformity.ts @@ -18,12 +18,14 @@ export class UniformityApiService extends BaseApiService< } async getUniformity( - location_id?: number, - project_flock_id?: number, - kandang_id?: number, - project_flock_kandang_id?: number, + location_id?: string, + project_flock_id?: string, + kandang_id?: string, + project_flock_kandang_id?: string, start_date?: string, - end_date?: string + end_date?: string, + page?: number, + limit?: number ): Promise | undefined> { return await this.customRequest>('', { method: 'GET', @@ -34,6 +36,8 @@ export class UniformityApiService extends BaseApiService< project_flock_kandang_id: project_flock_kandang_id, start_date: start_date, end_date: end_date, + page: page, + limit: limit, }, }); }