frontend/app/DeletedItems/DeletedItemsTable.tsx (101 lines of code) (raw):
import React, {useEffect, useRef, useState} from "react";
import {ColDef, DataGrid} from "@material-ui/data-grid";
import PathDisplayComponent from "../browse/PathDisplayComponent";
import {ArchiveEntry} from "../types";
import FileSizeView from "../Entry/FileSizeView";
import TimestampFormatter from "../common/TimestampFormatter";
import {Grid, IconButton, makeStyles, Tooltip} from "@material-ui/core";
import {DeleteForever, Launch} from "@material-ui/icons";
interface DeletedItemsTableProps {
entries: ArchiveEntry[];
requestDelete: (itemId:string)=>void;
currentlyLoading: boolean;
requestOpen: (itemId:string)=>void;
}
/**
* wrapper that only re-renders the table every 30 updates, to prevent slowing down the browser
* @param props
* @constructor
*/
const DeletedItemsTable:React.FC<DeletedItemsTableProps> = (props:DeletedItemsTableProps) => {
const [unrenderedItemCount, setUnrenderedItemCount] = useState(0);
const unrenderedItemCountRef = useRef<number>();
unrenderedItemCountRef.current = unrenderedItemCount;
const WrappedComponent = React.memo(DeletedItemsTableContent, (prevProps, nextProps)=>{
if(!nextProps.currentlyLoading) { //perform the update always if the state we are moving to is not a loading state
return false
}
if(unrenderedItemCountRef.current && unrenderedItemCountRef.current>30) {
setUnrenderedItemCount(0);
return false;
} else {
setUnrenderedItemCount((prev)=>prev+1);
return true;
}
})
return <WrappedComponent {...props}/>
}
const useStyles = makeStyles({
ellipsizedText: {
overflow: "hidden",
textOverflow: "ellipsis"
}
});
const DeletedItemsTableContent:React.FC<DeletedItemsTableProps> = (props) => {
const classes = useStyles();
const columns:ColDef[] = [
{
field: "bucket",
headerName: "Collection",
renderCell: (params)=><Tooltip title={params.value as string}>
<p className={classes.ellipsizedText}>{params.value as string}</p>
</Tooltip>
},
{
field: "path",
headerName: "Path",
width: 500,
renderCell: (params)=><Tooltip title={params.value as string}><p className={classes.ellipsizedText}>{params.value as string}</p></Tooltip>
},
{
field: "size",
headerName: "Size",
renderCell: (params)=><FileSizeView rawSize={params.getValue("size") as number}/>
},
{
field: "storageClass",
headerName: "Storage Class",
width: 150
},
{
field: "last_modified",
headerName: "Last Modified",
renderCell: (params)=><TimestampFormatter relative={false}
value={params.getValue("last_modified") as string}
formatString={"HH:mm ddd Do MMM YYYY Z"}
/>,
width: 250
},
{
field: "proxied",
headerName: "Proxied?",
},
{
field: "id",
headerName: " ",
width: 150,
renderCell: (params)=><Grid container direction="row" spacing={0}>
<Grid item>
<Tooltip title="Remove this tombstone">
<IconButton onClick={()=>props.requestDelete(params.value as string)}>
<DeleteForever/>
</IconButton>
</Tooltip>
</Grid>
<Grid item>
<Tooltip title="View the item">
<IconButton onClick={()=>props.requestOpen(params.value as string)}>
<Launch/>
</IconButton>
</Tooltip>
</Grid>
</Grid>
}
];
return <DataGrid columns={columns}
rows={props.entries}
/>
}
export default DeletedItemsTable;