refactor(FE-357): Make area/location/kandang filters multi-select

This commit is contained in:
rstubryan
2025-12-18 12:56:05 +07:00
parent f844c9ff2c
commit 843fa6ee7a
2 changed files with 129 additions and 93 deletions
@@ -43,9 +43,9 @@ const HppPerKandangTab = () => {
// ===== TABLE FILTER STATE ===== // ===== TABLE FILTER STATE =====
const { state: tableFilterState, updateFilter } = useTableFilter({ const { state: tableFilterState, updateFilter } = useTableFilter({
initial: { initial: {
area_id: '', area_id: [] as string[],
location_id: '', location_id: [] as string[],
kandang_id: '', kandang_id: [] as string[],
weight_min: '', weight_min: '',
weight_max: '', weight_max: '',
period: '', period: '',
@@ -78,8 +78,11 @@ const HppPerKandangTab = () => {
const areaChangeHandler = useCallback( const areaChangeHandler = useCallback(
(val: OptionType | OptionType[] | null) => { (val: OptionType | OptionType[] | null) => {
const newVal = val as OptionType; const arr = Array.isArray(val) ? val : val ? [val] : [];
updateFilter('area_id', newVal?.value ? String(newVal.value) : ''); updateFilter(
'area_id',
arr.map((v) => String((v as OptionType).value))
);
setIsSubmitted(false); setIsSubmitted(false);
}, },
[updateFilter] [updateFilter]
@@ -87,8 +90,11 @@ const HppPerKandangTab = () => {
const locationChangeHandler = useCallback( const locationChangeHandler = useCallback(
(val: OptionType | OptionType[] | null) => { (val: OptionType | OptionType[] | null) => {
const newVal = val as OptionType; const arr = Array.isArray(val) ? val : val ? [val] : [];
updateFilter('location_id', newVal?.value ? String(newVal.value) : ''); updateFilter(
'location_id',
arr.map((v) => String((v as OptionType).value))
);
setIsSubmitted(false); setIsSubmitted(false);
}, },
[updateFilter] [updateFilter]
@@ -96,8 +102,11 @@ const HppPerKandangTab = () => {
const kandangChangeHandler = useCallback( const kandangChangeHandler = useCallback(
(val: OptionType | OptionType[] | null) => { (val: OptionType | OptionType[] | null) => {
const newVal = val as OptionType; const arr = Array.isArray(val) ? val : val ? [val] : [];
updateFilter('kandang_id', newVal?.value ? String(newVal.value) : ''); updateFilter(
'kandang_id',
arr.map((v) => String((v as OptionType).value))
);
setIsSubmitted(false); setIsSubmitted(false);
}, },
[updateFilter] [updateFilter]
@@ -144,9 +153,9 @@ const HppPerKandangTab = () => {
); );
const resetFilters = useCallback(() => { const resetFilters = useCallback(() => {
updateFilter('area_id', ''); updateFilter('area_id', []);
updateFilter('location_id', ''); updateFilter('location_id', []);
updateFilter('kandang_id', ''); updateFilter('kandang_id', []);
updateFilter('weight_min', ''); updateFilter('weight_min', '');
updateFilter('weight_max', ''); updateFilter('weight_max', '');
updateFilter('period', ''); updateFilter('period', '');
@@ -168,15 +177,18 @@ const HppPerKandangTab = () => {
isSubmitted isSubmitted
? () => { ? () => {
const params = { const params = {
area_id: tableFilterState.area_id area_id:
? Number(tableFilterState.area_id) tableFilterState.area_id.length > 0
: undefined, ? tableFilterState.area_id.join(',')
location_id: tableFilterState.location_id : undefined,
? Number(tableFilterState.location_id) location_id:
: undefined, tableFilterState.location_id.length > 0
kandang_id: tableFilterState.kandang_id ? tableFilterState.location_id.join(',')
? Number(tableFilterState.kandang_id) : undefined,
: undefined, kandang_id:
tableFilterState.kandang_id.length > 0
? tableFilterState.kandang_id.join(',')
: undefined,
weight_min: tableFilterState.weight_min weight_min: tableFilterState.weight_min
? Number(tableFilterState.weight_min) ? Number(tableFilterState.weight_min)
: undefined, : undefined,
@@ -226,15 +238,18 @@ const HppPerKandangTab = () => {
const hppPerKandangExport = const hppPerKandangExport =
useCallback(async (): Promise<HppPerKandangReport | null> => { useCallback(async (): Promise<HppPerKandangReport | null> => {
const params = { const params = {
area_id: tableFilterState.area_id area_id:
? Number(tableFilterState.area_id) tableFilterState.area_id.length > 0
: undefined, ? tableFilterState.area_id.join(',')
location_id: tableFilterState.location_id : undefined,
? Number(tableFilterState.location_id) location_id:
: undefined, tableFilterState.location_id.length > 0
kandang_id: tableFilterState.kandang_id ? tableFilterState.location_id.join(',')
? Number(tableFilterState.kandang_id) : undefined,
: undefined, kandang_id:
tableFilterState.kandang_id.length > 0
? tableFilterState.kandang_id.join(',')
: undefined,
weight_min: tableFilterState.weight_min weight_min: tableFilterState.weight_min
? Number(tableFilterState.weight_min) ? Number(tableFilterState.weight_min)
: undefined, : undefined,
@@ -386,23 +401,38 @@ const HppPerKandangTab = () => {
const workbook = XLSX.utils.book_new(); const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, 'HPP Per Kandang'); XLSX.utils.book_append_sheet(workbook, worksheet, 'HPP Per Kandang');
const areaName = tableFilterState.area_id const areaName =
? areaOptions.find( tableFilterState.area_id.length > 0
(opt) => opt.value === Number(tableFilterState.area_id) ? tableFilterState.area_id
)?.label || 'Semua Area' .map(
: 'Semua Area'; (id) =>
areaOptions.find((opt) => opt.value === Number(id))?.label
)
.filter(Boolean)
.join(', ') || 'Semua Area'
: 'Semua Area';
const locationName = tableFilterState.location_id const locationName =
? locationOptions.find( tableFilterState.location_id.length > 0
(opt) => opt.value === Number(tableFilterState.location_id) ? tableFilterState.location_id
)?.label || 'Semua Lokasi' .map(
: 'Semua Lokasi'; (id) =>
locationOptions.find((opt) => opt.value === Number(id))?.label
)
.filter(Boolean)
.join(', ') || 'Semua Lokasi'
: 'Semua Lokasi';
const kandangName = tableFilterState.kandang_id const kandangName =
? kandangOptions.find( tableFilterState.kandang_id.length > 0
(opt) => opt.value === Number(tableFilterState.kandang_id) ? tableFilterState.kandang_id
)?.label || 'Semua Kandang' .map(
: 'Semua Kandang'; (id) =>
kandangOptions.find((opt) => opt.value === Number(id))?.label
)
.filter(Boolean)
.join(', ') || 'Semua Kandang'
: 'Semua Kandang';
const filename = `Laporan_HPP_Per_Kandang_${areaName}_${locationName}_${kandangName}_${tableFilterState.period}.xlsx`; const filename = `Laporan_HPP_Per_Kandang_${areaName}_${locationName}_${kandangName}_${tableFilterState.period}.xlsx`;
@@ -435,23 +465,38 @@ const HppPerKandangTab = () => {
return; return;
} }
const areaName = tableFilterState.area_id const areaName =
? areaOptions.find( tableFilterState.area_id.length > 0
(opt) => opt.value === Number(tableFilterState.area_id) ? tableFilterState.area_id
)?.label || 'Semua Area' .map(
: 'Semua Area'; (id) =>
areaOptions.find((opt) => opt.value === Number(id))?.label
)
.filter(Boolean)
.join(', ') || 'Semua Area'
: 'Semua Area';
const locationName = tableFilterState.location_id const locationName =
? locationOptions.find( tableFilterState.location_id.length > 0
(opt) => opt.value === Number(tableFilterState.location_id) ? tableFilterState.location_id
)?.label || 'Semua Lokasi' .map(
: 'Semua Lokasi'; (id) =>
locationOptions.find((opt) => opt.value === Number(id))?.label
)
.filter(Boolean)
.join(', ') || 'Semua Lokasi'
: 'Semua Lokasi';
const kandangName = tableFilterState.kandang_id const kandangName =
? kandangOptions.find( tableFilterState.kandang_id.length > 0
(opt) => opt.value === Number(tableFilterState.kandang_id) ? tableFilterState.kandang_id
)?.label || 'Semua Kandang' .map(
: 'Semua Kandang'; (id) =>
kandangOptions.find((opt) => opt.value === Number(id))?.label
)
.filter(Boolean)
.join(', ') || 'Semua Kandang'
: 'Semua Kandang';
await generateHppPerKandangPDF(allDataForExport, { await generateHppPerKandangPDF(allDataForExport, {
area_name: areaName, area_name: areaName,
@@ -716,15 +761,13 @@ const HppPerKandangTab = () => {
<SelectInput <SelectInput
label='Area' label='Area'
placeholder='Pilih Area' placeholder='Pilih Area'
isMulti
options={areaOptions} options={areaOptions}
value={ value={areaOptions.filter((opt) =>
tableFilterState.area_id (tableFilterState.area_id || [])
? areaOptions.find( .map(String)
(option) => .includes(String(opt.value))
option.value === Number(tableFilterState.area_id) )}
) || null
: null
}
onChange={areaChangeHandler} onChange={areaChangeHandler}
isLoading={isLoadingAreas} isLoading={isLoadingAreas}
isClearable isClearable
@@ -732,15 +775,13 @@ const HppPerKandangTab = () => {
<SelectInput <SelectInput
label='Lokasi' label='Lokasi'
placeholder='Pilih Lokasi' placeholder='Pilih Lokasi'
isMulti
options={locationOptions} options={locationOptions}
value={ value={locationOptions.filter((opt) =>
tableFilterState.location_id (tableFilterState.location_id || [])
? locationOptions.find( .map(String)
(option) => .includes(String(opt.value))
option.value === Number(tableFilterState.location_id) )}
) || null
: null
}
onChange={locationChangeHandler} onChange={locationChangeHandler}
isLoading={isLoadingLocations} isLoading={isLoadingLocations}
isClearable isClearable
@@ -748,15 +789,13 @@ const HppPerKandangTab = () => {
<SelectInput <SelectInput
label='Kandang' label='Kandang'
placeholder='Pilih Kandang' placeholder='Pilih Kandang'
isMulti
options={kandangOptions} options={kandangOptions}
value={ value={kandangOptions.filter((opt) =>
tableFilterState.kandang_id (tableFilterState.kandang_id || [])
? kandangOptions.find( .map(String)
(option) => .includes(String(opt.value))
option.value === Number(tableFilterState.kandang_id) )}
) || null
: null
}
onChange={kandangChangeHandler} onChange={kandangChangeHandler}
isLoading={isLoadingKandangs} isLoading={isLoadingKandangs}
isClearable isClearable
+6 -9
View File
@@ -12,9 +12,9 @@ export class MarketingSaleReportService extends BaseApiService<
} }
async getHppPerKandangReport( async getHppPerKandangReport(
area_id?: number, area_id?: string,
location_id?: number, location_id?: string,
kandang_id?: number, kandang_id?: string,
weight_min?: number, weight_min?: number,
weight_max?: number, weight_max?: number,
period?: string, period?: string,
@@ -48,9 +48,6 @@ export const SaleReportApi = new MarketingSaleReportService(
'reports/marketings' 'reports/marketings'
); );
/* For local testing purpose only // export const SaleReportApi = new MarketingSaleReportService(
export const SaleReportApi = new MarketingSaleReportService( // 'http://localhost:4010/api/reports/marketings'
'http://localhost:4010/api/reports/marketings' // );
'reports/marketings'
);
*/