feat(FE-316): Support multi-select filters in UniformityTable

This commit is contained in:
rstubryan
2025-12-30 10:17:46 +07:00
parent 02dc624036
commit c385c42c8f
2 changed files with 52 additions and 39 deletions
@@ -185,10 +185,11 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
const filterModal = useModal(); const filterModal = useModal();
// ===== FILTER STATE ===== // ===== FILTER STATE =====
const [filterLocation, setFilterLocation] = useState<OptionType | null>(null); const [filterLocation, setFilterLocation] = useState<OptionType[]>([]);
const [filterProjectFlock, setFilterProjectFlock] = const [filterProjectFlock, setFilterProjectFlock] = useState<OptionType[]>(
useState<OptionType | null>(null); []
const [filterKandang, setFilterKandang] = useState<OptionType | null>(null); );
const [filterKandang, setFilterKandang] = useState<OptionType[]>([]);
const [filterStartDate, setFilterStartDate] = useState(''); const [filterStartDate, setFilterStartDate] = useState('');
const [filterEndDate, setFilterEndDate] = useState(''); const [filterEndDate, setFilterEndDate] = useState('');
const [projectFlockSearchValue, setProjectFlockSearchValue] = useState(''); const [projectFlockSearchValue, setProjectFlockSearchValue] = useState('');
@@ -205,8 +206,9 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
search: projectFlockSearchValue || '', search: projectFlockSearchValue || '',
limit: '100', limit: '100',
}); });
if (filterLocation) { if (filterLocation.length > 0) {
params.append('location_id', filterLocation.value.toString()); const locationIds = filterLocation.map((loc) => loc.value).join(',');
params.append('location_id', locationIds);
} }
return `${ProjectFlockApi.basePath}?${params.toString()}`; return `${ProjectFlockApi.basePath}?${params.toString()}`;
}, [projectFlockSearchValue, filterLocation]); }, [projectFlockSearchValue, filterLocation]);
@@ -243,20 +245,21 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
const filterKandangOptions = useMemo(() => { const filterKandangOptions = useMemo(() => {
let options: OptionType[] = []; let options: OptionType[] = [];
if (filterProjectFlock && filterProjectFlocksDataList) { if (filterProjectFlock.length > 0 && filterProjectFlocksDataList) {
const selectedProjectFlockData = filterProjectFlocksDataList.find( const selectedProjectFlockIds = filterProjectFlock.map((pf) => pf.value);
(pf) => pf.id === filterProjectFlock.value
);
if (selectedProjectFlockData?.kandangs) { filterProjectFlocksDataList.forEach((projectFlock) => {
const kandangOpts = selectedProjectFlockData.kandangs.map( if (
(kandang: Kandang) => ({ selectedProjectFlockIds.includes(projectFlock.id) &&
projectFlock.kandangs
) {
const kandangOpts = projectFlock.kandangs.map((kandang: Kandang) => ({
value: kandang.id, value: kandang.id,
label: kandang.name || '', label: kandang.name || '',
}) }));
); options = options.concat(kandangOpts);
options = options.concat(kandangOpts); }
} });
} }
return options; return options;
@@ -267,17 +270,17 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
const basePath = UniformityApi.basePath; const basePath = UniformityApi.basePath;
const queryParams = new URLSearchParams(); const queryParams = new URLSearchParams();
if (filterLocation) { if (filterLocation.length > 0) {
queryParams.append('location_id', filterLocation.value.toString()); const locationIds = filterLocation.map((loc) => loc.value).join(',');
queryParams.append('location_id', locationIds);
} }
if (filterProjectFlock) { if (filterProjectFlock.length > 0) {
queryParams.append( const flockIds = filterProjectFlock.map((pf) => pf.value).join(',');
'project_flock_id', queryParams.append('project_flock_id', flockIds);
filterProjectFlock.value.toString()
);
} }
if (filterKandang) { if (filterKandang.length > 0) {
queryParams.append('kandang_id', filterKandang.value.toString()); const kandangIds = filterKandang.map((k) => k.value).join(',');
queryParams.append('kandang_id', kandangIds);
} }
if (filterStartDate) { if (filterStartDate) {
queryParams.append('start_date', filterStartDate); queryParams.append('start_date', filterStartDate);
@@ -315,29 +318,32 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
// ===== FILTER HANDLERS ===== // ===== FILTER HANDLERS =====
const handleFilterLocationChange = useCallback( const handleFilterLocationChange = useCallback(
(val: OptionType | OptionType[] | null) => { (val: OptionType | OptionType[] | null) => {
setFilterLocation(val as OptionType | null); const arr = Array.isArray(val) ? val : val ? [val] : [];
setFilterLocation(arr);
}, },
[] []
); );
const handleFilterProjectFlockChange = useCallback( const handleFilterProjectFlockChange = useCallback(
(val: OptionType | OptionType[] | null) => { (val: OptionType | OptionType[] | null) => {
setFilterProjectFlock(val as OptionType | null); const arr = Array.isArray(val) ? val : val ? [val] : [];
setFilterProjectFlock(arr);
}, },
[] []
); );
const handleFilterKandangChange = useCallback( const handleFilterKandangChange = useCallback(
(val: OptionType | OptionType[] | null) => { (val: OptionType | OptionType[] | null) => {
setFilterKandang(val as OptionType | null); const arr = Array.isArray(val) ? val : val ? [val] : [];
setFilterKandang(arr);
}, },
[] []
); );
const handleResetFilters = useCallback(() => { const handleResetFilters = useCallback(() => {
setFilterLocation(null); setFilterLocation([]);
setFilterProjectFlock(null); setFilterProjectFlock([]);
setFilterKandang(null); setFilterKandang([]);
setFilterStartDate(''); setFilterStartDate('');
setFilterEndDate(''); setFilterEndDate('');
}, []); }, []);
@@ -893,6 +899,7 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
onInputChange={setFilterLocationInputValue} onInputChange={setFilterLocationInputValue}
isLoading={isLoadingFilterLocations} isLoading={isLoadingFilterLocations}
isClearable isClearable
isMulti
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
/> />
@@ -904,8 +911,9 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
options={filterProjectFlockOptions} options={filterProjectFlockOptions}
onInputChange={setProjectFlockSearchValue} onInputChange={setProjectFlockSearchValue}
isLoading={isLoadingFilterProjectFlocks} isLoading={isLoadingFilterProjectFlocks}
isDisabled={!filterLocation} isDisabled={filterLocation.length === 0}
isClearable isClearable
isMulti
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
/> />
@@ -915,8 +923,9 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
value={filterKandang} value={filterKandang}
onChange={handleFilterKandangChange} onChange={handleFilterKandangChange}
options={filterKandangOptions} options={filterKandangOptions}
isDisabled={!filterProjectFlock} isDisabled={filterProjectFlock.length === 0}
isClearable isClearable
isMulti
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
/> />
</div> </div>
+9 -5
View File
@@ -18,12 +18,14 @@ export class UniformityApiService extends BaseApiService<
} }
async getUniformity( async getUniformity(
location_id?: number, location_id?: string,
project_flock_id?: number, project_flock_id?: string,
kandang_id?: number, kandang_id?: string,
project_flock_kandang_id?: number, project_flock_kandang_id?: string,
start_date?: string, start_date?: string,
end_date?: string end_date?: string,
page?: number,
limit?: number
): Promise<BaseApiResponse<Uniformity> | undefined> { ): Promise<BaseApiResponse<Uniformity> | undefined> {
return await this.customRequest<BaseApiResponse<Uniformity>>('', { return await this.customRequest<BaseApiResponse<Uniformity>>('', {
method: 'GET', method: 'GET',
@@ -34,6 +36,8 @@ export class UniformityApiService extends BaseApiService<
project_flock_kandang_id: project_flock_kandang_id, project_flock_kandang_id: project_flock_kandang_id,
start_date: start_date, start_date: start_date,
end_date: end_date, end_date: end_date,
page: page,
limit: limit,
}, },
}); });
} }