mirror of
https://github.com/hibiken/asynqmon.git
synced 2025-01-19 11:15:53 +08:00
Add alert dialog for delete action in QueuesOverviewTable
This commit is contained in:
parent
26e5890a4e
commit
003a88d17b
@ -2,6 +2,12 @@ import React, { useState } from "react";
|
|||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
|
import Button from "@material-ui/core/Button";
|
||||||
|
import Dialog from "@material-ui/core/Dialog";
|
||||||
|
import DialogActions from "@material-ui/core/DialogActions";
|
||||||
|
import DialogContent from "@material-ui/core/DialogContent";
|
||||||
|
import DialogContentText from "@material-ui/core/DialogContentText";
|
||||||
|
import DialogTitle from "@material-ui/core/DialogTitle";
|
||||||
import Table from "@material-ui/core/Table";
|
import Table from "@material-ui/core/Table";
|
||||||
import TableBody from "@material-ui/core/TableBody";
|
import TableBody from "@material-ui/core/TableBody";
|
||||||
import TableCell from "@material-ui/core/TableCell";
|
import TableCell from "@material-ui/core/TableCell";
|
||||||
@ -112,6 +118,7 @@ export default function QueuesOverviewTable(props: Props) {
|
|||||||
const [sortBy, setSortBy] = useState<SortBy>(SortBy.Queue);
|
const [sortBy, setSortBy] = useState<SortBy>(SortBy.Queue);
|
||||||
const [sortDir, setSortDir] = useState<SortDirection>(SortDirection.Asc);
|
const [sortDir, setSortDir] = useState<SortDirection>(SortDirection.Asc);
|
||||||
const [activeRowIndex, setActiveRowIndex] = useState<number>(-1);
|
const [activeRowIndex, setActiveRowIndex] = useState<number>(-1);
|
||||||
|
const [queueToDelete, setQueueToDelete] = useState<Queue | null>(null);
|
||||||
const total = getAggregateCounts(props.queues);
|
const total = getAggregateCounts(props.queues);
|
||||||
|
|
||||||
const createSortClickHandler = (sortKey: SortBy) => (e: React.MouseEvent) => {
|
const createSortClickHandler = (sortKey: SortBy) => (e: React.MouseEvent) => {
|
||||||
@ -168,156 +175,190 @@ export default function QueuesOverviewTable(props: Props) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleDialogClose = () => {
|
||||||
|
setQueueToDelete(null);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableContainer>
|
<React.Fragment>
|
||||||
<Table className={classes.table} aria-label="queues overview table">
|
<TableContainer>
|
||||||
<TableHead>
|
<Table className={classes.table} aria-label="queues overview table">
|
||||||
<TableRow>
|
<TableHead>
|
||||||
{colConfigs.map((cfg, i) => (
|
<TableRow>
|
||||||
<TableCell
|
{colConfigs.map((cfg, i) => (
|
||||||
key={cfg.key}
|
<TableCell
|
||||||
align={cfg.align}
|
key={cfg.key}
|
||||||
className={clsx(i === 0 && classes.fixedCell)}
|
align={cfg.align}
|
||||||
>
|
className={clsx(i === 0 && classes.fixedCell)}
|
||||||
{cfg.sortBy !== SortBy.None ? (
|
|
||||||
<TableSortLabel
|
|
||||||
active={sortBy === cfg.sortBy}
|
|
||||||
direction={sortDir}
|
|
||||||
onClick={createSortClickHandler(cfg.sortBy)}
|
|
||||||
>
|
|
||||||
{cfg.label}
|
|
||||||
</TableSortLabel>
|
|
||||||
) : (
|
|
||||||
<div>{cfg.label}</div>
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
))}
|
|
||||||
</TableRow>
|
|
||||||
</TableHead>
|
|
||||||
<TableBody>
|
|
||||||
{sortQueues(props.queues, cmpFunc).map((q, i) => (
|
|
||||||
<TableRow
|
|
||||||
key={q.queue}
|
|
||||||
onMouseEnter={() => setActiveRowIndex(i)}
|
|
||||||
onMouseLeave={() => setActiveRowIndex(-1)}
|
|
||||||
>
|
|
||||||
<TableCell
|
|
||||||
component="th"
|
|
||||||
scope="row"
|
|
||||||
className={clsx(classes.boldCell, classes.fixedCell)}
|
|
||||||
>
|
|
||||||
<Link to={queueDetailsPath(q.queue)}>
|
|
||||||
{q.queue}
|
|
||||||
{q.paused ? " (paused)" : ""}
|
|
||||||
</Link>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="right" className={classes.boldCell}>
|
|
||||||
{q.size}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="right">
|
|
||||||
<Link
|
|
||||||
to={queueDetailsPath(q.queue, "active")}
|
|
||||||
className={classes.linkCell}
|
|
||||||
>
|
>
|
||||||
{q.active}
|
{cfg.sortBy !== SortBy.None ? (
|
||||||
</Link>
|
<TableSortLabel
|
||||||
</TableCell>
|
active={sortBy === cfg.sortBy}
|
||||||
<TableCell align="right">
|
direction={sortDir}
|
||||||
<Link
|
onClick={createSortClickHandler(cfg.sortBy)}
|
||||||
to={queueDetailsPath(q.queue, "pending")}
|
>
|
||||||
className={classes.linkCell}
|
{cfg.label}
|
||||||
>
|
</TableSortLabel>
|
||||||
{q.pending}
|
|
||||||
</Link>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="right">
|
|
||||||
<Link
|
|
||||||
to={queueDetailsPath(q.queue, "scheduled")}
|
|
||||||
className={classes.linkCell}
|
|
||||||
>
|
|
||||||
{q.scheduled}
|
|
||||||
</Link>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="right">
|
|
||||||
<Link
|
|
||||||
to={queueDetailsPath(q.queue, "retry")}
|
|
||||||
className={classes.linkCell}
|
|
||||||
>
|
|
||||||
{q.retry}
|
|
||||||
</Link>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="right">
|
|
||||||
<Link
|
|
||||||
to={queueDetailsPath(q.queue, "dead")}
|
|
||||||
className={classes.linkCell}
|
|
||||||
>
|
|
||||||
{q.dead}
|
|
||||||
</Link>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="center">
|
|
||||||
<div className={classes.actionIconsContainer}>
|
|
||||||
{activeRowIndex === i ? (
|
|
||||||
<React.Fragment>
|
|
||||||
{q.paused ? (
|
|
||||||
<IconButton
|
|
||||||
color="secondary"
|
|
||||||
onClick={() => props.onResumeClick(q.queue)}
|
|
||||||
disabled={q.pauseRequestPending}
|
|
||||||
>
|
|
||||||
<PlayCircleFilledIcon />
|
|
||||||
</IconButton>
|
|
||||||
) : (
|
|
||||||
<IconButton
|
|
||||||
color="primary"
|
|
||||||
onClick={() => props.onPauseClick(q.queue)}
|
|
||||||
disabled={q.pauseRequestPending}
|
|
||||||
>
|
|
||||||
<PauseCircleFilledIcon />
|
|
||||||
</IconButton>
|
|
||||||
)}
|
|
||||||
<IconButton
|
|
||||||
onClick={() => console.log("TODO: delete this queue")}
|
|
||||||
>
|
|
||||||
<DeleteIcon />
|
|
||||||
</IconButton>
|
|
||||||
</React.Fragment>
|
|
||||||
) : (
|
) : (
|
||||||
<IconButton>
|
<div>{cfg.label}</div>
|
||||||
<MoreHorizIcon />
|
|
||||||
</IconButton>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{sortQueues(props.queues, cmpFunc).map((q, i) => (
|
||||||
|
<TableRow
|
||||||
|
key={q.queue}
|
||||||
|
onMouseEnter={() => setActiveRowIndex(i)}
|
||||||
|
onMouseLeave={() => setActiveRowIndex(-1)}
|
||||||
|
>
|
||||||
|
<TableCell
|
||||||
|
component="th"
|
||||||
|
scope="row"
|
||||||
|
className={clsx(classes.boldCell, classes.fixedCell)}
|
||||||
|
>
|
||||||
|
<Link to={queueDetailsPath(q.queue)}>
|
||||||
|
{q.queue}
|
||||||
|
{q.paused ? " (paused)" : ""}
|
||||||
|
</Link>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="right" className={classes.boldCell}>
|
||||||
|
{q.size}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="right">
|
||||||
|
<Link
|
||||||
|
to={queueDetailsPath(q.queue, "active")}
|
||||||
|
className={classes.linkCell}
|
||||||
|
>
|
||||||
|
{q.active}
|
||||||
|
</Link>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="right">
|
||||||
|
<Link
|
||||||
|
to={queueDetailsPath(q.queue, "pending")}
|
||||||
|
className={classes.linkCell}
|
||||||
|
>
|
||||||
|
{q.pending}
|
||||||
|
</Link>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="right">
|
||||||
|
<Link
|
||||||
|
to={queueDetailsPath(q.queue, "scheduled")}
|
||||||
|
className={classes.linkCell}
|
||||||
|
>
|
||||||
|
{q.scheduled}
|
||||||
|
</Link>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="right">
|
||||||
|
<Link
|
||||||
|
to={queueDetailsPath(q.queue, "retry")}
|
||||||
|
className={classes.linkCell}
|
||||||
|
>
|
||||||
|
{q.retry}
|
||||||
|
</Link>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="right">
|
||||||
|
<Link
|
||||||
|
to={queueDetailsPath(q.queue, "dead")}
|
||||||
|
className={classes.linkCell}
|
||||||
|
>
|
||||||
|
{q.dead}
|
||||||
|
</Link>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="center">
|
||||||
|
<div className={classes.actionIconsContainer}>
|
||||||
|
{activeRowIndex === i ? (
|
||||||
|
<React.Fragment>
|
||||||
|
{q.paused ? (
|
||||||
|
<IconButton
|
||||||
|
color="secondary"
|
||||||
|
onClick={() => props.onResumeClick(q.queue)}
|
||||||
|
disabled={q.pauseRequestPending}
|
||||||
|
>
|
||||||
|
<PlayCircleFilledIcon />
|
||||||
|
</IconButton>
|
||||||
|
) : (
|
||||||
|
<IconButton
|
||||||
|
color="primary"
|
||||||
|
onClick={() => props.onPauseClick(q.queue)}
|
||||||
|
disabled={q.pauseRequestPending}
|
||||||
|
>
|
||||||
|
<PauseCircleFilledIcon />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
<IconButton onClick={() => setQueueToDelete(q)}>
|
||||||
|
<DeleteIcon />
|
||||||
|
</IconButton>
|
||||||
|
</React.Fragment>
|
||||||
|
) : (
|
||||||
|
<IconButton>
|
||||||
|
<MoreHorizIcon />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
<TableFooter>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell
|
||||||
|
className={clsx(classes.fixedCell, classes.footerCell)}
|
||||||
|
>
|
||||||
|
Total
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className={classes.footerCell} align="right">
|
||||||
|
{total.size}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className={classes.footerCell} align="right">
|
||||||
|
{total.active}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className={classes.footerCell} align="right">
|
||||||
|
{total.pending}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className={classes.footerCell} align="right">
|
||||||
|
{total.scheduled}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className={classes.footerCell} align="right">
|
||||||
|
{total.retry}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className={classes.footerCell} align="right">
|
||||||
|
{total.dead}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
</TableFooter>
|
||||||
</TableBody>
|
</Table>
|
||||||
<TableFooter>
|
</TableContainer>
|
||||||
<TableRow>
|
<Dialog
|
||||||
<TableCell className={clsx(classes.fixedCell, classes.footerCell)}>
|
open={queueToDelete !== null}
|
||||||
Total
|
onClose={handleDialogClose}
|
||||||
</TableCell>
|
aria-labelledby="alert-dialog-title"
|
||||||
<TableCell className={classes.footerCell} align="right">
|
aria-describedby="alert-dialog-description"
|
||||||
{total.size}
|
>
|
||||||
</TableCell>
|
{queueToDelete !== null && (
|
||||||
<TableCell className={classes.footerCell} align="right">
|
<>
|
||||||
{total.active}
|
<DialogTitle id="alert-dialog-title">
|
||||||
</TableCell>
|
Are you sure you want to delete "{queueToDelete.queue}"?
|
||||||
<TableCell className={classes.footerCell} align="right">
|
</DialogTitle>
|
||||||
{total.pending}
|
<DialogContent>
|
||||||
</TableCell>
|
<DialogContentText id="alert-dialog-description">
|
||||||
<TableCell className={classes.footerCell} align="right">
|
All of the tasks in the queue will be deleted. You can't undo
|
||||||
{total.scheduled}
|
this action.
|
||||||
</TableCell>
|
</DialogContentText>
|
||||||
<TableCell className={classes.footerCell} align="right">
|
</DialogContent>
|
||||||
{total.retry}
|
<DialogActions>
|
||||||
</TableCell>
|
<Button onClick={handleDialogClose} color="primary">
|
||||||
<TableCell className={classes.footerCell} align="right">
|
Cancel
|
||||||
{total.dead}
|
</Button>
|
||||||
</TableCell>
|
<Button onClick={handleDialogClose} color="primary" autoFocus>
|
||||||
</TableRow>
|
Delete
|
||||||
</TableFooter>
|
</Button>
|
||||||
</Table>
|
</DialogActions>
|
||||||
</TableContainer>
|
</>
|
||||||
|
)}
|
||||||
|
</Dialog>
|
||||||
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user