frontend/app/ScanTargets/ScanTargetsList.tsx (88 lines of code) (raw):
import React, {useEffect, useState} from "react";
import {RouteComponentProps} from "react-router";
import {Button, Grid, makeStyles, Paper, Snackbar} from "@material-ui/core";
import LoadingThrobber from "../common/LoadingThrobber.jsx";
import axios from "axios";
import {DataGrid} from "@material-ui/data-grid";
import {makeScanTargetColumns} from "./ScanTargetsListContent";
import {ScanTarget, ScanTargetResponse} from "../types";
import AdminContainer from "../admin/AdminContainer";
import { baseStyles } from "../BaseStyles";
import MuiAlert from "@material-ui/lab/Alert";
import {formatError} from "../common/ErrorViewComponent";
import {Helmet} from "react-helmet";
const useStyles = makeStyles(Object.assign({
tableContainer: {
marginTop: "1em",
height: "80vh"
}
}, baseStyles));
const ScanTargetsList:React.FC<RouteComponentProps> = (props) => {
const [loading, setLoading] = useState(false);
const [currentActionCaption, setCurrentActionCaption] = useState("Loading...");
const [lastError, setLastError] = useState<string|null>(null)
const [scanTargets, setScanTargets] = useState<ScanTarget[]>([]);
const [showingAlert, setShowingAlert] = useState(false);
const classes = useStyles();
const doLoad = async ()=> {
try {
const response = await axios.get<ScanTargetResponse>("/api/scanTarget")
setScanTargets(response.data.entries.map((entry, idx)=>Object.assign({}, entry, {id: idx})));
setLoading(false);
} catch (err) {
console.error("Could not load in scan targets: ", err);
setLoading(false);
setLastError(err.toString());
}
}
useEffect(()=>{
setLoading(true);
doLoad();
}, []);
const newButtonClicked = () => {
props.history.push('/admin/scanTargets/new');
}
const deletionCb = async (targetName:string)=> {
try {
await axios.delete(`/api/scanTarget/${targetName}`);
window.setTimeout(()=> {
setScanTargets([]);
setLoading(true);
return doLoad();
}, 500);
} catch(err) {
console.error("Could not delete scan target: ", err);
setLastError(formatError(err, false));
setShowingAlert(true);
}
}
const scanTargetColumns = makeScanTargetColumns(deletionCb);
const closeAlert = ()=>setShowingAlert(false);
return <>
<Helmet>
<title>Scan Targets - Archive Hunter</title>
</Helmet>
<AdminContainer {...props}>
{lastError ?
<Snackbar open={showingAlert} onClose={closeAlert} autoHideDuration={8000}>
<MuiAlert onClose={closeAlert}>{lastError}</MuiAlert>
</Snackbar> : null
}
<Grid container justify="space-between">
<Grid item>
<LoadingThrobber show={loading} small={true} caption={currentActionCaption}/>
</Grid>
<Grid item >
<Button variant="contained" onClick={newButtonClicked}>New</Button>
</Grid>
</Grid>
<Paper elevation={3} className={classes.tableContainer}>
<DataGrid columns={scanTargetColumns}
rows={scanTargets}
pageSize={20}
pagination
rowsPerPageOptions={[5,10,20,50]}
/>
</Paper>
</AdminContainer>
</>
}
export default ScanTargetsList;