github.com/wfusion/gofusion@v1.1.14/common/infra/asynq/asynqmon/ui/src/components/PendingTasksTable.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 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    archiveAllPendingTasksAsync,
    16    archivePendingTaskAsync,
    17    batchArchivePendingTasksAsync,
    18    batchDeletePendingTasksAsync,
    19    deleteAllPendingTasksAsync,
    20    deletePendingTaskAsync,
    21    listPendingTasksAsync,
    22  } from "../actions/tasksActions";
    23  import { taskDetailsPath } from "../paths";
    24  import { AppState } from "../store";
    25  import { TableColumn } from "../types/table";
    26  import { prettifyPayload, 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.pendingTasks.loading,
    33      error: state.tasks.pendingTasks.error,
    34      tasks: state.tasks.pendingTasks.data,
    35      batchActionPending: state.tasks.pendingTasks.batchActionPending,
    36      allActionPending: state.tasks.pendingTasks.allActionPending,
    37      pollInterval: state.settings.pollInterval,
    38      pageSize: state.settings.taskRowsPerPage,
    39    };
    40  }
    41  
    42  const mapDispatchToProps = {
    43    listTasks: listPendingTasksAsync,
    44    deleteTask: deletePendingTaskAsync,
    45    batchDeleteTasks: batchDeletePendingTasksAsync,
    46    deleteAllTasks: deleteAllPendingTasksAsync,
    47    archiveTask: archivePendingTaskAsync,
    48    batchArchiveTasks: batchArchivePendingTasksAsync,
    49    archiveAllTasks: archiveAllPendingTasksAsync,
    50    taskRowsPerPageChange,
    51  };
    52  
    53  const connector = connect(mapStateToProps, mapDispatchToProps);
    54  
    55  type ReduxProps = ConnectedProps<typeof connector>;
    56  
    57  interface Props {
    58    queue: string;
    59    totalTaskCount: number; // total number of pending tasks
    60  }
    61  
    62  const columns: TableColumn[] = [
    63    { key: "id", label: "ID", align: "left" },
    64    { key: "type", label: "Type", align: "left" },
    65    { key: "paylod", label: "Payload", align: "left" },
    66    { key: "retried", label: "Retried", align: "right" },
    67    { key: "max_retry", label: "Max Retry", align: "right" },
    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 align="right">{task.retried}</TableCell>
   121        <TableCell align="right">{task.max_retry}</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                    onClick={props.onDeleteClick}
   135                    disabled={task.requestPending || props.allActionPending}
   136                    size="small"
   137                    className={classes.actionButton}
   138                  >
   139                    <DeleteIcon fontSize="small" />
   140                  </IconButton>
   141                </Tooltip>
   142                <Tooltip title="Archive">
   143                  <IconButton
   144                    onClick={props.onArchiveClick}
   145                    disabled={task.requestPending || props.allActionPending}
   146                    size="small"
   147                    className={classes.actionButton}
   148                  >
   149                    <ArchiveIcon 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 PendingTasksTable(props: Props & ReduxProps) {
   165    return (
   166      <TasksTable
   167        taskState="pending"
   168        columns={columns}
   169        renderRow={(rowProps: RowProps) => <Row {...rowProps} />}
   170        {...props}
   171      />
   172    );
   173  }
   174  
   175  export default connector(PendingTasksTable);