mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-23 14:55:44 +00:00
refactor(FE-316): Use single-select filters, add PF-Kandang lookup
This commit is contained in:
@@ -12,6 +12,7 @@ import { useTableFilter } from '@/services/hooks/useTableFilter';
|
|||||||
import { UniformityApi } from '@/services/api/uniformity';
|
import { UniformityApi } from '@/services/api/uniformity';
|
||||||
import { type Uniformity } from '@/types/api/uniformity/uniformity';
|
import { type Uniformity } from '@/types/api/uniformity/uniformity';
|
||||||
import { isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseSuccess } from '@/lib/api-helper';
|
||||||
|
import { type BaseApiResponse } from '@/types/api/api-general';
|
||||||
import Table from '@/components/Table';
|
import Table from '@/components/Table';
|
||||||
import Badge from '@/components/Badge';
|
import Badge from '@/components/Badge';
|
||||||
import CheckboxInput from '@/components/input/CheckboxInput';
|
import CheckboxInput from '@/components/input/CheckboxInput';
|
||||||
@@ -30,11 +31,9 @@ import SelectInput, {
|
|||||||
} from '@/components/input/SelectInput';
|
} from '@/components/input/SelectInput';
|
||||||
import DateInput from '@/components/input/DateInput';
|
import DateInput from '@/components/input/DateInput';
|
||||||
import { LocationApi } from '@/services/api/master-data';
|
import { LocationApi } from '@/services/api/master-data';
|
||||||
import {
|
import { ProjectFlockApi } from '@/services/api/production';
|
||||||
ProjectFlockApi,
|
|
||||||
ProjectFlockKandangApi,
|
|
||||||
} from '@/services/api/production';
|
|
||||||
import { Kandang } from '@/types/api/master-data/kandang';
|
import { Kandang } from '@/types/api/master-data/kandang';
|
||||||
|
import { ProjectFlockKandangLookup } from '@/types/api/production/project-flock';
|
||||||
import {
|
import {
|
||||||
getStatusColor,
|
getStatusColor,
|
||||||
getStatusIndicatorColor,
|
getStatusIndicatorColor,
|
||||||
@@ -185,11 +184,12 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
|
|||||||
const filterModal = useModal();
|
const filterModal = useModal();
|
||||||
|
|
||||||
// ===== FILTER STATE =====
|
// ===== FILTER STATE =====
|
||||||
const [filterLocation, setFilterLocation] = useState<OptionType[]>([]);
|
const [filterLocation, setFilterLocation] = useState<OptionType | null>(null);
|
||||||
const [filterProjectFlock, setFilterProjectFlock] = useState<OptionType[]>(
|
const [filterProjectFlock, setFilterProjectFlock] =
|
||||||
[]
|
useState<OptionType | null>(null);
|
||||||
);
|
const [filterKandang, setFilterKandang] = useState<OptionType | null>(null);
|
||||||
const [filterKandang, setFilterKandang] = useState<OptionType[]>([]);
|
const [filterProjectFlockKandangId, setFilterProjectFlockKandangId] =
|
||||||
|
useState<number | undefined>(undefined);
|
||||||
const [filterStartDate, setFilterStartDate] = useState('');
|
const [filterStartDate, setFilterStartDate] = useState('');
|
||||||
const [filterEndDate, setFilterEndDate] = useState('');
|
const [filterEndDate, setFilterEndDate] = useState('');
|
||||||
const [projectFlockSearchValue, setProjectFlockSearchValue] = useState('');
|
const [projectFlockSearchValue, setProjectFlockSearchValue] = useState('');
|
||||||
@@ -206,9 +206,8 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
|
|||||||
search: projectFlockSearchValue || '',
|
search: projectFlockSearchValue || '',
|
||||||
limit: '100',
|
limit: '100',
|
||||||
});
|
});
|
||||||
if (filterLocation.length > 0) {
|
if (filterLocation) {
|
||||||
const locationIds = filterLocation.map((loc) => loc.value).join(',');
|
params.append('location_id', filterLocation.value.toString());
|
||||||
params.append('location_id', locationIds);
|
|
||||||
}
|
}
|
||||||
return `${ProjectFlockApi.basePath}?${params.toString()}`;
|
return `${ProjectFlockApi.basePath}?${params.toString()}`;
|
||||||
}, [projectFlockSearchValue, filterLocation]);
|
}, [projectFlockSearchValue, filterLocation]);
|
||||||
@@ -245,42 +244,70 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
|
|||||||
const filterKandangOptions = useMemo(() => {
|
const filterKandangOptions = useMemo(() => {
|
||||||
let options: OptionType[] = [];
|
let options: OptionType[] = [];
|
||||||
|
|
||||||
if (filterProjectFlock.length > 0 && filterProjectFlocksDataList) {
|
if (filterProjectFlock && filterProjectFlocksDataList) {
|
||||||
const selectedProjectFlockIds = filterProjectFlock.map((pf) => pf.value);
|
const selectedProjectFlockData = filterProjectFlocksDataList.find(
|
||||||
|
(pf) => pf.id === filterProjectFlock.value
|
||||||
|
);
|
||||||
|
|
||||||
filterProjectFlocksDataList.forEach((projectFlock) => {
|
if (selectedProjectFlockData?.kandangs) {
|
||||||
if (
|
const kandangOpts = selectedProjectFlockData.kandangs.map(
|
||||||
selectedProjectFlockIds.includes(projectFlock.id) &&
|
(kandang: Kandang) => ({
|
||||||
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;
|
||||||
}, [filterProjectFlock, filterProjectFlocksDataList]);
|
}, [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 =====
|
// ===== BUILD SWR KEY WITH FILTERS =====
|
||||||
const uniformitySwrKey = useMemo(() => {
|
const uniformitySwrKey = useMemo(() => {
|
||||||
const basePath = UniformityApi.basePath;
|
const basePath = UniformityApi.basePath;
|
||||||
const queryParams = new URLSearchParams();
|
const queryParams = new URLSearchParams();
|
||||||
|
|
||||||
if (filterLocation.length > 0) {
|
if (filterProjectFlockKandangId) {
|
||||||
const locationIds = filterLocation.map((loc) => loc.value).join(',');
|
queryParams.append(
|
||||||
queryParams.append('location_id', locationIds);
|
'project_flock_kandang_id',
|
||||||
}
|
filterProjectFlockKandangId.toString()
|
||||||
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 (filterStartDate) {
|
if (filterStartDate) {
|
||||||
queryParams.append('start_date', filterStartDate);
|
queryParams.append('start_date', filterStartDate);
|
||||||
@@ -301,9 +328,7 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
|
|||||||
const queryString = queryParams.toString();
|
const queryString = queryParams.toString();
|
||||||
return queryString ? `${basePath}?${queryString}` : basePath;
|
return queryString ? `${basePath}?${queryString}` : basePath;
|
||||||
}, [
|
}, [
|
||||||
filterLocation,
|
filterProjectFlockKandangId,
|
||||||
filterProjectFlock,
|
|
||||||
filterKandang,
|
|
||||||
filterStartDate,
|
filterStartDate,
|
||||||
filterEndDate,
|
filterEndDate,
|
||||||
getTableFilterQueryString,
|
getTableFilterQueryString,
|
||||||
@@ -318,32 +343,33 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
|
|||||||
// ===== FILTER HANDLERS =====
|
// ===== FILTER HANDLERS =====
|
||||||
const handleFilterLocationChange = useCallback(
|
const handleFilterLocationChange = useCallback(
|
||||||
(val: OptionType | OptionType[] | null) => {
|
(val: OptionType | OptionType[] | null) => {
|
||||||
const arr = Array.isArray(val) ? val : val ? [val] : [];
|
setFilterLocation(val as OptionType | null);
|
||||||
setFilterLocation(arr);
|
setFilterProjectFlock(null);
|
||||||
|
setFilterKandang(null);
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleFilterProjectFlockChange = useCallback(
|
const handleFilterProjectFlockChange = useCallback(
|
||||||
(val: OptionType | OptionType[] | null) => {
|
(val: OptionType | OptionType[] | null) => {
|
||||||
const arr = Array.isArray(val) ? val : val ? [val] : [];
|
setFilterProjectFlock(val as OptionType | null);
|
||||||
setFilterProjectFlock(arr);
|
setFilterKandang(null);
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleFilterKandangChange = useCallback(
|
const handleFilterKandangChange = useCallback(
|
||||||
(val: OptionType | OptionType[] | null) => {
|
(val: OptionType | OptionType[] | null) => {
|
||||||
const arr = Array.isArray(val) ? val : val ? [val] : [];
|
setFilterKandang(val as OptionType | null);
|
||||||
setFilterKandang(arr);
|
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleResetFilters = useCallback(() => {
|
const handleResetFilters = useCallback(() => {
|
||||||
setFilterLocation([]);
|
setFilterLocation(null);
|
||||||
setFilterProjectFlock([]);
|
setFilterProjectFlock(null);
|
||||||
setFilterKandang([]);
|
setFilterKandang(null);
|
||||||
|
setFilterProjectFlockKandangId(undefined);
|
||||||
setFilterStartDate('');
|
setFilterStartDate('');
|
||||||
setFilterEndDate('');
|
setFilterEndDate('');
|
||||||
}, []);
|
}, []);
|
||||||
@@ -899,7 +925,6 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
|
|||||||
onInputChange={setFilterLocationInputValue}
|
onInputChange={setFilterLocationInputValue}
|
||||||
isLoading={isLoadingFilterLocations}
|
isLoading={isLoadingFilterLocations}
|
||||||
isClearable
|
isClearable
|
||||||
isMulti
|
|
||||||
className={{ wrapper: 'w-full' }}
|
className={{ wrapper: 'w-full' }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -911,9 +936,8 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
|
|||||||
options={filterProjectFlockOptions}
|
options={filterProjectFlockOptions}
|
||||||
onInputChange={setProjectFlockSearchValue}
|
onInputChange={setProjectFlockSearchValue}
|
||||||
isLoading={isLoadingFilterProjectFlocks}
|
isLoading={isLoadingFilterProjectFlocks}
|
||||||
isDisabled={filterLocation.length === 0}
|
isDisabled={!filterLocation}
|
||||||
isClearable
|
isClearable
|
||||||
isMulti
|
|
||||||
className={{ wrapper: 'w-full' }}
|
className={{ wrapper: 'w-full' }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -923,9 +947,8 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
|
|||||||
value={filterKandang}
|
value={filterKandang}
|
||||||
onChange={handleFilterKandangChange}
|
onChange={handleFilterKandangChange}
|
||||||
options={filterKandangOptions}
|
options={filterKandangOptions}
|
||||||
isDisabled={filterProjectFlock.length === 0}
|
isDisabled={!filterProjectFlock}
|
||||||
isClearable
|
isClearable
|
||||||
isMulti
|
|
||||||
className={{ wrapper: 'w-full' }}
|
className={{ wrapper: 'w-full' }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -18,10 +18,7 @@ export class UniformityApiService extends BaseApiService<
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getUniformity(
|
async getUniformity(
|
||||||
location_id?: string,
|
project_flock_kandang_id?: number,
|
||||||
project_flock_id?: string,
|
|
||||||
kandang_id?: string,
|
|
||||||
project_flock_kandang_id?: string,
|
|
||||||
start_date?: string,
|
start_date?: string,
|
||||||
end_date?: string,
|
end_date?: string,
|
||||||
page?: number,
|
page?: number,
|
||||||
@@ -30,9 +27,6 @@ export class UniformityApiService extends BaseApiService<
|
|||||||
return await this.customRequest<BaseApiResponse<Uniformity>>('', {
|
return await this.customRequest<BaseApiResponse<Uniformity>>('', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
params: {
|
params: {
|
||||||
location_id: location_id,
|
|
||||||
project_flock_id: project_flock_id,
|
|
||||||
kandang_id: kandang_id,
|
|
||||||
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,
|
||||||
|
|||||||
Reference in New Issue
Block a user