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