github.com/wfusion/gofusion@v1.1.14/common/infra/asynq/asynqmon/ui/src/components/RetryTasksTable.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 ArchiveIcon from "@material-ui/icons/Archive"; 7 import DeleteIcon from "@material-ui/icons/Delete"; 8 import FileCopyOutlinedIcon from "@material-ui/icons/FileCopyOutlined"; 9 import MoreHorizIcon from "@material-ui/icons/MoreHoriz"; 10 import PlayArrowIcon from "@material-ui/icons/PlayArrow"; 11 import React from "react"; 12 import { connect, ConnectedProps } from "react-redux"; 13 import { useHistory } from "react-router-dom"; 14 import { taskRowsPerPageChange } from "../actions/settingsActions"; 15 import { 16 archiveAllRetryTasksAsync, 17 archiveRetryTaskAsync, 18 batchArchiveRetryTasksAsync, 19 batchDeleteRetryTasksAsync, 20 batchRunRetryTasksAsync, 21 deleteAllRetryTasksAsync, 22 deleteRetryTaskAsync, 23 listRetryTasksAsync, 24 runAllRetryTasksAsync, 25 runRetryTaskAsync, 26 } from "../actions/tasksActions"; 27 import TasksTable, { RowProps, useRowStyles } from "./TasksTable"; 28 import { taskDetailsPath } from "../paths"; 29 import { AppState } from "../store"; 30 import { TableColumn } from "../types/table"; 31 import { durationBefore, prettifyPayload, uuidPrefix } from "../utils"; 32 import SyntaxHighlighter from "./SyntaxHighlighter"; 33 34 function mapStateToProps(state: AppState) { 35 return { 36 loading: state.tasks.retryTasks.loading, 37 error: state.tasks.retryTasks.error, 38 tasks: state.tasks.retryTasks.data, 39 batchActionPending: state.tasks.retryTasks.batchActionPending, 40 allActionPending: state.tasks.retryTasks.allActionPending, 41 pollInterval: state.settings.pollInterval, 42 pageSize: state.settings.taskRowsPerPage, 43 }; 44 } 45 46 const mapDispatchToProps = { 47 batchDeleteTasks: batchDeleteRetryTasksAsync, 48 batchRunTasks: batchRunRetryTasksAsync, 49 batchArchiveTasks: batchArchiveRetryTasksAsync, 50 deleteAllTasks: deleteAllRetryTasksAsync, 51 runAllTasks: runAllRetryTasksAsync, 52 archiveAllTasks: archiveAllRetryTasksAsync, 53 listTasks: listRetryTasksAsync, 54 deleteTask: deleteRetryTaskAsync, 55 runTask: runRetryTaskAsync, 56 archiveTask: archiveRetryTaskAsync, 57 taskRowsPerPageChange, 58 }; 59 60 const connector = connect(mapStateToProps, mapDispatchToProps); 61 62 type ReduxProps = ConnectedProps<typeof connector>; 63 64 interface Props { 65 queue: string; // name of the queue. 66 totalTaskCount: number; // totoal number of scheduled tasks. 67 } 68 69 const columns: TableColumn[] = [ 70 { key: "id", label: "ID", align: "left" }, 71 { key: "type", label: "Type", align: "left" }, 72 { key: "payload", label: "Payload", align: "left" }, 73 { key: "retry_in", label: "Retry In", align: "left" }, 74 { key: "last_error", label: "Last Error", align: "left" }, 75 { key: "retried", label: "Retried", align: "right" }, 76 { key: "max_retry", label: "Max Retry", align: "right" }, 77 { key: "actions", label: "Actions", align: "center" }, 78 ]; 79 80 function Row(props: RowProps) { 81 const { task } = props; 82 const classes = useRowStyles(); 83 const history = useHistory(); 84 85 return ( 86 <TableRow 87 key={task.id} 88 className={classes.root} 89 selected={props.isSelected} 90 onClick={() => history.push(taskDetailsPath(task.queue, task.id))} 91 > 92 {!window.READ_ONLY && ( 93 <TableCell padding="checkbox" onClick={(e) => e.stopPropagation()}> 94 <IconButton> 95 <Checkbox 96 onChange={(event: React.ChangeEvent<HTMLInputElement>) => 97 props.onSelectChange(event.target.checked) 98 } 99 checked={props.isSelected} 100 /> 101 </IconButton> 102 </TableCell> 103 )} 104 <TableCell component="th" scope="row" className={classes.idCell}> 105 <div className={classes.IdGroup}> 106 {uuidPrefix(task.id)} 107 <Tooltip title="Copy full ID to clipboard"> 108 <IconButton 109 onClick={(e) => { 110 e.stopPropagation(); 111 navigator.clipboard.writeText(task.id); 112 }} 113 size="small" 114 className={classes.copyButton} 115 > 116 <FileCopyOutlinedIcon fontSize="small" /> 117 </IconButton> 118 </Tooltip> 119 </div> 120 </TableCell> 121 <TableCell>{task.type}</TableCell> 122 <TableCell> 123 <SyntaxHighlighter 124 language="json" 125 customStyle={{ margin: 0, maxWidth: 400 }} 126 > 127 {prettifyPayload(task.payload)} 128 </SyntaxHighlighter> 129 </TableCell> 130 <TableCell>{durationBefore(task.next_process_at)}</TableCell> 131 <TableCell>{task.error_message}</TableCell> 132 <TableCell align="right">{task.retried}</TableCell> 133 <TableCell align="right">{task.max_retry}</TableCell> 134 {!window.READ_ONLY && ( 135 <TableCell 136 align="center" 137 className={classes.actionCell} 138 onMouseEnter={props.onActionCellEnter} 139 onMouseLeave={props.onActionCellLeave} 140 onClick={(e) => e.stopPropagation()} 141 > 142 {props.showActions ? ( 143 <React.Fragment> 144 <Tooltip title="Delete"> 145 <IconButton 146 onClick={props.onDeleteClick} 147 disabled={task.requestPending || props.allActionPending} 148 size="small" 149 className={classes.actionButton} 150 > 151 <DeleteIcon fontSize="small" /> 152 </IconButton> 153 </Tooltip> 154 <Tooltip title="Archive"> 155 <IconButton 156 onClick={props.onArchiveClick} 157 disabled={task.requestPending || props.allActionPending} 158 size="small" 159 className={classes.actionButton} 160 > 161 <ArchiveIcon fontSize="small" /> 162 </IconButton> 163 </Tooltip> 164 <Tooltip title="Run"> 165 <IconButton 166 onClick={props.onRunClick} 167 disabled={task.requestPending || props.allActionPending} 168 size="small" 169 className={classes.actionButton} 170 > 171 <PlayArrowIcon fontSize="small" /> 172 </IconButton> 173 </Tooltip> 174 </React.Fragment> 175 ) : ( 176 <IconButton size="small" onClick={props.onActionCellEnter}> 177 <MoreHorizIcon fontSize="small" /> 178 </IconButton> 179 )} 180 </TableCell> 181 )} 182 </TableRow> 183 ); 184 } 185 186 function RetryTasksTable(props: Props & ReduxProps) { 187 return ( 188 <TasksTable 189 taskState="retry" 190 columns={columns} 191 renderRow={(rowProps: RowProps) => <Row {...rowProps} />} 192 {...props} 193 /> 194 ); 195 } 196 197 export default connector(RetryTasksTable);