@@ -1,7 +1,7 @@ | |||||
"use server"; | "use server"; | ||||
import { serverFetchBlob } from "@/app/utils/fetchUtil"; | import { serverFetchBlob } from "@/app/utils/fetchUtil"; | ||||
import { MonthlyWorkHoursReportRequest, ProjectCashFlowReportRequest, LateStartReportRequest, ProjectResourceOverconsumptionReportRequest, ProjectPandLReportRequest, ProjectCompletionReportRequest, ProjectPotentialDelayReportRequest, CostAndExpenseReportRequest, CrossTeamChargeReportRequest, ProjectManhourSummaryReportRequest, ProjectMonthlyReportRequest, LastModifiedReportRequest } from "."; | |||||
import { MonthlyWorkHoursReportRequest, ProjectCashFlowReportRequest, LateStartReportRequest, ProjectResourceOverconsumptionReportRequest, ProjectPandLReportRequest, ProjectCompletionReportRequest, ProjectPotentialDelayReportRequest, CostAndExpenseReportRequest, CrossTeamChargeReportRequest, ProjectManhourSummaryReportRequest, ProjectMonthlyReportRequest, LastModifiedReportRequest, ExportCurrentStaffInfoRequest } from "."; | |||||
import { BASE_API_URL } from "@/config/api"; | import { BASE_API_URL } from "@/config/api"; | ||||
export interface FileResponse { | export interface FileResponse { | ||||
@@ -176,3 +176,16 @@ export const fetchLastModifiedReport = async (data: LastModifiedReportRequest) = | |||||
return reportBlob | return reportBlob | ||||
}; | }; | ||||
export const fetchStaffCurrentInfo = async (data: ExportCurrentStaffInfoRequest) => { | |||||
const reportBlob = await serverFetchBlob<FileResponse>( | |||||
`${BASE_API_URL}/reports/export-staff-current-info`, | |||||
{ | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}, | |||||
); | |||||
return reportBlob | |||||
}; |
@@ -155,4 +155,8 @@ export interface LastModifiedReportFilter { | |||||
export interface LastModifiedReportRequest { | export interface LastModifiedReportRequest { | ||||
dateString: string; | dateString: string; | ||||
} | |||||
export interface ExportCurrentStaffInfoRequest { | |||||
staffIds: number[]; | |||||
} | } |
@@ -14,6 +14,10 @@ import { MAINTAIN_STAFF, MAINTAIN_USER } from "@/middleware"; | |||||
import { TeamResult } from "@/app/api/team"; | import { TeamResult } from "@/app/api/team"; | ||||
import { Grade } from "@/app/api/grades"; | import { Grade } from "@/app/api/grades"; | ||||
import { PositionResult } from "@/app/api/positions"; | import { PositionResult } from "@/app/api/positions"; | ||||
import { Button, Stack } from "@mui/material"; | |||||
import FileDownloadIcon from '@mui/icons-material/FileDownload'; | |||||
import { fetchStaffCurrentInfo } from "@/app/api/reports/actions"; | |||||
import { downloadFile } from "@/app/utils/commonUtil"; | |||||
interface Props { | interface Props { | ||||
staff: StaffResult[]; | staff: StaffResult[]; | ||||
@@ -102,6 +106,16 @@ const StaffSearch: React.FC<Props> = ({ staff, teams, grades, positions, abiliti | |||||
}, t); | }, t); | ||||
}, []); | }, []); | ||||
const handleExport = useCallback(async (ids: number[]) => { | |||||
console.log(ids) | |||||
const response = await fetchStaffCurrentInfo( | |||||
{staffIds: ids} | |||||
) | |||||
if (response) { | |||||
downloadFile(new Uint8Array(response.blobValue), response.filename!!) | |||||
} | |||||
},[filteredStaff]) | |||||
useEffect(() => { | useEffect(() => { | ||||
setFilteredStaff(staff) | setFilteredStaff(staff) | ||||
}, [staff]); | }, [staff]); | ||||
@@ -147,6 +161,7 @@ const StaffSearch: React.FC<Props> = ({ staff, teams, grades, positions, abiliti | |||||
return ( | return ( | ||||
<> | <> | ||||
… | |||||
<SearchBox | <SearchBox | ||||
criteria={searchCriteria} | criteria={searchCriteria} | ||||
onSearch={(query) => { | onSearch={(query) => { | ||||
@@ -165,6 +180,21 @@ const StaffSearch: React.FC<Props> = ({ staff, teams, grades, positions, abiliti | |||||
}} | }} | ||||
/> | /> | ||||
<SearchResults<StaffResult> items={filteredStaff} columns={columns} /> | <SearchResults<StaffResult> items={filteredStaff} columns={columns} /> | ||||
<Stack | |||||
direction="row" | |||||
justifyContent="flex-end" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
> | |||||
<Button | |||||
variant="contained" | |||||
startIcon={<FileDownloadIcon />} | |||||
onClick={() => handleExport(filteredStaff.map(staff => staff.id))} | |||||
> | |||||
{t("Export")} | |||||
</Button> | |||||
</Stack> | |||||
</> | </> | ||||
); | ); | ||||
}; | }; | ||||