improved export button

This commit is contained in:
juhanikat
2025-05-27 16:20:34 +03:00
parent 777035bd50
commit dcf30bc0d8
3 changed files with 83 additions and 24 deletions
@@ -0,0 +1,44 @@
import { useState } from 'react'
import { useNotify } from '@/hooks/notification'
import { BACKEND_URL } from '@/util/config'
import { Box, Button, CircularProgress } from '@mui/material'
export const CrossSearchExportButton = () => {
const [loading, setLoading] = useState(false)
const notify = useNotify()
const fetchCSVFile = () => {
setLoading(true)
notify('Download started, please wait...')
fetch(`${BACKEND_URL}/crosssearch/export`)
.then(response => {
if (!response.ok) {
throw new Error('Server response was not OK.')
}
return response.blob()
})
.then(blob => {
const url = window.URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'cross_search_export.csv'
document.body.appendChild(a)
a.click()
a.remove()
window.URL.revokeObjectURL(url)
})
.catch(_ => {
notify('Downloading cross-search export failed.', 'error')
})
.finally(() => setLoading(false))
}
return (
<Box>
<Button onClick={() => fetchCSVFile()} variant="contained" disabled={loading}>
Export table
</Button>
{loading && <CircularProgress />}
</Box>
)
}
@@ -29,30 +29,6 @@ type TableStateInUrl = 'sorting' | 'columnfilters' | 'pagination'
selectorFn should only be defined if using this as a selecting table
*/
const CrossSearchExportButton = () => {
// loading is set to false after a timeout because actually knowing
// once the file is downloaded is impossible when implemented this way
const [loading, setLoading] = useState(false)
return (
<Box>
<Button
href={`${BACKEND_URL}/crosssearch/export`}
onClick={() => {
setLoading(true)
setTimeout(() => {
setLoading(false)
}, 20000)
}}
variant="contained"
disabled={loading}
>
Export cross search table
</Button>
{loading && <CircularProgress />}
</Box>
)
}
export const TableView = <T extends MRT_RowData>({
data,
columns,
@@ -135,6 +111,15 @@ export const TableView = <T extends MRT_RowData>({
else rowCount = data.length
}
let toolbar
if (isCrossSearchTable) {
toolbar = renderCustomToolbarCrossSearchVersion
} else if (selectorFn) {
toolbar = renderCustomToolbarModalVersion
} else {
toolbar = renderCustomToolbar
}
const table = useMaterialReactTable({
columns: columns,
data: data || [],
@@ -7,6 +7,7 @@ import {
} from 'material-react-table'
import { mkConfig, generateCsv, download } from 'export-to-csv'
import { AcceptedData } from 'node_modules/export-to-csv/output/lib/types'
import { CrossSearchExportButton } from '../CrossSearch/CrossSearchExportButton'
export type ExportFn<T> = (data: T) => { [k: string]: AcceptedData }
@@ -47,3 +48,32 @@ export const renderCustomToolbarModalVersion = <T extends MRT_RowData>({ table }
<MRT_ShowHideColumnsButton table={table} />
</Box>
)
export const renderCustomToolbarCrossSearchVersion = <T extends MRT_RowData>({
table,
}: {
table: MRT_TableInstance<T>
}) => (
<>
<Box>
<MRT_ShowHideColumnsButton table={table} />
<MRT_ToggleFullScreenButton table={table} />
</Box>
<Box>
<CrossSearchExportButton />
</Box>
</>
)
export const renderCustomToolbar = <T extends MRT_RowData>({ table }: { table: MRT_TableInstance<T> }) => (
<>
<Box>
<MRT_ShowHideColumnsButton table={table} />
<MRT_ToggleFullScreenButton table={table} />
</Box>
<Box>
<Button onClick={() => exportRows(table)} variant="contained">
Export table
</Button>
</Box>
</>
)