forked from VinokurovVE/tests
126 lines
5.0 KiB
TypeScript
126 lines
5.0 KiB
TypeScript
import { Fragment, useEffect, useState } from "react"
|
||
import { Autocomplete, Box, Button, CircularProgress, IconButton, TextField } from "@mui/material"
|
||
import { DataGrid } from "@mui/x-data-grid"
|
||
import { useCities, useReport, useReportExport } from "../hooks/swrHooks"
|
||
import { useDebounce } from "@uidotdev/usehooks"
|
||
import { ICity } from "../interfaces/fuel"
|
||
import { Update } from "@mui/icons-material"
|
||
import { mutate } from "swr"
|
||
|
||
export default function Reports() {
|
||
const [download, setDownload] = useState(false)
|
||
|
||
const [search, setSearch] = useState<string | null>("")
|
||
const debouncedSearch = useDebounce(search, 500)
|
||
const [selectedOption, setSelectedOption] = useState<ICity | null>(null)
|
||
const { cities, isLoading } = useCities(10, 1, debouncedSearch)
|
||
|
||
const { report, isLoading: reportLoading } = useReport(selectedOption?.id)
|
||
|
||
const { reportExported } = useReportExport(selectedOption?.id, download)
|
||
|
||
const refreshReport = async () => {
|
||
mutate(`/info/reports/${selectedOption?.id}?to_export=false`)
|
||
}
|
||
|
||
useEffect(() => {
|
||
if (selectedOption && reportExported && download) {
|
||
const url = window.URL.createObjectURL(reportExported)
|
||
const link = document.createElement('a')
|
||
link.href = url
|
||
link.setAttribute('download', 'report.xlsx')
|
||
document.body.appendChild(link);
|
||
link.click();
|
||
link.remove();
|
||
setDownload(false)
|
||
}
|
||
}, [selectedOption, reportExported, download])
|
||
|
||
const exportReport = async () => {
|
||
setDownload(true)
|
||
}
|
||
|
||
return (
|
||
<>
|
||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
||
<Box sx={{ display: 'flex', gap: '16px' }}>
|
||
<Autocomplete
|
||
fullWidth
|
||
onInputChange={(_, value) => setSearch(value)}
|
||
onChange={(_, value) => setSelectedOption(value)}
|
||
isOptionEqualToValue={(option: ICity, value: ICity) => option.id === value.id}
|
||
getOptionLabel={(option: ICity) => option.name ? option.name : ""}
|
||
options={cities || []}
|
||
loading={isLoading}
|
||
value={selectedOption}
|
||
renderInput={(params) => (
|
||
<TextField
|
||
{...params}
|
||
size='small'
|
||
label="Населенный пункт"
|
||
InputProps={{
|
||
...params.InputProps,
|
||
endAdornment: (
|
||
<Fragment>
|
||
{isLoading ? <CircularProgress color="inherit" size={20} /> : null}
|
||
{params.InputProps.endAdornment}
|
||
</Fragment>
|
||
)
|
||
}}
|
||
/>
|
||
)}
|
||
/>
|
||
|
||
<IconButton onClick={() => refreshReport()}>
|
||
<Update />
|
||
</IconButton>
|
||
|
||
<Button onClick={() => exportReport()}>
|
||
Экспорт
|
||
</Button>
|
||
</Box>
|
||
|
||
<DataGrid
|
||
autoHeight
|
||
style={{ width: "100%" }}
|
||
loading={reportLoading}
|
||
rows={
|
||
report ?
|
||
[...new Set(Object.keys(report).flatMap(key => Object.keys(report[key])))].map(id => {
|
||
const row: any = { id: Number(id) };
|
||
Object.keys(report).forEach(key => {
|
||
row[key] = report[key][id];
|
||
});
|
||
return row;
|
||
})
|
||
:
|
||
[]
|
||
}
|
||
columns={[
|
||
{ field: 'id', headerName: '№', width: 70 },
|
||
...Object.keys(report).map(key => ({
|
||
field: key,
|
||
headerName: key.charAt(0).toUpperCase() + key.slice(1),
|
||
width: 150
|
||
}))
|
||
]}
|
||
initialState={{
|
||
pagination: {
|
||
paginationModel: { page: 0, pageSize: 10 },
|
||
},
|
||
}}
|
||
pageSizeOptions={[10, 20, 50, 100]}
|
||
checkboxSelection={false}
|
||
disableRowSelectionOnClick
|
||
|
||
processRowUpdate={(updatedRow) => {
|
||
return updatedRow
|
||
}}
|
||
|
||
onProcessRowUpdateError={() => {
|
||
}}
|
||
/>
|
||
</Box>
|
||
</>
|
||
)
|
||
} |