forked from VinokurovVE/tests
2 changed files with 126 additions and 58 deletions
@ -1,82 +1,134 @@ |
|||
import { useState } from "react" |
|||
import { Box, Button } from "@mui/material" |
|||
import { Fragment, useEffect, useState } from "react" |
|||
import { Autocomplete, Box, Button, CircularProgress, IconButton, TextField } from "@mui/material" |
|||
import axiosInstance from "../http/axiosInstance" |
|||
import { DataGrid } from "@mui/x-data-grid" |
|||
import { BASE_URL } from "../constants" |
|||
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 [state, setState] = useState(null) |
|||
const [download, setDownload] = useState(false) |
|||
|
|||
const fetch = async () => { |
|||
await axiosInstance.get(`/info/reports/0?to_export=true`, { |
|||
responseType: 'blob', |
|||
baseURL: BASE_URL.info |
|||
}).then(response => { |
|||
const url = window.URL.createObjectURL(response.data) |
|||
const [options, setOptions] = useState<ICity[]>([]) |
|||
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) |
|||
|
|||
useEffect(() => { |
|||
if (cities) { |
|||
setOptions([...cities]) |
|||
} |
|||
}, [cities]) |
|||
|
|||
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 fetchBlob = async () => { |
|||
await axiosInstance.get(`/info/reports/0`).then(response => { |
|||
setState(JSON.parse(response.data)) |
|||
}) |
|||
const exportReport = async () => { |
|||
setDownload(true) |
|||
} |
|||
|
|||
return ( |
|||
<> |
|||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '16px' }}> |
|||
<Box> |
|||
<Button onClick={() => fetchBlob()}> |
|||
Получить отчет |
|||
</Button> |
|||
<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={options} |
|||
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> |
|||
) |
|||
}} |
|||
/> |
|||
)} |
|||
/> |
|||
|
|||
<Button onClick={() => fetch()}> |
|||
<IconButton onClick={() => refreshReport()}> |
|||
<Update /> |
|||
</IconButton> |
|||
|
|||
<Button onClick={() => exportReport()}> |
|||
Экспорт |
|||
</Button> |
|||
</Box> |
|||
|
|||
{state && |
|||
<DataGrid |
|||
autoHeight |
|||
style={{ width: "100%" }} |
|||
rows={[...new Set(Object.keys(state).flatMap(key => Object.keys(state[key])))].map(id => { |
|||
const row: any = { id: Number(id) }; |
|||
Object.keys(state).forEach(key => { |
|||
row[key] = state[key][id]; |
|||
}); |
|||
return row; |
|||
})} |
|||
columns={[ |
|||
{ field: 'id', headerName: '№', width: 70 }, |
|||
...Object.keys(state).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 |
|||
<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 |
|||
}} |
|||
processRowUpdate={(updatedRow) => { |
|||
return updatedRow |
|||
}} |
|||
|
|||
onProcessRowUpdateError={() => { |
|||
}} |
|||
/> |
|||
} |
|||
onProcessRowUpdateError={() => { |
|||
}} |
|||
/> |
|||
</Box> |
|||
</> |
|||
) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue