diff --git a/ui/src/components/DeadTasksTable.tsx b/ui/src/components/DeadTasksTable.tsx index 2e25e13..122e1a1 100644 --- a/ui/src/components/DeadTasksTable.tsx +++ b/ui/src/components/DeadTasksTable.tsx @@ -5,6 +5,8 @@ import Table from "@material-ui/core/Table"; import TableBody from "@material-ui/core/TableBody"; import TableCell from "@material-ui/core/TableCell"; import Button from "@material-ui/core/Button"; +import ButtonGroup from "@material-ui/core/ButtonGroup"; +import Checkbox from "@material-ui/core/Checkbox"; import TableContainer from "@material-ui/core/TableContainer"; import TableHead from "@material-ui/core/TableHead"; import TableRow from "@material-ui/core/TableRow"; @@ -17,6 +19,7 @@ import KeyboardArrowDownIcon from "@material-ui/icons/KeyboardArrowDown"; import Typography from "@material-ui/core/Typography"; import TableFooter from "@material-ui/core/TableFooter"; import TablePagination from "@material-ui/core/TablePagination"; +import MoreHorizIcon from "@material-ui/icons/MoreHoriz"; import Alert from "@material-ui/lab/Alert"; import AlertTitle from "@material-ui/lab/AlertTitle"; import SyntaxHighlighter from "react-syntax-highlighter"; @@ -38,6 +41,12 @@ const useStyles = makeStyles({ table: { minWidth: 650, }, + actionsContainer: { + padding: "4px", + }, + moreIcon: { + marginRight: "8px", + }, }); const useRowStyles = makeStyles({ @@ -72,6 +81,7 @@ function DeadTasksTable(props: Props & ReduxProps) { const classes = useStyles(); const [page, setPage] = useState(0); const [pageSize, setPageSize] = useState(defaultPageSize); + const [selected, setSelected] = useState([]); const handleChangePage = ( event: React.MouseEvent | null, @@ -87,6 +97,15 @@ function DeadTasksTable(props: Props & ReduxProps) { setPage(0); }; + const handleSelectAllClick = (event: React.ChangeEvent) => { + if (event.target.checked) { + const newSelected = props.tasks.map((t) => t.id); + setSelected(newSelected); + } else { + setSelected([]); + } + }; + const fetchData = useCallback(() => { const pageOpts = { page: page + 1, size: pageSize }; listDeadTasksAsync(queue, pageOpts); @@ -112,67 +131,116 @@ function DeadTasksTable(props: Props & ReduxProps) { { label: "Actions" }, ]; + const rowCount = props.tasks.length; + const numSelected = selected.length; return ( - - - - - {columns.map((col) => ( - {col.label} +
+
+ + + + {numSelected > 0 && ( + + + + + + )} +
+ +
+ + + + 0 && numSelected < rowCount} + checked={rowCount > 0 && numSelected === rowCount} + onChange={handleSelectAllClick} + inputProps={{ "aria-label": "select all dead tasks" }} + /> + + {columns.map((col) => ( + {col.label} + ))} + + + + {props.tasks.map((task) => ( + { + if (checked) { + setSelected(selected.concat(task.id)); + } else { + setSelected(selected.filter((id) => id !== task.id)); + } + }} + onDeleteClick={() => { + props.deleteDeadTaskAsync(queue, task.key); + }} + /> ))} - - - - {props.tasks.map((task) => ( - { - props.deleteDeadTaskAsync(queue, task.key); - }} - /> - ))} - - - - - - -
-
+ + + + + + + + + ); } interface RowProps { task: DeadTaskExtended; + isSelected: boolean; + onSelectChange: (checked: boolean) => void; onDeleteClick: () => void; } function Row(props: RowProps) { const { task } = props; - const [open, setOpen] = React.useState(false); + const [open, setOpen] = useState(false); const classes = useRowStyles(); + + const labelId = `dead-tasks-table-checkbox-${task.id}`; return ( + + ) => + props.onSelectChange(event.target.checked) + } + checked={props.isSelected} + inputProps={{ "aria-labelledby": labelId }} + /> + - +