refactor(FE-316): Use single-select filters, add PF-Kandang lookup

This commit is contained in:
rstubryan
2025-12-30 10:23:01 +07:00
parent c385c42c8f
commit f51236fcfc
2 changed files with 76 additions and 59 deletions
@@ -12,6 +12,7 @@ import { useTableFilter } from '@/services/hooks/useTableFilter';
import { UniformityApi } from '@/services/api/uniformity';
import { type Uniformity } from '@/types/api/uniformity/uniformity';
import { isResponseSuccess } from '@/lib/api-helper';
import { type BaseApiResponse } from '@/types/api/api-general';
import Table from '@/components/Table';
import Badge from '@/components/Badge';
import CheckboxInput from '@/components/input/CheckboxInput';
@@ -30,11 +31,9 @@ import SelectInput, {
} from '@/components/input/SelectInput';
import DateInput from '@/components/input/DateInput';
import { LocationApi } from '@/services/api/master-data';
import {
ProjectFlockApi,
ProjectFlockKandangApi,
} from '@/services/api/production';
import { ProjectFlockApi } from '@/services/api/production';
import { Kandang } from '@/types/api/master-data/kandang';
import { ProjectFlockKandangLookup } from '@/types/api/production/project-flock';
import {
getStatusColor,
getStatusIndicatorColor,
@@ -185,11 +184,12 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
const filterModal = useModal();
// ===== FILTER STATE =====
const [filterLocation, setFilterLocation] = useState<OptionType[]>([]);
const [filterProjectFlock, setFilterProjectFlock] = useState<OptionType[]>(
[]
);
const [filterKandang, setFilterKandang] = useState<OptionType[]>([]);
const [filterLocation, setFilterLocation] = useState<OptionType | null>(null);
const [filterProjectFlock, setFilterProjectFlock] =
useState<OptionType | null>(null);
const [filterKandang, setFilterKandang] = useState<OptionType | null>(null);
const [filterProjectFlockKandangId, setFilterProjectFlockKandangId] =
useState<number | undefined>(undefined);
const [filterStartDate, setFilterStartDate] = useState('');
const [filterEndDate, setFilterEndDate] = useState('');
const [projectFlockSearchValue, setProjectFlockSearchValue] = useState('');
@@ -206,9 +206,8 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
search: projectFlockSearchValue || '',
limit: '100',
});
if (filterLocation.length > 0) {
const locationIds = filterLocation.map((loc) => loc.value).join(',');
params.append('location_id', locationIds);
if (filterLocation) {
params.append('location_id', filterLocation.value.toString());
}
return `${ProjectFlockApi.basePath}?${params.toString()}`;
}, [projectFlockSearchValue, filterLocation]);
@@ -245,42 +244,70 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
const filterKandangOptions = useMemo(() => {
let options: OptionType[] = [];
if (filterProjectFlock.length > 0 && filterProjectFlocksDataList) {
const selectedProjectFlockIds = filterProjectFlock.map((pf) => pf.value);
if (filterProjectFlock && filterProjectFlocksDataList) {
const selectedProjectFlockData = filterProjectFlocksDataList.find(
(pf) => pf.id === filterProjectFlock.value
);
filterProjectFlocksDataList.forEach((projectFlock) => {
if (
selectedProjectFlockIds.includes(projectFlock.id) &&
projectFlock.kandangs
) {
const kandangOpts = projectFlock.kandangs.map((kandang: Kandang) => ({
if (selectedProjectFlockData?.kandangs) {
const kandangOpts = selectedProjectFlockData.kandangs.map(
(kandang: Kandang) => ({
value: kandang.id,
label: kandang.name || '',
}));
options = options.concat(kandangOpts);
}
});
})
);
options = options.concat(kandangOpts);
}
}
return options;
}, [filterProjectFlock, filterProjectFlocksDataList]);
// ===== PROJECT FLOCK KANDANG LOOKUP =====
const projectFlockKandangLookupUrl = useMemo(() => {
if (!filterProjectFlock || !filterKandang) return null;
const params = new URLSearchParams({
project_flock_id: filterProjectFlock.value.toString(),
kandang_id: filterKandang.value.toString(),
withpopulation: Boolean(true).toString(),
});
return `${ProjectFlockApi.basePath}/kandangs/lookup?${params.toString()}`;
}, [filterProjectFlock, filterKandang]);
const { data: projectFlockKandangLookupData } = useSWR(
projectFlockKandangLookupUrl,
projectFlockKandangLookupUrl
? () =>
ProjectFlockApi.getAllFetcher(
projectFlockKandangLookupUrl
) as Promise<BaseApiResponse<ProjectFlockKandangLookup>>
: null
);
const projectFlockKandangLookup =
projectFlockKandangLookupData?.status === 'success'
? projectFlockKandangLookupData.data
: undefined;
// Update filterProjectFlockKandangId when lookup changes
useEffect(() => {
if (projectFlockKandangLookup?.id) {
setFilterProjectFlockKandangId(projectFlockKandangLookup.id);
} else {
setFilterProjectFlockKandangId(undefined);
}
}, [projectFlockKandangLookup]);
// ===== BUILD SWR KEY WITH FILTERS =====
const uniformitySwrKey = useMemo(() => {
const basePath = UniformityApi.basePath;
const queryParams = new URLSearchParams();
if (filterLocation.length > 0) {
const locationIds = filterLocation.map((loc) => loc.value).join(',');
queryParams.append('location_id', locationIds);
}
if (filterProjectFlock.length > 0) {
const flockIds = filterProjectFlock.map((pf) => pf.value).join(',');
queryParams.append('project_flock_id', flockIds);
}
if (filterKandang.length > 0) {
const kandangIds = filterKandang.map((k) => k.value).join(',');
queryParams.append('kandang_id', kandangIds);
if (filterProjectFlockKandangId) {
queryParams.append(
'project_flock_kandang_id',
filterProjectFlockKandangId.toString()
);
}
if (filterStartDate) {
queryParams.append('start_date', filterStartDate);
@@ -301,9 +328,7 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
const queryString = queryParams.toString();
return queryString ? `${basePath}?${queryString}` : basePath;
}, [
filterLocation,
filterProjectFlock,
filterKandang,
filterProjectFlockKandangId,
filterStartDate,
filterEndDate,
getTableFilterQueryString,
@@ -318,32 +343,33 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
// ===== FILTER HANDLERS =====
const handleFilterLocationChange = useCallback(
(val: OptionType | OptionType[] | null) => {
const arr = Array.isArray(val) ? val : val ? [val] : [];
setFilterLocation(arr);
setFilterLocation(val as OptionType | null);
setFilterProjectFlock(null);
setFilterKandang(null);
},
[]
);
const handleFilterProjectFlockChange = useCallback(
(val: OptionType | OptionType[] | null) => {
const arr = Array.isArray(val) ? val : val ? [val] : [];
setFilterProjectFlock(arr);
setFilterProjectFlock(val as OptionType | null);
setFilterKandang(null);
},
[]
);
const handleFilterKandangChange = useCallback(
(val: OptionType | OptionType[] | null) => {
const arr = Array.isArray(val) ? val : val ? [val] : [];
setFilterKandang(arr);
setFilterKandang(val as OptionType | null);
},
[]
);
const handleResetFilters = useCallback(() => {
setFilterLocation([]);
setFilterProjectFlock([]);
setFilterKandang([]);
setFilterLocation(null);
setFilterProjectFlock(null);
setFilterKandang(null);
setFilterProjectFlockKandangId(undefined);
setFilterStartDate('');
setFilterEndDate('');
}, []);
@@ -899,7 +925,6 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
onInputChange={setFilterLocationInputValue}
isLoading={isLoadingFilterLocations}
isClearable
isMulti
className={{ wrapper: 'w-full' }}
/>
@@ -911,9 +936,8 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
options={filterProjectFlockOptions}
onInputChange={setProjectFlockSearchValue}
isLoading={isLoadingFilterProjectFlocks}
isDisabled={filterLocation.length === 0}
isDisabled={!filterLocation}
isClearable
isMulti
className={{ wrapper: 'w-full' }}
/>
@@ -923,9 +947,8 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
value={filterKandang}
onChange={handleFilterKandangChange}
options={filterKandangOptions}
isDisabled={filterProjectFlock.length === 0}
isDisabled={!filterProjectFlock}
isClearable
isMulti
className={{ wrapper: 'w-full' }}
/>
</div>
+1 -7
View File
@@ -18,10 +18,7 @@ export class UniformityApiService extends BaseApiService<
}
async getUniformity(
location_id?: string,
project_flock_id?: string,
kandang_id?: string,
project_flock_kandang_id?: string,
project_flock_kandang_id?: number,
start_date?: string,
end_date?: string,
page?: number,
@@ -30,9 +27,6 @@ export class UniformityApiService extends BaseApiService<
return await this.customRequest<BaseApiResponse<Uniformity>>('', {
method: 'GET',
params: {
location_id: location_id,
project_flock_id: project_flock_id,
kandang_id: kandang_id,
project_flock_kandang_id: project_flock_kandang_id,
start_date: start_date,
end_date: end_date,