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 axiosInstance from "../http/axiosInstance" |
||||
import { DataGrid } from "@mui/x-data-grid" |
import { DataGrid } from "@mui/x-data-grid" |
||||
import { BASE_URL } from "../constants" |
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() { |
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') |
const link = document.createElement('a') |
||||
link.href = url |
link.href = url |
||||
link.setAttribute('download', 'report.xlsx') |
link.setAttribute('download', 'report.xlsx') |
||||
document.body.appendChild(link); |
document.body.appendChild(link); |
||||
link.click(); |
link.click(); |
||||
link.remove(); |
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 ( |
return ( |
||||
<> |
<> |
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '16px' }}> |
<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> |
</Button> |
||||
</Box> |
</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> |
</Box> |
||||
</> |
</> |
||||
) |
) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue