github.com/wfusion/gofusion@v1.1.14/common/infra/asynq/asynqmon/ui/src/components/ActiveTasksTable.tsx (about) 1 import Checkbox from "@material-ui/core/Checkbox"; 2 import IconButton from "@material-ui/core/IconButton"; 3 import TableCell from "@material-ui/core/TableCell"; 4 import TableRow from "@material-ui/core/TableRow"; 5 import Tooltip from "@material-ui/core/Tooltip"; 6 import CancelIcon from "@material-ui/icons/Cancel"; 7 import FileCopyOutlinedIcon from "@material-ui/icons/FileCopyOutlined"; 8 import MoreHorizIcon from "@material-ui/icons/MoreHoriz"; 9 import React from "react"; 10 import { connect, ConnectedProps } from "react-redux"; 11 import { useHistory } from "react-router-dom"; 12 import { taskRowsPerPageChange } from "../actions/settingsActions"; 13 import { 14 batchCancelActiveTasksAsync, 15 cancelActiveTaskAsync, 16 cancelAllActiveTasksAsync, 17 listActiveTasksAsync, 18 } from "../actions/tasksActions"; 19 import { taskDetailsPath } from "../paths"; 20 import { AppState } from "../store"; 21 import { TableColumn } from "../types/table"; 22 import { durationBefore, prettifyPayload, timeAgo, uuidPrefix } from "../utils"; 23 import SyntaxHighlighter from "./SyntaxHighlighter"; 24 import TasksTable, { RowProps, useRowStyles } from "./TasksTable"; 25 26 function mapStateToProps(state: AppState) { 27 return { 28 loading: state.tasks.activeTasks.loading, 29 error: state.tasks.activeTasks.error, 30 tasks: state.tasks.activeTasks.data, 31 batchActionPending: state.tasks.activeTasks.batchActionPending, 32 allActionPending: state.tasks.activeTasks.allActionPending, 33 pollInterval: state.settings.pollInterval, 34 pageSize: state.settings.taskRowsPerPage, 35 }; 36 } 37 38 const mapDispatchToProps = { 39 listTasks: listActiveTasksAsync, 40 cancelTask: cancelActiveTaskAsync, 41 batchCancelTasks: batchCancelActiveTasksAsync, 42 cancelAllTasks: cancelAllActiveTasksAsync, 43 taskRowsPerPageChange, 44 }; 45 46 const columns: TableColumn[] = [ 47 { key: "id", label: "ID", align: "left" }, 48 { key: "type", label: "Type", align: "left" }, 49 { key: "payload", label: "Payload", align: "left" }, 50 { key: "status", label: "Status", align: "left" }, 51 { key: "start-time", label: "Started", align: "left" }, 52 { key: "deadline", label: "Deadline", align: "left" }, 53 { key: "actions", label: "Actions", align: "center" }, 54 ]; 55 56 const connector = connect(mapStateToProps, mapDispatchToProps); 57 58 type ReduxProps = ConnectedProps<typeof connector>; 59 60 interface Props { 61 queue: string; // name of the queue 62 totalTaskCount: number; // total number of active tasks 63 } 64 65 function Row(props: RowProps) { 66 const { task } = props; 67 const classes = useRowStyles(); 68 const history = useHistory(); 69 return ( 70 <TableRow 71 key={task.id} 72 className={classes.root} 73 selected={props.isSelected} 74 onClick={() => history.push(taskDetailsPath(task.queue, task.id))} 75 > 76 {!window.READ_ONLY && ( 77 <TableCell padding="checkbox" onClick={(e) => e.stopPropagation()}> 78 <IconButton> 79 <Checkbox 80 onChange={(event: React.ChangeEvent<HTMLInputElement>) => 81 props.onSelectChange(event.target.checked) 82 } 83 checked={props.isSelected} 84 /> 85 </IconButton> 86 </TableCell> 87 )} 88 <TableCell component="th" scope="row" className={classes.idCell}> 89 <div className={classes.IdGroup}> 90 {uuidPrefix(task.id)} 91 <Tooltip title="Copy full ID to clipboard"> 92 <IconButton 93 onClick={(e) => { 94 e.stopPropagation(); 95 navigator.clipboard.writeText(task.id); 96 }} 97 size="small" 98 className={classes.copyButton} 99 > 100 <FileCopyOutlinedIcon fontSize="small" /> 101 </IconButton> 102 </Tooltip> 103 </div> 104 </TableCell> 105 <TableCell>{task.type}</TableCell> 106 <TableCell> 107 <SyntaxHighlighter 108 language="json" 109 customStyle={{ margin: 0, maxWidth: 400 }} 110 > 111 {prettifyPayload(task.payload)} 112 </SyntaxHighlighter> 113 </TableCell> 114 <TableCell> 115 {task.canceling 116 ? "Canceling" 117 : task.is_orphaned 118 ? "Orphaned" 119 : "Running"} 120 </TableCell> 121 <TableCell> 122 {task.is_orphaned 123 ? "-" 124 : task.start_time === "-" 125 ? "just now" 126 : timeAgo(task.start_time)} 127 </TableCell> 128 <TableCell> 129 {task.deadline === "-" ? "-" : durationBefore(task.deadline)} 130 </TableCell> 131 {!window.READ_ONLY && ( 132 <TableCell 133 align="center" 134 onMouseEnter={props.onActionCellEnter} 135 onMouseLeave={props.onActionCellLeave} 136 onClick={(e) => e.stopPropagation()} 137 > 138 {props.showActions ? ( 139 <React.Fragment> 140 <Tooltip title="Cancel"> 141 <IconButton 142 onClick={props.onCancelClick} 143 disabled={ 144 task.requestPending || task.canceling || task.is_orphaned 145 } 146 size="small" 147 > 148 <CancelIcon fontSize="small" /> 149 </IconButton> 150 </Tooltip> 151 </React.Fragment> 152 ) : ( 153 <IconButton size="small" onClick={props.onActionCellEnter}> 154 <MoreHorizIcon fontSize="small" /> 155 </IconButton> 156 )} 157 </TableCell> 158 )} 159 </TableRow> 160 ); 161 } 162 163 function ActiveTasksTable(props: Props & ReduxProps) { 164 return ( 165 <TasksTable 166 taskState="active" 167 columns={columns} 168 renderRow={(rowProps: RowProps) => <Row {...rowProps} />} 169 {...props} 170 /> 171 ); 172 } 173 174 export default connector(ActiveTasksTable);