From edd39d47e7a7d67b928ae3f91b33de1edc5cfaa4 Mon Sep 17 00:00:00 2001 From: Ken Hibino Date: Fri, 1 Jan 2021 06:47:42 -0800 Subject: [PATCH] Refine ServersTable component --- ui/src/components/ServersTable.tsx | 211 +++++++++++++++++++++++++---- 1 file changed, 182 insertions(+), 29 deletions(-) diff --git a/ui/src/components/ServersTable.tsx b/ui/src/components/ServersTable.tsx index d04dafe..5300ff0 100644 --- a/ui/src/components/ServersTable.tsx +++ b/ui/src/components/ServersTable.tsx @@ -1,6 +1,11 @@ import React, { useState } from "react"; +import { Link } from "react-router-dom"; import clsx from "clsx"; import { makeStyles } from "@material-ui/core/styles"; +import Grid from "@material-ui/core/Grid"; +import Box from "@material-ui/core/Box"; +import Collapse from "@material-ui/core/Collapse"; +import IconButton from "@material-ui/core/IconButton"; import Table from "@material-ui/core/Table"; import TableBody from "@material-ui/core/TableBody"; import TableCell from "@material-ui/core/TableCell"; @@ -8,11 +13,18 @@ import TableContainer from "@material-ui/core/TableContainer"; import TableHead from "@material-ui/core/TableHead"; import TableRow from "@material-ui/core/TableRow"; import TableSortLabel from "@material-ui/core/TableSortLabel"; +import Tooltip from "@material-ui/core/Tooltip"; +import KeyboardArrowDownIcon from "@material-ui/icons/KeyboardArrowDown"; +import KeyboardArrowUpIcon from "@material-ui/icons/KeyboardArrowUp"; import Alert from "@material-ui/lab/Alert"; import AlertTitle from "@material-ui/lab/AlertTitle"; +import SyntaxHighlighter from "react-syntax-highlighter"; +import syntaxHighlightStyle from "react-syntax-highlighter/dist/esm/styles/hljs/github"; import { ServerInfo } from "../api"; import { SortDirection, SortableTableColumn } from "../types/table"; -import { timeAgo } from "../utils"; +import { timeAgo, uuidPrefix } from "../utils"; +import { queueDetailsPath } from "../paths"; +import Typography from "@material-ui/core/Typography"; const useStyles = makeStyles((theme) => ({ table: { @@ -27,8 +39,7 @@ const useStyles = makeStyles((theme) => ({ })); enum SortBy { - Host, - PID, + HostPID, Status, ActiveWorkers, Queues, @@ -36,15 +47,15 @@ enum SortBy { } const colConfigs: SortableTableColumn[] = [ { - label: "Host", + label: "Host:PID", key: "host", - sortBy: SortBy.Host, + sortBy: SortBy.HostPID, align: "left", }, { - label: "PID", - key: "pid", - sortBy: SortBy.PID, + label: "Started", + key: "started", + sortBy: SortBy.Started, align: "left", }, { @@ -53,12 +64,6 @@ const colConfigs: SortableTableColumn[] = [ sortBy: SortBy.Status, align: "left", }, - { - label: "Active Workers", - key: "workers", - sortBy: SortBy.ActiveWorkers, - align: "left", - }, { label: "Queues", key: "queues", @@ -66,9 +71,9 @@ const colConfigs: SortableTableColumn[] = [ align: "left", }, { - label: "Started", - key: "started", - sortBy: SortBy.Started, + label: "Active Workers", + key: "workers", + sortBy: SortBy.ActiveWorkers, align: "left", }, ]; @@ -90,7 +95,7 @@ interface Props { export default function ServersTable(props: Props) { const classes = useStyles(); - const [sortBy, setSortBy] = useState(SortBy.Host); + const [sortBy, setSortBy] = useState(SortBy.HostPID); const [sortDir, setSortDir] = useState(SortDirection.Asc); const createSortClickHandler = (sortKey: SortBy) => (e: React.MouseEvent) => { @@ -106,7 +111,47 @@ export default function ServersTable(props: Props) { }; const cmpFunc = (s1: ServerInfo, s2: ServerInfo): number => { - return 0; // TODO: implement this + let isS1Smaller = false; + switch (sortBy) { + case SortBy.HostPID: + if (s1.host === s2.host && s1.pid === s2.pid) return 0; + if (s1.host === s2.host) { + isS1Smaller = s1.pid < s2.pid; + } else { + isS1Smaller = s1.host < s2.host; + } + break; + case SortBy.Started: + const s1StartTime = Date.parse(s1.start_time); + const s2StartTime = Date.parse(s2.start_time); + if (s1StartTime === s2StartTime) return 0; + isS1Smaller = s1StartTime < s2StartTime; + break; + case SortBy.Status: + if (s1.status === s2.status) return 0; + isS1Smaller = s1.status < s2.status; + break; + case SortBy.Queues: + const s1Queues = Object.keys(s1.queue_priorities).join(","); + const s2Queues = Object.keys(s2.queue_priorities).join(","); + if (s1Queues === s2Queues) return 0; + isS1Smaller = s1Queues < s2Queues; + break; + case SortBy.ActiveWorkers: + if (s1.active_workers.length === s2.active_workers.length) { + return 0; + } + isS1Smaller = s1.active_workers.length < s2.active_workers.length; + break; + default: + // eslint-disable-next-line no-throw-literal + throw `Unexpected order by value: ${sortBy}`; + } + if (sortDir === SortDirection.Asc) { + return isS1Smaller ? -1 : 1; + } else { + return isS1Smaller ? 1 : -1; + } }; if (props.servers.length === 0) { @@ -138,6 +183,7 @@ export default function ServersTable(props: Props) { ))} + @@ -167,16 +213,123 @@ const useRowStyles = makeStyles((theme) => ({ function Row(props: RowProps) { const classes = useRowStyles(); const { server } = props; + const [open, setOpen] = useState(false); + const qnames = Object.keys(server.queue_priorities); return ( - - {server.host} - {server.pid} - {server.status} - - {server.active_workers.length}/{server.concurrency} - - {JSON.stringify(server.queue_priorities)} - {timeAgo(server.start_time)} - + + + + {server.host}:{server.pid} + + {timeAgo(server.start_time)} + {server.status} + + {qnames.map((qname, idx) => ( + + {qname} + {idx === qnames.length - 1 ? "" : ", "} + + ))} + + + {server.active_workers.length}/{server.concurrency} + + + + setOpen(!open)} + > + {open ? : } + + + + + + + + + + + Active Workers + + + + + Task ID + Task Payload + Queue + Started + + + + {server.active_workers.map((worker) => ( + + + {uuidPrefix(worker.task.id)} + + + + {JSON.stringify(worker.task.payload)} + + + {worker.task.queue} + {timeAgo(worker.start_time)} + + ))} + +
+
+ + + Queue Priority + + + + + Queue + Priority + + + + {qnames.map((qname) => ( + + + {qname} + + + {server.queue_priorities[qname]} + + + ))} + +
+ + + Strict Priority:{" "} + + + {server.strict_priority_enabled ? "ON" : "OFF"} + + +
+
+
+
+
+
); }