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