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);