diff --git a/ui/src/components/ActiveTasksTable.tsx b/ui/src/components/ActiveTasksTable.tsx index 87b4d46..6ed5395 100644 --- a/ui/src/components/ActiveTasksTable.tsx +++ b/ui/src/components/ActiveTasksTable.tsx @@ -14,6 +14,7 @@ import TableFooter from "@material-ui/core/TableFooter"; import TablePagination from "@material-ui/core/TablePagination"; import Paper from "@material-ui/core/Paper"; import Box from "@material-ui/core/Box"; +import Checkbox from "@material-ui/core/Checkbox"; import Collapse from "@material-ui/core/Collapse"; import IconButton from "@material-ui/core/IconButton"; import KeyboardArrowUpIcon from "@material-ui/icons/KeyboardArrowUp"; @@ -63,6 +64,7 @@ function ActiveTasksTable(props: Props & ReduxProps) { const classes = useStyles(); const [page, setPage] = useState(0); const [pageSize, setPageSize] = useState(defaultPageSize); + const [selectedIds, setSelectedIds] = useState([]); const handleChangePage = ( event: React.MouseEvent | null, @@ -78,6 +80,15 @@ function ActiveTasksTable(props: Props & ReduxProps) { setPage(0); }; + const handleSelectAllClick = (event: React.ChangeEvent) => { + if (event.target.checked) { + const newSelected = props.tasks.map((t) => t.id); + setSelectedIds(newSelected); + } else { + setSelectedIds([]); + } + }; + const fetchData = useCallback(() => { const pageOpts = { page: page + 1, size: pageSize }; listActiveTasksAsync(queue, pageOpts); @@ -101,6 +112,8 @@ function ActiveTasksTable(props: Props & ReduxProps) { { label: "Actions", align: "center" }, ]; + const rowCount = props.tasks.length; + const numSelected = selectedIds.length; return ( + + 0 && numSelected < rowCount} + checked={rowCount > 0 && numSelected === rowCount} + onChange={handleSelectAllClick} + inputProps={{ + "aria-label": "select all tasks shown in the table", + }} + /> + {columns.map((col) => ( {col.label} @@ -124,6 +147,14 @@ function ActiveTasksTable(props: Props & ReduxProps) { { + if (checked) { + setSelectedIds(selectedIds.concat(task.id)); + } else { + setSelectedIds(selectedIds.filter((id) => id !== task.id)); + } + }} onCancelClick={() => { props.cancelActiveTaskAsync(queue, task.id); }} @@ -161,13 +192,32 @@ const useRowStyles = makeStyles({ }, }); -function Row(props: { task: ActiveTaskExtended; onCancelClick: () => void }) { +interface RowProps { + task: ActiveTaskExtended; + isSelected: boolean; + onSelectChange: (checked: boolean) => void; + onCancelClick: () => void; +} + +function Row(props: RowProps) { const { task } = props; const [open, setOpen] = React.useState(false); const classes = useRowStyles(); return ( - + + + ) => + props.onSelectChange(event.target.checked) + } + checked={props.isSelected} + /> + void }) { - +